mcp-crypto-price 5.0.2 → 5.0.4
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/README.md +4 -4
- package/dist/http.js +8 -20
- package/dist/index.js +1 -1
- package/dist/mcp-crypto-price-5.0.4.tgz +0 -0
- package/dist/services/coincap.js +3 -18
- package/dist/services/formatters.js +9 -10
- package/dist/services/schemas.js +7 -7
- package/dist/tools/candlestick.js +13 -30
- package/package.json +1 -1
- package/dist/mcp-crypto-price-5.0.2.tgz +0 -0
package/README.md
CHANGED
|
@@ -234,9 +234,9 @@ Returns the latest technical indicators for any cryptocurrency:
|
|
|
234
234
|
|
|
235
235
|
#### analysis-candlestick
|
|
236
236
|
|
|
237
|
-
Retrieves OHLCV candlestick data
|
|
237
|
+
Retrieves OHLCV candlestick data for a cryptocurrency:
|
|
238
238
|
- Open, high, low, close, and volume for each candle
|
|
239
|
-
- Configurable
|
|
239
|
+
- Configurable interval (`5m`, `15m`, `30m`, `1h`, `2h`, `6h`, `12h`, `1d`)
|
|
240
240
|
- Supports 1–30 days of historical candles
|
|
241
241
|
|
|
242
242
|
## Resources
|
|
@@ -273,7 +273,7 @@ The server exposes the following MCP prompts that clients can invoke:
|
|
|
273
273
|
- "Search for cryptocurrencies matching 'sol'"
|
|
274
274
|
- "Give me a global overview of the crypto market"
|
|
275
275
|
- "Compare BTC, ETH, and SOL side by side"
|
|
276
|
-
- "Show me 1-hour candlestick data for BTC
|
|
276
|
+
- "Show me 1-hour candlestick data for BTC over the last 3 days"
|
|
277
277
|
- "Convert 2.5 BTC to EUR"
|
|
278
278
|
- "Get detailed info about the Ethereum asset"
|
|
279
279
|
- "Generate a comprehensive analysis of a cryptocurrency covering price, market, and historical trends"
|
|
@@ -284,7 +284,7 @@ The server exposes the following MCP prompts that clients can invoke:
|
|
|
284
284
|
- "Convert 100 SOL to GBP and show the exchange rate"
|
|
285
285
|
- "Give me a full market snapshot: global metrics, top gainers, and BTC dominance"
|
|
286
286
|
- "What are the best and worst performing cryptos in the last 24 hours?"
|
|
287
|
-
- "Show me 15-minute candlestick data for ETH
|
|
287
|
+
- "Show me 15-minute candlestick data for ETH over the last 2 days"
|
|
288
288
|
- "Compare DeFi tokens: UNI, AAVE, COMP, and MKR"
|
|
289
289
|
- "What's the VWAP and max supply of Bitcoin?"
|
|
290
290
|
- "Search for layer-2 tokens and compare the top results"
|
package/dist/http.js
CHANGED
|
@@ -556,7 +556,7 @@ const serverCard = {
|
|
|
556
556
|
},
|
|
557
557
|
{
|
|
558
558
|
name: 'analysis-candlestick',
|
|
559
|
-
description: 'Get OHLCV candlestick data for a cryptocurrency
|
|
559
|
+
description: 'Get OHLCV candlestick data for a cryptocurrency. Useful for charting and technical analysis.',
|
|
560
560
|
inputSchema: {
|
|
561
561
|
type: 'object',
|
|
562
562
|
properties: {
|
|
@@ -564,16 +564,6 @@ const serverCard = {
|
|
|
564
564
|
type: 'string',
|
|
565
565
|
description: 'Cryptocurrency symbol or name (e.g. BTC or Bitcoin)',
|
|
566
566
|
},
|
|
567
|
-
exchange: {
|
|
568
|
-
type: 'string',
|
|
569
|
-
default: 'poloniex',
|
|
570
|
-
description: 'Exchange ID (e.g. "poloniex", "bittrex", "kraken", "binance")',
|
|
571
|
-
},
|
|
572
|
-
quote: {
|
|
573
|
-
type: 'string',
|
|
574
|
-
default: 'usd',
|
|
575
|
-
description: 'Quote currency ID (e.g. "usd", "usdt", "btc")',
|
|
576
|
-
},
|
|
577
567
|
interval: {
|
|
578
568
|
type: 'string',
|
|
579
569
|
enum: ['m5', 'm15', 'm30', 'h1', 'h2', 'h6', 'h12', 'd1'],
|
|
@@ -595,24 +585,22 @@ const serverCard = {
|
|
|
595
585
|
properties: {
|
|
596
586
|
name: { type: 'string' },
|
|
597
587
|
symbol: { type: 'string' },
|
|
598
|
-
exchange: { type: 'string' },
|
|
599
588
|
candles: {
|
|
600
589
|
type: 'array',
|
|
601
590
|
items: {
|
|
602
591
|
type: 'object',
|
|
603
592
|
properties: {
|
|
604
|
-
open: { type: '
|
|
605
|
-
high: { type: '
|
|
606
|
-
low: { type: '
|
|
607
|
-
close: { type: '
|
|
608
|
-
|
|
609
|
-
period: { type: 'number' },
|
|
593
|
+
open: { type: 'number' },
|
|
594
|
+
high: { type: 'number' },
|
|
595
|
+
low: { type: 'number' },
|
|
596
|
+
close: { type: 'number' },
|
|
597
|
+
time: { type: 'number' },
|
|
610
598
|
},
|
|
611
|
-
required: ['open', 'high', 'low', 'close', '
|
|
599
|
+
required: ['open', 'high', 'low', 'close', 'time'],
|
|
612
600
|
},
|
|
613
601
|
},
|
|
614
602
|
},
|
|
615
|
-
required: ['name', 'symbol', '
|
|
603
|
+
required: ['name', 'symbol', 'candles'],
|
|
616
604
|
},
|
|
617
605
|
annotations: {
|
|
618
606
|
title: 'Get Candlestick Data',
|
package/dist/index.js
CHANGED
|
@@ -199,7 +199,7 @@ export function createServer({ config, }) {
|
|
|
199
199
|
});
|
|
200
200
|
server.registerTool('analysis-candlestick', {
|
|
201
201
|
title: 'Get Candlestick Data',
|
|
202
|
-
description: 'Get OHLCV candlestick data for a cryptocurrency
|
|
202
|
+
description: 'Get OHLCV candlestick data for a cryptocurrency. Useful for charting and technical analysis.',
|
|
203
203
|
inputSchema: GetCandlestickDataSchema.shape,
|
|
204
204
|
outputSchema: CandlestickOutputSchema.shape,
|
|
205
205
|
annotations: {
|
|
Binary file
|
package/dist/services/coincap.js
CHANGED
|
@@ -266,30 +266,15 @@ export async function getExchange(exchangeId) {
|
|
|
266
266
|
return null;
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
|
-
|
|
270
|
-
usd: 'us-dollar',
|
|
271
|
-
eur: 'euro',
|
|
272
|
-
gbp: 'british-pound',
|
|
273
|
-
jpy: 'japanese-yen',
|
|
274
|
-
usdt: 'tether',
|
|
275
|
-
usdc: 'usd-coin',
|
|
276
|
-
btc: 'bitcoin',
|
|
277
|
-
eth: 'ethereum',
|
|
278
|
-
};
|
|
279
|
-
function normalizeQuoteId(quote) {
|
|
280
|
-
const lower = quote.toLowerCase();
|
|
281
|
-
return QUOTE_ID_MAP[lower] ?? lower;
|
|
282
|
-
}
|
|
283
|
-
export async function getCandles(exchange, baseId, quoteId, interval, start, end) {
|
|
284
|
-
const normalizedQuoteId = normalizeQuoteId(quoteId);
|
|
269
|
+
export async function getCandles(assetId, interval, start, end) {
|
|
285
270
|
try {
|
|
286
|
-
return await makeCoinCapRequest(`/
|
|
271
|
+
return await makeCoinCapRequest(`/ta/${encodeURIComponent(assetId)}/candlesticks?interval=${interval}&start=${start}&end=${end}`, CandlesResponseSchema);
|
|
287
272
|
}
|
|
288
273
|
catch (error) {
|
|
289
274
|
if (error instanceof MissingApiKeyError)
|
|
290
275
|
throw error;
|
|
291
276
|
const detail = error instanceof Error ? error.message : String(error);
|
|
292
|
-
console.error(`Failed to get
|
|
277
|
+
console.error(`Failed to get candlesticks for ${assetId}:`, detail);
|
|
293
278
|
return null;
|
|
294
279
|
}
|
|
295
280
|
}
|
|
@@ -251,21 +251,20 @@ export function formatComparison(assets) {
|
|
|
251
251
|
});
|
|
252
252
|
return ['Cryptocurrency Comparison', '', header, separator, ...rows].join('\n');
|
|
253
253
|
}
|
|
254
|
-
export function formatCandlestickData(asset, candles
|
|
254
|
+
export function formatCandlestickData(asset, candles) {
|
|
255
255
|
if (candles.length === 0) {
|
|
256
|
-
return `No candlestick data available for ${asset.name} (${asset.symbol})
|
|
256
|
+
return `No candlestick data available for ${asset.name} (${asset.symbol}).`;
|
|
257
257
|
}
|
|
258
258
|
const lines = candles.map((c) => {
|
|
259
|
-
const date = new Date(c.
|
|
260
|
-
const open = formatPrice(
|
|
261
|
-
const high = formatPrice(
|
|
262
|
-
const low = formatPrice(
|
|
263
|
-
const close = formatPrice(
|
|
264
|
-
|
|
265
|
-
return `${date} | O: $${open} | H: $${high} | L: $${low} | C: $${close} | Vol: ${volume}M`;
|
|
259
|
+
const date = new Date(c.time).toISOString().split('T')[0];
|
|
260
|
+
const open = formatPrice(c.open);
|
|
261
|
+
const high = formatPrice(c.high);
|
|
262
|
+
const low = formatPrice(c.low);
|
|
263
|
+
const close = formatPrice(c.close);
|
|
264
|
+
return `${date} | O: $${open} | H: $${high} | L: $${low} | C: $${close}`;
|
|
266
265
|
});
|
|
267
266
|
return [
|
|
268
|
-
`Candlestick Data for ${asset.name} (${asset.symbol})
|
|
267
|
+
`Candlestick Data for ${asset.name} (${asset.symbol})`,
|
|
269
268
|
'',
|
|
270
269
|
...lines,
|
|
271
270
|
].join('\n');
|
package/dist/services/schemas.js
CHANGED
|
@@ -101,13 +101,13 @@ export const ExchangeResponseSchema = z.object({
|
|
|
101
101
|
data: ExchangeSchema,
|
|
102
102
|
});
|
|
103
103
|
export const CandleSchema = z.object({
|
|
104
|
-
open: z.
|
|
105
|
-
high: z.
|
|
106
|
-
low: z.
|
|
107
|
-
close: z.
|
|
108
|
-
|
|
109
|
-
period: z.number(),
|
|
104
|
+
open: z.number(),
|
|
105
|
+
high: z.number(),
|
|
106
|
+
low: z.number(),
|
|
107
|
+
close: z.number(),
|
|
108
|
+
time: z.number(),
|
|
110
109
|
});
|
|
111
110
|
export const CandlesResponseSchema = z.object({
|
|
112
|
-
|
|
111
|
+
candles: z.array(CandleSchema),
|
|
112
|
+
timestamp: z.number(),
|
|
113
113
|
});
|
|
@@ -6,14 +6,6 @@ export const GetCandlestickDataSchema = z.object({
|
|
|
6
6
|
.string()
|
|
7
7
|
.min(1)
|
|
8
8
|
.describe('Cryptocurrency symbol or name (e.g. BTC or Bitcoin)'),
|
|
9
|
-
exchange: z
|
|
10
|
-
.string()
|
|
11
|
-
.default('poloniex')
|
|
12
|
-
.describe('Exchange ID (e.g. "poloniex", "bittrex", "kraken", "binance")'),
|
|
13
|
-
quote: z
|
|
14
|
-
.string()
|
|
15
|
-
.default('usd')
|
|
16
|
-
.describe('Quote currency code (e.g. "usd", "usdt", "btc", "eur"). Common mappings: usd→us-dollar, usdt→tether, usdc→usd-coin. Not all exchanges support all quote currencies — e.g. Binance uses "usdt" not "usd".'),
|
|
17
9
|
interval: z
|
|
18
10
|
.enum(['m5', 'm15', 'm30', 'h1', 'h2', 'h6', 'h12', 'd1'])
|
|
19
11
|
.default('h1')
|
|
@@ -28,19 +20,17 @@ export const GetCandlestickDataSchema = z.object({
|
|
|
28
20
|
export const CandlestickOutputSchema = z.object({
|
|
29
21
|
name: z.string(),
|
|
30
22
|
symbol: z.string(),
|
|
31
|
-
exchange: z.string(),
|
|
32
23
|
candles: z.array(z.object({
|
|
33
|
-
open: z.
|
|
34
|
-
high: z.
|
|
35
|
-
low: z.
|
|
36
|
-
close: z.
|
|
37
|
-
|
|
38
|
-
period: z.number(),
|
|
24
|
+
open: z.number(),
|
|
25
|
+
high: z.number(),
|
|
26
|
+
low: z.number(),
|
|
27
|
+
close: z.number(),
|
|
28
|
+
time: z.number(),
|
|
39
29
|
})),
|
|
40
30
|
});
|
|
41
31
|
export async function handleGetCandlestickData(args) {
|
|
42
32
|
try {
|
|
43
|
-
const { symbol,
|
|
33
|
+
const { symbol, interval, days } = GetCandlestickDataSchema.parse(args);
|
|
44
34
|
const upperSymbol = symbol.toUpperCase();
|
|
45
35
|
const asset = await searchAsset(upperSymbol);
|
|
46
36
|
if (!asset) {
|
|
@@ -54,7 +44,6 @@ export async function handleGetCandlestickData(args) {
|
|
|
54
44
|
structuredContent: {
|
|
55
45
|
name: '',
|
|
56
46
|
symbol: upperSymbol,
|
|
57
|
-
exchange,
|
|
58
47
|
candles: [],
|
|
59
48
|
},
|
|
60
49
|
};
|
|
@@ -62,35 +51,33 @@ export async function handleGetCandlestickData(args) {
|
|
|
62
51
|
const now = Date.now();
|
|
63
52
|
const end = now - (now % 60000);
|
|
64
53
|
const start = end - days * 24 * 60 * 60 * 1000;
|
|
65
|
-
const candlesData = await getCandles(
|
|
54
|
+
const candlesData = await getCandles(asset.id, interval, start, end);
|
|
66
55
|
if (!candlesData) {
|
|
67
56
|
return {
|
|
68
57
|
content: [
|
|
69
58
|
{
|
|
70
59
|
type: 'text',
|
|
71
|
-
text: `Failed to retrieve candlestick data for ${asset.name} (${asset.symbol})
|
|
60
|
+
text: `Failed to retrieve candlestick data for ${asset.name} (${asset.symbol}).`,
|
|
72
61
|
},
|
|
73
62
|
],
|
|
74
63
|
structuredContent: {
|
|
75
64
|
name: asset.name,
|
|
76
65
|
symbol: asset.symbol,
|
|
77
|
-
exchange,
|
|
78
66
|
candles: [],
|
|
79
67
|
},
|
|
80
68
|
};
|
|
81
69
|
}
|
|
82
|
-
if (!candlesData.
|
|
70
|
+
if (!candlesData.candles.length) {
|
|
83
71
|
return {
|
|
84
72
|
content: [
|
|
85
73
|
{
|
|
86
74
|
type: 'text',
|
|
87
|
-
text: `No candlestick data available for ${asset.name} (${asset.symbol})
|
|
75
|
+
text: `No candlestick data available for ${asset.name} (${asset.symbol})`,
|
|
88
76
|
},
|
|
89
77
|
],
|
|
90
78
|
structuredContent: {
|
|
91
79
|
name: asset.name,
|
|
92
80
|
symbol: asset.symbol,
|
|
93
|
-
exchange,
|
|
94
81
|
candles: [],
|
|
95
82
|
},
|
|
96
83
|
};
|
|
@@ -99,20 +86,18 @@ export async function handleGetCandlestickData(args) {
|
|
|
99
86
|
content: [
|
|
100
87
|
{
|
|
101
88
|
type: 'text',
|
|
102
|
-
text: formatCandlestickData(asset, candlesData.
|
|
89
|
+
text: formatCandlestickData(asset, candlesData.candles),
|
|
103
90
|
},
|
|
104
91
|
],
|
|
105
92
|
structuredContent: {
|
|
106
93
|
name: asset.name,
|
|
107
94
|
symbol: asset.symbol,
|
|
108
|
-
|
|
109
|
-
candles: candlesData.data.map((c) => ({
|
|
95
|
+
candles: candlesData.candles.map((c) => ({
|
|
110
96
|
open: c.open,
|
|
111
97
|
high: c.high,
|
|
112
98
|
low: c.low,
|
|
113
99
|
close: c.close,
|
|
114
|
-
|
|
115
|
-
period: c.period,
|
|
100
|
+
time: c.time,
|
|
116
101
|
})),
|
|
117
102
|
},
|
|
118
103
|
};
|
|
@@ -130,7 +115,6 @@ export async function handleGetCandlestickData(args) {
|
|
|
130
115
|
structuredContent: {
|
|
131
116
|
name: '',
|
|
132
117
|
symbol: '',
|
|
133
|
-
exchange: '',
|
|
134
118
|
candles: [],
|
|
135
119
|
},
|
|
136
120
|
};
|
|
@@ -147,7 +131,6 @@ export async function handleGetCandlestickData(args) {
|
|
|
147
131
|
structuredContent: {
|
|
148
132
|
name: '',
|
|
149
133
|
symbol: '',
|
|
150
|
-
exchange: '',
|
|
151
134
|
candles: [],
|
|
152
135
|
},
|
|
153
136
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-crypto-price",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.4",
|
|
4
4
|
"description": "A Model Context Protocol (MCP) server that provides real-time cryptocurrency data and analysis through CoinCap's API. Features include price tracking, market analysis, and historical trends.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
Binary file
|