├── Dockerfile ├── README.md ├── pyproject.toml ├── smithery.yaml ├── src └── coin_api_mcp │ ├── __init__.py │ ├── __main__.py │ └── server.py └── uv.lock /Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile 2 | # Use a Python image with uv pre-installed 3 | FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS uv 4 | 5 | # Install the project into /app 6 | WORKDIR /app 7 | 8 | # Enable bytecode compilation 9 | ENV UV_COMPILE_BYTECODE=1 10 | 11 | # Copy from the cache instead of linking since it's a mounted volume 12 | ENV UV_LINK_MODE=copy 13 | 14 | # Install the project's dependencies using the lockfile and settings 15 | RUN --mount=type=cache,target=/root/.cache/uv --mount=type=bind,source=uv.lock,target=uv.lock --mount=type=bind,source=pyproject.toml,target=pyproject.toml uv sync --frozen --no-install-project --no-dev --no-editable 16 | 17 | # Then, add the rest of the project source code and install it 18 | # Installing separately from its dependencies allows optimal layer caching 19 | ADD . /app 20 | RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev --no-editable 21 | 22 | FROM python:3.12-slim-bookworm 23 | 24 | WORKDIR /app 25 | 26 | COPY --from=uv /root/.local /root/.local 27 | COPY --from=uv --chown=app:app /app/.venv /app/.venv 28 | 29 | # Place executables in the environment at the front of the path 30 | ENV PATH="/app/.venv/bin:$PATH" 31 | 32 | # Environment variable for the CoinMarketCap API Key 33 | ENV COINMARKETCAP_API_KEY=your_api_key_here 34 | 35 | ENTRYPOINT ["python", "-m", "coin_api_mcp"] 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Coin MCP Server 2 | 3 | [![smithery badge](https://smithery.ai/badge/coin-api-mcp)](https://smithery.ai/server/coin-api-mcp) 4 | 5 | A Model Context Protocol server that provides access to CoinMarketCap's cryptocurrency data. This server enables AI-powered applications to retrieve cryptocurrency listings, quotes, and detailed information about various coins. 6 | 7 | ### Available Tools 8 | 9 | - `listing-coins` - Fetches a paginated list of all active cryptocurrencies with the latest market data. 10 | - `start` (integer, optional): Offset the start (1-based index) of the paginated list of items to return. 11 | - `limit` (integer, optional): Number of results to return (default: 10, max: 5000). 12 | - `price_min` (number, optional): Minimum USD price to filter results. 13 | - `price_max` (number, optional): Maximum USD price to filter results. 14 | - `market_cap_min` (number, optional): Minimum market cap to filter results. 15 | - `market_cap_max` (number, optional): Maximum market cap to filter results. 16 | - `convert` (string, optional): Calculate market quotes in multiple currencies. 17 | - `sort` (string, optional): Field to sort the list of cryptocurrencies by. 18 | - `sort_dir` (string, optional): Direction to order cryptocurrencies (asc or desc). 19 | 20 | - `get-coin-info` - Retrieves detailed information about a specific cryptocurrency. 21 | - `id` (string, optional): One or more comma-separated CoinMarketCap cryptocurrency IDs. 22 | - `slug` (string, optional): A comma-separated list of cryptocurrency slugs. 23 | - `symbol` (string, optional): One or more comma-separated cryptocurrency symbols. 24 | 25 | - `get-coin-quotes` - Fetches the latest market quotes for one or more cryptocurrencies. 26 | - `id` (string, optional): One or more comma-separated cryptocurrency CoinMarketCap IDs. 27 | - `slug` (string, optional): A comma-separated list of cryptocurrency slugs. 28 | - `symbol` (string, optional): One or more comma-separated cryptocurrency symbols. 29 | 30 | ## Installation 31 | 32 | ### Installing via Smithery 33 | 34 | To install Cryptocurrency Data for Claude Desktop automatically via [Smithery](https://smithery.ai/server/coin-api-mcp): 35 | 36 | ```bash 37 | npx -y @smithery/cli install coin-api-mcp --client claude 38 | ``` 39 | 40 | ### Build the Server 41 | Clone this repository and build and install the program with your default Python interpreter (recommended). 42 | 43 | ```bash 44 | git clone https://github.com/longmans/coin_api_mcp.git 45 | cd coin_api_mcp 46 | uv build 47 | uv pip install . 48 | ``` 49 | 50 | After installation, you can run it as a script using: 51 | 52 | ```bash 53 | python -m coin_api_mcp 54 | ``` 55 | 56 | 57 | 58 | ## Configuration 59 | 60 | ### API Key 61 | 62 | The server requires a CoinMarketCap API key to function. You can obtain one from [CoinMarketCap's website](https://coinmarketcap.com/api/). The API key can be provided in two ways: 63 | 64 | 1. As an environment variable: 65 | ```bash 66 | export COINMARKETCAP_API_KEY=your_api_key_here 67 | ``` 68 | 69 | 2. As a command-line argument: 70 | ```bash 71 | python -m coin_api_mcp --api-key=your_api_key_here 72 | ``` 73 | 74 | 75 | ### Configure for Claude.app 76 | 77 | Add to your Claude settings: 78 | 79 |
80 | Using pip installation 81 | 82 | ```json 83 | "mcpServers": { 84 | "coin_api": { 85 | "command": "python", 86 | "args": ["-m", "coin_api_mcp"] 87 | }, 88 | "env": { 89 | "COINMARKETCAP_API_KEY": "your_api_key_here" 90 | } 91 | } 92 | ``` 93 |
94 | 95 | If you see any issue, you may want to use the full path for the Python interpreter you are using. You can do a `which python` to find out the exact path if needed. 96 | 97 | Remember to set the COINMARKETCAP_API_KEY environment variable or provide it via the --api-key argument. 98 | 99 | 100 | ## Debugging 101 | 102 | You can use the MCP inspector to debug the server 103 | 104 | 105 | ## Contributing 106 | 107 | We encourage contributions to help expand and improve Coin MCP Server. Whether you want to add new search capabilities, enhance existing functionality, or improve documentation, your input is valuable. 108 | 109 | For examples of other MCP servers and implementation patterns, see: 110 | https://github.com/modelcontextprotocol/servers 111 | 112 | Pull requests are welcome! Feel free to contribute new ideas, bug fixes, or enhancements to make Coin MCP Server even more powerful and useful. 113 | 114 | ## License 115 | 116 | Coin MCP Server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository. -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "coin-api-mcp" 3 | version = "0.1.0" 4 | description = "the crypto api" 5 | readme = "README.md" 6 | requires-python = ">=3.12" 7 | dependencies = [ 8 | "httpx>=0.28.1", 9 | "mcp>=1.1.2", 10 | ] 11 | 12 | [build-system] 13 | requires = [ "hatchling",] 14 | build-backend = "hatchling.build" 15 | 16 | [tool.hatch.build.targets.wheel] 17 | packages = ["src/coin_api_mcp"] 18 | 19 | [project.scripts] 20 | coin-api = "coin_api_mcp.__main__:main" 21 | -------------------------------------------------------------------------------- /smithery.yaml: -------------------------------------------------------------------------------- 1 | # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml 2 | 3 | startCommand: 4 | type: stdio 5 | configSchema: 6 | # JSON Schema defining the configuration options for the MCP. 7 | type: object 8 | required: 9 | - coinmarketcapApiKey 10 | properties: 11 | coinmarketcapApiKey: 12 | type: string 13 | description: The API key for the CoinMarketCap server. 14 | commandFunction: 15 | # A function that produces the CLI command to start the MCP on stdio. 16 | |- 17 | config=>({command:'python',args:['-m','coin_api_mcp'],env:{COINMARKETCAP_API_KEY:config.coinmarketcapApiKey}}) 18 | -------------------------------------------------------------------------------- /src/coin_api_mcp/__init__.py: -------------------------------------------------------------------------------- 1 | from . import server 2 | import asyncio 3 | 4 | def main(): 5 | 6 | """MCP coin-api Server - A CoinMarketCap API wrapper for MCP.""" 7 | import argparse 8 | import asyncio 9 | import os 10 | 11 | parser = argparse.ArgumentParser( 12 | description="give a model the ability to get coin/crypto data" 13 | ) 14 | parser.add_argument( 15 | "--api-key", 16 | type=str, 17 | help="CoinMarketCap API key (can also be set via COINMARKETCAP_API_KEY environment variable)", 18 | ) 19 | 20 | args = parser.parse_args() 21 | 22 | # Check for API key in args first, then environment 23 | api_key = args.api_key or os.getenv("COINMARKETCAP_API_KEY") 24 | if not api_key: 25 | parser.error("CoinMarketCap API key must be provided either via --api-key or COINMARKETCAP_API_KEY environment variable") 26 | 27 | """Main entry point for the package.""" 28 | asyncio.run(server.main(api_key)) 29 | 30 | # Optionally expose other important items at package level 31 | __all__ = ['main', 'server'] 32 | -------------------------------------------------------------------------------- /src/coin_api_mcp/__main__.py: -------------------------------------------------------------------------------- 1 | from coin_api_mcp import main 2 | 3 | main() -------------------------------------------------------------------------------- /src/coin_api_mcp/server.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | import asyncio 3 | import httpx 4 | from mcp.server.models import InitializationOptions 5 | import mcp.types as types 6 | from mcp.server import NotificationOptions, Server 7 | import mcp.server.stdio 8 | import urllib.parse 9 | import json 10 | 11 | 12 | API_BASE = "pro-api.coinmarketcap.com" 13 | API_KEY = None 14 | 15 | 16 | 17 | server = Server("coin-api") 18 | 19 | 20 | @server.list_tools() 21 | async def handle_list_tools() -> list[types.Tool]: 22 | """ 23 | List available tools. 24 | Each tool specifies its arguments using JSON Schema validation. 25 | """ 26 | return [ 27 | types.Tool( 28 | name="listing-coins", 29 | description="Returns a paginated list of all active cryptocurrencies with latest market data", 30 | inputSchema={ 31 | "type": "object", 32 | "properties": { 33 | "start": { 34 | "type": "integer", 35 | "description": "Optionally offset the start (1-based index) of the paginated list of items to return.", 36 | "minimum": 1, 37 | }, 38 | "limit": { 39 | "type": "integer", 40 | "description": "Optionally specify the number of results to return.", 41 | "minimum": 1, 42 | "maximum": 5000, 43 | }, 44 | "price_min": { 45 | "type": "number", 46 | "description": "Optionally specify a threshold of minimum USD price to filter results by.", 47 | "minimum": 0, 48 | }, 49 | "price_max": { 50 | "type": "number", 51 | "description": "Optionally specify a threshold of maximum USD price to filter results by.", 52 | "minimum": 0, 53 | }, 54 | "market_cap_min": { 55 | "type": "number", 56 | "description": "Optionally specify a threshold of minimum market cap to filter results by.", 57 | "minimum": 0, 58 | }, 59 | "market_cap_max": { 60 | "type": "number", 61 | "description": "Optionally specify a threshold of maximum market cap to filter results by.", 62 | "minimum": 0, 63 | }, 64 | "volume_24h_min": { 65 | "type": "number", 66 | "description": "Optionally specify a threshold of minimum 24 hour USD volume to filter results by.", 67 | "minimum": 0, 68 | }, 69 | "volume_24h_max": { 70 | "type": "number", 71 | "description": "Optionally specify a threshold of maximum 24 hour USD volume to filter results by.", 72 | "minimum": 0, 73 | }, 74 | "circulating_supply_min": { 75 | "type": "number", 76 | "description": "Optionally specify a threshold of minimum circulating supply to filter results by.", 77 | "minimum": 0, 78 | }, 79 | "circulating_supply_max": { 80 | "type": "number", 81 | "description": "Optionally specify a threshold of maximum circulating supply to filter results by.", 82 | "minimum": 0, 83 | }, 84 | "percent_change_24h_min": { 85 | "type": "number", 86 | "description": "Optionally specify a threshold of minimum 24 hour percent change to filter results by.", 87 | "minimum": -100, 88 | }, 89 | "percent_change_24h_max": { 90 | "type": "number", 91 | "description": "Optionally specify a threshold of maximum 24 hour percent change to filter results by.", 92 | "minimum": -100, 93 | }, 94 | "convert": { 95 | "type": "string", 96 | "description": "Optionally calculate market quotes in up to 120 currencies at once by passing a comma-separated list of cryptocurrency or fiat currency symbols.", 97 | }, 98 | "convert_id": { 99 | "type": "string", 100 | "description": "Optionally calculate market quotes by CoinMarketCap ID instead of symbol.", 101 | }, 102 | "sort": { 103 | "type": "string", 104 | "description": "What field to sort the list of cryptocurrencies by.", 105 | "enum": [ 106 | "market_cap", 107 | "name", 108 | "symbol", 109 | "date_added", 110 | "market_cap_strict", 111 | "price", 112 | "circulating_supply", 113 | "total_supply", 114 | "max_supply", 115 | "num_market_pairs", 116 | "volume_24h", 117 | "percent_change_1h", 118 | "percent_change_24h", 119 | "percent_change_7d", 120 | "market_cap_by_total_supply_strict", 121 | "volume_7d", 122 | "volume_30d", 123 | ], 124 | }, 125 | "sort_dir": { 126 | "type": "string", 127 | "description": "The direction in which to order cryptocurrencies against the specified sort.", 128 | "enum": ["asc", "desc"], 129 | }, 130 | "cryptocurrency_type": { 131 | "type": "string", 132 | "description": "The type of cryptocurrency to include.", 133 | "enum": ["all", "coins", "tokens"], 134 | }, 135 | "tag": { 136 | "type": "string", 137 | "description": "The tag of cryptocurrency to include.", 138 | "enum": ["all", "defi", "filesharing"], 139 | }, 140 | "aux": { 141 | "type": "string", 142 | "description": "Optionally specify a comma-separated list of supplemental data fields to return.", 143 | }, 144 | 145 | }, 146 | "required": [], 147 | }, 148 | ), 149 | types.Tool( 150 | name="get-coin-info", 151 | description="Get coins' information includes details like logo, description, official website URL, social links, and links to a cryptocurrency's technical documentation.", 152 | inputSchema={ 153 | "type": "object", 154 | "properties": { 155 | "id": { 156 | "type": "string", 157 | "description": "One or more comma-separated CoinMarketCap cryptocurrency IDs. Example: \"1,2\"", 158 | }, 159 | "slug": { 160 | "type": "string", 161 | "description": "Alternatively pass a comma-separated list of cryptocurrency slugs. Example: \"bitcoin,ethereum\"", 162 | }, 163 | "symbol": { 164 | "type": "string", 165 | "description": "Alternatively pass one or more comma-separated cryptocurrency symbols. Example: \"BTC,ETH\"", 166 | }, 167 | "address": { 168 | "type": "string", 169 | "description": "Alternatively pass in a contract address. Example: \"0xc40af1e4fecfa05ce6bab79dcd8b373d2e436c4e\"", 170 | }, 171 | "skip_invalid": { 172 | "type": "boolean", 173 | "description": "Pass true to relax request validation rules. When requesting records on multiple cryptocurrencies an error is returned if any invalid cryptocurrencies are requested or a cryptocurrency does not have matching records in the requested timeframe. If set to true, invalid lookups will be skipped allowing valid cryptocurrencies to still be returned.", 174 | "default": False, 175 | }, 176 | "aux": { 177 | "type": "string", 178 | "description": "Optionally specify a comma-separated list of supplemental data fields to return. Pass urls,logo,description,tags,platform,date_added,notice,status to include all auxiliary fields.", 179 | }, 180 | }, 181 | "required": [], 182 | } 183 | ), 184 | types.Tool( 185 | name="get-coin-quotes", 186 | description='''the latest market quote for 1 or more cryptocurrencies. Use the "convert" option to return market values in multiple fiat and cryptocurrency conversions in the same call.''', 187 | inputSchema={ 188 | "type": "object", 189 | "properties": { 190 | "id": { 191 | "type": "string", 192 | "description": "One or more comma-separated cryptocurrency CoinMarketCap IDs. Example: 1,2", 193 | }, 194 | "slug": { 195 | "type": "string", 196 | "description": "Alternatively pass a comma-separated list of cryptocurrency slugs. Example: \"bitcoin,ethereum\"", 197 | }, 198 | "symbol": { 199 | "type": "string", 200 | "description": "Alternatively pass one or more comma-separated cryptocurrency symbols. Example: \"BTC,ETH\"", 201 | }, 202 | "convert": { 203 | "type": "string", 204 | "description": "Optionally calculate market quotes in up to 120 currencies at once by passing a comma-separated list of cryptocurrency or fiat currency symbols.", 205 | }, 206 | "convert_id": { 207 | "type": "string", 208 | "description": "Optionally calculate market quotes by CoinMarketCap ID instead of symbol. This option is identical to convert outside of ID format.", 209 | }, 210 | "aux": { 211 | "type": "string", 212 | "description": "\"num_market_pairs,cmc_rank,date_added,tags,platform,max_supply,circulating_supply,total_supply,is_active,is_fiat\"Optionally specify a comma-separated list of supplemental data fields to return.", 213 | }, 214 | "skip_invalid": { 215 | "type": "boolean", 216 | "description": "Pass true to relax request validation rules.", 217 | "default": False, 218 | }, 219 | }, 220 | "required": [], 221 | }, 222 | ), 223 | ] 224 | 225 | 226 | async def make_coinmarketcap_request(client: httpx.AsyncClient, url: str) -> dict[str, Any] | None: 227 | """Make a request to the CoinMarketCap API with proper error handling.""" 228 | headers = { 229 | 'Accepts': 'application/json', 230 | 'X-CMC_PRO_API_KEY': API_KEY, 231 | } 232 | try: 233 | response = await client.get(url, headers=headers, timeout=10.0) 234 | response.raise_for_status() 235 | return response.json() 236 | except Exception: 237 | return None 238 | 239 | 240 | @server.call_tool() 241 | async def handle_call_tool( 242 | name: str, arguments: dict | None 243 | ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: 244 | """ 245 | Handle tool execution requests. 246 | Currently supported tools: 247 | - listing-coins: fetches a list of all cryptocurrencies. 248 | - get-coin-quotes: fetches quotes for a specific cryptocurrency. 249 | - get-coin-info: fetches information for a specific cryptocurrency. 250 | """ 251 | 252 | if name == "listing-coins": 253 | request_data = {} 254 | if arguments is not None: 255 | condi_keys = [ 256 | "start", 257 | "limit", 258 | "price_min", 259 | "price_max", 260 | "market_cap_min", 261 | "market_cap_max", 262 | "volume_24h_min", 263 | "volume_24h_max", 264 | "circulating_supply_min", 265 | "circulating_supply_max", 266 | "percent_change_24h_min", 267 | "percent_change_24h_max", 268 | "convert", 269 | "convert_id", 270 | "sort", 271 | "sort_dir", 272 | "cryptocurrency_type", 273 | "tag", 274 | "aux", 275 | ] 276 | 277 | for key in arguments.keys(): 278 | if key in condi_keys: 279 | request_data[key] = arguments[key] 280 | 281 | async with httpx.AsyncClient() as client: 282 | listing_url = f"https://{API_BASE}/v1/cryptocurrency/listings/latest?{urllib.parse.urlencode(request_data)}" 283 | 284 | listing_data = await make_coinmarketcap_request(client, listing_url) 285 | 286 | if not listing_data: 287 | return [types.TextContent(type="text", text="Failed to retrieve listing data")] 288 | 289 | return [ 290 | types.TextContent( 291 | type="text", 292 | text=json.dumps(listing_data) 293 | ) 294 | ] 295 | elif name == "get-coin-info": 296 | request_data = {} 297 | if arguments is not None: 298 | condi_keys = [ 299 | "id", 300 | "slug", 301 | "symbol", 302 | "address", 303 | "skip_invalid", 304 | "aux", 305 | ] 306 | 307 | for key in arguments.keys(): 308 | if key in condi_keys: 309 | request_data[key] = arguments[key] 310 | 311 | async with httpx.AsyncClient() as client: 312 | coin_info_url = f"https://{API_BASE}/v2/cryptocurrency/info?{urllib.parse.urlencode(request_data)}" 313 | 314 | coin_info_data = await make_coinmarketcap_request(client, coin_info_url) 315 | 316 | if not coin_info_data: 317 | return [types.TextContent(type="text", text="Failed to retrieve coin info data")] 318 | 319 | return [ 320 | types.TextContent( 321 | type="text", 322 | text=json.dumps(coin_info_data) 323 | ) 324 | ] 325 | elif name == "get-coin-quotes": 326 | request_data = {} 327 | if arguments is not None: 328 | condi_keys = [ 329 | "id", 330 | "slug", 331 | "symbol", 332 | "convert", 333 | "convert_id", 334 | "aux", 335 | "skip_invalid", 336 | ] 337 | 338 | for key in arguments.keys(): 339 | if key in condi_keys: 340 | request_data[key] = arguments[key] 341 | 342 | async with httpx.AsyncClient() as client: 343 | coin_quotes_url = f"https://{API_BASE}/v2/cryptocurrency/quotes/latest?{urllib.parse.urlencode(request_data)}" 344 | 345 | coin_quotes_data = await make_coinmarketcap_request(client, coin_quotes_url) 346 | 347 | if not coin_quotes_data: 348 | return [types.TextContent(type="text", text="Failed to retrieve coin quotes data")] 349 | 350 | return [ 351 | types.TextContent( 352 | type="text", 353 | text=json.dumps(coin_quotes_data) 354 | ) 355 | ] 356 | else: 357 | raise ValueError(f"Unknown tool: {name}") 358 | 359 | 360 | 361 | 362 | async def main(api_key: str): 363 | global API_KEY 364 | API_KEY = api_key 365 | # Run the server using stdin/stdout streams 366 | async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): 367 | await server.run( 368 | read_stream, 369 | write_stream, 370 | InitializationOptions( 371 | server_name="coin-api", 372 | server_version="0.1.0", 373 | capabilities=server.get_capabilities( 374 | notification_options=NotificationOptions(), 375 | experimental_capabilities={}, 376 | ), 377 | ), 378 | ) 379 | 380 | # This is needed if you'd like to connect to a custom client 381 | if __name__ == "__main__": 382 | #get api key from coinmarketcap 383 | api_key = "xxxxxxx" 384 | asyncio.run(main(api_key)) -------------------------------------------------------------------------------- /uv.lock: -------------------------------------------------------------------------------- 1 | version = 1 2 | requires-python = ">=3.12" 3 | 4 | [[package]] 5 | name = "annotated-types" 6 | version = "0.7.0" 7 | source = { registry = "https://pypi.org/simple" } 8 | sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } 9 | wheels = [ 10 | { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, 11 | ] 12 | 13 | [[package]] 14 | name = "anyio" 15 | version = "4.7.0" 16 | source = { registry = "https://pypi.org/simple" } 17 | dependencies = [ 18 | { name = "idna" }, 19 | { name = "sniffio" }, 20 | { name = "typing-extensions", marker = "python_full_version < '3.13'" }, 21 | ] 22 | sdist = { url = "https://files.pythonhosted.org/packages/f6/40/318e58f669b1a9e00f5c4453910682e2d9dd594334539c7b7817dabb765f/anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48", size = 177076 } 23 | wheels = [ 24 | { url = "https://files.pythonhosted.org/packages/a0/7a/4daaf3b6c08ad7ceffea4634ec206faeff697526421c20f07628c7372156/anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352", size = 93052 }, 25 | ] 26 | 27 | [[package]] 28 | name = "certifi" 29 | version = "2024.12.14" 30 | source = { registry = "https://pypi.org/simple" } 31 | sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } 32 | wheels = [ 33 | { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, 34 | ] 35 | 36 | [[package]] 37 | name = "click" 38 | version = "8.1.7" 39 | source = { registry = "https://pypi.org/simple" } 40 | dependencies = [ 41 | { name = "colorama", marker = "platform_system == 'Windows'" }, 42 | ] 43 | sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } 44 | wheels = [ 45 | { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, 46 | ] 47 | 48 | [[package]] 49 | name = "coin-api" 50 | version = "0.1.0" 51 | source = { editable = "." } 52 | dependencies = [ 53 | { name = "httpx" }, 54 | { name = "mcp" }, 55 | ] 56 | 57 | [package.metadata] 58 | requires-dist = [ 59 | { name = "httpx", specifier = ">=0.28.1" }, 60 | { name = "mcp", specifier = ">=1.1.2" }, 61 | ] 62 | 63 | [[package]] 64 | name = "colorama" 65 | version = "0.4.6" 66 | source = { registry = "https://pypi.org/simple" } 67 | sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } 68 | wheels = [ 69 | { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, 70 | ] 71 | 72 | [[package]] 73 | name = "h11" 74 | version = "0.14.0" 75 | source = { registry = "https://pypi.org/simple" } 76 | sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } 77 | wheels = [ 78 | { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, 79 | ] 80 | 81 | [[package]] 82 | name = "httpcore" 83 | version = "1.0.7" 84 | source = { registry = "https://pypi.org/simple" } 85 | dependencies = [ 86 | { name = "certifi" }, 87 | { name = "h11" }, 88 | ] 89 | sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 } 90 | wheels = [ 91 | { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 }, 92 | ] 93 | 94 | [[package]] 95 | name = "httpx" 96 | version = "0.28.1" 97 | source = { registry = "https://pypi.org/simple" } 98 | dependencies = [ 99 | { name = "anyio" }, 100 | { name = "certifi" }, 101 | { name = "httpcore" }, 102 | { name = "idna" }, 103 | ] 104 | sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } 105 | wheels = [ 106 | { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, 107 | ] 108 | 109 | [[package]] 110 | name = "httpx-sse" 111 | version = "0.4.0" 112 | source = { registry = "https://pypi.org/simple" } 113 | sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 } 114 | wheels = [ 115 | { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 }, 116 | ] 117 | 118 | [[package]] 119 | name = "idna" 120 | version = "3.10" 121 | source = { registry = "https://pypi.org/simple" } 122 | sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } 123 | wheels = [ 124 | { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, 125 | ] 126 | 127 | [[package]] 128 | name = "mcp" 129 | version = "1.1.2" 130 | source = { registry = "https://pypi.org/simple" } 131 | dependencies = [ 132 | { name = "anyio" }, 133 | { name = "httpx" }, 134 | { name = "httpx-sse" }, 135 | { name = "pydantic" }, 136 | { name = "sse-starlette" }, 137 | { name = "starlette" }, 138 | ] 139 | sdist = { url = "https://files.pythonhosted.org/packages/9b/f3/5cf212e60681ea6da0dbb6e0d1bc0ab2dbf5eebc749b69663d46f114fea1/mcp-1.1.2.tar.gz", hash = "sha256:694aa9df7a8641b24953c935eb72c63136dc948981021525a0add199bdfee402", size = 57628 } 140 | wheels = [ 141 | { url = "https://files.pythonhosted.org/packages/df/40/9883eac3718b860d4006eba1920bfcb628f0a1fe37fac46a4f4e391edca6/mcp-1.1.2-py3-none-any.whl", hash = "sha256:a4d32d60fd80a1702440ba4751b847a8a88957a1f7b059880953143e9759965a", size = 36652 }, 142 | ] 143 | 144 | [[package]] 145 | name = "pydantic" 146 | version = "2.10.3" 147 | source = { registry = "https://pypi.org/simple" } 148 | dependencies = [ 149 | { name = "annotated-types" }, 150 | { name = "pydantic-core" }, 151 | { name = "typing-extensions" }, 152 | ] 153 | sdist = { url = "https://files.pythonhosted.org/packages/45/0f/27908242621b14e649a84e62b133de45f84c255eecb350ab02979844a788/pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9", size = 786486 } 154 | wheels = [ 155 | { url = "https://files.pythonhosted.org/packages/62/51/72c18c55cf2f46ff4f91ebcc8f75aa30f7305f3d726be3f4ebffb4ae972b/pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d", size = 456997 }, 156 | ] 157 | 158 | [[package]] 159 | name = "pydantic-core" 160 | version = "2.27.1" 161 | source = { registry = "https://pypi.org/simple" } 162 | dependencies = [ 163 | { name = "typing-extensions" }, 164 | ] 165 | sdist = { url = "https://files.pythonhosted.org/packages/a6/9f/7de1f19b6aea45aeb441838782d68352e71bfa98ee6fa048d5041991b33e/pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235", size = 412785 } 166 | wheels = [ 167 | { url = "https://files.pythonhosted.org/packages/be/51/2e9b3788feb2aebff2aa9dfbf060ec739b38c05c46847601134cc1fed2ea/pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f", size = 1895239 }, 168 | { url = "https://files.pythonhosted.org/packages/7b/9e/f8063952e4a7d0127f5d1181addef9377505dcce3be224263b25c4f0bfd9/pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02", size = 1805070 }, 169 | { url = "https://files.pythonhosted.org/packages/2c/9d/e1d6c4561d262b52e41b17a7ef8301e2ba80b61e32e94520271029feb5d8/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c", size = 1828096 }, 170 | { url = "https://files.pythonhosted.org/packages/be/65/80ff46de4266560baa4332ae3181fffc4488ea7d37282da1a62d10ab89a4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac", size = 1857708 }, 171 | { url = "https://files.pythonhosted.org/packages/d5/ca/3370074ad758b04d9562b12ecdb088597f4d9d13893a48a583fb47682cdf/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb", size = 2037751 }, 172 | { url = "https://files.pythonhosted.org/packages/b1/e2/4ab72d93367194317b99d051947c071aef6e3eb95f7553eaa4208ecf9ba4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529", size = 2733863 }, 173 | { url = "https://files.pythonhosted.org/packages/8a/c6/8ae0831bf77f356bb73127ce5a95fe115b10f820ea480abbd72d3cc7ccf3/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35", size = 2161161 }, 174 | { url = "https://files.pythonhosted.org/packages/f1/f4/b2fe73241da2429400fc27ddeaa43e35562f96cf5b67499b2de52b528cad/pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089", size = 1993294 }, 175 | { url = "https://files.pythonhosted.org/packages/77/29/4bb008823a7f4cc05828198153f9753b3bd4c104d93b8e0b1bfe4e187540/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381", size = 2001468 }, 176 | { url = "https://files.pythonhosted.org/packages/f2/a9/0eaceeba41b9fad851a4107e0cf999a34ae8f0d0d1f829e2574f3d8897b0/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb", size = 2091413 }, 177 | { url = "https://files.pythonhosted.org/packages/d8/36/eb8697729725bc610fd73940f0d860d791dc2ad557faaefcbb3edbd2b349/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae", size = 2154735 }, 178 | { url = "https://files.pythonhosted.org/packages/52/e5/4f0fbd5c5995cc70d3afed1b5c754055bb67908f55b5cb8000f7112749bf/pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c", size = 1833633 }, 179 | { url = "https://files.pythonhosted.org/packages/ee/f2/c61486eee27cae5ac781305658779b4a6b45f9cc9d02c90cb21b940e82cc/pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16", size = 1986973 }, 180 | { url = "https://files.pythonhosted.org/packages/df/a6/e3f12ff25f250b02f7c51be89a294689d175ac76e1096c32bf278f29ca1e/pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e", size = 1883215 }, 181 | { url = "https://files.pythonhosted.org/packages/0f/d6/91cb99a3c59d7b072bded9959fbeab0a9613d5a4935773c0801f1764c156/pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073", size = 1895033 }, 182 | { url = "https://files.pythonhosted.org/packages/07/42/d35033f81a28b27dedcade9e967e8a40981a765795c9ebae2045bcef05d3/pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08", size = 1807542 }, 183 | { url = "https://files.pythonhosted.org/packages/41/c2/491b59e222ec7e72236e512108ecad532c7f4391a14e971c963f624f7569/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf", size = 1827854 }, 184 | { url = "https://files.pythonhosted.org/packages/e3/f3/363652651779113189cefdbbb619b7b07b7a67ebb6840325117cc8cc3460/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737", size = 1857389 }, 185 | { url = "https://files.pythonhosted.org/packages/5f/97/be804aed6b479af5a945daec7538d8bf358d668bdadde4c7888a2506bdfb/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2", size = 2037934 }, 186 | { url = "https://files.pythonhosted.org/packages/42/01/295f0bd4abf58902917e342ddfe5f76cf66ffabfc57c2e23c7681a1a1197/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107", size = 2735176 }, 187 | { url = "https://files.pythonhosted.org/packages/9d/a0/cd8e9c940ead89cc37812a1a9f310fef59ba2f0b22b4e417d84ab09fa970/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51", size = 2160720 }, 188 | { url = "https://files.pythonhosted.org/packages/73/ae/9d0980e286627e0aeca4c352a60bd760331622c12d576e5ea4441ac7e15e/pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a", size = 1992972 }, 189 | { url = "https://files.pythonhosted.org/packages/bf/ba/ae4480bc0292d54b85cfb954e9d6bd226982949f8316338677d56541b85f/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc", size = 2001477 }, 190 | { url = "https://files.pythonhosted.org/packages/55/b7/e26adf48c2f943092ce54ae14c3c08d0d221ad34ce80b18a50de8ed2cba8/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960", size = 2091186 }, 191 | { url = "https://files.pythonhosted.org/packages/ba/cc/8491fff5b608b3862eb36e7d29d36a1af1c945463ca4c5040bf46cc73f40/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23", size = 2154429 }, 192 | { url = "https://files.pythonhosted.org/packages/78/d8/c080592d80edd3441ab7f88f865f51dae94a157fc64283c680e9f32cf6da/pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05", size = 1833713 }, 193 | { url = "https://files.pythonhosted.org/packages/83/84/5ab82a9ee2538ac95a66e51f6838d6aba6e0a03a42aa185ad2fe404a4e8f/pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337", size = 1987897 }, 194 | { url = "https://files.pythonhosted.org/packages/df/c3/b15fb833926d91d982fde29c0624c9f225da743c7af801dace0d4e187e71/pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5", size = 1882983 }, 195 | ] 196 | 197 | [[package]] 198 | name = "sniffio" 199 | version = "1.3.1" 200 | source = { registry = "https://pypi.org/simple" } 201 | sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } 202 | wheels = [ 203 | { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, 204 | ] 205 | 206 | [[package]] 207 | name = "sse-starlette" 208 | version = "2.1.3" 209 | source = { registry = "https://pypi.org/simple" } 210 | dependencies = [ 211 | { name = "anyio" }, 212 | { name = "starlette" }, 213 | { name = "uvicorn" }, 214 | ] 215 | sdist = { url = "https://files.pythonhosted.org/packages/72/fc/56ab9f116b2133521f532fce8d03194cf04dcac25f583cf3d839be4c0496/sse_starlette-2.1.3.tar.gz", hash = "sha256:9cd27eb35319e1414e3d2558ee7414487f9529ce3b3cf9b21434fd110e017169", size = 19678 } 216 | wheels = [ 217 | { url = "https://files.pythonhosted.org/packages/52/aa/36b271bc4fa1d2796311ee7c7283a3a1c348bad426d37293609ca4300eef/sse_starlette-2.1.3-py3-none-any.whl", hash = "sha256:8ec846438b4665b9e8c560fcdea6bc8081a3abf7942faa95e5a744999d219772", size = 9383 }, 218 | ] 219 | 220 | [[package]] 221 | name = "starlette" 222 | version = "0.42.0" 223 | source = { registry = "https://pypi.org/simple" } 224 | dependencies = [ 225 | { name = "anyio" }, 226 | ] 227 | sdist = { url = "https://files.pythonhosted.org/packages/3e/ae/0c98794b248370ce30f71018d0f39889f1d90c73a631e68e2f47e5efda2f/starlette-0.42.0.tar.gz", hash = "sha256:91f1fbd612f3e3d821a8a5f46bf381afe2a9722a7b8bbde1c07fb83384c2882a", size = 2575136 } 228 | wheels = [ 229 | { url = "https://files.pythonhosted.org/packages/c0/38/f790c69b2cbfe9cd4a8a89db1ef50d0a10e5121c07ff8b1d7c16d7807f41/starlette-0.42.0-py3-none-any.whl", hash = "sha256:02f877201a3d6d301714b5c72f15cac305ea5cc9e213c4b46a5af7eecad0d625", size = 73356 }, 230 | ] 231 | 232 | [[package]] 233 | name = "typing-extensions" 234 | version = "4.12.2" 235 | source = { registry = "https://pypi.org/simple" } 236 | sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } 237 | wheels = [ 238 | { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, 239 | ] 240 | 241 | [[package]] 242 | name = "uvicorn" 243 | version = "0.33.0" 244 | source = { registry = "https://pypi.org/simple" } 245 | dependencies = [ 246 | { name = "click" }, 247 | { name = "h11" }, 248 | ] 249 | sdist = { url = "https://files.pythonhosted.org/packages/cb/81/a083ae41716b00df56d45d4b5f6ca8e90fc233a62e6c04ab3ad3c476b6c4/uvicorn-0.33.0.tar.gz", hash = "sha256:3577119f82b7091cf4d3d4177bfda0bae4723ed92ab1439e8d779de880c9cc59", size = 76590 } 250 | wheels = [ 251 | { url = "https://files.pythonhosted.org/packages/98/79/2e2620337ef1e4ef7a058b351603b765f59ac28e6e3ac7c5e7cdee9ea1ab/uvicorn-0.33.0-py3-none-any.whl", hash = "sha256:2c30de4aeea83661a520abab179b24084a0019c0c1bbe137e5409f741cbde5f8", size = 62297 }, 252 | ] 253 | --------------------------------------------------------------------------------