get_exchange_ticker
Retrieve real-time bid, ask, last price, and 24h stats for any symbol on a specific exchange. Solves the need for venue-specific price and spread data by providing ticker details for a given exchange and trading pair.
Instructions
Get a real-time ticker (bid/ask/last/24h stats) for one symbol on one exchange.
Use when the user asks about price on a specific venue ("BTC on Coinbase", "ETH on Binance") or wants tight bid-ask spread info.
Args: exchange_id: CCXT exchange ID, e.g. "binance". symbol: CCXT unified symbol, e.g. "BTC/USDT", "ETH/USD", "BTC/USDT:USDT" for a linear perp on Binance.
Returns:
Ticker object with symbol, timestamp, datetime, bid, ask,
last, high, low, open, close, vwap, baseVolume,
quoteVolume, percentage, change.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| exchange_id | Yes | ||
| symbol | Yes |
Implementation Reference
- coin_mcp/ccxt_tools.py:67-88 (handler)The core handler function for the 'get_exchange_ticker' tool. It is an async function decorated with @mcp.tool(), takes exchange_id and symbol as parameters, and calls CCXT's fetch_ticker(symbol) via the _ccxt_call helper to get real-time bid/ask/last/24h stats.
@mcp.tool() async def get_exchange_ticker(exchange_id: str, symbol: str) -> Any: """Get a real-time ticker (bid/ask/last/24h stats) for one symbol on one exchange. Use when the user asks about price on a specific venue ("BTC on Coinbase", "ETH on Binance") or wants tight bid-ask spread info. Args: exchange_id: CCXT exchange ID, e.g. "binance". symbol: CCXT unified symbol, e.g. "BTC/USDT", "ETH/USD", "BTC/USDT:USDT" for a linear perp on Binance. Returns: Ticker object with `symbol`, `timestamp`, `datetime`, `bid`, `ask`, `last`, `high`, `low`, `open`, `close`, `vwap`, `baseVolume`, `quoteVolume`, `percentage`, `change`. """ def _do() -> Any: ex = _get_ccxt_exchange(exchange_id) return ex.fetch_ticker(symbol) return await _ccxt_call(_do) - coin_mcp/core.py:58-180 (registration)The FastMCP server instance is created here (line 58). The @mcp.tool() decorator on line 67 of ccxt_tools.py registers the handler with this mcp instance. The instructions table on line 104 documents the tool.
mcp = FastMCP( name="coin-mcp", instructions="""\ This MCP server provides comprehensive cryptocurrency market data from multiple complementary sources: - **CoinGecko** — aggregated market data (volume-weighted prices, market cap, OHLC, history, exchange directory, NFTs, categories, derivatives directory, public-company crypto treasuries, trending searches, search index). - **CCXT** — real-time per-exchange data via a unified API for 100+ centralized exchanges (order books, recent trades, tickers, OHLCV candles, market lists, perpetual-futures funding rates). - **DefiLlama** — protocol-level TVL, chain TVL, stablecoin caps, yield pools, DEX volumes, fees & revenue, oracle token prices. - **DexScreener** — DEX-side prices and liquidity for tokens too small or new for CoinGecko aggregation, across all major chains. - **Alternative.me** — Crypto Fear & Greed Index sentiment indicator. - **Local technical indicators** — RSI, MACD, Bollinger, EMA/SMA, ATR computed in-process from any OHLCV input. ================================================================ HOW TO PICK THE RIGHT TOOL (43 tools total) ================================================================ | Question | Tool | |----------|------| | What's BTC's price right now? | get_price | | Tell me about Solana | get_coin_details | | 30-day price/volume/market-cap chart | get_market_chart | | Daily candlesticks for ETH (aggregated) | get_aggregated_ohlc | | Which exchanges support a coin? | get_coin_tickers | | Coin name -> CoinGecko ID (also exchanges/categories/NFTs) | search | | Top 100 coins by market cap | list_top_coins | | What's hot/trending today? | get_trending | | Biggest 24h gainers and losers | get_top_gainers_losers | | Total market cap, BTC dominance | get_global_market | | DeFi TVL totals (high level, CoinGecko view) | get_global_defi | | Categories (Layer 1, DeFi, Meme...) | list_categories | | Browse all exchanges (CoinGecko directory) | list_exchanges_directory | | Single-exchange metadata (CoinGecko directory) | get_exchange_info | | Derivatives platforms | list_derivatives_exchanges | | NFT collections list | list_nfts | | Single NFT collection detail | get_nft_collection | | Public companies holding BTC/ETH | get_companies_holdings | | What exchanges can I query in real time? | list_supported_exchanges | | All trading pairs on Binance/etc. | get_exchange_markets | | Best bid/ask/last on a specific exchange | get_exchange_ticker | | Real-time order book on a specific exchange | get_orderbook | | Recent public trades on a specific exchange | get_recent_trades | | 1-minute candles on Binance for BTC/USDT | get_exchange_ohlcv | | Funding rate for a perp | get_funding_rate | | Sentiment: fearful or greedy? | get_fear_greed_index | | Compute RSI/MACD/Bollinger/ATR/etc on OHLCV | compute_indicators | | Per-protocol TVL / TVL history | get_protocol_tvl | | Browse DefiLlama protocols by TVL | list_protocols | | Chain-level TVL ranking (Ethereum, Solana, ...) | list_chains_tvl | | Historical TVL for one chain or all of DeFi | get_chain_tvl_history | | Stablecoin caps and chain breakdown | list_stablecoins | | Yield-pool APYs | list_yield_pools | | DEX 24h volume rankings | list_dex_volumes | | Per-protocol fees and revenue | list_fees_revenue | | DefiLlama oracle price for `chain:address` tokens | get_token_dex_price | | DEX price for a small/new token (any chain) | dex_search | | All DEX pairs for a given token address | get_dex_token_pairs | | Single DEX pair detail | get_dex_pair | | Newly profiled DEX tokens | list_latest_dex_tokens | | Currently boosted (paid) DEX tokens | list_top_boosted_tokens | | What's currently cached (rate-limit relief) | cache_stats | | Drop the HTTP cache | clear_cache | | Funding-rate time series for a perp | get_funding_rate_history | | Current open interest for a perp | get_open_interest | | Compare funding rates across exchanges | compare_funding_rates | | Are all data sources healthy / fast? | health_check | | Same coin's price across CG + multiple CEX + DEX | compare_prices | | Best bid/ask merged across many exchanges | get_consolidated_orderbook | ================================================================ KEY THINGS TO REMEMBER ================================================================ 1. **CoinGecko uses coin IDs**, not ticker symbols. IDs look like "bitcoin", "ethereum", "solana". Resolve unknown names via `search` first. 2. **CCXT uses unified symbols + exchange IDs.** Symbols: "BTC/USDT", "ETH/USD". Linear perps use settle suffix: "BTC/USDT:USDT". Exchange IDs are lowercase ("binance", "okx", "coinbase", "kraken", "bybit", "kucoin"). 3. **Aggregated vs per-exchange.** CoinGecko = volume-weighted across all venues. CCXT = one specific exchange. Use CoinGecko for "the market"; use CCXT for venue-specific or sub-hour granularity. 4. **DEX vs CEX prices.** For tokens listed on CoinGecko, prefer CoinGecko/ CCXT. For new/long-tail tokens, use DexScreener (`dex_search`, `get_dex_token_pairs`, `get_dex_pair`) or DefiLlama (`get_token_dex_price`). 5. **Default vs_currency is "usd"**. CCXT symbols already encode quote currency. 6. **Rate limits.** CoinGecko public allows ~30 req/min — but this server caches responses with TTLs tuned per endpoint. Repeated identical calls come from cache; check `cache_stats` if surprised by stale data, and `clear_cache` to force-refresh everything. 7. **Time ranges.** `get_market_chart` and `get_aggregated_ohlc` accept a `days` parameter. CoinGecko auto-selects granularity: minute when days<=1, hourly when days<=90, daily otherwise. 8. **Presentation.** Tools return raw numbers. Format prices/percentages/ timestamps appropriately when answering the user. ================================================================ NAMING & VALIDATION CONVENTIONS ================================================================ - Coin / exchange / NFT IDs must match `^[a-z0-9._-]+$` (lowercase slugs). - Token addresses are either EVM (`0x` followed by 40 hex chars) or Solana base58 (32-44 chars). Tools validate the shape before sending requests. - Tools never run network requests until validation passes — invalid input returns a `{"error": ...}` envelope synchronously. - Tools may return `{"error": ...}` envelopes on upstream failure. Callers should check the result with the structured-error helper before assuming success and indexing into other fields. """, ) - coin_mcp/ccxt_tools.py:1-9 (helper)Imports and module dependencies for the CCXT tools module. Imports ccxt for exchange data, and imports _ccxt_call and _get_ccxt_exchange from .core as shared helpers used by get_exchange_ticker.
"""CCXT tools — real-time per-exchange data: tickers, order books, trades, OHLCV, funding rates.""" from __future__ import annotations from typing import Any, Literal import ccxt from .core import _ccxt_call, _get_ccxt_exchange, mcp - coin_mcp/core.py:309-331 (helper)The _ccxt_call helper that runs blocking CCXT calls in a thread executor. It handles error wrapping and per-exchange serialization via locks. Used by get_exchange_ticker to safely invoke ex.fetch_ticker(symbol).
async def _ccxt_call(fn, *args, exchange_id: str | None = None, **kwargs): """Run a blocking CCXT call in a thread; return structured error on failure. When `exchange_id` is supplied, the call is serialized through the per-exchange lock so concurrent fetches against the same instance don't corrupt CCXT's internal session/rate-limit state. When omitted (legacy callers), no lock is taken — preserving prior behavior. """ loop = asyncio.get_running_loop() def _runner(): if exchange_id: with _per_lock(exchange_id): return fn(*args, **kwargs) return fn(*args, **kwargs) try: return await loop.run_in_executor(None, _runner) except ccxt.BaseError as e: return {"error": f"{type(e).__name__}: {e}"} except Exception as e: # pragma: no cover - safety net return {"error": f"unexpected error: {type(e).__name__}: {e}"}