@coinpaprika/mcp 1.3.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,12 @@
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
+
5
11
  ## [1.3.0] - 2026-07-27
6
12
 
7
13
  ### Changed
package/dist/index.js CHANGED
@@ -770,7 +770,7 @@ server.tool = (...regArgs) => {
770
770
  // ─── Tool 1: status ───
771
771
  server.tool(
772
772
  'status',
773
- '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.",
774
774
  {},
775
775
  async () => {
776
776
  const statusData = {
@@ -790,7 +790,7 @@ server.tool(
790
790
  // ─── Tool 2: getGlobal ───
791
791
  server.tool(
792
792
  'getGlobal',
793
- '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.",
794
794
  {},
795
795
  async () => {
796
796
  try {
@@ -805,7 +805,7 @@ server.tool(
805
805
  // ─── Tool 3: getCoins ───
806
806
  server.tool(
807
807
  'getCoins',
808
- '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.",
809
809
  { limit: z.number().optional().default(50).describe("Number of coins to return (default: 50, max: 250)") },
810
810
  async ({ limit = 50 }) => {
811
811
  try {
@@ -823,7 +823,7 @@ server.tool(
823
823
  // ─── Tool 4: getTickers ───
824
824
  server.tool(
825
825
  'getTickers',
826
- '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.",
827
827
  {
828
828
  quotes: z.string().optional().describe("Comma-separated quote currencies (e.g., USD,BTC,ETH)"),
829
829
  limit: z.number().optional().default(50).describe("Number of tickers to return (default: 50, max: 250)")
@@ -845,7 +845,7 @@ server.tool(
845
845
  // ─── Tool 5: getCoinOHLCVLatest ───
846
846
  server.tool(
847
847
  'getCoinOHLCVLatest',
848
- '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.",
849
849
  {
850
850
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
851
851
  quote: z.string().optional().default('usd').describe("Quote currency (default: usd)")
@@ -863,7 +863,7 @@ server.tool(
863
863
  // ─── Tool 6: getCoinOHLCVToday ───
864
864
  server.tool(
865
865
  'getCoinOHLCVToday',
866
- '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.",
867
867
  {
868
868
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
869
869
  quote: z.string().optional().default('usd').describe("Quote currency (default: usd)")
@@ -881,7 +881,7 @@ server.tool(
881
881
  // ─── Tool 7: getCoinOHLCVHistorical (paid: Starter+) ───
882
882
  server.tool(
883
883
  'getCoinOHLCVHistorical',
884
- '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.",
885
885
  {
886
886
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
887
887
  start: z.string().describe("Start date (ISO 8601 or yyyy-mm-dd)"),
@@ -903,7 +903,7 @@ server.tool(
903
903
  // ─── Tool 8: getCoinById ───
904
904
  server.tool(
905
905
  'getCoinById',
906
- '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.",
907
907
  { coinId: z.string().describe(COIN_ID_DESCRIPTION) },
908
908
  async ({ coinId }) => {
909
909
  try {
@@ -918,7 +918,7 @@ server.tool(
918
918
  // ─── Tool 9: getCoinEvents ───
919
919
  server.tool(
920
920
  'getCoinEvents',
921
- '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.",
922
922
  {
923
923
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
924
924
  limit: z.number().optional().default(50).describe("Number of events to return (default: 50, max: 250)")
@@ -939,7 +939,7 @@ server.tool(
939
939
  // ─── Tool 10: getCoinExchanges ───
940
940
  server.tool(
941
941
  'getCoinExchanges',
942
- '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.",
943
943
  {
944
944
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
945
945
  limit: z.number().optional().default(50).describe("Number of exchanges to return (default: 50, max: 250)")
@@ -960,7 +960,7 @@ server.tool(
960
960
  // ─── Tool 11: getCoinMarkets ───
961
961
  server.tool(
962
962
  'getCoinMarkets',
963
- '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.",
964
964
  {
965
965
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
966
966
  quotes: z.string().optional().describe("Comma-separated quote currencies"),
@@ -983,7 +983,7 @@ server.tool(
983
983
  // ─── Tool 12: getTickersById ───
984
984
  server.tool(
985
985
  'getTickersById',
986
- '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.",
987
987
  {
988
988
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
989
989
  quotes: z.string().optional().describe("Comma-separated quote currencies")
@@ -1002,7 +1002,7 @@ server.tool(
1002
1002
  // ─── Tool 13: getTickersHistoricalById (paid: Starter+) ───
1003
1003
  server.tool(
1004
1004
  'getTickersHistoricalById',
1005
- '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).",
1006
1006
  {
1007
1007
  coinId: z.string().describe(COIN_ID_DESCRIPTION),
1008
1008
  start: z.string().describe("Start date (ISO 8601 or yyyy-mm-dd)"),
@@ -1024,7 +1024,7 @@ server.tool(
1024
1024
  // ─── Tool 14: getPeopleById ───
1025
1025
  server.tool(
1026
1026
  'getPeopleById',
1027
- '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.",
1028
1028
  { personId: z.string().describe("Person ID (e.g., vitalik-buterin)") },
1029
1029
  async ({ personId }) => {
1030
1030
  try {
@@ -1039,7 +1039,7 @@ server.tool(
1039
1039
  // ─── Tool 15: getTags ───
1040
1040
  server.tool(
1041
1041
  'getTags',
1042
- '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.",
1043
1043
  {
1044
1044
  additionalFields: z.string().optional().describe("Comma-separated additional fields (e.g., coins,icos)"),
1045
1045
  limit: z.number().optional().default(50).describe("Number of tags to return (default: 50, max: 250)")
@@ -1061,7 +1061,7 @@ server.tool(
1061
1061
  // ─── Tool 16: getTagById ───
1062
1062
  server.tool(
1063
1063
  'getTagById',
1064
- '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.",
1065
1065
  {
1066
1066
  tagId: z.string().describe("Tag ID (e.g., blockchain-service)"),
1067
1067
  additionalFields: z.string().optional().describe("Comma-separated additional fields (e.g., coins,icos)")
@@ -1080,7 +1080,7 @@ server.tool(
1080
1080
  // ─── Tool 17: getExchanges ───
1081
1081
  server.tool(
1082
1082
  'getExchanges',
1083
- '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.",
1084
1084
  {
1085
1085
  quotes: z.string().optional().describe("Comma-separated quote currencies"),
1086
1086
  limit: z.number().optional().default(50).describe("Number of exchanges to return (default: 50, max: 250)")
@@ -1102,7 +1102,7 @@ server.tool(
1102
1102
  // ─── Tool 18: getExchangeByID ───
1103
1103
  server.tool(
1104
1104
  'getExchangeByID',
1105
- '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.",
1106
1106
  {
1107
1107
  exchangeId: z.string().describe("Exchange ID (e.g., binance)"),
1108
1108
  quotes: z.string().optional().describe("Comma-separated quote currencies")
@@ -1121,7 +1121,7 @@ server.tool(
1121
1121
  // ─── Tool 19: getExchangeMarkets ───
1122
1122
  server.tool(
1123
1123
  'getExchangeMarkets',
1124
- '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.",
1125
1125
  {
1126
1126
  exchangeId: z.string().describe("Exchange ID (e.g., binance)"),
1127
1127
  quotes: z.string().optional().describe("Comma-separated quote currencies"),
@@ -1144,7 +1144,7 @@ server.tool(
1144
1144
  // ─── Tool 20: getPlatforms ───
1145
1145
  server.tool(
1146
1146
  'getPlatforms',
1147
- '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.",
1148
1148
  { limit: z.number().optional().default(50).describe("Number of platforms to return (default: 50, max: 250)") },
1149
1149
  async ({ limit = 50 }) => {
1150
1150
  try {
@@ -1162,7 +1162,7 @@ server.tool(
1162
1162
  // ─── Tool 21: getContracts ───
1163
1163
  server.tool(
1164
1164
  'getContracts',
1165
- '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.",
1166
1166
  {
1167
1167
  platformId: z.string().describe("Platform ID (e.g., eth-ethereum)"),
1168
1168
  limit: z.number().optional().default(50).describe("Number of contracts to return (default: 50, max: 250)")
@@ -1183,7 +1183,7 @@ server.tool(
1183
1183
  // ─── Tool 22: getTickerByContract ───
1184
1184
  server.tool(
1185
1185
  'getTickerByContract',
1186
- '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.",
1187
1187
  {
1188
1188
  platformId: z.string().describe("Platform ID (e.g., eth-ethereum)"),
1189
1189
  contractAddress: z.string().describe("Contract address")
@@ -1201,7 +1201,7 @@ server.tool(
1201
1201
  // ─── Tool 23: getHistoricalTickerByContract (paid: Starter+) ───
1202
1202
  server.tool(
1203
1203
  'getHistoricalTickerByContract',
1204
- '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).",
1205
1205
  {
1206
1206
  platformId: z.string().describe("Platform ID (e.g., eth-ethereum)"),
1207
1207
  contractAddress: z.string().describe("Contract address"),
@@ -1224,7 +1224,7 @@ server.tool(
1224
1224
  // ─── Tool 24: search ───
1225
1225
  server.tool(
1226
1226
  'search',
1227
- '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.",
1228
1228
  {
1229
1229
  q: z.string().describe("Search query"),
1230
1230
  categories: z.string().optional().describe("Comma-separated categories to search (e.g., currencies,exchanges,icos,people,tags)"),
@@ -1248,7 +1248,7 @@ server.tool(
1248
1248
  // ─── Tool 25: resolveId ───
1249
1249
  server.tool(
1250
1250
  'resolveId',
1251
- '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.",
1252
1252
  {
1253
1253
  type: z.enum(['coin', 'exchange', 'people', 'tags']).describe("Resource type to resolve"),
1254
1254
  query: z.string().describe("Fuzzy search query"),
@@ -1272,7 +1272,7 @@ server.tool(
1272
1272
  // ─── Tool 26: priceConverter ───
1273
1273
  server.tool(
1274
1274
  'priceConverter',
1275
- '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.",
1276
1276
  {
1277
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."),
1278
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."),
@@ -1296,7 +1296,7 @@ server.tool(
1296
1296
  // ─── Tool 27: keyInfo (paid: Pro) ───
1297
1297
  server.tool(
1298
1298
  'keyInfo',
1299
- '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.",
1300
1300
  {},
1301
1301
  async () => {
1302
1302
  if (!API_KEY) {
@@ -1315,7 +1315,7 @@ server.tool(
1315
1315
  // ─── Tool 28: getMappings (paid: Business) ───
1316
1316
  server.tool(
1317
1317
  'getMappings',
1318
- '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).",
1319
1319
  {
1320
1320
  coinpaprika: z.string().optional().describe("CoinPaprika ID to look up"),
1321
1321
  coinmarketcap: z.string().optional().describe("CoinMarketCap ID to look up"),
@@ -1342,7 +1342,7 @@ server.tool(
1342
1342
  // ─── Tool 29: getChangelogIDs (paid: Starter+) ───
1343
1343
  server.tool(
1344
1344
  'getChangelogIDs',
1345
- '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).",
1346
1346
  {
1347
1347
  page: z.number().optional().default(1).describe("Page number (default: 1)"),
1348
1348
  limit: z.number().optional().default(50).describe("Number of results per page (default: 50)")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinpaprika/mcp",
3
- "version": "1.3.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",