@coinpaprika/mcp 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  All notable changes to the CoinPaprika MCP Server will be documented in this file.
4
4
 
5
+ ## [1.3.1] - 2026-07-29
6
+
7
+ ### Changed
8
+
9
+ - **Registered tool descriptions now carry the full intent-first text.** The 1.3.0 rewrite reached the `getCapabilities` manifest and the hosted worker, but the actual `server.tool()` registrations still shipped two-word stubs (`"Exchange details"`, `"Tag details"`), which is what MCP clients and catalogs read from `tools/list`. All 29 data-tool descriptions were rewritten to state the action and return value, give usage guidance and sibling alternatives, disclose that every tool is read-only and note plan requirements for paid-tier tools, and add parameter intent beyond the schema. No behavior, parameter, or output change.
10
+
11
+ ## [1.3.0] - 2026-07-27
12
+
13
+ ### Changed
14
+
15
+ - **Intent-first tool descriptions.** Every tool description was rewritten so agents select the right tool from the description alone, each leading with what the tool returns plus `Use when asked '...'` cues (e.g. `getTickers` vs `getCoinById` vs `getContracts`). Matches the descriptions now served by the hosted worker at `mcp.coinpaprika.com`, so hosted and self-host read identically.
16
+ - `getCapabilities` description aligned with the hosted worker (onboarding-first wording; clarifies it describes the MCP server itself, not crypto data).
17
+
18
+ ### Added
19
+
20
+ - `server.json` manifest for publication to the official MCP Registry (`registry.modelcontextprotocol.io`).
21
+
5
22
  ## [1.1.1] - 2026-05-05
6
23
 
7
24
  ### Fixed
package/README.md CHANGED
@@ -12,7 +12,7 @@ npm install -g @coinpaprika/mcp
12
12
  coinpaprika-mcp
13
13
 
14
14
  # Or run directly without installation
15
- npx @coinpaprika/mcp
15
+ npx @coinpaprika/mcp@latest
16
16
  ```
17
17
 
18
18
  CoinPaprika MCP connects Claude to live crypto market data for 8,000+ coins. No API key required for free-tier features. [Installation](#installation) | [Configuration](#claude-desktop-integration) | [API Reference](https://api.coinpaprika.com)
@@ -25,7 +25,7 @@ CoinPaprika MCP connects Claude to live crypto market data for 8,000+ coins. No
25
25
  - **Coin Analysis Tools**: Deep-dive into any cryptocurrency — price, team, events, exchanges, and markets
26
26
  - **Price Trackers**: Track prices across multiple quote currencies with historical OHLCV data
27
27
  - **Exchange Comparisons**: Compare trading pairs and volumes across 200+ exchanges
28
- - **Portfolio Valuations**: Convert between currencies and track price changes over time
28
+ - **Portfolio Valuations**: Convert an amount between currencies ('0.5 BTC in USD') and track price changes over time
29
29
  - **Contract Lookup**: Find tokens by their smart contract address across multiple platforms
30
30
 
31
31
  ## Installation
@@ -59,7 +59,7 @@ Add the following to your Claude Desktop configuration file:
59
59
  "mcpServers": {
60
60
  "coinpaprika": {
61
61
  "command": "npx",
62
- "args": ["@coinpaprika/mcp"]
62
+ "args": ["@coinpaprika/mcp@latest"]
63
63
  }
64
64
  }
65
65
  }
@@ -72,7 +72,7 @@ Add the following to your Claude Desktop configuration file:
72
72
  "mcpServers": {
73
73
  "coinpaprika": {
74
74
  "command": "npx",
75
- "args": ["@coinpaprika/mcp"],
75
+ "args": ["@coinpaprika/mcp@latest"],
76
76
  "env": {
77
77
  "COINPAPRIKA_API_KEY": "your-api-key-here"
78
78
  }
@@ -85,10 +85,10 @@ Add the following to your Claude Desktop configuration file:
85
85
 
86
86
  ```bash
87
87
  # Add as MCP server in Claude Code
88
- claude mcp add coinpaprika -- npx @coinpaprika/mcp
88
+ claude mcp add coinpaprika -- npx @coinpaprika/mcp@latest
89
89
 
90
90
  # With API key
91
- COINPAPRIKA_API_KEY=your-key claude mcp add coinpaprika -- npx @coinpaprika/mcp
91
+ COINPAPRIKA_API_KEY=your-key claude mcp add coinpaprika -- npx @coinpaprika/mcp@latest
92
92
  ```
93
93
 
94
94
  ### Hosted Alternative (No Installation)
@@ -122,27 +122,27 @@ If you prefer zero setup, point any MCP-compatible client directly at the hosted
122
122
  |------|-------------|
123
123
  | `getCapabilities` | Server capabilities, workflow patterns, validation rules, and best practices. **Start here.** |
124
124
  | `status` | Server status and configuration |
125
- | `getGlobal` | Global crypto market overview (market cap, volume, BTC dominance) |
125
+ | `getGlobal` | Global market overview: total market cap, 24h volume, BTC dominance ('how is the market doing') |
126
126
 
127
127
  ### Coins
128
128
 
129
129
  | Tool | Description | Required Parameters |
130
130
  |------|-------------|---------------------|
131
- | `getCoins` | List all coins (id, name, symbol, rank) | — |
132
- | `getCoinById` | Coin details (description, team, links) | `coinId` |
131
+ | `getCoins` | List all coins (id, name, symbol, rank); no prices, use getTickers for prices | — |
132
+ | `getCoinById` | Coin project details (description, team, links); no price, use getTickersById | `coinId` |
133
133
  | `getCoinEvents` | Upcoming events for a coin | `coinId` |
134
134
  | `getCoinExchanges` | Exchanges listing a coin | `coinId` |
135
- | `getCoinMarkets` | Markets/trading pairs for a coin | `coinId` |
135
+ | `getCoinMarkets` | Markets/exchanges trading a coin ('where to buy X', 'X price on Binance') | `coinId` |
136
136
 
137
137
  ### Tickers & Prices
138
138
 
139
139
  | Tool | Description | Required Parameters |
140
140
  |------|-------------|---------------------|
141
- | `getTickers` | All tickers with price quotes | — |
142
- | `getTickersById` | Ticker for a specific coin | `coinId` |
143
- | `getCoinOHLCVLatest` | OHLCV for the last full day | `coinId` |
144
- | `getCoinOHLCVToday` | OHLCV for today (in progress) | `coinId` |
145
- | `priceConverter` | Convert between currencies | `baseCurrencyId`, `quoteCurrencyId` |
141
+ | `getTickers` | Current prices + market caps for top coins by market cap ('top 5 coins', market snapshot) | — |
142
+ | `getTickersById` | Current price, market cap & 24h change of one coin ('BTC price', 'how much is ETH') | `coinId` |
143
+ | `getCoinOHLCVLatest` | Latest full-day OHLC candle (not the live price) | `coinId` |
144
+ | `getCoinOHLCVToday` | Today's in-progress OHLC candle | `coinId` |
145
+ | `priceConverter` | Convert an amount between currencies ('0.5 BTC in USD') | `baseCurrencyId`, `quoteCurrencyId` |
146
146
 
147
147
  ### Exchanges
148
148
 
@@ -166,14 +166,14 @@ If you prefer zero setup, point any MCP-compatible client directly at the hosted
166
166
  |------|-------------|---------------------|
167
167
  | `getPlatforms` | List contract platforms | — |
168
168
  | `getContracts` | Contracts on a platform | `platformId` |
169
- | `getTickerByContract` | Ticker by contract address | `platformId`, `contractAddress` |
169
+ | `getTickerByContract` | Token price by contract address (on-chain/DeFi tokens) | `platformId`, `contractAddress` |
170
170
 
171
171
  ### Search & Resolution
172
172
 
173
173
  | Tool | Description | Required Parameters |
174
174
  |------|-------------|---------------------|
175
- | `search` | Search coins, exchanges, ICOs, people, tags | `q` |
176
- | `resolveId` | Resolve fuzzy query to canonical CoinPaprika IDs | `type`, `query` |
175
+ | `search` | Search coins/exchanges/people/tags by name; use FIRST to get an id | `q` |
176
+ | `resolveId` | Resolve a name/symbol to canonical id; call FIRST before price tools | `type`, `query` |
177
177
 
178
178
  ### Paid-Tier Tools
179
179
 
@@ -198,7 +198,7 @@ export COINPAPRIKA_API_KEY=your-api-key-here
198
198
  coinpaprika-mcp
199
199
 
200
200
  # Or pass inline
201
- COINPAPRIKA_API_KEY=your-api-key-here npx @coinpaprika/mcp
201
+ COINPAPRIKA_API_KEY=your-api-key-here npx @coinpaprika/mcp@latest
202
202
  ```
203
203
 
204
204
  Get an API key at [coinpaprika.com/api/pricing](https://coinpaprika.com/api/pricing/).
package/dist/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { createRequire } from 'module';
3
4
  import fetch from 'node-fetch';
4
5
  import { z } from 'zod';
5
6
 
6
- // Server version
7
- const SERVER_VERSION = '1.0.0';
7
+ // Server version, read from package.json so the banner, capabilities
8
+ // document, and status tool always report the published version.
9
+ const SERVER_VERSION = createRequire(import.meta.url)('../package.json').version;
8
10
 
9
11
  // Optional API key from environment
10
12
  const API_KEY = process.env.COINPAPRIKA_API_KEY || '';
@@ -277,17 +279,17 @@ function buildCapabilitiesDocument() {
277
279
  service: "coinpaprika",
278
280
  aliases: SERVER_ALIASES,
279
281
  version: SERVER_VERSION,
280
- description: "Cryptocurrency market data for 8000+ coins",
282
+ description: "Real-time cryptocurrency prices and market data for 12,000+ coins",
281
283
  server: {
282
284
  name: "CoinPaprika MCP Server",
283
285
  version: SERVER_VERSION,
284
- description: "Cryptocurrency market data — prices, tickers, exchanges, OHLCV, and more",
286
+ description: "Real-time cryptocurrency prices, market caps, 24h changes and volumes for 12,000+ coins (Bitcoin, Ethereum, Solana, and more) and 350+ exchanges. Use for how much a crypto is worth, top coins by market cap, or live market data.",
285
287
  documentation_url: "https://api.coinpaprika.com",
286
288
  },
287
289
  tools: [
288
290
  {
289
291
  name: "status",
290
- description: "Server status and configuration",
292
+ description: "Get the CoinPaprika MCP server's status and configuration (uptime, mode, enabled features). Use when asked 'is the server up', 'what mode am I in', 'server status'. This reports the MCP server itself, not the crypto market; for market health use getGlobal.",
291
293
  category: "system",
292
294
  parameters: {},
293
295
  returns: { type: "object" },
@@ -295,7 +297,7 @@ function buildCapabilitiesDocument() {
295
297
  },
296
298
  {
297
299
  name: "getGlobal",
298
- description: "Get global cryptocurrency market statistics",
300
+ description: "Get a global crypto market overview: total market cap, total 24h volume, Bitcoin dominance, and market-wide 24h change. Use for 'how is the crypto market doing', 'total market cap', 'BTC dominance'. For a single coin's price use getTickersById.",
299
301
  category: "market",
300
302
  parameters: {},
301
303
  returns: { type: "object", properties: ["market_cap_usd", "volume_24h_usd", "bitcoin_dominance_percentage"] },
@@ -303,7 +305,7 @@ function buildCapabilitiesDocument() {
303
305
  },
304
306
  {
305
307
  name: "getCoins",
306
- description: "List all available coins",
308
+ description: "List available coins (id, name, symbol, rank). Use to discover coins or map a name to an id. Does NOT include prices; for prices use getTickers or getTickersById.",
307
309
  category: "coins",
308
310
  parameters: { limit: { type: "integer", required: false, default: 50, min: 1, max: 250 } },
309
311
  returns: { type: "array", items: "Coin" },
@@ -311,7 +313,7 @@ function buildCapabilitiesDocument() {
311
313
  },
312
314
  {
313
315
  name: "getTickers",
314
- description: "Get market data for all active cryptocurrencies",
316
+ description: "Get current prices, market caps and 24h changes for the top cryptocurrencies ranked by market cap. Use for 'top 5 coins', 'top crypto today', 'biggest cryptocurrencies', or a market snapshot. For one specific coin use getTickersById.",
315
317
  category: "market",
316
318
  parameters: {
317
319
  quotes: { type: "string", required: false, default: "USD", description: "Comma-separated quote currencies" },
@@ -322,7 +324,7 @@ function buildCapabilitiesDocument() {
322
324
  },
323
325
  {
324
326
  name: "getCoinOHLCVLatest",
325
- description: "Get OHLCV data for last full day",
327
+ description: "Get the latest full-day OHLC candle (open/high/low/close plus volume) for a coin. For the live spot price use getTickersById.",
326
328
  category: "coins",
327
329
  parameters: {
328
330
  coinId: { type: "string", required: true, format: "coin-id", example: "btc-bitcoin" },
@@ -333,7 +335,7 @@ function buildCapabilitiesDocument() {
333
335
  },
334
336
  {
335
337
  name: "getCoinOHLCVToday",
336
- description: "Get OHLCV data for today",
338
+ description: "Get today's in-progress OHLC candle for a coin. For the current spot price use getTickersById; for past candles use getCoinOHLCVHistorical.",
337
339
  category: "coins",
338
340
  parameters: {
339
341
  coinId: { type: "string", required: true, format: "coin-id" },
@@ -344,7 +346,7 @@ function buildCapabilitiesDocument() {
344
346
  },
345
347
  {
346
348
  name: "getCoinOHLCVHistorical",
347
- description: "Get historical OHLCV data (requires Starter+ plan)",
349
+ description: "Get OHLC candles (open/high/low/close plus volume) for a coin over a date range, for price charts, backtests and technical analysis. Use for 'daily chart for the last month', 'hourly candles since Jan 1'. For a single past date's spot value use getTickersHistoricalById; not for the current price. Requires Starter+ plan.",
348
350
  category: "coins",
349
351
  parameters: {
350
352
  coinId: { type: "string", required: true, format: "coin-id" },
@@ -359,7 +361,7 @@ function buildCapabilitiesDocument() {
359
361
  },
360
362
  {
361
363
  name: "getCoinById",
362
- description: "Get detailed information about a specific cryptocurrency",
364
+ description: "Get descriptive project information about a coin (description, links, team, tags). Does NOT include price; for price/market cap use getTickersById.",
363
365
  category: "coins",
364
366
  parameters: { coinId: { type: "string", required: true, format: "coin-id", example: "btc-bitcoin" } },
365
367
  returns: { type: "object", properties: ["id", "name", "symbol", "description", "links", "rank"] },
@@ -367,7 +369,7 @@ function buildCapabilitiesDocument() {
367
369
  },
368
370
  {
369
371
  name: "getCoinEvents",
370
- description: "Get events for a specific coin",
372
+ description: "Get the timeline of events for a coin (launches, partnerships, hard forks, conference talks) with dates and descriptions. Use when asked 'what is happening with X', 'upcoming events for Ethereum', 'X roadmap events'. For prices or market data use getTickersById.",
371
373
  category: "coins",
372
374
  parameters: {
373
375
  coinId: { type: "string", required: true, format: "coin-id" },
@@ -378,7 +380,7 @@ function buildCapabilitiesDocument() {
378
380
  },
379
381
  {
380
382
  name: "getCoinExchanges",
381
- description: "Get exchanges where a coin is traded",
383
+ description: "List the exchanges that LIST a specific coin (venue names only). Use for 'which exchanges list X', 'is X on Coinbase', 'where is X listed'. For where to BUY with per-market price and volume use getCoinMarkets; for the coin's live price use getTickersById.",
382
384
  category: "coins",
383
385
  parameters: {
384
386
  coinId: { type: "string", required: true, format: "coin-id" },
@@ -389,7 +391,7 @@ function buildCapabilitiesDocument() {
389
391
  },
390
392
  {
391
393
  name: "getCoinMarkets",
392
- description: "Get markets for a specific coin",
394
+ description: "Get the specific markets and trading pairs where a coin trades, with per-market price and 24h volume. Use for 'where can I buy X', 'X price on Binance', 'best market for X'. For just the list of exchange names use getCoinExchanges.",
393
395
  category: "coins",
394
396
  parameters: {
395
397
  coinId: { type: "string", required: true, format: "coin-id" },
@@ -401,7 +403,7 @@ function buildCapabilitiesDocument() {
401
403
  },
402
404
  {
403
405
  name: "getTickersById",
404
- description: "Get ticker data for a specific coin",
406
+ description: "Get the current price, market cap, 24h change and volume of a specific cryptocurrency in USD (or another quote currency). Use when asked 'what is the price of X', 'how much is Bitcoin worth', 'BTC to USD', 'ETH price now'. For past prices use getTickersHistoricalById.",
405
407
  category: "market",
406
408
  parameters: {
407
409
  coinId: { type: "string", required: true, format: "coin-id" },
@@ -412,7 +414,7 @@ function buildCapabilitiesDocument() {
412
414
  },
413
415
  {
414
416
  name: "getTickersHistoricalById",
415
- description: "Get historical ticker data (requires Starter+ plan)",
417
+ description: "Get a coin's price and market cap at a single past date or time (a point-in-time value). Use for 'price of BTC last Tuesday', 'ETH market cap on 2024-01-01'. For OHLC chart candles over a range use getCoinOHLCVHistorical, not this. Not for the current price (use getTickersById). Requires Starter+ plan.",
416
418
  category: "market",
417
419
  parameters: {
418
420
  coinId: { type: "string", required: true, format: "coin-id" },
@@ -427,7 +429,7 @@ function buildCapabilitiesDocument() {
427
429
  },
428
430
  {
429
431
  name: "getPeopleById",
430
- description: "Get information about a person in crypto space",
432
+ description: "Get profile information about a person in crypto (bio, roles, linked projects and accounts). Use when asked 'who is Vitalik Buterin', 'background on X founder', 'projects tied to this person'. Look up the person id first with search.",
431
433
  category: "people",
432
434
  parameters: { personId: { type: "string", required: true } },
433
435
  returns: { type: "object" },
@@ -435,7 +437,7 @@ function buildCapabilitiesDocument() {
435
437
  },
436
438
  {
437
439
  name: "getTags",
438
- description: "Get list of all tags",
440
+ description: "List all CoinPaprika tags (categories such as defi, stablecoin, memecoin, ai) used to group coins. Use when asked 'what categories exist', 'list crypto sectors', or to find a tag id before calling getTagById.",
439
441
  category: "tags",
440
442
  parameters: {
441
443
  additionalFields: { type: "string", required: false },
@@ -446,7 +448,7 @@ function buildCapabilitiesDocument() {
446
448
  },
447
449
  {
448
450
  name: "getTagById",
449
- description: "Get details about a specific tag",
451
+ description: "Get details for a specific tag: its description and the coins and ICOs grouped under it. Use when asked 'what coins are in the defi tag', 'show the stablecoin category', 'tokens tagged X'. Get the tag id first from getTags.",
450
452
  category: "tags",
451
453
  parameters: {
452
454
  tagId: { type: "string", required: true },
@@ -457,7 +459,7 @@ function buildCapabilitiesDocument() {
457
459
  },
458
460
  {
459
461
  name: "getExchanges",
460
- description: "Get list of all exchanges",
462
+ description: "List all exchanges tracked by CoinPaprika with rank, trust score and volume. Use when asked 'top exchanges', 'biggest crypto exchanges', 'list exchanges by volume', or to find an exchange id before calling getExchangeByID.",
461
463
  category: "exchanges",
462
464
  parameters: {
463
465
  quotes: { type: "string", required: false },
@@ -468,7 +470,7 @@ function buildCapabilitiesDocument() {
468
470
  },
469
471
  {
470
472
  name: "getExchangeByID",
471
- description: "Get details about a specific exchange",
473
+ description: "Get details for a specific exchange (volume, market count, trust score, links, fiat support). Use when asked 'tell me about Binance', 'Coinbase exchange stats', 'is X a trustworthy exchange'. For the pairs traded there use getExchangeMarkets; find the exchange id first with search or getExchanges.",
472
474
  category: "exchanges",
473
475
  parameters: {
474
476
  exchangeId: { type: "string", required: true },
@@ -479,7 +481,7 @@ function buildCapabilitiesDocument() {
479
481
  },
480
482
  {
481
483
  name: "getExchangeMarkets",
482
- description: "Get markets on a specific exchange",
484
+ description: "List the trading pairs (markets) on a specific exchange with price and 24h volume per pair. Use when asked 'what pairs trade on Binance', 'markets on Kraken', 'BTC pairs on X exchange'. For exchange-level stats use getExchangeByID.",
483
485
  category: "exchanges",
484
486
  parameters: {
485
487
  exchangeId: { type: "string", required: true },
@@ -491,7 +493,7 @@ function buildCapabilitiesDocument() {
491
493
  },
492
494
  {
493
495
  name: "getPlatforms",
494
- description: "Get list of contract platforms",
496
+ description: "List the smart-contract platforms (blockchains such as ethereum, bnb, polygon) for which CoinPaprika indexes token contracts. Use when asked 'which chains are supported for contract lookups', 'list contract platforms', or to pick a platform id before calling getContracts.",
495
497
  category: "contracts",
496
498
  parameters: { limit: { type: "integer", required: false, default: 50 } },
497
499
  returns: { type: "array", items: "Platform" },
@@ -499,7 +501,7 @@ function buildCapabilitiesDocument() {
499
501
  },
500
502
  {
501
503
  name: "getContracts",
502
- description: "Get contracts for a specific platform",
504
+ description: "List the token contract addresses tracked on a specific platform, mapping each contract to its CoinPaprika coin id. Use when asked 'contracts on ethereum', 'what tokens does X chain have', or to map a contract address to a coin id. Get the platform id first from getPlatforms; for a single contract's price use getTickerByContract.",
503
505
  category: "contracts",
504
506
  parameters: {
505
507
  platformId: { type: "string", required: true },
@@ -510,7 +512,7 @@ function buildCapabilitiesDocument() {
510
512
  },
511
513
  {
512
514
  name: "getTickerByContract",
513
- description: "Get ticker by contract address",
515
+ description: "Get the current price and market data of a token by its contract address (for on-chain and DeFi tokens). Use when you have a 0x... or contract address rather than a name. For history use getHistoricalTickerByContract.",
514
516
  category: "contracts",
515
517
  parameters: {
516
518
  platformId: { type: "string", required: true },
@@ -521,7 +523,7 @@ function buildCapabilitiesDocument() {
521
523
  },
522
524
  {
523
525
  name: "getHistoricalTickerByContract",
524
- description: "Get historical ticker by contract address (requires Starter+ plan)",
526
+ description: "Get historical price and market data of a token by its contract address. Not for the current price (use getTickerByContract). Requires Starter+ plan.",
525
527
  category: "contracts",
526
528
  parameters: {
527
529
  platformId: { type: "string", required: true },
@@ -537,7 +539,7 @@ function buildCapabilitiesDocument() {
537
539
  },
538
540
  {
539
541
  name: "search",
540
- description: "Search for currencies, exchanges, ICOs, people, and tags",
542
+ description: "Broadly search CoinPaprika across coins, exchanges, ICOs, people and tags by name or symbol when the entity type is unknown or you are exploring. Use for 'find anything called X'. If you specifically need a coin's canonical id to fetch its price, prefer resolveId.",
541
543
  category: "search",
542
544
  parameters: {
543
545
  q: { type: "string", required: true },
@@ -550,7 +552,7 @@ function buildCapabilitiesDocument() {
550
552
  },
551
553
  {
552
554
  name: "resolveId",
553
- description: "Resolve fuzzy query to canonical coin/exchange/people/tag IDs",
555
+ description: "Resolve a coin name or symbol ('bitcoin', 'BTC', 'AAVE') to its single canonical CoinPaprika id ('btc-bitcoin', 'aave-new'). Call this FIRST whenever you have a bare symbol or name and want the coin's price, since ids are not derivable from symbols; then pass the id to getTickersById.",
554
556
  category: "search",
555
557
  parameters: {
556
558
  type: { type: "string", required: true, enum: ["coin", "exchange", "people", "tags"] },
@@ -562,7 +564,7 @@ function buildCapabilitiesDocument() {
562
564
  },
563
565
  {
564
566
  name: "priceConverter",
565
- description: "Convert amount from base currency to quote currency",
567
+ description: "Convert an amount from one crypto or fiat to another at the current rate ('how much is 0.5 BTC in USD', 'convert 100 USDC to EUR'). For a plain coin price without an amount, use getTickersById.",
566
568
  category: "tools",
567
569
  parameters: {
568
570
  baseCurrencyId: { type: "string", required: true },
@@ -574,7 +576,7 @@ function buildCapabilitiesDocument() {
574
576
  },
575
577
  {
576
578
  name: "keyInfo",
577
- description: "Verify API key (requires Pro plan)",
579
+ description: "Get details and usage for the current CoinPaprika API key (plan, quota, requests remaining, expiry). Use when asked 'what plan am I on', 'how many requests are left', 'is my API key valid'. Requires a Pro plan.",
578
580
  category: "system",
579
581
  parameters: {},
580
582
  returns: { type: "object" },
@@ -582,7 +584,7 @@ function buildCapabilitiesDocument() {
582
584
  },
583
585
  {
584
586
  name: "getMappings",
585
- description: "Get API ID mappings (requires Business plan)",
587
+ description: "Get mappings between CoinPaprika ids and external or legacy identifiers so you can reconcile ids across systems. Use when asked 'map CoinPaprika ids to X', 'id crosswalk', 'external id mapping'. Requires a Business plan.",
586
588
  category: "system",
587
589
  parameters: {
588
590
  coinpaprika: { type: "string", required: false },
@@ -597,7 +599,7 @@ function buildCapabilitiesDocument() {
597
599
  },
598
600
  {
599
601
  name: "getChangelogIDs",
600
- description: "Get changelog IDs (requires Starter+ plan)",
602
+ description: "Get the ids of recent changes to CoinPaprika's coin and exchange listings (additions, renames, delistings) for syncing a local dataset. Use when asked 'what changed recently', 'new or delisted coins', 'listing changelog'. Requires a Starter+ plan.",
601
603
  category: "system",
602
604
  parameters: {
603
605
  page: { type: "integer", required: false, default: 1 },
@@ -668,7 +670,7 @@ function buildCapabilitiesDocument() {
668
670
  steps: [
669
671
  "getPlatforms - List available contract platforms",
670
672
  "getContracts - List contracts on a platform",
671
- "getTickerByContract - Get ticker by contract address",
673
+ "getTickerByContract - Get the current price and market data of a token by its contract address (for on-chain/DeFi tokens). Use when you have a 0x.../contract address rather than a name. For history use getHistoricalTickerByContract.",
672
674
  ],
673
675
  example_use_case: "Looking up an ERC-20 token by its Ethereum contract",
674
676
  },
@@ -768,7 +770,7 @@ server.tool = (...regArgs) => {
768
770
  // ─── Tool 1: status ───
769
771
  server.tool(
770
772
  'status',
771
- 'Server status and configuration',
773
+ "Get the CoinPaprika MCP server's status and configuration (uptime, mode, enabled features). Use when asked 'is the server up', 'what mode am I in', 'server status'. This reports the MCP server itself, not the crypto market; for market health use getGlobal. Read-only; takes no parameters and needs no API key.",
772
774
  {},
773
775
  async () => {
774
776
  const statusData = {
@@ -788,7 +790,7 @@ server.tool(
788
790
  // ─── Tool 2: getGlobal ───
789
791
  server.tool(
790
792
  'getGlobal',
791
- 'Market overview',
793
+ "Get a global crypto market overview: total market cap, total 24h volume, Bitcoin dominance, and market-wide 24h change. Use for 'how is the crypto market doing', 'total market cap', 'BTC dominance'. For a single coin's price use getTickersById. Read-only; takes no parameters and needs no API key.",
792
794
  {},
793
795
  async () => {
794
796
  try {
@@ -803,7 +805,7 @@ server.tool(
803
805
  // ─── Tool 3: getCoins ───
804
806
  server.tool(
805
807
  'getCoins',
806
- 'List coins (limit, mode)',
808
+ "List all available coins with id, name, symbol and rank. Use to discover coins or map a name to an id. Does NOT include prices; for prices use getTickers or getTickersById. Read-only; limit caps the number of coins returned. No API key required.",
807
809
  { limit: z.number().optional().default(50).describe("Number of coins to return (default: 50, max: 250)") },
808
810
  async ({ limit = 50 }) => {
809
811
  try {
@@ -821,7 +823,7 @@ server.tool(
821
823
  // ─── Tool 4: getTickers ───
822
824
  server.tool(
823
825
  'getTickers',
824
- 'All tickers (quotes, limit)',
826
+ "Get current prices, market caps and 24h changes for the top cryptocurrencies ranked by market cap. Use for 'top 5 coins', 'top crypto today', 'biggest cryptocurrencies', or a market snapshot. For one specific coin use getTickersById. Read-only; quotes sets the quote currencies (default USD), limit caps results. No API key required.",
825
827
  {
826
828
  quotes: z.string().optional().describe("Comma-separated quote currencies (e.g., USD,BTC,ETH)"),
827
829
  limit: z.number().optional().default(50).describe("Number of tickers to return (default: 50, max: 250)")
@@ -843,7 +845,7 @@ server.tool(
843
845
  // ─── Tool 5: getCoinOHLCVLatest ───
844
846
  server.tool(
845
847
  'getCoinOHLCVLatest',
846
- 'OHLCV last full day',
848
+ "Get the latest full-day OHLC candle (open, high, low, close and volume) for a coin. Use for 'yesterday's candle for BTC'. For the live spot price use getTickersById. Read-only; coinId must be a canonical id (resolve a bare symbol with resolveId first), quote defaults to usd. No API key required.",
847
849
  {
848
850
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
849
851
  quote: z.string().optional().default('usd').describe("Quote currency (default: usd)")
@@ -861,7 +863,7 @@ server.tool(
861
863
  // ─── Tool 6: getCoinOHLCVToday ───
862
864
  server.tool(
863
865
  'getCoinOHLCVToday',
864
- 'OHLCV today',
866
+ "Get today's in-progress OHLC candle for a coin. Use for 'today's high and low for ETH'. For the current spot price use getTickersById; for past candles use getCoinOHLCVHistorical. Read-only; coinId is a canonical id (resolve with resolveId). No API key required.",
865
867
  {
866
868
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
867
869
  quote: z.string().optional().default('usd').describe("Quote currency (default: usd)")
@@ -879,7 +881,7 @@ server.tool(
879
881
  // ─── Tool 7: getCoinOHLCVHistorical (paid: Starter+) ───
880
882
  server.tool(
881
883
  'getCoinOHLCVHistorical',
882
- 'OHLCV historical (plan-dependent)',
884
+ "Get OHLC candles (open, high, low, close and volume) for a coin over a date range, for price charts, backtests and technical analysis. Use for 'daily chart for the last month', 'hourly candles since Jan 1'. For a single past date's value use getTickersHistoricalById; not for the current price. Read-only; start and end accept YYYY-MM-DD, interval sets the candle size. Requires a Starter+ plan (COINPAPRIKA_API_KEY); without a valid key the call is rejected.",
883
885
  {
884
886
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
885
887
  start: z.string().describe("Start date (ISO 8601 or yyyy-mm-dd)"),
@@ -901,7 +903,7 @@ server.tool(
901
903
  // ─── Tool 8: getCoinById ───
902
904
  server.tool(
903
905
  'getCoinById',
904
- 'Coin details (descriptive info)',
906
+ "Get descriptive project information about a coin: description, links, team and tags. Use for 'tell me about Uniswap', 'what is this project'. Does NOT include price; for price and market cap use getTickersById. Read-only; coinId is a canonical id (resolve with resolveId). No API key required.",
905
907
  { coinId: z.string().describe(COIN_ID_DESCRIPTION) },
906
908
  async ({ coinId }) => {
907
909
  try {
@@ -916,7 +918,7 @@ server.tool(
916
918
  // ─── Tool 9: getCoinEvents ───
917
919
  server.tool(
918
920
  'getCoinEvents',
919
- 'Events for a coin',
921
+ "Get the timeline of events for a coin (launches, partnerships, hard forks, conference talks) with dates and descriptions. Use for 'what is happening with X', 'upcoming events for Ethereum', 'X roadmap events'. For prices use getTickersById. Read-only; coinId is a canonical id, limit caps results. No API key required.",
920
922
  {
921
923
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
922
924
  limit: z.number().optional().default(50).describe("Number of events to return (default: 50, max: 250)")
@@ -937,7 +939,7 @@ server.tool(
937
939
  // ─── Tool 10: getCoinExchanges ───
938
940
  server.tool(
939
941
  'getCoinExchanges',
940
- 'Exchanges for a coin',
942
+ "List the exchanges that LIST a specific coin (venue names only). Use for 'which exchanges list X', 'is X on Coinbase', 'where is X listed'. For where to BUY with per-market price and volume use getCoinMarkets; for the live price use getTickersById. Read-only; coinId is a canonical id, limit caps results. No API key required.",
941
943
  {
942
944
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
943
945
  limit: z.number().optional().default(50).describe("Number of exchanges to return (default: 50, max: 250)")
@@ -958,7 +960,7 @@ server.tool(
958
960
  // ─── Tool 11: getCoinMarkets ───
959
961
  server.tool(
960
962
  'getCoinMarkets',
961
- 'Markets for a coin',
963
+ "Get the specific markets and trading pairs where a coin trades, with per-market price and 24h volume. Use for 'where can I buy X', 'X price on Binance', 'best market for X'. For just the list of exchange names use getCoinExchanges. Read-only; coinId is a canonical id, quotes sets quote currencies, limit caps results. No API key required.",
962
964
  {
963
965
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
964
966
  quotes: z.string().optional().describe("Comma-separated quote currencies"),
@@ -981,7 +983,7 @@ server.tool(
981
983
  // ─── Tool 12: getTickersById ───
982
984
  server.tool(
983
985
  'getTickersById',
984
- 'Ticker for a specific coin',
986
+ "Get the current price, market cap, 24h change and volume of one cryptocurrency in USD or another quote currency. Use for 'what is the price of X', 'how much is Bitcoin worth', 'BTC to USD', 'ETH price now'. For past prices use getTickersHistoricalById. Read-only; coinId is a canonical id (resolve a bare symbol with resolveId first), quotes sets the quote currency (default USD). No API key required.",
985
987
  {
986
988
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
987
989
  quotes: z.string().optional().describe("Comma-separated quote currencies")
@@ -1000,7 +1002,7 @@ server.tool(
1000
1002
  // ─── Tool 13: getTickersHistoricalById (paid: Starter+) ───
1001
1003
  server.tool(
1002
1004
  'getTickersHistoricalById',
1003
- 'Historical ticks for a coin (plan dependent)',
1005
+ "Get a coin's price and market cap at a single past date or time (a point-in-time value). Use for 'price of BTC last Tuesday', 'ETH market cap on 2024-01-01'. For OHLC chart candles over a range use getCoinOHLCVHistorical; not for the current price (use getTickersById). Read-only; start and end accept YYYY-MM-DD, interval sets the sampling step. Requires a Starter+ plan (COINPAPRIKA_API_KEY).",
1004
1006
  {
1005
1007
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
1006
1008
  start: z.string().describe("Start date (ISO 8601 or yyyy-mm-dd)"),
@@ -1022,7 +1024,7 @@ server.tool(
1022
1024
  // ─── Tool 14: getPeopleById ───
1023
1025
  server.tool(
1024
1026
  'getPeopleById',
1025
- 'Person details',
1027
+ "Get profile information about a person in crypto: bio, roles, and linked projects and accounts. Use for 'who is Vitalik Buterin', 'background on X founder', 'projects tied to this person'. Look up the person id first with search. Read-only; personId is a canonical id from search. No API key required.",
1026
1028
  { personId: z.string().describe("Person ID (e.g., vitalik-buterin)") },
1027
1029
  async ({ personId }) => {
1028
1030
  try {
@@ -1037,7 +1039,7 @@ server.tool(
1037
1039
  // ─── Tool 15: getTags ───
1038
1040
  server.tool(
1039
1041
  'getTags',
1040
- 'List tags',
1042
+ "List all CoinPaprika tags (categories such as defi, stablecoin, memecoin, ai) used to group coins. Use for 'what categories exist', 'list crypto sectors', or to find a tag id before calling getTagById. Read-only; limit caps results. No API key required.",
1041
1043
  {
1042
1044
  additionalFields: z.string().optional().describe("Comma-separated additional fields (e.g., coins,icos)"),
1043
1045
  limit: z.number().optional().default(50).describe("Number of tags to return (default: 50, max: 250)")
@@ -1059,7 +1061,7 @@ server.tool(
1059
1061
  // ─── Tool 16: getTagById ───
1060
1062
  server.tool(
1061
1063
  'getTagById',
1062
- 'Tag details',
1064
+ "Get details for a specific tag: its description and the coins and ICOs grouped under it. Use for 'what coins are in the defi tag', 'show the stablecoin category', 'tokens tagged X'. Get the tag id first from getTags. Read-only; tagId is a tag id from getTags. No API key required.",
1063
1065
  {
1064
1066
  tagId: z.string().describe("Tag ID (e.g., blockchain-service)"),
1065
1067
  additionalFields: z.string().optional().describe("Comma-separated additional fields (e.g., coins,icos)")
@@ -1078,7 +1080,7 @@ server.tool(
1078
1080
  // ─── Tool 17: getExchanges ───
1079
1081
  server.tool(
1080
1082
  'getExchanges',
1081
- 'List exchanges',
1083
+ "List all exchanges tracked by CoinPaprika with rank, trust score and 24h volume. Use for 'top exchanges', 'biggest crypto exchanges', 'list exchanges by volume', or to find an exchange id before calling getExchangeByID. Read-only; quotes sets the volume quote currency, limit caps results. No API key required.",
1082
1084
  {
1083
1085
  quotes: z.string().optional().describe("Comma-separated quote currencies"),
1084
1086
  limit: z.number().optional().default(50).describe("Number of exchanges to return (default: 50, max: 250)")
@@ -1100,7 +1102,7 @@ server.tool(
1100
1102
  // ─── Tool 18: getExchangeByID ───
1101
1103
  server.tool(
1102
1104
  'getExchangeByID',
1103
- 'Exchange details',
1105
+ "Get details for a specific exchange: 24h volume, market count, trust score, links and fiat support. Use for 'tell me about Binance', 'Coinbase exchange stats', 'is X a trustworthy exchange'. For the pairs traded there use getExchangeMarkets; find the exchange id first with search or getExchanges. Read-only; exchangeId is an exchange id such as binance. No API key required.",
1104
1106
  {
1105
1107
  exchangeId: z.string().describe("Exchange ID (e.g., binance)"),
1106
1108
  quotes: z.string().optional().describe("Comma-separated quote currencies")
@@ -1119,7 +1121,7 @@ server.tool(
1119
1121
  // ─── Tool 19: getExchangeMarkets ───
1120
1122
  server.tool(
1121
1123
  'getExchangeMarkets',
1122
- 'Markets on exchange',
1124
+ "List the trading pairs (markets) on a specific exchange with price and 24h volume per pair. Use for 'what pairs trade on Binance', 'markets on Kraken', 'BTC pairs on X exchange'. For exchange-level stats use getExchangeByID. Read-only; exchangeId is an exchange id, limit caps results (max 250). No API key required.",
1123
1125
  {
1124
1126
  exchangeId: z.string().describe("Exchange ID (e.g., binance)"),
1125
1127
  quotes: z.string().optional().describe("Comma-separated quote currencies"),
@@ -1142,7 +1144,7 @@ server.tool(
1142
1144
  // ─── Tool 20: getPlatforms ───
1143
1145
  server.tool(
1144
1146
  'getPlatforms',
1145
- 'List contract platforms',
1147
+ "List the smart-contract platforms (blockchains such as ethereum, bnb, polygon) for which CoinPaprika indexes token contracts. Use for 'which chains are supported for contract lookups', 'list contract platforms', or to pick a platform id before calling getContracts. Read-only; limit caps results. No API key required.",
1146
1148
  { limit: z.number().optional().default(50).describe("Number of platforms to return (default: 50, max: 250)") },
1147
1149
  async ({ limit = 50 }) => {
1148
1150
  try {
@@ -1160,7 +1162,7 @@ server.tool(
1160
1162
  // ─── Tool 21: getContracts ───
1161
1163
  server.tool(
1162
1164
  'getContracts',
1163
- 'Contracts for a platform',
1165
+ "List the token contract addresses tracked on a specific platform, mapping each contract to its CoinPaprika coin id. Use for 'contracts on ethereum', 'what tokens does X chain have', or to map a contract address to a coin id. Get the platform id first from getPlatforms; for a single contract's price use getTickerByContract. Read-only; platformId is a platform id, limit caps results. No API key required.",
1164
1166
  {
1165
1167
  platformId: z.string().describe("Platform ID (e.g., eth-ethereum)"),
1166
1168
  limit: z.number().optional().default(50).describe("Number of contracts to return (default: 50, max: 250)")
@@ -1181,7 +1183,7 @@ server.tool(
1181
1183
  // ─── Tool 22: getTickerByContract ───
1182
1184
  server.tool(
1183
1185
  'getTickerByContract',
1184
- 'Ticker by contract address (redirect)',
1186
+ "Get the current price and market data of a token by its contract address (for on-chain and DeFi tokens). Use when you have a contract address (0x...) rather than a name. For history use getHistoricalTickerByContract. Read-only; platformId is the chain (e.g. eth-ethereum) and contractAddress the token address. No API key required.",
1185
1187
  {
1186
1188
  platformId: z.string().describe("Platform ID (e.g., eth-ethereum)"),
1187
1189
  contractAddress: z.string().describe("Contract address")
@@ -1199,7 +1201,7 @@ server.tool(
1199
1201
  // ─── Tool 23: getHistoricalTickerByContract (paid: Starter+) ───
1200
1202
  server.tool(
1201
1203
  'getHistoricalTickerByContract',
1202
- 'Historical by contract address (plan dependent)',
1204
+ "Get historical price and market data of a token by its contract address. Use for 'this token's price on 2024-01-01 by address'. Not for the current price (use getTickerByContract). Read-only; platformId and contractAddress identify the token, start and end accept YYYY-MM-DD. Requires a Starter+ plan (COINPAPRIKA_API_KEY).",
1203
1205
  {
1204
1206
  platformId: z.string().describe("Platform ID (e.g., eth-ethereum)"),
1205
1207
  contractAddress: z.string().describe("Contract address"),
@@ -1222,7 +1224,7 @@ server.tool(
1222
1224
  // ─── Tool 24: search ───
1223
1225
  server.tool(
1224
1226
  'search',
1225
- 'Search currencies, exchanges, icos, people, tags',
1227
+ "Broadly search CoinPaprika across coins, exchanges, ICOs, people and tags by name or symbol when the entity type is unknown or you are exploring. Use for 'find anything called X'. If you specifically need a coin's canonical id to fetch its price, prefer resolveId. Read-only; q is the query, categories filters entity types, limit caps results. No API key required.",
1226
1228
  {
1227
1229
  q: z.string().describe("Search query"),
1228
1230
  categories: z.string().optional().describe("Comma-separated categories to search (e.g., currencies,exchanges,icos,people,tags)"),
@@ -1246,7 +1248,7 @@ server.tool(
1246
1248
  // ─── Tool 25: resolveId ───
1247
1249
  server.tool(
1248
1250
  'resolveId',
1249
- 'Resolve fuzzy query to canonical ids',
1251
+ "Resolve a coin name or symbol ('bitcoin', 'BTC', 'AAVE') to its single canonical CoinPaprika id ('btc-bitcoin', 'aave-new'). Call this FIRST whenever you have a bare symbol or name and want the coin's price, since ids are not derivable from symbols; then pass the id to getTickersById. Read-only; query is the name or symbol, type narrows the entity kind. No API key required.",
1250
1252
  {
1251
1253
  type: z.enum(['coin', 'exchange', 'people', 'tags']).describe("Resource type to resolve"),
1252
1254
  query: z.string().describe("Fuzzy search query"),
@@ -1270,7 +1272,7 @@ server.tool(
1270
1272
  // ─── Tool 26: priceConverter ───
1271
1273
  server.tool(
1272
1274
  'priceConverter',
1273
- 'Convert base -> quote',
1275
+ "Convert an amount from one crypto or fiat to another at the current rate, e.g. 'how much is 0.5 BTC in USD', 'convert 100 USDC to EUR'. For a plain coin price without an amount, use getTickersById. Read-only; baseCurrencyId and quoteCurrencyId are canonical ids and amount is the quantity to convert. No API key required.",
1274
1276
  {
1275
1277
  baseCurrencyId: z.string().describe("Required. Source CoinPaprika coin slug (e.g., 'btc-bitcoin'). Full slugs only; ticker symbols like 'BTC' are rejected upstream. Call search or resolveId first."),
1276
1278
  quoteCurrencyId: z.string().describe("Required. Target CoinPaprika coin slug (e.g., 'usd-us-dollars', 'eth-ethereum'). Full slugs only; ticker symbols like 'USD' are rejected upstream."),
@@ -1294,7 +1296,7 @@ server.tool(
1294
1296
  // ─── Tool 27: keyInfo (paid: Pro) ───
1295
1297
  server.tool(
1296
1298
  'keyInfo',
1297
- 'Verify API key (Pro)',
1299
+ "Get details and usage for the current CoinPaprika API key: plan, quota, requests remaining and expiry. Use for 'what plan am I on', 'how many requests are left', 'is my API key valid'. Read-only; takes no parameters. Requires a configured COINPAPRIKA_API_KEY (Pro plan); without a key the call is rejected.",
1298
1300
  {},
1299
1301
  async () => {
1300
1302
  if (!API_KEY) {
@@ -1313,7 +1315,7 @@ server.tool(
1313
1315
  // ─── Tool 28: getMappings (paid: Business) ───
1314
1316
  server.tool(
1315
1317
  'getMappings',
1316
- 'API ID mappings (Business)',
1318
+ "Get mappings between CoinPaprika ids and external or legacy identifiers (CoinMarketCap, CoinGecko, CryptoCompare, ISIN, DTI) so you can reconcile ids across systems. Use for 'map CoinPaprika ids to X', 'id crosswalk', 'external id mapping'. Read-only; each source parameter filters by that identifier. Requires a Business plan (COINPAPRIKA_API_KEY).",
1317
1319
  {
1318
1320
  coinpaprika: z.string().optional().describe("CoinPaprika ID to look up"),
1319
1321
  coinmarketcap: z.string().optional().describe("CoinMarketCap ID to look up"),
@@ -1340,7 +1342,7 @@ server.tool(
1340
1342
  // ─── Tool 29: getChangelogIDs (paid: Starter+) ───
1341
1343
  server.tool(
1342
1344
  'getChangelogIDs',
1343
- 'Changelog IDs (Starter+)',
1345
+ "Get the ids of recent changes to CoinPaprika's coin and exchange listings (additions, renames, delistings) for syncing a local dataset. Use for 'what changed recently', 'new or delisted coins', 'listing changelog'. Read-only; page and limit paginate the results. Requires a Starter+ plan (COINPAPRIKA_API_KEY).",
1344
1346
  {
1345
1347
  page: z.number().optional().default(1).describe("Page number (default: 1)"),
1346
1348
  limit: z.number().optional().default(50).describe("Number of results per page (default: 50)")
@@ -1356,7 +1358,7 @@ server.tool(
1356
1358
  // ─── Tool 30: getCapabilities ───
1357
1359
  server.tool(
1358
1360
  'getCapabilities',
1359
- 'Return server capabilities, workflow patterns, validation rules, and best-practice sequences. Use this to onboard agents quickly.',
1361
+ "Get the server's capabilities, supported workflow patterns, validation rules and recommended tool sequences. Use FIRST to onboard as an agent, or when asked 'what can this server do', 'how should I chain these tools', 'what are the parameter rules'. This describes the MCP server itself, not crypto data.",
1360
1362
  {},
1361
1363
  async () => {
1362
1364
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinpaprika/mcp",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "A Model Context Protocol server for CoinPaprika cryptocurrency market data — prices, tickers, exchanges, and more",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",