# Directory Structure ``` ├── .github │ └── workflows │ └── ci.yml ├── .gitignore ├── .python-version ├── assets │ ├── polygon_banner_darkmode.png │ └── polygon_banner_lightmode.png ├── docker-compose.yml ├── Dockerfile ├── entrypoint.py ├── glama.json ├── justfile ├── LICENSE ├── manifest.json ├── pyproject.toml ├── README.md ├── src │ └── mcp_polygon │ ├── __init__.py │ └── server.py └── uv.lock ``` # Files -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- ``` 1 | 3.13 2 | ``` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- ``` 1 | # Python-generated files 2 | __pycache__/ 3 | *.py[oc] 4 | build/ 5 | dist/ 6 | wheels/ 7 | *.egg-info 8 | .ruff-cache/ 9 | 10 | # Virtual environments 11 | .venv 12 | .env 13 | venv/ 14 | env/ 15 | ENV/ 16 | .python-version 17 | 18 | # IDE-specific files 19 | .idea/ 20 | .vscode/ 21 | *.swp 22 | *.swo 23 | 24 | # OS-specific files 25 | .DS_Store 26 | Thumbs.db 27 | 28 | # Environment and secrets 29 | .env.local 30 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- ```markdown 1 | <a href="https://polygon.io"> 2 | <div align="center"> 3 | <picture> 4 | <source media="(prefers-color-scheme: light)" srcset="assets/polygon_banner_lightmode.png"> 5 | <source media="(prefers-color-scheme: dark)" srcset="assets/polygon_banner_darkmode.png"> 6 | <img alt="Polygon.io logo" src="assets/polygon_banner_lightmode.png" height="100"> 7 | </picture> 8 | </div> 9 | </a> 10 | <br> 11 | 12 | > [!IMPORTANT] 13 | > :test_tube: This project is experimental and could be subject to breaking changes. 14 | 15 | # Polygon.io MCP Server 16 | 17 | [](https://github.com/polygon-io/mcp_polygon/releases) 18 | 19 | A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that provides access to [Polygon.io](https://polygon.io?utm_campaign=mcp&utm_medium=referral&utm_source=github) financial market data API through an LLM-friendly interface. 20 | 21 | ## Overview 22 | 23 | This server exposes all Polygon.io API endpoints as MCP tools, providing access to comprehensive financial market data including: 24 | 25 | - Stock, options, forex, and crypto aggregates and bars 26 | - Real-time and historical trades and quotes 27 | - Market snapshots 28 | - Ticker details and reference data 29 | - Dividends and splits data 30 | - Financial fundamentals 31 | - Market status and holidays 32 | 33 | ## Installation 34 | 35 | ### Prerequisites 36 | 37 | - Python 3.10+ 38 | - A Polygon.io API key <br> [![Button]][Link] 39 | - [Astral UV](https://docs.astral.sh/uv/getting-started/installation/) 40 | - For existing installs, check that you have a version that supports the `uvx` command. 41 | 42 | ### Claude Code 43 | First, install [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview) 44 | 45 | ```bash 46 | npm install -g @anthropic-ai/claude-code 47 | ``` 48 | 49 | Use the following command to add the Polygon MCP server to your local environment. 50 | This assumes `uvx` is in your $PATH; if not, then you need to provide the full 51 | path to `uvx`. 52 | 53 | ```bash 54 | # Claude CLI 55 | claude mcp add polygon -e POLYGON_API_KEY=your_api_key_here -- uvx --from git+https://github.com/polygon-io/[email protected] mcp_polygon 56 | ``` 57 | 58 | This command will install the MCP server in your current project. 59 | If you want to install it globally, you can run the command with `-s <scope>` flag. 60 | See `claude mcp add --help` for more options. 61 | 62 | To start Claude Code, run `claude` in your terminal. 63 | - If this is your first time using, follow the setup prompts to authenticate 64 | 65 | You can also run `claude mcp add-from-claude-desktop` if the MCP server is installed already for Claude Desktop. 66 | 67 | ### Claude Desktop 68 | 69 | 1. Follow the [Claude Desktop MCP installation instructions](https://modelcontextprotocol.io/quickstart/user) to complete the initial installation and find your configuration file. 70 | 1. Use the following example as reference to add Polygon's MCP server. 71 | Make sure you complete the various fields. 72 | 1. Path find your path to `uvx`, run `which uvx` in your terminal. 73 | 2. Replace `<your_api_key_here>` with your actual Polygon.io API key. 74 | 3. Replace `<your_home_directory>` with your home directory path, e.g., `/home/username` (Mac/Linux) or `C:\Users\username` (Windows). 75 | 76 | <details> 77 | <summary>claude_desktop_config.json</summary> 78 | 79 | ```json 80 | { 81 | "mcpServers": { 82 | "polygon": { 83 | "command": "<path_to_your_uvx_install>/uvx", 84 | "args": [ 85 | "--from", 86 | "git+https://github.com/polygon-io/[email protected]", 87 | "mcp_polygon" 88 | ], 89 | "env": { 90 | "POLYGON_API_KEY": "<your_api_key_here>", 91 | "HOME": "<your_home_directory>" 92 | } 93 | } 94 | } 95 | } 96 | ``` 97 | </details> 98 | 99 | ## Transport Configuration 100 | 101 | By default, STDIO transport is used. 102 | 103 | To configure [SSE](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports#http-with-sse) or [Streamable HTTP](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http), set the `MCP_TRANSPORT` environment variable. 104 | 105 | Example: 106 | 107 | ```bash 108 | MCP_TRANSPORT=streamable-http \ 109 | POLYGON_API_KEY=<your_api_key_here> \ 110 | uv run entrypoint.py 111 | ``` 112 | 113 | ## Usage Examples 114 | 115 | Once integrated, you can prompt Claude to access Polygon.io data: 116 | 117 | ``` 118 | Get the latest price for AAPL stock 119 | Show me yesterday's trading volume for MSFT 120 | What were the biggest stock market gainers today? 121 | Get me the latest crypto market data for BTC-USD 122 | ``` 123 | 124 | ## Available Tools 125 | 126 | This MCP server implements all Polygon.io API endpoints as tools, including: 127 | 128 | - `get_aggs` - Stock aggregates (OHLC) data for a specific ticker 129 | - `list_trades` - Historical trade data 130 | - `get_last_trade` - Latest trade for a symbol 131 | - `list_ticker_news` - Recent news articles for tickers 132 | - `get_snapshot_ticker` - Current market snapshot for a ticker 133 | - `get_market_status` - Current market status and trading hours 134 | - `list_stock_financials` - Fundamental financial data 135 | - And many more... 136 | 137 | Each tool follows the Polygon.io SDK parameter structure while converting responses to standard JSON that LLMs can easily process. 138 | 139 | ## Development 140 | 141 | ### Running Locally 142 | 143 | Check to ensure you have the [Prerequisites](#prerequisites) installed. 144 | 145 | ```bash 146 | # Sync dependencies 147 | uv sync 148 | 149 | # Run the server 150 | POLYGON_API_KEY=your_api_key_here uv run mcp_polygon 151 | ``` 152 | 153 | <details> 154 | <summary>Local Dev Config for claude_desktop_config.json</summary> 155 | 156 | ```json 157 | 158 | "mcpServers": { 159 | "polygon": { 160 | "command": "/your/path/.cargo/bin/uv", 161 | "args": [ 162 | "run", 163 | "--with", 164 | "/your/path/mcp_polygon", 165 | "mcp_polygon" 166 | ], 167 | "env": { 168 | "POLYGON_API_KEY": "your_api_key_here", 169 | "HOME": "/Users/danny" 170 | } 171 | } 172 | } 173 | ``` 174 | </details> 175 | 176 | ### Debugging 177 | 178 | For debugging and testing, we recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector): 179 | 180 | ```bash 181 | npx @modelcontextprotocol/inspector uv --directory /path/to/mcp_polygon run mcp_polygon 182 | ``` 183 | 184 | This will launch a browser interface where you can interact with your MCP server directly and see input/output for each tool. 185 | 186 | ### Code Linting 187 | 188 | This project uses [just](https://github.com/casey/just) for common development tasks. To lint your code before submitting a PR: 189 | 190 | ```bash 191 | just lint 192 | ``` 193 | 194 | This will run `ruff format` and `ruff check --fix` to automatically format your code and fix linting issues. 195 | 196 | ## Links 197 | - [Polygon.io Documentation](https://polygon.io/docs?utm_campaign=mcp&utm_medium=referral&utm_source=github) 198 | - [Model Context Protocol](https://modelcontextprotocol.io) 199 | - [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) 200 | 201 | ## Privacy Policy 202 | 203 | This MCP server interacts with Polygon.io's API to fetch market data. All data requests are subject to Polygon.io's privacy policy and terms of service. 204 | 205 | - **Polygon.io Privacy Policy**: https://polygon.io/legal/privacy 206 | - **Data Handling**: This server does not store or cache any user data. All requests are proxied directly to Polygon.io's API. 207 | - **API Key**: Your Polygon.io API key is used only for authenticating requests to their API. 208 | 209 | ## Contributing 210 | If you found a bug or have an idea for a new feature, please first discuss it with us by submitting a new issue. 211 | We will respond to issues within at most 3 weeks. 212 | We're also open to volunteers if you want to submit a PR for any open issues but please discuss it with us beforehand. 213 | PRs that aren't linked to an existing issue or discussed with us ahead of time will generally be declined. 214 | 215 | <!-----------------------------------------------------------------------------> 216 | [Link]: https://polygon.io/?utm_campaign=mcp&utm_medium=referral&utm_source=github 'Polygon.io Home Page' 217 | <!---------------------------------[ Buttons ]---------------------------------> 218 | [Button]: https://img.shields.io/badge/Get_One_For_Free-5F5CFF?style=for-the-badge&logoColor=white 219 | ``` -------------------------------------------------------------------------------- /src/mcp_polygon/__init__.py: -------------------------------------------------------------------------------- ```python 1 | from .server import run 2 | 3 | __all__ = ["run"] 4 | ``` -------------------------------------------------------------------------------- /glama.json: -------------------------------------------------------------------------------- ```json 1 | { 2 | "$schema": "https://glama.ai/mcp/schemas/server.json", 3 | "maintainers": [ 4 | "DanStough", 5 | "joedursun", 6 | "penelopus", 7 | "qrpike" 8 | ] 9 | } 10 | ``` -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- ```yaml 1 | services: 2 | mcp_polygon: 3 | build: . 4 | volumes: 5 | - .:/app 6 | container_name: mcp_polygon_server 7 | environment: 8 | - POLYGON_API_KEY=${POLYGON_API_KEY} 9 | stdin_open: true 10 | tty: true 11 | ``` -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- ```dockerfile 1 | FROM python:3.13-slim 2 | 3 | WORKDIR /app 4 | 5 | # Install uv for dependency management 6 | RUN pip install uv 7 | 8 | COPY . ./ 9 | 10 | RUN uv pip install --system -e . 11 | RUN chmod +x entrypoint.py 12 | 13 | ENV PYTHONPATH=/app/src:$PYTHONPATH 14 | 15 | ENTRYPOINT ["uv", "run", "./entrypoint.py"] 16 | ``` -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- ```toml 1 | [project] 2 | name = "mcp_polygon" 3 | version = "0.4.1" 4 | description = "A MCP server project" 5 | readme = "README.md" 6 | requires-python = ">=3.10" 7 | dependencies = [ 8 | "mcp[cli]>=1.9.3", 9 | "polygon-api-client>=1.15.3", 10 | ] 11 | [[project.authors]] 12 | name = "Polygon" 13 | email = "[email protected]" 14 | 15 | [build-system] 16 | requires = [ "hatchling",] 17 | build-backend = "hatchling.build" 18 | 19 | [dependency-groups] 20 | dev = [ 21 | "ruff>=0.12.4", 22 | ] 23 | 24 | [project.scripts] 25 | mcp_polygon = "mcp_polygon:run" 26 | ``` -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- ```yaml 1 | name: Validate Code Quality 2 | 3 | permissions: 4 | contents: read 5 | 6 | on: 7 | pull_request: 8 | branches: 9 | - 'master' 10 | 11 | jobs: 12 | lint: 13 | name: Code Quality & Testing 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: Install UV 19 | uses: astral-sh/setup-uv@v4 20 | with: 21 | enable-cache: true 22 | 23 | - name: Set up Python 24 | uses: actions/setup-python@v5 25 | with: 26 | python-version-file: "pyproject.toml" 27 | 28 | - name: Install dependencies 29 | run: uv sync 30 | 31 | - name: Run Ruff check 32 | run: uv run ruff check 33 | 34 | - name: Run Ruff format 35 | run: uv run ruff format --check 36 | ``` -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- ```json 1 | { 2 | "manifest_version": "0.2", 3 | "name": "mcp_polygon", 4 | "version": "0.4.1", 5 | "description": "MCP server providing access to Polygon.io financial market data API", 6 | "author": { 7 | "name": "Polygon.io", 8 | "email": "[email protected]", 9 | "url": "https://polygon.io" 10 | }, 11 | "privacy_policies": [ 12 | "https://polygon.io/legal/privacy" 13 | ], 14 | "server": { 15 | "type": "python", 16 | "entry_point": "mcp_polygon", 17 | "mcp_config": { 18 | "command": "uvx", 19 | "args": [ 20 | "--from", 21 | "git+https://github.com/polygon-io/mcp_polygon", 22 | "mcp_polygon" 23 | ] 24 | } 25 | }, 26 | "user_config": { 27 | "POLYGON_API_KEY": { 28 | "type": "string", 29 | "description": "Your Polygon.io API key for accessing market data", 30 | "required": true, 31 | "sensitive": true 32 | } 33 | }, 34 | "compatibility": { 35 | "python": ">=3.10" 36 | }, 37 | "repository": "https://github.com/polygon-io/mcp_polygon", 38 | "license": "MIT" 39 | } 40 | ``` -------------------------------------------------------------------------------- /entrypoint.py: -------------------------------------------------------------------------------- ```python 1 | #!/usr/bin/env python 2 | import os 3 | from typing import Literal 4 | from mcp_polygon import server 5 | 6 | 7 | def transport() -> Literal["stdio", "sse", "streamable-http"]: 8 | """ 9 | Determine the transport type for the MCP server. 10 | Defaults to 'stdio' if not set in environment variables. 11 | """ 12 | mcp_transport_str = os.environ.get("MCP_TRANSPORT", "stdio") 13 | 14 | # These are currently the only supported transports 15 | supported_transports: dict[str, Literal["stdio", "sse", "streamable-http"]] = { 16 | "stdio": "stdio", 17 | "sse": "sse", 18 | "streamable-http": "streamable-http", 19 | } 20 | 21 | return supported_transports.get(mcp_transport_str, "stdio") 22 | 23 | 24 | # Ensure the server process doesn't exit immediately when run as an MCP server 25 | def start_server(): 26 | polygon_api_key = os.environ.get("POLYGON_API_KEY", "") 27 | if not polygon_api_key: 28 | print("Warning: POLYGON_API_KEY environment variable not set.") 29 | else: 30 | print("Starting Polygon MCP server with API key configured.") 31 | 32 | server.run(transport=transport()) 33 | 34 | 35 | if __name__ == "__main__": 36 | start_server() 37 | ``` -------------------------------------------------------------------------------- /src/mcp_polygon/server.py: -------------------------------------------------------------------------------- ```python 1 | import os 2 | import json 3 | from typing import Optional, Any, Dict, Union, List, Literal 4 | from mcp.server.fastmcp import FastMCP 5 | from mcp.types import ToolAnnotations 6 | from polygon import RESTClient 7 | from importlib.metadata import version, PackageNotFoundError 8 | 9 | from datetime import datetime, date 10 | 11 | POLYGON_API_KEY = os.environ.get("POLYGON_API_KEY", "") 12 | if not POLYGON_API_KEY: 13 | print("Warning: POLYGON_API_KEY environment variable not set.") 14 | 15 | version_number = "MCP-Polygon/unknown" 16 | try: 17 | version_number = f"MCP-Polygon/{version('mcp_polygon')}" 18 | except PackageNotFoundError: 19 | pass 20 | 21 | polygon_client = RESTClient(POLYGON_API_KEY) 22 | polygon_client.headers["User-Agent"] += f" {version_number}" 23 | 24 | poly_mcp = FastMCP("Polygon", dependencies=["polygon"]) 25 | 26 | 27 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 28 | async def get_aggs( 29 | ticker: str, 30 | multiplier: int, 31 | timespan: str, 32 | from_: Union[str, int, datetime, date], 33 | to: Union[str, int, datetime, date], 34 | adjusted: Optional[bool] = None, 35 | sort: Optional[str] = None, 36 | limit: Optional[int] = None, 37 | params: Optional[Dict[str, Any]] = None, 38 | ) -> Dict[str, Any]: 39 | """ 40 | List aggregate bars for a ticker over a given date range in custom time window sizes. 41 | """ 42 | try: 43 | results = polygon_client.get_aggs( 44 | ticker=ticker, 45 | multiplier=multiplier, 46 | timespan=timespan, 47 | from_=from_, 48 | to=to, 49 | adjusted=adjusted, 50 | sort=sort, 51 | limit=limit, 52 | params=params, 53 | raw=True, 54 | ) 55 | 56 | # Parse the binary data to string and then to JSON 57 | data_str = results.data.decode("utf-8") 58 | return json.loads(data_str) 59 | except Exception as e: 60 | return {"error": str(e)} 61 | 62 | 63 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 64 | async def list_aggs( 65 | ticker: str, 66 | multiplier: int, 67 | timespan: str, 68 | from_: Union[str, int, datetime, date], 69 | to: Union[str, int, datetime, date], 70 | adjusted: Optional[bool] = None, 71 | sort: Optional[str] = None, 72 | limit: Optional[int] = None, 73 | params: Optional[Dict[str, Any]] = None, 74 | ) -> Dict[str, Any]: 75 | """ 76 | Iterate through aggregate bars for a ticker over a given date range. 77 | """ 78 | try: 79 | results = polygon_client.list_aggs( 80 | ticker=ticker, 81 | multiplier=multiplier, 82 | timespan=timespan, 83 | from_=from_, 84 | to=to, 85 | adjusted=adjusted, 86 | sort=sort, 87 | limit=limit, 88 | params=params, 89 | raw=True, 90 | ) 91 | 92 | data_str = results.data.decode("utf-8") 93 | return json.loads(data_str) 94 | except Exception as e: 95 | return {"error": str(e)} 96 | 97 | 98 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 99 | async def get_grouped_daily_aggs( 100 | date: str, 101 | adjusted: Optional[bool] = None, 102 | include_otc: Optional[bool] = None, 103 | locale: Optional[str] = None, 104 | market_type: Optional[str] = None, 105 | params: Optional[Dict[str, Any]] = None, 106 | ) -> Dict[str, Any]: 107 | """ 108 | Get grouped daily bars for entire market for a specific date. 109 | """ 110 | try: 111 | results = polygon_client.get_grouped_daily_aggs( 112 | date=date, 113 | adjusted=adjusted, 114 | include_otc=include_otc, 115 | locale=locale, 116 | market_type=market_type, 117 | params=params, 118 | raw=True, 119 | ) 120 | 121 | data_str = results.data.decode("utf-8") 122 | return json.loads(data_str) 123 | except Exception as e: 124 | return {"error": str(e)} 125 | 126 | 127 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 128 | async def get_daily_open_close_agg( 129 | ticker: str, 130 | date: str, 131 | adjusted: Optional[bool] = None, 132 | params: Optional[Dict[str, Any]] = None, 133 | ) -> Dict[str, Any]: 134 | """ 135 | Get daily open, close, high, and low for a specific ticker and date. 136 | """ 137 | try: 138 | results = polygon_client.get_daily_open_close_agg( 139 | ticker=ticker, date=date, adjusted=adjusted, params=params, raw=True 140 | ) 141 | 142 | data_str = results.data.decode("utf-8") 143 | return json.loads(data_str) 144 | except Exception as e: 145 | return {"error": str(e)} 146 | 147 | 148 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 149 | async def get_previous_close_agg( 150 | ticker: str, 151 | adjusted: Optional[bool] = None, 152 | params: Optional[Dict[str, Any]] = None, 153 | ) -> Dict[str, Any]: 154 | """ 155 | Get previous day's open, close, high, and low for a specific ticker. 156 | """ 157 | try: 158 | results = polygon_client.get_previous_close_agg( 159 | ticker=ticker, adjusted=adjusted, params=params, raw=True 160 | ) 161 | 162 | data_str = results.data.decode("utf-8") 163 | return json.loads(data_str) 164 | except Exception as e: 165 | return {"error": str(e)} 166 | 167 | 168 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 169 | async def list_trades( 170 | ticker: str, 171 | timestamp: Optional[Union[str, int, datetime, date]] = None, 172 | timestamp_lt: Optional[Union[str, int, datetime, date]] = None, 173 | timestamp_lte: Optional[Union[str, int, datetime, date]] = None, 174 | timestamp_gt: Optional[Union[str, int, datetime, date]] = None, 175 | timestamp_gte: Optional[Union[str, int, datetime, date]] = None, 176 | limit: Optional[int] = None, 177 | sort: Optional[str] = None, 178 | order: Optional[str] = None, 179 | params: Optional[Dict[str, Any]] = None, 180 | ) -> Dict[str, Any]: 181 | """ 182 | Get trades for a ticker symbol. 183 | """ 184 | try: 185 | results = polygon_client.list_trades( 186 | ticker=ticker, 187 | timestamp=timestamp, 188 | timestamp_lt=timestamp_lt, 189 | timestamp_lte=timestamp_lte, 190 | timestamp_gt=timestamp_gt, 191 | timestamp_gte=timestamp_gte, 192 | limit=limit, 193 | sort=sort, 194 | order=order, 195 | params=params, 196 | raw=True, 197 | ) 198 | 199 | data_str = results.data.decode("utf-8") 200 | return json.loads(data_str) 201 | except Exception as e: 202 | return {"error": str(e)} 203 | 204 | 205 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 206 | async def get_last_trade( 207 | ticker: str, 208 | params: Optional[Dict[str, Any]] = None, 209 | ) -> Dict[str, Any]: 210 | """ 211 | Get the most recent trade for a ticker symbol. 212 | """ 213 | try: 214 | results = polygon_client.get_last_trade(ticker=ticker, params=params, raw=True) 215 | 216 | data_str = results.data.decode("utf-8") 217 | return json.loads(data_str) 218 | except Exception as e: 219 | return {"error": str(e)} 220 | 221 | 222 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 223 | async def get_last_crypto_trade( 224 | from_: str, 225 | to: str, 226 | params: Optional[Dict[str, Any]] = None, 227 | ) -> Dict[str, Any]: 228 | """ 229 | Get the most recent trade for a crypto pair. 230 | """ 231 | try: 232 | results = polygon_client.get_last_crypto_trade( 233 | from_=from_, to=to, params=params, raw=True 234 | ) 235 | 236 | data_str = results.data.decode("utf-8") 237 | return json.loads(data_str) 238 | except Exception as e: 239 | return {"error": str(e)} 240 | 241 | 242 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 243 | async def list_quotes( 244 | ticker: str, 245 | timestamp: Optional[Union[str, int, datetime, date]] = None, 246 | timestamp_lt: Optional[Union[str, int, datetime, date]] = None, 247 | timestamp_lte: Optional[Union[str, int, datetime, date]] = None, 248 | timestamp_gt: Optional[Union[str, int, datetime, date]] = None, 249 | timestamp_gte: Optional[Union[str, int, datetime, date]] = None, 250 | limit: Optional[int] = None, 251 | sort: Optional[str] = None, 252 | order: Optional[str] = None, 253 | params: Optional[Dict[str, Any]] = None, 254 | ) -> Dict[str, Any]: 255 | """ 256 | Get quotes for a ticker symbol. 257 | """ 258 | try: 259 | results = polygon_client.list_quotes( 260 | ticker=ticker, 261 | timestamp=timestamp, 262 | timestamp_lt=timestamp_lt, 263 | timestamp_lte=timestamp_lte, 264 | timestamp_gt=timestamp_gt, 265 | timestamp_gte=timestamp_gte, 266 | limit=limit, 267 | sort=sort, 268 | order=order, 269 | params=params, 270 | raw=True, 271 | ) 272 | 273 | data_str = results.data.decode("utf-8") 274 | return json.loads(data_str) 275 | except Exception as e: 276 | return {"error": str(e)} 277 | 278 | 279 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 280 | async def get_last_quote( 281 | ticker: str, 282 | params: Optional[Dict[str, Any]] = None, 283 | ) -> Dict[str, Any]: 284 | """ 285 | Get the most recent quote for a ticker symbol. 286 | """ 287 | try: 288 | results = polygon_client.get_last_quote(ticker=ticker, params=params, raw=True) 289 | 290 | data_str = results.data.decode("utf-8") 291 | return json.loads(data_str) 292 | except Exception as e: 293 | return {"error": str(e)} 294 | 295 | 296 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 297 | async def get_last_forex_quote( 298 | from_: str, 299 | to: str, 300 | params: Optional[Dict[str, Any]] = None, 301 | ) -> Dict[str, Any]: 302 | """ 303 | Get the most recent forex quote. 304 | """ 305 | try: 306 | results = polygon_client.get_last_forex_quote( 307 | from_=from_, to=to, params=params, raw=True 308 | ) 309 | 310 | data_str = results.data.decode("utf-8") 311 | return json.loads(data_str) 312 | except Exception as e: 313 | return {"error": str(e)} 314 | 315 | 316 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 317 | async def get_real_time_currency_conversion( 318 | from_: str, 319 | to: str, 320 | amount: Optional[float] = None, 321 | precision: Optional[int] = None, 322 | params: Optional[Dict[str, Any]] = None, 323 | ) -> Dict[str, Any]: 324 | """ 325 | Get real-time currency conversion. 326 | """ 327 | try: 328 | results = polygon_client.get_real_time_currency_conversion( 329 | from_=from_, 330 | to=to, 331 | amount=amount, 332 | precision=precision, 333 | params=params, 334 | raw=True, 335 | ) 336 | 337 | data_str = results.data.decode("utf-8") 338 | return json.loads(data_str) 339 | except Exception as e: 340 | return {"error": str(e)} 341 | 342 | 343 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 344 | async def list_universal_snapshots( 345 | type: str, 346 | ticker_any_of: Optional[List[str]] = None, 347 | order: Optional[str] = None, 348 | limit: Optional[int] = None, 349 | sort: Optional[str] = None, 350 | params: Optional[Dict[str, Any]] = None, 351 | ) -> Dict[str, Any]: 352 | """ 353 | Get universal snapshots for multiple assets of a specific type. 354 | """ 355 | try: 356 | results = polygon_client.list_universal_snapshots( 357 | type=type, 358 | ticker_any_of=ticker_any_of, 359 | order=order, 360 | limit=limit, 361 | sort=sort, 362 | params=params, 363 | raw=True, 364 | ) 365 | 366 | data_str = results.data.decode("utf-8") 367 | return json.loads(data_str) 368 | except Exception as e: 369 | return {"error": str(e)} 370 | 371 | 372 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 373 | async def get_snapshot_all( 374 | market_type: str, 375 | tickers: Optional[List[str]] = None, 376 | include_otc: Optional[bool] = None, 377 | params: Optional[Dict[str, Any]] = None, 378 | ) -> Dict[str, Any]: 379 | """ 380 | Get a snapshot of all tickers in a market. 381 | """ 382 | try: 383 | results = polygon_client.get_snapshot_all( 384 | market_type=market_type, 385 | tickers=tickers, 386 | include_otc=include_otc, 387 | params=params, 388 | raw=True, 389 | ) 390 | 391 | data_str = results.data.decode("utf-8") 392 | return json.loads(data_str) 393 | except Exception as e: 394 | return {"error": str(e)} 395 | 396 | 397 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 398 | async def get_snapshot_direction( 399 | market_type: str, 400 | direction: str, 401 | include_otc: Optional[bool] = None, 402 | params: Optional[Dict[str, Any]] = None, 403 | ) -> Dict[str, Any]: 404 | """ 405 | Get gainers or losers for a market. 406 | """ 407 | try: 408 | results = polygon_client.get_snapshot_direction( 409 | market_type=market_type, 410 | direction=direction, 411 | include_otc=include_otc, 412 | params=params, 413 | raw=True, 414 | ) 415 | 416 | data_str = results.data.decode("utf-8") 417 | return json.loads(data_str) 418 | except Exception as e: 419 | return {"error": str(e)} 420 | 421 | 422 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 423 | async def get_snapshot_ticker( 424 | market_type: str, 425 | ticker: str, 426 | params: Optional[Dict[str, Any]] = None, 427 | ) -> Dict[str, Any]: 428 | """ 429 | Get snapshot for a specific ticker. 430 | """ 431 | try: 432 | results = polygon_client.get_snapshot_ticker( 433 | market_type=market_type, ticker=ticker, params=params, raw=True 434 | ) 435 | 436 | data_str = results.data.decode("utf-8") 437 | return json.loads(data_str) 438 | except Exception as e: 439 | return {"error": str(e)} 440 | 441 | 442 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 443 | async def get_snapshot_option( 444 | underlying_asset: str, 445 | option_contract: str, 446 | params: Optional[Dict[str, Any]] = None, 447 | ) -> Dict[str, Any]: 448 | """ 449 | Get snapshot for a specific option contract. 450 | """ 451 | try: 452 | results = polygon_client.get_snapshot_option( 453 | underlying_asset=underlying_asset, 454 | option_contract=option_contract, 455 | params=params, 456 | raw=True, 457 | ) 458 | 459 | data_str = results.data.decode("utf-8") 460 | return json.loads(data_str) 461 | except Exception as e: 462 | return {"error": str(e)} 463 | 464 | 465 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 466 | async def get_snapshot_crypto_book( 467 | ticker: str, 468 | params: Optional[Dict[str, Any]] = None, 469 | ) -> Dict[str, Any]: 470 | """ 471 | Get snapshot for a crypto ticker's order book. 472 | """ 473 | try: 474 | results = polygon_client.get_snapshot_crypto_book( 475 | ticker=ticker, params=params, raw=True 476 | ) 477 | 478 | data_str = results.data.decode("utf-8") 479 | return json.loads(data_str) 480 | except Exception as e: 481 | return {"error": str(e)} 482 | 483 | 484 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 485 | async def get_market_holidays( 486 | params: Optional[Dict[str, Any]] = None, 487 | ) -> Dict[str, Any]: 488 | """ 489 | Get upcoming market holidays and their open/close times. 490 | """ 491 | try: 492 | results = polygon_client.get_market_holidays(params=params, raw=True) 493 | 494 | data_str = results.data.decode("utf-8") 495 | return json.loads(data_str) 496 | except Exception as e: 497 | return {"error": str(e)} 498 | 499 | 500 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 501 | async def get_market_status( 502 | params: Optional[Dict[str, Any]] = None, 503 | ) -> Dict[str, Any]: 504 | """ 505 | Get current trading status of exchanges and financial markets. 506 | """ 507 | try: 508 | results = polygon_client.get_market_status(params=params, raw=True) 509 | 510 | data_str = results.data.decode("utf-8") 511 | return json.loads(data_str) 512 | except Exception as e: 513 | return {"error": str(e)} 514 | 515 | 516 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 517 | async def list_tickers( 518 | ticker: Optional[str] = None, 519 | type: Optional[str] = None, 520 | market: Optional[str] = None, 521 | exchange: Optional[str] = None, 522 | cusip: Optional[str] = None, 523 | cik: Optional[str] = None, 524 | date: Optional[Union[str, datetime, date]] = None, 525 | search: Optional[str] = None, 526 | active: Optional[bool] = None, 527 | sort: Optional[str] = None, 528 | order: Optional[str] = None, 529 | limit: Optional[int] = None, 530 | params: Optional[Dict[str, Any]] = None, 531 | ) -> Dict[str, Any]: 532 | """ 533 | Query supported ticker symbols across stocks, indices, forex, and crypto. 534 | """ 535 | try: 536 | results = polygon_client.list_tickers( 537 | ticker=ticker, 538 | type=type, 539 | market=market, 540 | exchange=exchange, 541 | cusip=cusip, 542 | cik=cik, 543 | date=date, 544 | search=search, 545 | active=active, 546 | sort=sort, 547 | order=order, 548 | limit=limit, 549 | params=params, 550 | raw=True, 551 | ) 552 | 553 | data_str = results.data.decode("utf-8") 554 | return json.loads(data_str) 555 | except Exception as e: 556 | return {"error": str(e)} 557 | 558 | 559 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 560 | async def get_ticker_details( 561 | ticker: str, 562 | date: Optional[Union[str, datetime, date]] = None, 563 | params: Optional[Dict[str, Any]] = None, 564 | ) -> Dict[str, Any]: 565 | """ 566 | Get detailed information about a specific ticker. 567 | """ 568 | try: 569 | results = polygon_client.get_ticker_details( 570 | ticker=ticker, date=date, params=params, raw=True 571 | ) 572 | 573 | data_str = results.data.decode("utf-8") 574 | return json.loads(data_str) 575 | except Exception as e: 576 | return {"error": str(e)} 577 | 578 | 579 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 580 | async def list_ticker_news( 581 | ticker: Optional[str] = None, 582 | published_utc: Optional[Union[str, datetime, date]] = None, 583 | limit: Optional[int] = None, 584 | sort: Optional[str] = None, 585 | order: Optional[str] = None, 586 | params: Optional[Dict[str, Any]] = None, 587 | ) -> Dict[str, Any]: 588 | """ 589 | Get recent news articles for a stock ticker. 590 | """ 591 | try: 592 | results = polygon_client.list_ticker_news( 593 | ticker=ticker, 594 | published_utc=published_utc, 595 | limit=limit, 596 | sort=sort, 597 | order=order, 598 | params=params, 599 | raw=True, 600 | ) 601 | 602 | data_str = results.data.decode("utf-8") 603 | return json.loads(data_str) 604 | except Exception as e: 605 | return {"error": str(e)} 606 | 607 | 608 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 609 | async def get_ticker_types( 610 | asset_class: Optional[str] = None, 611 | locale: Optional[str] = None, 612 | params: Optional[Dict[str, Any]] = None, 613 | ) -> Dict[str, Any]: 614 | """ 615 | List all ticker types supported by Polygon.io. 616 | """ 617 | try: 618 | results = polygon_client.get_ticker_types( 619 | asset_class=asset_class, locale=locale, params=params, raw=True 620 | ) 621 | 622 | data_str = results.data.decode("utf-8") 623 | return json.loads(data_str) 624 | except Exception as e: 625 | return {"error": str(e)} 626 | 627 | 628 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 629 | async def list_splits( 630 | ticker: Optional[str] = None, 631 | execution_date: Optional[Union[str, datetime, date]] = None, 632 | reverse_split: Optional[bool] = None, 633 | limit: Optional[int] = None, 634 | params: Optional[Dict[str, Any]] = None, 635 | ) -> Dict[str, Any]: 636 | """ 637 | Get historical stock splits. 638 | """ 639 | try: 640 | results = polygon_client.list_splits( 641 | ticker=ticker, 642 | execution_date=execution_date, 643 | reverse_split=reverse_split, 644 | limit=limit, 645 | params=params, 646 | raw=True, 647 | ) 648 | 649 | data_str = results.data.decode("utf-8") 650 | return json.loads(data_str) 651 | except Exception as e: 652 | return {"error": str(e)} 653 | 654 | 655 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 656 | async def list_dividends( 657 | ticker: Optional[str] = None, 658 | ex_dividend_date: Optional[Union[str, datetime, date]] = None, 659 | frequency: Optional[int] = None, 660 | dividend_type: Optional[str] = None, 661 | limit: Optional[int] = None, 662 | params: Optional[Dict[str, Any]] = None, 663 | ) -> Dict[str, Any]: 664 | """ 665 | Get historical cash dividends. 666 | """ 667 | try: 668 | results = polygon_client.list_dividends( 669 | ticker=ticker, 670 | ex_dividend_date=ex_dividend_date, 671 | frequency=frequency, 672 | dividend_type=dividend_type, 673 | limit=limit, 674 | params=params, 675 | raw=True, 676 | ) 677 | 678 | data_str = results.data.decode("utf-8") 679 | return json.loads(data_str) 680 | except Exception as e: 681 | return {"error": str(e)} 682 | 683 | 684 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 685 | async def list_conditions( 686 | asset_class: Optional[str] = None, 687 | data_type: Optional[str] = None, 688 | id: Optional[int] = None, 689 | sip: Optional[str] = None, 690 | params: Optional[Dict[str, Any]] = None, 691 | ) -> Dict[str, Any]: 692 | """ 693 | List conditions used by Polygon.io. 694 | """ 695 | try: 696 | results = polygon_client.list_conditions( 697 | asset_class=asset_class, 698 | data_type=data_type, 699 | id=id, 700 | sip=sip, 701 | params=params, 702 | raw=True, 703 | ) 704 | 705 | data_str = results.data.decode("utf-8") 706 | return json.loads(data_str) 707 | except Exception as e: 708 | return {"error": str(e)} 709 | 710 | 711 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 712 | async def get_exchanges( 713 | asset_class: Optional[str] = None, 714 | locale: Optional[str] = None, 715 | params: Optional[Dict[str, Any]] = None, 716 | ) -> Dict[str, Any]: 717 | """ 718 | List exchanges known by Polygon.io. 719 | """ 720 | try: 721 | results = polygon_client.get_exchanges( 722 | asset_class=asset_class, locale=locale, params=params, raw=True 723 | ) 724 | 725 | data_str = results.data.decode("utf-8") 726 | return json.loads(data_str) 727 | except Exception as e: 728 | return {"error": str(e)} 729 | 730 | 731 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 732 | async def list_stock_financials( 733 | ticker: Optional[str] = None, 734 | cik: Optional[str] = None, 735 | company_name: Optional[str] = None, 736 | company_name_search: Optional[str] = None, 737 | sic: Optional[str] = None, 738 | filing_date: Optional[Union[str, datetime, date]] = None, 739 | filing_date_lt: Optional[Union[str, datetime, date]] = None, 740 | filing_date_lte: Optional[Union[str, datetime, date]] = None, 741 | filing_date_gt: Optional[Union[str, datetime, date]] = None, 742 | filing_date_gte: Optional[Union[str, datetime, date]] = None, 743 | period_of_report_date: Optional[Union[str, datetime, date]] = None, 744 | period_of_report_date_lt: Optional[Union[str, datetime, date]] = None, 745 | period_of_report_date_lte: Optional[Union[str, datetime, date]] = None, 746 | period_of_report_date_gt: Optional[Union[str, datetime, date]] = None, 747 | period_of_report_date_gte: Optional[Union[str, datetime, date]] = None, 748 | timeframe: Optional[str] = None, 749 | include_sources: Optional[bool] = None, 750 | limit: Optional[int] = None, 751 | sort: Optional[str] = None, 752 | order: Optional[str] = None, 753 | params: Optional[Dict[str, Any]] = None, 754 | ) -> Dict[str, Any]: 755 | """ 756 | Get fundamental financial data for companies. 757 | """ 758 | try: 759 | results = polygon_client.vx.list_stock_financials( 760 | ticker=ticker, 761 | cik=cik, 762 | company_name=company_name, 763 | company_name_search=company_name_search, 764 | sic=sic, 765 | filing_date=filing_date, 766 | filing_date_lt=filing_date_lt, 767 | filing_date_lte=filing_date_lte, 768 | filing_date_gt=filing_date_gt, 769 | filing_date_gte=filing_date_gte, 770 | period_of_report_date=period_of_report_date, 771 | period_of_report_date_lt=period_of_report_date_lt, 772 | period_of_report_date_lte=period_of_report_date_lte, 773 | period_of_report_date_gt=period_of_report_date_gt, 774 | period_of_report_date_gte=period_of_report_date_gte, 775 | timeframe=timeframe, 776 | include_sources=include_sources, 777 | limit=limit, 778 | sort=sort, 779 | order=order, 780 | params=params, 781 | raw=True, 782 | ) 783 | 784 | data_str = results.data.decode("utf-8") 785 | return json.loads(data_str) 786 | except Exception as e: 787 | return {"error": str(e)} 788 | 789 | 790 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 791 | async def list_ipos( 792 | ticker: Optional[str] = None, 793 | listing_date: Optional[Union[str, datetime, date]] = None, 794 | listing_date_lt: Optional[Union[str, datetime, date]] = None, 795 | listing_date_lte: Optional[Union[str, datetime, date]] = None, 796 | listing_date_gt: Optional[Union[str, datetime, date]] = None, 797 | listing_date_gte: Optional[Union[str, datetime, date]] = None, 798 | ipo_status: Optional[str] = None, 799 | limit: Optional[int] = None, 800 | sort: Optional[str] = None, 801 | order: Optional[str] = None, 802 | params: Optional[Dict[str, Any]] = None, 803 | ) -> Dict[str, Any]: 804 | """ 805 | Retrieve upcoming or historical IPOs. 806 | """ 807 | try: 808 | results = polygon_client.vx.list_ipos( 809 | ticker=ticker, 810 | listing_date=listing_date, 811 | listing_date_lt=listing_date_lt, 812 | listing_date_lte=listing_date_lte, 813 | listing_date_gt=listing_date_gt, 814 | listing_date_gte=listing_date_gte, 815 | ipo_status=ipo_status, 816 | limit=limit, 817 | sort=sort, 818 | order=order, 819 | params=params, 820 | raw=True, 821 | ) 822 | 823 | data_str = results.data.decode("utf-8") 824 | return json.loads(data_str) 825 | except Exception as e: 826 | return {"error": str(e)} 827 | 828 | 829 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 830 | async def list_short_interest( 831 | ticker: Optional[str] = None, 832 | settlement_date: Optional[Union[str, datetime, date]] = None, 833 | settlement_date_lt: Optional[Union[str, datetime, date]] = None, 834 | settlement_date_lte: Optional[Union[str, datetime, date]] = None, 835 | settlement_date_gt: Optional[Union[str, datetime, date]] = None, 836 | settlement_date_gte: Optional[Union[str, datetime, date]] = None, 837 | limit: Optional[int] = None, 838 | sort: Optional[str] = None, 839 | order: Optional[str] = None, 840 | params: Optional[Dict[str, Any]] = None, 841 | ) -> Dict[str, Any]: 842 | """ 843 | Retrieve short interest data for stocks. 844 | """ 845 | try: 846 | results = polygon_client.list_short_interest( 847 | ticker=ticker, 848 | settlement_date=settlement_date, 849 | settlement_date_lt=settlement_date_lt, 850 | settlement_date_lte=settlement_date_lte, 851 | settlement_date_gt=settlement_date_gt, 852 | settlement_date_gte=settlement_date_gte, 853 | limit=limit, 854 | sort=sort, 855 | order=order, 856 | params=params, 857 | raw=True, 858 | ) 859 | 860 | data_str = results.data.decode("utf-8") 861 | return json.loads(data_str) 862 | except Exception as e: 863 | return {"error": str(e)} 864 | 865 | 866 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 867 | async def list_short_volume( 868 | ticker: Optional[str] = None, 869 | date: Optional[Union[str, datetime, date]] = None, 870 | date_lt: Optional[Union[str, datetime, date]] = None, 871 | date_lte: Optional[Union[str, datetime, date]] = None, 872 | date_gt: Optional[Union[str, datetime, date]] = None, 873 | date_gte: Optional[Union[str, datetime, date]] = None, 874 | limit: Optional[int] = None, 875 | sort: Optional[str] = None, 876 | order: Optional[str] = None, 877 | params: Optional[Dict[str, Any]] = None, 878 | ) -> Dict[str, Any]: 879 | """ 880 | Retrieve short volume data for stocks. 881 | """ 882 | try: 883 | results = polygon_client.list_short_volume( 884 | ticker=ticker, 885 | date=date, 886 | date_lt=date_lt, 887 | date_lte=date_lte, 888 | date_gt=date_gt, 889 | date_gte=date_gte, 890 | limit=limit, 891 | sort=sort, 892 | order=order, 893 | params=params, 894 | raw=True, 895 | ) 896 | 897 | data_str = results.data.decode("utf-8") 898 | return json.loads(data_str) 899 | except Exception as e: 900 | return {"error": str(e)} 901 | 902 | 903 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 904 | async def list_treasury_yields( 905 | date: Optional[Union[str, datetime, date]] = None, 906 | date_any_of: Optional[str] = None, 907 | date_lt: Optional[Union[str, datetime, date]] = None, 908 | date_lte: Optional[Union[str, datetime, date]] = None, 909 | date_gt: Optional[Union[str, datetime, date]] = None, 910 | date_gte: Optional[Union[str, datetime, date]] = None, 911 | limit: Optional[int] = None, 912 | sort: Optional[str] = None, 913 | order: Optional[str] = None, 914 | params: Optional[Dict[str, Any]] = None, 915 | ) -> Dict[str, Any]: 916 | """ 917 | Retrieve treasury yield data. 918 | """ 919 | try: 920 | results = polygon_client.list_treasury_yields( 921 | date=date, 922 | date_lt=date_lt, 923 | date_lte=date_lte, 924 | date_gt=date_gt, 925 | date_gte=date_gte, 926 | limit=limit, 927 | sort=sort, 928 | order=order, 929 | params=params, 930 | raw=True, 931 | ) 932 | 933 | data_str = results.data.decode("utf-8") 934 | return json.loads(data_str) 935 | except Exception as e: 936 | return {"error": str(e)} 937 | 938 | 939 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 940 | async def list_inflation( 941 | date: Optional[Union[str, datetime, date]] = None, 942 | date_any_of: Optional[str] = None, 943 | date_gt: Optional[Union[str, datetime, date]] = None, 944 | date_gte: Optional[Union[str, datetime, date]] = None, 945 | date_lt: Optional[Union[str, datetime, date]] = None, 946 | date_lte: Optional[Union[str, datetime, date]] = None, 947 | limit: Optional[int] = None, 948 | sort: Optional[str] = None, 949 | params: Optional[Dict[str, Any]] = None, 950 | ) -> Dict[str, Any]: 951 | """ 952 | Get inflation data from the Federal Reserve. 953 | """ 954 | try: 955 | results = polygon_client.list_inflation( 956 | date=date, 957 | date_any_of=date_any_of, 958 | date_gt=date_gt, 959 | date_gte=date_gte, 960 | date_lt=date_lt, 961 | date_lte=date_lte, 962 | limit=limit, 963 | sort=sort, 964 | params=params, 965 | raw=True, 966 | ) 967 | 968 | data_str = results.data.decode("utf-8") 969 | return json.loads(data_str) 970 | except Exception as e: 971 | return {"error": str(e)} 972 | 973 | 974 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 975 | async def list_benzinga_analyst_insights( 976 | date: Optional[Union[str, date]] = None, 977 | date_any_of: Optional[str] = None, 978 | date_gt: Optional[Union[str, date]] = None, 979 | date_gte: Optional[Union[str, date]] = None, 980 | date_lt: Optional[Union[str, date]] = None, 981 | date_lte: Optional[Union[str, date]] = None, 982 | ticker: Optional[str] = None, 983 | ticker_any_of: Optional[str] = None, 984 | ticker_gt: Optional[str] = None, 985 | ticker_gte: Optional[str] = None, 986 | ticker_lt: Optional[str] = None, 987 | ticker_lte: Optional[str] = None, 988 | last_updated: Optional[str] = None, 989 | last_updated_any_of: Optional[str] = None, 990 | last_updated_gt: Optional[str] = None, 991 | last_updated_gte: Optional[str] = None, 992 | last_updated_lt: Optional[str] = None, 993 | last_updated_lte: Optional[str] = None, 994 | firm: Optional[str] = None, 995 | firm_any_of: Optional[str] = None, 996 | firm_gt: Optional[str] = None, 997 | firm_gte: Optional[str] = None, 998 | firm_lt: Optional[str] = None, 999 | firm_lte: Optional[str] = None, 1000 | rating_action: Optional[str] = None, 1001 | rating_action_any_of: Optional[str] = None, 1002 | rating_action_gt: Optional[str] = None, 1003 | rating_action_gte: Optional[str] = None, 1004 | rating_action_lt: Optional[str] = None, 1005 | rating_action_lte: Optional[str] = None, 1006 | benzinga_firm_id: Optional[str] = None, 1007 | benzinga_firm_id_any_of: Optional[str] = None, 1008 | benzinga_firm_id_gt: Optional[str] = None, 1009 | benzinga_firm_id_gte: Optional[str] = None, 1010 | benzinga_firm_id_lt: Optional[str] = None, 1011 | benzinga_firm_id_lte: Optional[str] = None, 1012 | benzinga_rating_id: Optional[str] = None, 1013 | benzinga_rating_id_any_of: Optional[str] = None, 1014 | benzinga_rating_id_gt: Optional[str] = None, 1015 | benzinga_rating_id_gte: Optional[str] = None, 1016 | benzinga_rating_id_lt: Optional[str] = None, 1017 | benzinga_rating_id_lte: Optional[str] = None, 1018 | limit: Optional[int] = None, 1019 | sort: Optional[str] = None, 1020 | params: Optional[Dict[str, Any]] = None, 1021 | ) -> Dict[str, Any]: 1022 | """ 1023 | List Benzinga analyst insights. 1024 | """ 1025 | try: 1026 | results = polygon_client.list_benzinga_analyst_insights( 1027 | date=date, 1028 | date_any_of=date_any_of, 1029 | date_gt=date_gt, 1030 | date_gte=date_gte, 1031 | date_lt=date_lt, 1032 | date_lte=date_lte, 1033 | ticker=ticker, 1034 | ticker_any_of=ticker_any_of, 1035 | ticker_gt=ticker_gt, 1036 | ticker_gte=ticker_gte, 1037 | ticker_lt=ticker_lt, 1038 | ticker_lte=ticker_lte, 1039 | last_updated=last_updated, 1040 | last_updated_any_of=last_updated_any_of, 1041 | last_updated_gt=last_updated_gt, 1042 | last_updated_gte=last_updated_gte, 1043 | last_updated_lt=last_updated_lt, 1044 | last_updated_lte=last_updated_lte, 1045 | firm=firm, 1046 | firm_any_of=firm_any_of, 1047 | firm_gt=firm_gt, 1048 | firm_gte=firm_gte, 1049 | firm_lt=firm_lt, 1050 | firm_lte=firm_lte, 1051 | rating_action=rating_action, 1052 | rating_action_any_of=rating_action_any_of, 1053 | rating_action_gt=rating_action_gt, 1054 | rating_action_gte=rating_action_gte, 1055 | rating_action_lt=rating_action_lt, 1056 | rating_action_lte=rating_action_lte, 1057 | benzinga_firm_id=benzinga_firm_id, 1058 | benzinga_firm_id_any_of=benzinga_firm_id_any_of, 1059 | benzinga_firm_id_gt=benzinga_firm_id_gt, 1060 | benzinga_firm_id_gte=benzinga_firm_id_gte, 1061 | benzinga_firm_id_lt=benzinga_firm_id_lt, 1062 | benzinga_firm_id_lte=benzinga_firm_id_lte, 1063 | benzinga_rating_id=benzinga_rating_id, 1064 | benzinga_rating_id_any_of=benzinga_rating_id_any_of, 1065 | benzinga_rating_id_gt=benzinga_rating_id_gt, 1066 | benzinga_rating_id_gte=benzinga_rating_id_gte, 1067 | benzinga_rating_id_lt=benzinga_rating_id_lt, 1068 | benzinga_rating_id_lte=benzinga_rating_id_lte, 1069 | limit=limit, 1070 | sort=sort, 1071 | params=params, 1072 | raw=True, 1073 | ) 1074 | 1075 | data_str = results.data.decode("utf-8") 1076 | return json.loads(data_str) 1077 | except Exception as e: 1078 | return {"error": str(e)} 1079 | 1080 | 1081 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1082 | async def list_benzinga_analysts( 1083 | benzinga_id: Optional[str] = None, 1084 | benzinga_id_any_of: Optional[str] = None, 1085 | benzinga_id_gt: Optional[str] = None, 1086 | benzinga_id_gte: Optional[str] = None, 1087 | benzinga_id_lt: Optional[str] = None, 1088 | benzinga_id_lte: Optional[str] = None, 1089 | benzinga_firm_id: Optional[str] = None, 1090 | benzinga_firm_id_any_of: Optional[str] = None, 1091 | benzinga_firm_id_gt: Optional[str] = None, 1092 | benzinga_firm_id_gte: Optional[str] = None, 1093 | benzinga_firm_id_lt: Optional[str] = None, 1094 | benzinga_firm_id_lte: Optional[str] = None, 1095 | firm_name: Optional[str] = None, 1096 | firm_name_any_of: Optional[str] = None, 1097 | firm_name_gt: Optional[str] = None, 1098 | firm_name_gte: Optional[str] = None, 1099 | firm_name_lt: Optional[str] = None, 1100 | firm_name_lte: Optional[str] = None, 1101 | full_name: Optional[str] = None, 1102 | full_name_any_of: Optional[str] = None, 1103 | full_name_gt: Optional[str] = None, 1104 | full_name_gte: Optional[str] = None, 1105 | full_name_lt: Optional[str] = None, 1106 | full_name_lte: Optional[str] = None, 1107 | limit: Optional[int] = None, 1108 | sort: Optional[str] = None, 1109 | params: Optional[Dict[str, Any]] = None, 1110 | ) -> Dict[str, Any]: 1111 | """ 1112 | List Benzinga analysts. 1113 | """ 1114 | try: 1115 | results = polygon_client.list_benzinga_analysts( 1116 | benzinga_id=benzinga_id, 1117 | benzinga_id_any_of=benzinga_id_any_of, 1118 | benzinga_id_gt=benzinga_id_gt, 1119 | benzinga_id_gte=benzinga_id_gte, 1120 | benzinga_id_lt=benzinga_id_lt, 1121 | benzinga_id_lte=benzinga_id_lte, 1122 | benzinga_firm_id=benzinga_firm_id, 1123 | benzinga_firm_id_any_of=benzinga_firm_id_any_of, 1124 | benzinga_firm_id_gt=benzinga_firm_id_gt, 1125 | benzinga_firm_id_gte=benzinga_firm_id_gte, 1126 | benzinga_firm_id_lt=benzinga_firm_id_lt, 1127 | benzinga_firm_id_lte=benzinga_firm_id_lte, 1128 | firm_name=firm_name, 1129 | firm_name_any_of=firm_name_any_of, 1130 | firm_name_gt=firm_name_gt, 1131 | firm_name_gte=firm_name_gte, 1132 | firm_name_lt=firm_name_lt, 1133 | firm_name_lte=firm_name_lte, 1134 | full_name=full_name, 1135 | full_name_any_of=full_name_any_of, 1136 | full_name_gt=full_name_gt, 1137 | full_name_gte=full_name_gte, 1138 | full_name_lt=full_name_lt, 1139 | full_name_lte=full_name_lte, 1140 | limit=limit, 1141 | sort=sort, 1142 | params=params, 1143 | raw=True, 1144 | ) 1145 | 1146 | data_str = results.data.decode("utf-8") 1147 | return json.loads(data_str) 1148 | except Exception as e: 1149 | return {"error": str(e)} 1150 | 1151 | 1152 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1153 | async def list_benzinga_consensus_ratings( 1154 | ticker: str, 1155 | date: Optional[Union[str, date]] = None, 1156 | date_gt: Optional[Union[str, date]] = None, 1157 | date_gte: Optional[Union[str, date]] = None, 1158 | date_lt: Optional[Union[str, date]] = None, 1159 | date_lte: Optional[Union[str, date]] = None, 1160 | limit: Optional[int] = None, 1161 | params: Optional[Dict[str, Any]] = None, 1162 | ) -> Dict[str, Any]: 1163 | """ 1164 | List Benzinga consensus ratings for a ticker. 1165 | """ 1166 | try: 1167 | results = polygon_client.list_benzinga_consensus_ratings( 1168 | ticker=ticker, 1169 | date=date, 1170 | date_gt=date_gt, 1171 | date_gte=date_gte, 1172 | date_lt=date_lt, 1173 | date_lte=date_lte, 1174 | limit=limit, 1175 | params=params, 1176 | raw=True, 1177 | ) 1178 | 1179 | data_str = results.data.decode("utf-8") 1180 | return json.loads(data_str) 1181 | except Exception as e: 1182 | return {"error": str(e)} 1183 | 1184 | 1185 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1186 | async def list_benzinga_earnings( 1187 | date: Optional[Union[str, date]] = None, 1188 | date_any_of: Optional[str] = None, 1189 | date_gt: Optional[Union[str, date]] = None, 1190 | date_gte: Optional[Union[str, date]] = None, 1191 | date_lt: Optional[Union[str, date]] = None, 1192 | date_lte: Optional[Union[str, date]] = None, 1193 | ticker: Optional[str] = None, 1194 | ticker_any_of: Optional[str] = None, 1195 | ticker_gt: Optional[str] = None, 1196 | ticker_gte: Optional[str] = None, 1197 | ticker_lt: Optional[str] = None, 1198 | ticker_lte: Optional[str] = None, 1199 | importance: Optional[int] = None, 1200 | importance_any_of: Optional[str] = None, 1201 | importance_gt: Optional[int] = None, 1202 | importance_gte: Optional[int] = None, 1203 | importance_lt: Optional[int] = None, 1204 | importance_lte: Optional[int] = None, 1205 | last_updated: Optional[str] = None, 1206 | last_updated_any_of: Optional[str] = None, 1207 | last_updated_gt: Optional[str] = None, 1208 | last_updated_gte: Optional[str] = None, 1209 | last_updated_lt: Optional[str] = None, 1210 | last_updated_lte: Optional[str] = None, 1211 | date_status: Optional[str] = None, 1212 | date_status_any_of: Optional[str] = None, 1213 | date_status_gt: Optional[str] = None, 1214 | date_status_gte: Optional[str] = None, 1215 | date_status_lt: Optional[str] = None, 1216 | date_status_lte: Optional[str] = None, 1217 | eps_surprise_percent: Optional[float] = None, 1218 | eps_surprise_percent_any_of: Optional[str] = None, 1219 | eps_surprise_percent_gt: Optional[float] = None, 1220 | eps_surprise_percent_gte: Optional[float] = None, 1221 | eps_surprise_percent_lt: Optional[float] = None, 1222 | eps_surprise_percent_lte: Optional[float] = None, 1223 | revenue_surprise_percent: Optional[float] = None, 1224 | revenue_surprise_percent_any_of: Optional[str] = None, 1225 | revenue_surprise_percent_gt: Optional[float] = None, 1226 | revenue_surprise_percent_gte: Optional[float] = None, 1227 | revenue_surprise_percent_lt: Optional[float] = None, 1228 | revenue_surprise_percent_lte: Optional[float] = None, 1229 | fiscal_year: Optional[int] = None, 1230 | fiscal_year_any_of: Optional[str] = None, 1231 | fiscal_year_gt: Optional[int] = None, 1232 | fiscal_year_gte: Optional[int] = None, 1233 | fiscal_year_lt: Optional[int] = None, 1234 | fiscal_year_lte: Optional[int] = None, 1235 | fiscal_period: Optional[str] = None, 1236 | fiscal_period_any_of: Optional[str] = None, 1237 | fiscal_period_gt: Optional[str] = None, 1238 | fiscal_period_gte: Optional[str] = None, 1239 | fiscal_period_lt: Optional[str] = None, 1240 | fiscal_period_lte: Optional[str] = None, 1241 | limit: Optional[int] = None, 1242 | sort: Optional[str] = None, 1243 | params: Optional[Dict[str, Any]] = None, 1244 | ) -> Dict[str, Any]: 1245 | """ 1246 | List Benzinga earnings. 1247 | """ 1248 | try: 1249 | results = polygon_client.list_benzinga_earnings( 1250 | date=date, 1251 | date_any_of=date_any_of, 1252 | date_gt=date_gt, 1253 | date_gte=date_gte, 1254 | date_lt=date_lt, 1255 | date_lte=date_lte, 1256 | ticker=ticker, 1257 | ticker_any_of=ticker_any_of, 1258 | ticker_gt=ticker_gt, 1259 | ticker_gte=ticker_gte, 1260 | ticker_lt=ticker_lt, 1261 | ticker_lte=ticker_lte, 1262 | importance=importance, 1263 | importance_any_of=importance_any_of, 1264 | importance_gt=importance_gt, 1265 | importance_gte=importance_gte, 1266 | importance_lt=importance_lt, 1267 | importance_lte=importance_lte, 1268 | last_updated=last_updated, 1269 | last_updated_any_of=last_updated_any_of, 1270 | last_updated_gt=last_updated_gt, 1271 | last_updated_gte=last_updated_gte, 1272 | last_updated_lt=last_updated_lt, 1273 | last_updated_lte=last_updated_lte, 1274 | date_status=date_status, 1275 | date_status_any_of=date_status_any_of, 1276 | date_status_gt=date_status_gt, 1277 | date_status_gte=date_status_gte, 1278 | date_status_lt=date_status_lt, 1279 | date_status_lte=date_status_lte, 1280 | eps_surprise_percent=eps_surprise_percent, 1281 | eps_surprise_percent_any_of=eps_surprise_percent_any_of, 1282 | eps_surprise_percent_gt=eps_surprise_percent_gt, 1283 | eps_surprise_percent_gte=eps_surprise_percent_gte, 1284 | eps_surprise_percent_lt=eps_surprise_percent_lt, 1285 | eps_surprise_percent_lte=eps_surprise_percent_lte, 1286 | revenue_surprise_percent=revenue_surprise_percent, 1287 | revenue_surprise_percent_any_of=revenue_surprise_percent_any_of, 1288 | revenue_surprise_percent_gt=revenue_surprise_percent_gt, 1289 | revenue_surprise_percent_gte=revenue_surprise_percent_gte, 1290 | revenue_surprise_percent_lt=revenue_surprise_percent_lt, 1291 | revenue_surprise_percent_lte=revenue_surprise_percent_lte, 1292 | fiscal_year=fiscal_year, 1293 | fiscal_year_any_of=fiscal_year_any_of, 1294 | fiscal_year_gt=fiscal_year_gt, 1295 | fiscal_year_gte=fiscal_year_gte, 1296 | fiscal_year_lt=fiscal_year_lt, 1297 | fiscal_year_lte=fiscal_year_lte, 1298 | fiscal_period=fiscal_period, 1299 | fiscal_period_any_of=fiscal_period_any_of, 1300 | fiscal_period_gt=fiscal_period_gt, 1301 | fiscal_period_gte=fiscal_period_gte, 1302 | fiscal_period_lt=fiscal_period_lt, 1303 | fiscal_period_lte=fiscal_period_lte, 1304 | limit=limit, 1305 | sort=sort, 1306 | params=params, 1307 | raw=True, 1308 | ) 1309 | 1310 | data_str = results.data.decode("utf-8") 1311 | return json.loads(data_str) 1312 | except Exception as e: 1313 | return {"error": str(e)} 1314 | 1315 | 1316 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1317 | async def list_benzinga_firms( 1318 | benzinga_id: Optional[str] = None, 1319 | benzinga_id_any_of: Optional[str] = None, 1320 | benzinga_id_gt: Optional[str] = None, 1321 | benzinga_id_gte: Optional[str] = None, 1322 | benzinga_id_lt: Optional[str] = None, 1323 | benzinga_id_lte: Optional[str] = None, 1324 | limit: Optional[int] = None, 1325 | sort: Optional[str] = None, 1326 | params: Optional[Dict[str, Any]] = None, 1327 | ) -> Dict[str, Any]: 1328 | """ 1329 | List Benzinga firms. 1330 | """ 1331 | try: 1332 | results = polygon_client.list_benzinga_firms( 1333 | benzinga_id=benzinga_id, 1334 | benzinga_id_any_of=benzinga_id_any_of, 1335 | benzinga_id_gt=benzinga_id_gt, 1336 | benzinga_id_gte=benzinga_id_gte, 1337 | benzinga_id_lt=benzinga_id_lt, 1338 | benzinga_id_lte=benzinga_id_lte, 1339 | limit=limit, 1340 | sort=sort, 1341 | params=params, 1342 | raw=True, 1343 | ) 1344 | 1345 | data_str = results.data.decode("utf-8") 1346 | return json.loads(data_str) 1347 | except Exception as e: 1348 | return {"error": str(e)} 1349 | 1350 | 1351 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1352 | async def list_benzinga_guidance( 1353 | date: Optional[Union[str, date]] = None, 1354 | date_any_of: Optional[str] = None, 1355 | date_gt: Optional[Union[str, date]] = None, 1356 | date_gte: Optional[Union[str, date]] = None, 1357 | date_lt: Optional[Union[str, date]] = None, 1358 | date_lte: Optional[Union[str, date]] = None, 1359 | ticker: Optional[str] = None, 1360 | ticker_any_of: Optional[str] = None, 1361 | ticker_gt: Optional[str] = None, 1362 | ticker_gte: Optional[str] = None, 1363 | ticker_lt: Optional[str] = None, 1364 | ticker_lte: Optional[str] = None, 1365 | positioning: Optional[str] = None, 1366 | positioning_any_of: Optional[str] = None, 1367 | positioning_gt: Optional[str] = None, 1368 | positioning_gte: Optional[str] = None, 1369 | positioning_lt: Optional[str] = None, 1370 | positioning_lte: Optional[str] = None, 1371 | importance: Optional[int] = None, 1372 | importance_any_of: Optional[str] = None, 1373 | importance_gt: Optional[int] = None, 1374 | importance_gte: Optional[int] = None, 1375 | importance_lt: Optional[int] = None, 1376 | importance_lte: Optional[int] = None, 1377 | last_updated: Optional[str] = None, 1378 | last_updated_any_of: Optional[str] = None, 1379 | last_updated_gt: Optional[str] = None, 1380 | last_updated_gte: Optional[str] = None, 1381 | last_updated_lt: Optional[str] = None, 1382 | last_updated_lte: Optional[str] = None, 1383 | fiscal_year: Optional[int] = None, 1384 | fiscal_year_any_of: Optional[str] = None, 1385 | fiscal_year_gt: Optional[int] = None, 1386 | fiscal_year_gte: Optional[int] = None, 1387 | fiscal_year_lt: Optional[int] = None, 1388 | fiscal_year_lte: Optional[int] = None, 1389 | fiscal_period: Optional[str] = None, 1390 | fiscal_period_any_of: Optional[str] = None, 1391 | fiscal_period_gt: Optional[str] = None, 1392 | fiscal_period_gte: Optional[str] = None, 1393 | fiscal_period_lt: Optional[str] = None, 1394 | fiscal_period_lte: Optional[str] = None, 1395 | limit: Optional[int] = None, 1396 | sort: Optional[str] = None, 1397 | params: Optional[Dict[str, Any]] = None, 1398 | ) -> Dict[str, Any]: 1399 | """ 1400 | List Benzinga guidance. 1401 | """ 1402 | try: 1403 | results = polygon_client.list_benzinga_guidance( 1404 | date=date, 1405 | date_any_of=date_any_of, 1406 | date_gt=date_gt, 1407 | date_gte=date_gte, 1408 | date_lt=date_lt, 1409 | date_lte=date_lte, 1410 | ticker=ticker, 1411 | ticker_any_of=ticker_any_of, 1412 | ticker_gt=ticker_gt, 1413 | ticker_gte=ticker_gte, 1414 | ticker_lt=ticker_lt, 1415 | ticker_lte=ticker_lte, 1416 | positioning=positioning, 1417 | positioning_any_of=positioning_any_of, 1418 | positioning_gt=positioning_gt, 1419 | positioning_gte=positioning_gte, 1420 | positioning_lt=positioning_lt, 1421 | positioning_lte=positioning_lte, 1422 | importance=importance, 1423 | importance_any_of=importance_any_of, 1424 | importance_gt=importance_gt, 1425 | importance_gte=importance_gte, 1426 | importance_lt=importance_lt, 1427 | importance_lte=importance_lte, 1428 | last_updated=last_updated, 1429 | last_updated_any_of=last_updated_any_of, 1430 | last_updated_gt=last_updated_gt, 1431 | last_updated_gte=last_updated_gte, 1432 | last_updated_lt=last_updated_lt, 1433 | last_updated_lte=last_updated_lte, 1434 | fiscal_year=fiscal_year, 1435 | fiscal_year_any_of=fiscal_year_any_of, 1436 | fiscal_year_gt=fiscal_year_gt, 1437 | fiscal_year_gte=fiscal_year_gte, 1438 | fiscal_year_lt=fiscal_year_lt, 1439 | fiscal_year_lte=fiscal_year_lte, 1440 | fiscal_period=fiscal_period, 1441 | fiscal_period_any_of=fiscal_period_any_of, 1442 | fiscal_period_gt=fiscal_period_gt, 1443 | fiscal_period_gte=fiscal_period_gte, 1444 | fiscal_period_lt=fiscal_period_lt, 1445 | fiscal_period_lte=fiscal_period_lte, 1446 | limit=limit, 1447 | sort=sort, 1448 | params=params, 1449 | raw=True, 1450 | ) 1451 | 1452 | data_str = results.data.decode("utf-8") 1453 | return json.loads(data_str) 1454 | except Exception as e: 1455 | return {"error": str(e)} 1456 | 1457 | 1458 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1459 | async def list_benzinga_news( 1460 | published: Optional[str] = None, 1461 | published_any_of: Optional[str] = None, 1462 | published_gt: Optional[str] = None, 1463 | published_gte: Optional[str] = None, 1464 | published_lt: Optional[str] = None, 1465 | published_lte: Optional[str] = None, 1466 | last_updated: Optional[str] = None, 1467 | last_updated_any_of: Optional[str] = None, 1468 | last_updated_gt: Optional[str] = None, 1469 | last_updated_gte: Optional[str] = None, 1470 | last_updated_lt: Optional[str] = None, 1471 | last_updated_lte: Optional[str] = None, 1472 | tickers: Optional[str] = None, 1473 | tickers_all_of: Optional[str] = None, 1474 | tickers_any_of: Optional[str] = None, 1475 | channels: Optional[str] = None, 1476 | channels_all_of: Optional[str] = None, 1477 | channels_any_of: Optional[str] = None, 1478 | tags: Optional[str] = None, 1479 | tags_all_of: Optional[str] = None, 1480 | tags_any_of: Optional[str] = None, 1481 | author: Optional[str] = None, 1482 | author_any_of: Optional[str] = None, 1483 | author_gt: Optional[str] = None, 1484 | author_gte: Optional[str] = None, 1485 | author_lt: Optional[str] = None, 1486 | author_lte: Optional[str] = None, 1487 | limit: Optional[int] = None, 1488 | sort: Optional[str] = None, 1489 | params: Optional[Dict[str, Any]] = None, 1490 | ) -> Dict[str, Any]: 1491 | """ 1492 | List Benzinga news. 1493 | """ 1494 | try: 1495 | results = polygon_client.list_benzinga_news( 1496 | published=published, 1497 | published_any_of=published_any_of, 1498 | published_gt=published_gt, 1499 | published_gte=published_gte, 1500 | published_lt=published_lt, 1501 | published_lte=published_lte, 1502 | last_updated=last_updated, 1503 | last_updated_any_of=last_updated_any_of, 1504 | last_updated_gt=last_updated_gt, 1505 | last_updated_gte=last_updated_gte, 1506 | last_updated_lt=last_updated_lt, 1507 | last_updated_lte=last_updated_lte, 1508 | tickers=tickers, 1509 | tickers_all_of=tickers_all_of, 1510 | tickers_any_of=tickers_any_of, 1511 | channels=channels, 1512 | channels_all_of=channels_all_of, 1513 | channels_any_of=channels_any_of, 1514 | tags=tags, 1515 | tags_all_of=tags_all_of, 1516 | tags_any_of=tags_any_of, 1517 | author=author, 1518 | author_any_of=author_any_of, 1519 | author_gt=author_gt, 1520 | author_gte=author_gte, 1521 | author_lt=author_lt, 1522 | author_lte=author_lte, 1523 | limit=limit, 1524 | sort=sort, 1525 | params=params, 1526 | raw=True, 1527 | ) 1528 | 1529 | data_str = results.data.decode("utf-8") 1530 | return json.loads(data_str) 1531 | except Exception as e: 1532 | return {"error": str(e)} 1533 | 1534 | 1535 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1536 | async def list_benzinga_ratings( 1537 | date: Optional[Union[str, date]] = None, 1538 | date_any_of: Optional[str] = None, 1539 | date_gt: Optional[Union[str, date]] = None, 1540 | date_gte: Optional[Union[str, date]] = None, 1541 | date_lt: Optional[Union[str, date]] = None, 1542 | date_lte: Optional[Union[str, date]] = None, 1543 | ticker: Optional[str] = None, 1544 | ticker_any_of: Optional[str] = None, 1545 | ticker_gt: Optional[str] = None, 1546 | ticker_gte: Optional[str] = None, 1547 | ticker_lt: Optional[str] = None, 1548 | ticker_lte: Optional[str] = None, 1549 | importance: Optional[int] = None, 1550 | importance_any_of: Optional[str] = None, 1551 | importance_gt: Optional[int] = None, 1552 | importance_gte: Optional[int] = None, 1553 | importance_lt: Optional[int] = None, 1554 | importance_lte: Optional[int] = None, 1555 | last_updated: Optional[str] = None, 1556 | last_updated_any_of: Optional[str] = None, 1557 | last_updated_gt: Optional[str] = None, 1558 | last_updated_gte: Optional[str] = None, 1559 | last_updated_lt: Optional[str] = None, 1560 | last_updated_lte: Optional[str] = None, 1561 | rating_action: Optional[str] = None, 1562 | rating_action_any_of: Optional[str] = None, 1563 | rating_action_gt: Optional[str] = None, 1564 | rating_action_gte: Optional[str] = None, 1565 | rating_action_lt: Optional[str] = None, 1566 | rating_action_lte: Optional[str] = None, 1567 | price_target_action: Optional[str] = None, 1568 | price_target_action_any_of: Optional[str] = None, 1569 | price_target_action_gt: Optional[str] = None, 1570 | price_target_action_gte: Optional[str] = None, 1571 | price_target_action_lt: Optional[str] = None, 1572 | price_target_action_lte: Optional[str] = None, 1573 | benzinga_id: Optional[str] = None, 1574 | benzinga_id_any_of: Optional[str] = None, 1575 | benzinga_id_gt: Optional[str] = None, 1576 | benzinga_id_gte: Optional[str] = None, 1577 | benzinga_id_lt: Optional[str] = None, 1578 | benzinga_id_lte: Optional[str] = None, 1579 | benzinga_analyst_id: Optional[str] = None, 1580 | benzinga_analyst_id_any_of: Optional[str] = None, 1581 | benzinga_analyst_id_gt: Optional[str] = None, 1582 | benzinga_analyst_id_gte: Optional[str] = None, 1583 | benzinga_analyst_id_lt: Optional[str] = None, 1584 | benzinga_analyst_id_lte: Optional[str] = None, 1585 | benzinga_firm_id: Optional[str] = None, 1586 | benzinga_firm_id_any_of: Optional[str] = None, 1587 | benzinga_firm_id_gt: Optional[str] = None, 1588 | benzinga_firm_id_gte: Optional[str] = None, 1589 | benzinga_firm_id_lt: Optional[str] = None, 1590 | benzinga_firm_id_lte: Optional[str] = None, 1591 | limit: Optional[int] = None, 1592 | sort: Optional[str] = None, 1593 | params: Optional[Dict[str, Any]] = None, 1594 | ) -> Dict[str, Any]: 1595 | """ 1596 | List Benzinga ratings. 1597 | """ 1598 | try: 1599 | results = polygon_client.list_benzinga_ratings( 1600 | date=date, 1601 | date_any_of=date_any_of, 1602 | date_gt=date_gt, 1603 | date_gte=date_gte, 1604 | date_lt=date_lt, 1605 | date_lte=date_lte, 1606 | ticker=ticker, 1607 | ticker_any_of=ticker_any_of, 1608 | ticker_gt=ticker_gt, 1609 | ticker_gte=ticker_gte, 1610 | ticker_lt=ticker_lt, 1611 | ticker_lte=ticker_lte, 1612 | importance=importance, 1613 | importance_any_of=importance_any_of, 1614 | importance_gt=importance_gt, 1615 | importance_gte=importance_gte, 1616 | importance_lt=importance_lt, 1617 | importance_lte=importance_lte, 1618 | last_updated=last_updated, 1619 | last_updated_any_of=last_updated_any_of, 1620 | last_updated_gt=last_updated_gt, 1621 | last_updated_gte=last_updated_gte, 1622 | last_updated_lt=last_updated_lt, 1623 | last_updated_lte=last_updated_lte, 1624 | rating_action=rating_action, 1625 | rating_action_any_of=rating_action_any_of, 1626 | rating_action_gt=rating_action_gt, 1627 | rating_action_gte=rating_action_gte, 1628 | rating_action_lt=rating_action_lt, 1629 | rating_action_lte=rating_action_lte, 1630 | price_target_action=price_target_action, 1631 | price_target_action_any_of=price_target_action_any_of, 1632 | price_target_action_gt=price_target_action_gt, 1633 | price_target_action_gte=price_target_action_gte, 1634 | price_target_action_lt=price_target_action_lt, 1635 | price_target_action_lte=price_target_action_lte, 1636 | benzinga_id=benzinga_id, 1637 | benzinga_id_any_of=benzinga_id_any_of, 1638 | benzinga_id_gt=benzinga_id_gt, 1639 | benzinga_id_gte=benzinga_id_gte, 1640 | benzinga_id_lt=benzinga_id_lt, 1641 | benzinga_id_lte=benzinga_id_lte, 1642 | benzinga_analyst_id=benzinga_analyst_id, 1643 | benzinga_analyst_id_any_of=benzinga_analyst_id_any_of, 1644 | benzinga_analyst_id_gt=benzinga_analyst_id_gt, 1645 | benzinga_analyst_id_gte=benzinga_analyst_id_gte, 1646 | benzinga_analyst_id_lt=benzinga_analyst_id_lt, 1647 | benzinga_analyst_id_lte=benzinga_analyst_id_lte, 1648 | benzinga_firm_id=benzinga_firm_id, 1649 | benzinga_firm_id_any_of=benzinga_firm_id_any_of, 1650 | benzinga_firm_id_gt=benzinga_firm_id_gt, 1651 | benzinga_firm_id_gte=benzinga_firm_id_gte, 1652 | benzinga_firm_id_lt=benzinga_firm_id_lt, 1653 | benzinga_firm_id_lte=benzinga_firm_id_lte, 1654 | limit=limit, 1655 | sort=sort, 1656 | params=params, 1657 | raw=True, 1658 | ) 1659 | 1660 | data_str = results.data.decode("utf-8") 1661 | return json.loads(data_str) 1662 | except Exception as e: 1663 | return {"error": str(e)} 1664 | 1665 | 1666 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1667 | async def list_futures_aggregates( 1668 | ticker: str, 1669 | resolution: str, 1670 | window_start: Optional[str] = None, 1671 | window_start_lt: Optional[str] = None, 1672 | window_start_lte: Optional[str] = None, 1673 | window_start_gt: Optional[str] = None, 1674 | window_start_gte: Optional[str] = None, 1675 | limit: Optional[int] = None, 1676 | sort: Optional[str] = None, 1677 | params: Optional[Dict[str, Any]] = None, 1678 | ) -> Dict[str, Any]: 1679 | """ 1680 | Get aggregates for a futures contract in a given time range. 1681 | """ 1682 | try: 1683 | results = polygon_client.list_futures_aggregates( 1684 | ticker=ticker, 1685 | resolution=resolution, 1686 | window_start=window_start, 1687 | window_start_lt=window_start_lt, 1688 | window_start_lte=window_start_lte, 1689 | window_start_gt=window_start_gt, 1690 | window_start_gte=window_start_gte, 1691 | limit=limit, 1692 | sort=sort, 1693 | params=params, 1694 | raw=True, 1695 | ) 1696 | 1697 | data_str = results.data.decode("utf-8") 1698 | return json.loads(data_str) 1699 | except Exception as e: 1700 | return {"error": str(e)} 1701 | 1702 | 1703 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1704 | async def list_futures_contracts( 1705 | product_code: Optional[str] = None, 1706 | first_trade_date: Optional[Union[str, date]] = None, 1707 | last_trade_date: Optional[Union[str, date]] = None, 1708 | as_of: Optional[Union[str, date]] = None, 1709 | active: Optional[str] = None, 1710 | type: Optional[str] = None, 1711 | limit: Optional[int] = None, 1712 | sort: Optional[str] = None, 1713 | params: Optional[Dict[str, Any]] = None, 1714 | ) -> Dict[str, Any]: 1715 | """ 1716 | Get a paginated list of futures contracts. 1717 | """ 1718 | try: 1719 | results = polygon_client.list_futures_contracts( 1720 | product_code=product_code, 1721 | first_trade_date=first_trade_date, 1722 | last_trade_date=last_trade_date, 1723 | as_of=as_of, 1724 | active=active, 1725 | type=type, 1726 | limit=limit, 1727 | sort=sort, 1728 | params=params, 1729 | raw=True, 1730 | ) 1731 | 1732 | data_str = results.data.decode("utf-8") 1733 | return json.loads(data_str) 1734 | except Exception as e: 1735 | return {"error": str(e)} 1736 | 1737 | 1738 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1739 | async def get_futures_contract_details( 1740 | ticker: str, 1741 | as_of: Optional[Union[str, date]] = None, 1742 | params: Optional[Dict[str, Any]] = None, 1743 | ) -> Dict[str, Any]: 1744 | """ 1745 | Get details for a single futures contract at a specified point in time. 1746 | """ 1747 | try: 1748 | results = polygon_client.get_futures_contract_details( 1749 | ticker=ticker, 1750 | as_of=as_of, 1751 | params=params, 1752 | raw=True, 1753 | ) 1754 | 1755 | data_str = results.data.decode("utf-8") 1756 | return json.loads(data_str) 1757 | except Exception as e: 1758 | return {"error": str(e)} 1759 | 1760 | 1761 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1762 | async def list_futures_products( 1763 | name: Optional[str] = None, 1764 | name_search: Optional[str] = None, 1765 | as_of: Optional[Union[str, date]] = None, 1766 | trading_venue: Optional[str] = None, 1767 | sector: Optional[str] = None, 1768 | sub_sector: Optional[str] = None, 1769 | asset_class: Optional[str] = None, 1770 | asset_sub_class: Optional[str] = None, 1771 | type: Optional[str] = None, 1772 | limit: Optional[int] = None, 1773 | sort: Optional[str] = None, 1774 | params: Optional[Dict[str, Any]] = None, 1775 | ) -> Dict[str, Any]: 1776 | """ 1777 | Get a list of futures products (including combos). 1778 | """ 1779 | try: 1780 | results = polygon_client.list_futures_products( 1781 | name=name, 1782 | name_search=name_search, 1783 | as_of=as_of, 1784 | trading_venue=trading_venue, 1785 | sector=sector, 1786 | sub_sector=sub_sector, 1787 | asset_class=asset_class, 1788 | asset_sub_class=asset_sub_class, 1789 | type=type, 1790 | limit=limit, 1791 | sort=sort, 1792 | params=params, 1793 | raw=True, 1794 | ) 1795 | 1796 | data_str = results.data.decode("utf-8") 1797 | return json.loads(data_str) 1798 | except Exception as e: 1799 | return {"error": str(e)} 1800 | 1801 | 1802 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1803 | async def get_futures_product_details( 1804 | product_code: str, 1805 | type: Optional[str] = None, 1806 | as_of: Optional[Union[str, date]] = None, 1807 | params: Optional[Dict[str, Any]] = None, 1808 | ) -> Dict[str, Any]: 1809 | """ 1810 | Get details for a single futures product as it was at a specific day. 1811 | """ 1812 | try: 1813 | results = polygon_client.get_futures_product_details( 1814 | product_code=product_code, 1815 | type=type, 1816 | as_of=as_of, 1817 | params=params, 1818 | raw=True, 1819 | ) 1820 | 1821 | data_str = results.data.decode("utf-8") 1822 | return json.loads(data_str) 1823 | except Exception as e: 1824 | return {"error": str(e)} 1825 | 1826 | 1827 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1828 | async def list_futures_quotes( 1829 | ticker: str, 1830 | timestamp: Optional[str] = None, 1831 | timestamp_lt: Optional[str] = None, 1832 | timestamp_lte: Optional[str] = None, 1833 | timestamp_gt: Optional[str] = None, 1834 | timestamp_gte: Optional[str] = None, 1835 | session_end_date: Optional[str] = None, 1836 | session_end_date_lt: Optional[str] = None, 1837 | session_end_date_lte: Optional[str] = None, 1838 | session_end_date_gt: Optional[str] = None, 1839 | session_end_date_gte: Optional[str] = None, 1840 | limit: Optional[int] = None, 1841 | sort: Optional[str] = None, 1842 | params: Optional[Dict[str, Any]] = None, 1843 | ) -> Dict[str, Any]: 1844 | """ 1845 | Get quotes for a futures contract in a given time range. 1846 | """ 1847 | try: 1848 | results = polygon_client.list_futures_quotes( 1849 | ticker=ticker, 1850 | timestamp=timestamp, 1851 | timestamp_lt=timestamp_lt, 1852 | timestamp_lte=timestamp_lte, 1853 | timestamp_gt=timestamp_gt, 1854 | timestamp_gte=timestamp_gte, 1855 | session_end_date=session_end_date, 1856 | session_end_date_lt=session_end_date_lt, 1857 | session_end_date_lte=session_end_date_lte, 1858 | session_end_date_gt=session_end_date_gt, 1859 | session_end_date_gte=session_end_date_gte, 1860 | limit=limit, 1861 | sort=sort, 1862 | params=params, 1863 | raw=True, 1864 | ) 1865 | 1866 | data_str = results.data.decode("utf-8") 1867 | return json.loads(data_str) 1868 | except Exception as e: 1869 | return {"error": str(e)} 1870 | 1871 | 1872 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1873 | async def list_futures_trades( 1874 | ticker: str, 1875 | timestamp: Optional[str] = None, 1876 | timestamp_lt: Optional[str] = None, 1877 | timestamp_lte: Optional[str] = None, 1878 | timestamp_gt: Optional[str] = None, 1879 | timestamp_gte: Optional[str] = None, 1880 | session_end_date: Optional[str] = None, 1881 | session_end_date_lt: Optional[str] = None, 1882 | session_end_date_lte: Optional[str] = None, 1883 | session_end_date_gt: Optional[str] = None, 1884 | session_end_date_gte: Optional[str] = None, 1885 | limit: Optional[int] = None, 1886 | sort: Optional[str] = None, 1887 | params: Optional[Dict[str, Any]] = None, 1888 | ) -> Dict[str, Any]: 1889 | """ 1890 | Get trades for a futures contract in a given time range. 1891 | """ 1892 | try: 1893 | results = polygon_client.list_futures_trades( 1894 | ticker=ticker, 1895 | timestamp=timestamp, 1896 | timestamp_lt=timestamp_lt, 1897 | timestamp_lte=timestamp_lte, 1898 | timestamp_gt=timestamp_gt, 1899 | timestamp_gte=timestamp_gte, 1900 | session_end_date=session_end_date, 1901 | session_end_date_lt=session_end_date_lt, 1902 | session_end_date_lte=session_end_date_lte, 1903 | session_end_date_gt=session_end_date_gt, 1904 | session_end_date_gte=session_end_date_gte, 1905 | limit=limit, 1906 | sort=sort, 1907 | params=params, 1908 | raw=True, 1909 | ) 1910 | 1911 | data_str = results.data.decode("utf-8") 1912 | return json.loads(data_str) 1913 | except Exception as e: 1914 | return {"error": str(e)} 1915 | 1916 | 1917 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1918 | async def list_futures_schedules( 1919 | session_end_date: Optional[str] = None, 1920 | trading_venue: Optional[str] = None, 1921 | limit: Optional[int] = None, 1922 | sort: Optional[str] = None, 1923 | params: Optional[Dict[str, Any]] = None, 1924 | ) -> Dict[str, Any]: 1925 | """ 1926 | Get trading schedules for multiple futures products on a specific date. 1927 | """ 1928 | try: 1929 | results = polygon_client.list_futures_schedules( 1930 | session_end_date=session_end_date, 1931 | trading_venue=trading_venue, 1932 | limit=limit, 1933 | sort=sort, 1934 | params=params, 1935 | raw=True, 1936 | ) 1937 | 1938 | data_str = results.data.decode("utf-8") 1939 | return json.loads(data_str) 1940 | except Exception as e: 1941 | return {"error": str(e)} 1942 | 1943 | 1944 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1945 | async def list_futures_schedules_by_product_code( 1946 | product_code: str, 1947 | session_end_date: Optional[str] = None, 1948 | session_end_date_lt: Optional[str] = None, 1949 | session_end_date_lte: Optional[str] = None, 1950 | session_end_date_gt: Optional[str] = None, 1951 | session_end_date_gte: Optional[str] = None, 1952 | limit: Optional[int] = None, 1953 | sort: Optional[str] = None, 1954 | params: Optional[Dict[str, Any]] = None, 1955 | ) -> Dict[str, Any]: 1956 | """ 1957 | Get schedule data for a single futures product across many trading dates. 1958 | """ 1959 | try: 1960 | results = polygon_client.list_futures_schedules_by_product_code( 1961 | product_code=product_code, 1962 | session_end_date=session_end_date, 1963 | session_end_date_lt=session_end_date_lt, 1964 | session_end_date_lte=session_end_date_lte, 1965 | session_end_date_gt=session_end_date_gt, 1966 | session_end_date_gte=session_end_date_gte, 1967 | limit=limit, 1968 | sort=sort, 1969 | params=params, 1970 | raw=True, 1971 | ) 1972 | 1973 | data_str = results.data.decode("utf-8") 1974 | return json.loads(data_str) 1975 | except Exception as e: 1976 | return {"error": str(e)} 1977 | 1978 | 1979 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 1980 | async def list_futures_market_statuses( 1981 | product_code_any_of: Optional[str] = None, 1982 | product_code: Optional[str] = None, 1983 | limit: Optional[int] = None, 1984 | sort: Optional[str] = None, 1985 | params: Optional[Dict[str, Any]] = None, 1986 | ) -> Dict[str, Any]: 1987 | """ 1988 | Get market statuses for futures products. 1989 | """ 1990 | try: 1991 | results = polygon_client.list_futures_market_statuses( 1992 | product_code_any_of=product_code_any_of, 1993 | product_code=product_code, 1994 | limit=limit, 1995 | sort=sort, 1996 | params=params, 1997 | raw=True, 1998 | ) 1999 | 2000 | data_str = results.data.decode("utf-8") 2001 | return json.loads(data_str) 2002 | except Exception as e: 2003 | return {"error": str(e)} 2004 | 2005 | 2006 | @poly_mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) 2007 | async def get_futures_snapshot( 2008 | ticker: Optional[str] = None, 2009 | ticker_any_of: Optional[str] = None, 2010 | ticker_gt: Optional[str] = None, 2011 | ticker_gte: Optional[str] = None, 2012 | ticker_lt: Optional[str] = None, 2013 | ticker_lte: Optional[str] = None, 2014 | product_code: Optional[str] = None, 2015 | product_code_any_of: Optional[str] = None, 2016 | product_code_gt: Optional[str] = None, 2017 | product_code_gte: Optional[str] = None, 2018 | product_code_lt: Optional[str] = None, 2019 | product_code_lte: Optional[str] = None, 2020 | limit: Optional[int] = None, 2021 | sort: Optional[str] = None, 2022 | params: Optional[Dict[str, Any]] = None, 2023 | ) -> Dict[str, Any]: 2024 | """ 2025 | Get snapshots for futures contracts. 2026 | """ 2027 | try: 2028 | results = polygon_client.get_futures_snapshot( 2029 | ticker=ticker, 2030 | ticker_any_of=ticker_any_of, 2031 | ticker_gt=ticker_gt, 2032 | ticker_gte=ticker_gte, 2033 | ticker_lt=ticker_lt, 2034 | ticker_lte=ticker_lte, 2035 | product_code=product_code, 2036 | product_code_any_of=product_code_any_of, 2037 | product_code_gt=product_code_gt, 2038 | product_code_gte=product_code_gte, 2039 | product_code_lt=product_code_lt, 2040 | product_code_lte=product_code_lte, 2041 | limit=limit, 2042 | sort=sort, 2043 | params=params, 2044 | raw=True, 2045 | ) 2046 | 2047 | data_str = results.data.decode("utf-8") 2048 | return json.loads(data_str) 2049 | except Exception as e: 2050 | return {"error": str(e)} 2051 | 2052 | 2053 | # Directly expose the MCP server object 2054 | # It will be run from entrypoint.py 2055 | 2056 | 2057 | def run(transport: Literal["stdio", "sse", "streamable-http"] = "stdio") -> None: 2058 | """Run the Polygon MCP server.""" 2059 | poly_mcp.run(transport) 2060 | ```