Crypto market data via CoinGecko — prices, markets, history, trending, and deep coin metadata.
Runs on your machine from its package; the steps are below.
At most: only reads or looks up information.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
npx -y @cyanheads/coingecko-mcp-server
MCP client config
{
"mcpServers": {
"coingecko": {
"command": "npx",
"args": [
"-y",
"@cyanheads/coingecko-mcp-server"
]
}
}
}Run
npx -y @cyanheads/coingecko-mcp-server
MCP client config
{
"mcpServers": {
"coingecko": {
"command": "npx",
"args": [
"-y",
"@cyanheads/coingecko-mcp-server"
]
}
}
}Market data for 15,000+ cryptocurrencies — prices, history, trends, and deep coin metadata via CoinGecko.
Cryptocurrency market data from CoinGecko — prices, rankings, historical charts, and deep coin profiles across 15,000+ coins. Resolve a name or ticker to CoinGecko's slug-keyed ID, then chain into price lookups, ranked markets, and trend charts.
| Tool | Description |
|---|---|
coingecko_search_coins | Resolve a coin name or ticker symbol to a CoinGecko ID (slug). The required first step before any ID-keyed tool. |
coingecko_get_prices | Current prices and core market stats across coin/currency batches. |
coingecko_list_markets | Ranked market table — coins by market cap, volume, or ID, optionally filtered to a category or selected IDs. |
coingecko_get_coin | Deep single-coin profile — description, links, market data, developer activity, community, sentiment. sections trims the large record. |
coingecko_get_market_chart | Historical price, market cap, and volume series. recent (last N days, auto-granularity) or range (explicit Unix-second window) mode. |
coingecko_get_trending | Coins trending on CoinGecko in the last 24 hours, by search volume. |
coingecko_get_global | Global crypto market snapshot — total market cap and volume, BTC/ETH dominance, active counts, ongoing ICOs, 24h change. |
coingecko_list_categories | Coin categories (category_id + display name) — the valid slugs for coingecko_list_markets's category filter. |
| Resource | Description |
|---|---|
coingecko://coin/{id} | Deep coin record by slug — same data as coingecko_get_coin (full record, USD market figures). |
coingecko://global | Global crypto market snapshot — same data as coingecko_get_global. |
All resource data is also reachable via tools — the resources mirror coingecko_get_coin and coingecko_get_global exactly, so tool-only clients lose nothing. Large collections (markets, categories) are not exposed as resources; use coingecko_list_markets and coingecko_list_categories instead.
| Prompt | Description |
|---|---|
coingecko_coin_research | Guides a full single-coin research pass through the search → get_coin → get_market_chart → get_global chain. |
coingecko_search_coins toolETH/USDC) — returns ranked candidates with id, symbol, name, and marketCapRank to disambiguateenrichment.truncated plus shown/cap disclose when the list is cappedenrichment.notice suggests broadening the querycoingecko_get_prices toolskippedIds lists the rest and missing lists ids that didn't resolve, since an unknown slug returns an empty upstream response rather than an error(id, currency) that returned a price; market cap, 24h volume, and 24h change are optional per row. Currencies with no quotes are noted in enrichment.noticelastUpdatedAtUnixSec is Unix seconds — coingecko_get_market_chart's point timestamps are millisecondsall_missing when no requested id resolves, no_price_data when IDs resolve but no requested currency returns a numeric quotecoingecko_list_markets toolorder; paginate with page and per_page (default 50, max 250 rows)ids (same 500-raw/250-unique bounds as price batches; appliedIds and skippedIds show the selection) or by category (a categoryId from coingecko_list_categories), not both — combining them returns conflicting_filtersenrichment.truncated flags a full pageunknown_category when CoinGecko returns HTTP 404 for a category-filtered requestcoingecko_get_coin toolprofile, market, links, developer, community, sentiment; sections trims the response to just what's needed (the full record is large)vs_currency (defaults to usd); missing upstream fields are omitted rather than fabricatedprofile.categories are display names (e.g. "Layer 1 (L1)"), distinct from the categoryId slugs coingecko_list_categories returnscoin_not_found when the slug isn't recognized upstream, unsupported_currency when the requested market currency isn't a supported onecoingecko_get_market_chart toolrecent mode takes 1–365 days ("max" aliases the 365-day window and emits a notice); range mode takes from/to as Unix secondsinterval selects auto (upstream default), daily, or hourly, subject to upstream tier/window availabilitypoint_offset (default 0) and point_limit (default 100, cap 250); per-series totals and nextPointOffset support continuation, and each page refetches upstream datagranularity reports the series spacing as 5-minute, hourly, daily, irregular, or unknown; point timestamps are Unix milliseconds, while coingecko_get_prices's lastUpdatedAtUnixSec is secondsinvalid_range on a mode/parameter mismatch, coin_not_found when the slug isn't recognizedcoingecko_get_trending toolmarketCapRank, priceUsd, priceBtc, and priceChangePercentage24hUsd when availablenftCount reports the trending-NFT count upstream also returns; NFT detail itself isn't surfacedcoingecko_get_global toolvs_currency (default usd) scopes only total market cap and volume; dominance and the 24h change percentages are always USD-denominated upstreamunsupported_currency when the requested currency has no entry in upstream's per-currency maps — /global has no upstream currency validation, so an unknown code silently returns no totalscoingecko_list_categories toolname_contains filters by whitespace-separated tokens, case- and punctuation-insensitive; every token must appear in the nameenrichment.totalCount reports the full category count before filtering; a filter that matches nothing returns enrichment.noticecategoryId values are what coingecko_list_markets's category param expectscoingecko://coin/{id} resourcecoingecko_get_coin's full record, always denominated in USD{id} is a CoinGecko slug (e.g. "bitcoin") — resolve tickers with coingecko_search_coinscoin_not_found when the slug isn't recognized upstreamcoingecko://global resourcecoingecko_get_global, always denominated in USDcoingecko_coin_research promptcoin required — a name, ticker, or CoinGecko slugBuilt on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
CoinGecko-specific:
x-cg-demo-api-key) raises the rate ceiling with no other config changeRetry-After, and permanent refusals fail immediatelyAgent-friendly output:
coingecko_search_coinsAdd the following to your MCP client configuration file. No API key is required — set COINGECKO_API_KEY only to attach the higher CoinGecko Demo tier (see Configuration).
{
"mcpServers": {
"coingecko-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/coingecko-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"coingecko-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/coingecko-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"coingecko-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/coingecko-mcp-server:latest"
]
}
}
}
To attach a CoinGecko Demo key, add "COINGECKO_API_KEY": "your-demo-key" to the env block (or -e COINGECKO_API_KEY=your-demo-key for Docker).
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/coingecko-mcp-server.git
cd coingecko-mcp-server
bun install
cp .env.example .env
# the server runs with no .env at all; edit only to set COINGECKO_API_KEY
The server runs with zero configuration. The one server-specific variable is optional:
| Variable | Description | Default |
|---|---|---|
COINGECKO_API_KEY | Optional CoinGecko Demo API key, sent as the x-cg-demo-api-key header (10k/mo, 100 req/min). Absent → keyless public tier. | — |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for the HTTP server. | 3010 |
MCP_HTTP_ENDPOINT_PATH | HTTP endpoint path. | /mcp |
MCP_SESSION_MODE | HTTP session mode: stateless, stateful, or auto. | stateless |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry instrumentation (spans, metrics, completion logs). | false |
See .env.example for the full list of optional overrides.
Rate limits and freshness. The keyless public tier shares an IP-throttled pool, so bursty multi-tool workflows can hit 429s under light load; the server backs off and retries, but cannot raise the ceiling — a free Demo key does. CoinGecko data refreshes roughly every 60 seconds and is not tick-level.
Build and run:
# One-time build
bun run rebuild
# Run the built server
bun run start:stdio
# or
bun run start:http
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against spec
docker build -t coingecko-mcp-server .
docker run --rm -e MCP_TRANSPORT_TYPE=http -p 3010:3010 coingecko-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/coingecko-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools/resources/prompts and inits the CoinGecko service. |
src/config | Server-specific environment variable parsing and validation with Zod. |
src/mcp-server/tools | Tool definitions (*.tool.ts). |
src/mcp-server/resources | Resource definitions (*.resource.ts). |
src/mcp-server/prompts | Prompt definitions (*.prompt.ts). |
src/services/coingecko | CoinGecko v3 REST API service — HTTP client, retry/error mapping, response normalization, domain types. |
tests/ | Unit and integration tests mirroring src/. |
See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagecreateApp() arrays in src/index.tsIssues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.