From 1edc7549991028a2909fea1e11830d9b9dd5a5b9 Mon Sep 17 00:00:00 2001 From: triepod-ai Date: Mon, 29 Dec 2025 13:25:24 -0600 Subject: [PATCH] feat: Add MCP tool annotations for improved LLM integration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ToolAnnotations to all 11 tools with appropriate hints: - readOnlyHint: true for all tools (data retrieval only) - destructiveHint: false for all tools (no data modification) - openWorldHint: true for all tools (external Financial Datasets API) - title: Human-readable tool names for UI display Also upgrades mcp[cli] from 1.3.0 to 1.8.0 (required for annotations support). Tool annotations help LLM clients understand tool behavior and make better decisions about tool selection and user confirmations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- pyproject.toml | 2 +- server.py | 100 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 90 insertions(+), 12 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9aa3f2c..ee5ab80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,6 @@ readme = "README.md" requires-python = ">=3.11" dependencies = [ "httpx>=0.28.1", - "mcp[cli]>=1.3.0", + "mcp[cli]>=1.8.0", "python-dotenv>=1.0.0", ] diff --git a/server.py b/server.py index b605551..3cb74c6 100644 --- a/server.py +++ b/server.py @@ -4,6 +4,7 @@ import logging import sys from mcp.server.fastmcp import FastMCP +from mcp.types import ToolAnnotations from dotenv import load_dotenv # Configure logging to write to stderr @@ -40,7 +41,14 @@ async def make_request(url: str) -> dict[str, any] | None: return {"Error": str(e)} -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get Income Statements", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_income_statements( ticker: str, period: str = "annual", @@ -72,7 +80,14 @@ async def get_income_statements( return json.dumps(income_statements, indent=2) -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get Balance Sheets", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_balance_sheets( ticker: str, period: str = "annual", @@ -104,7 +119,14 @@ async def get_balance_sheets( return json.dumps(balance_sheets, indent=2) -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get Cash Flow Statements", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_cash_flow_statements( ticker: str, period: str = "annual", @@ -136,7 +158,14 @@ async def get_cash_flow_statements( return json.dumps(cash_flow_statements, indent=2) -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get Current Stock Price", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_current_stock_price(ticker: str) -> str: """Get the current / latest price of a company. @@ -162,7 +191,14 @@ async def get_current_stock_price(ticker: str) -> str: return json.dumps(snapshot, indent=2) -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get Historical Stock Prices", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_historical_stock_prices( ticker: str, start_date: str, @@ -198,7 +234,14 @@ async def get_historical_stock_prices( return json.dumps(prices, indent=2) -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get Company News", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_company_news(ticker: str) -> str: """Get news for a company. @@ -222,7 +265,14 @@ async def get_company_news(ticker: str) -> str: return json.dumps(news, indent=2) -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get Available Crypto Tickers", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_available_crypto_tickers() -> str: """ Gets all available crypto tickers. @@ -242,7 +292,14 @@ async def get_available_crypto_tickers() -> str: return json.dumps(tickers, indent=2) -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get Crypto Prices", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_crypto_prices( ticker: str, start_date: str, @@ -272,7 +329,14 @@ async def get_crypto_prices( return json.dumps(prices, indent=2) -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get Historical Crypto Prices", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_historical_crypto_prices( ticker: str, start_date: str, @@ -308,7 +372,14 @@ async def get_historical_crypto_prices( return json.dumps(prices, indent=2) -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get Current Crypto Price", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_current_crypto_price(ticker: str) -> str: """Get the current / latest price of a crypto currency. @@ -334,7 +405,14 @@ async def get_current_crypto_price(ticker: str) -> str: return json.dumps(snapshot, indent=2) -@mcp.tool() +@mcp.tool( + annotations=ToolAnnotations( + title="Get SEC Filings", + readOnlyHint=True, + destructiveHint=False, + openWorldHint=True, + ) +) async def get_sec_filings( ticker: str, limit: int = 10,