bykaranteli-mcp 0.24.1 → 0.26.0
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 +26 -17
- package/dist/tools.d.ts +9 -0
- package/dist/tools.js +14 -76
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
# bykaranteli-mcp
|
|
2
2
|
|
|
3
|
-
MCP (Model Context Protocol) server for **live crypto derivatives data**: funding rates, cross-exchange funding arbitrage, open interest pressure,
|
|
3
|
+
MCP (Model Context Protocol) server for **live crypto derivatives data**: funding rates, cross-exchange funding arbitrage, open interest pressure, liquidations, options, ETF flows, Fear & Greed and BTC dominance.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
45 read-only tools over the public JSON API of [bykaranteli.com](https://bykaranteli.com/developers). Since 2026-09-17 the API asks programs for an account key: a **free key** comes with any verified account at <https://bykaranteli.com/dashboard/api> (30 requests a minute, public depth), and the Builder, Business and Scale plans raise the rate and unlock member depth (LiqMap on seven timeframes, 5-minute series, the x402 catalog included). Set it as `BYKARANTELI_API_KEY`. Data covers Binance USDT-M perpetuals (funding arbitrage additionally compares OKX, Bybit, Gate, HTX, BingX, Kraken, MEXC and Bitget).
|
|
6
6
|
|
|
7
7
|
## Hosted endpoint (no install)
|
|
8
8
|
|
|
9
9
|
Paste `https://mcp.bykaranteli.com` as a custom connector in any MCP-capable
|
|
10
|
-
assistant. Same
|
|
10
|
+
assistant. Same 45 tools, nothing to install. Without a key it runs on the
|
|
11
|
+
shared Free pool; a connector header `Authorization: Bearer bk_...` (Builder
|
|
12
|
+
and above) brings your own rate limit and member depth.
|
|
11
13
|
|
|
12
14
|
## Quick start
|
|
13
15
|
|
|
14
16
|
### Claude Code
|
|
15
17
|
|
|
16
18
|
```bash
|
|
17
|
-
claude mcp add bykaranteli -- npx -y bykaranteli-mcp
|
|
19
|
+
claude mcp add bykaranteli -e BYKARANTELI_API_KEY=bk_... -- npx -y bykaranteli-mcp
|
|
18
20
|
```
|
|
19
21
|
|
|
20
22
|
### Claude Desktop
|
|
@@ -26,7 +28,8 @@ Add to `claude_desktop_config.json`:
|
|
|
26
28
|
"mcpServers": {
|
|
27
29
|
"bykaranteli": {
|
|
28
30
|
"command": "npx",
|
|
29
|
-
"args": ["-y", "bykaranteli-mcp"]
|
|
31
|
+
"args": ["-y", "bykaranteli-mcp"],
|
|
32
|
+
"env": { "BYKARANTELI_API_KEY": "bk_..." }
|
|
30
33
|
}
|
|
31
34
|
}
|
|
32
35
|
}
|
|
@@ -34,7 +37,7 @@ Add to `claude_desktop_config.json`:
|
|
|
34
37
|
|
|
35
38
|
### Cursor / other MCP clients
|
|
36
39
|
|
|
37
|
-
Any stdio MCP client works: command `npx`, args `["-y", "bykaranteli-mcp"]`.
|
|
40
|
+
Any stdio MCP client works: command `npx`, args `["-y", "bykaranteli-mcp"]`, env `BYKARANTELI_API_KEY`.
|
|
38
41
|
|
|
39
42
|
Requires Node.js 18 or newer.
|
|
40
43
|
|
|
@@ -47,9 +50,6 @@ Requires Node.js 18 or newer.
|
|
|
47
50
|
| `get_funding_arbitrage` | "Any funding arb opportunities?", "Best venue to long/short BTC for carry?" |
|
|
48
51
|
| `get_pressure_scores` | "Which coins are over-leveraged / crowded right now?" |
|
|
49
52
|
| `get_top_movers` | "Biggest OI spikes today?", "Most extreme funding right now?" |
|
|
50
|
-
| `get_recent_signals` | "How did the signals do in the last 24h?" |
|
|
51
|
-
| `get_symbol_performance` | "Win rate on ETHUSDT over 90 days?" |
|
|
52
|
-
| `get_strategy_leaderboard` | "Which strategies are performing best?" |
|
|
53
53
|
| `get_liquidations` | "How much was liquidated today?", "Did longs or shorts get flushed this week?" |
|
|
54
54
|
| `get_etf_flows` | "Did the Bitcoin ETFs buy or sell yesterday?", "Cumulative ETH ETF inflow?" |
|
|
55
55
|
| `get_cot_positioning` | "Are hedge funds long or short Bitcoin?", "What did the COT report show?" |
|
|
@@ -97,11 +97,12 @@ All responses are JSON and carry a `generatedAt` timestamp plus a `source` URL t
|
|
|
97
97
|
|
|
98
98
|
| Env var | Default | Purpose |
|
|
99
99
|
|---|---|---|
|
|
100
|
+
| `BYKARANTELI_API_KEY` | none | Account key (`bk_...`) sent as `Authorization: Bearer`. Free at <https://bykaranteli.com/dashboard/api>; required for programs from 2026-09-17 |
|
|
100
101
|
| `BYKARANTELI_BASE_URL` | `https://bykaranteli.com` | Override the API host (testing only) |
|
|
101
102
|
|
|
102
103
|
## Data notes
|
|
103
104
|
|
|
104
|
-
-
|
|
105
|
+
- The signal engine was retired in September 2026; this server publishes recorded market data only, no trading signals or performance claims.
|
|
105
106
|
- Funding, OI and pressure data refresh every 15 to 30 minutes; indices every 30 minutes.
|
|
106
107
|
- Nothing here is financial advice. See [bykaranteli.com/risk-guide](https://bykaranteli.com/risk-guide).
|
|
107
108
|
|
|
@@ -115,12 +116,20 @@ node dist/index.js # speaks MCP over stdio
|
|
|
115
116
|
|
|
116
117
|
## License
|
|
117
118
|
|
|
118
|
-
MIT.
|
|
119
|
+
Server: MIT. Data: personal and research use with attribution "ByKaranteli (bykaranteli.com)"; commercial use with the Business plan. Licence text: <https://bykaranteli.com/data#license>.
|
|
119
120
|
|
|
120
|
-
##
|
|
121
|
+
## Plans and paid depth
|
|
121
122
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
| Plan | Price | Rate | Depth |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| Free API | $0 | 30 / min | public pages |
|
|
126
|
+
| Builder | $49 / mo | 300 / min | member depth, x402 catalog included |
|
|
127
|
+
| Business | $149 / mo | 1,200 / min | member depth, commercial licence, monthly bulk |
|
|
128
|
+
| Scale | $399 / mo | 3,000 / min | member depth, derived redistribution, daily raw |
|
|
129
|
+
|
|
130
|
+
Full table: <https://bykaranteli.com/developers#tiers>. For recorded history and
|
|
131
|
+
raw records beyond the live snapshots, bykaranteli.com also exposes pay-per-call
|
|
132
|
+
x402 endpoints for anonymous agents (USDC on Solana or Base, priced per call,
|
|
133
|
+
no account): <https://bykaranteli.com/developers#x402> · machine catalog:
|
|
134
|
+
<https://bykaranteli.com/api/x402>. Builder and higher keys call those routes
|
|
135
|
+
unpaid within their plan limits.
|
package/dist/tools.d.ts
CHANGED
|
@@ -15,5 +15,14 @@ export type RegisterOptions = {
|
|
|
15
15
|
publicUrl?: string;
|
|
16
16
|
/** Version string for the outbound user-agent. */
|
|
17
17
|
version?: string;
|
|
18
|
+
/** Account API key (bk_...) sent as Authorization: Bearer on every fetch.
|
|
19
|
+
* Since 2026-09-17 the public API asks programs for one; a free key comes
|
|
20
|
+
* with any verified account (https://bykaranteli.com/dashboard/api) and paid
|
|
21
|
+
* plans raise the rate and unlock member depth. Falls back to the
|
|
22
|
+
* BYKARANTELI_API_KEY environment variable. */
|
|
23
|
+
apiKey?: string;
|
|
24
|
+
/** Per-call Authorization value, for hosts that forward their caller's key
|
|
25
|
+
* (the hosted endpoint). Takes precedence over apiKey when it returns one. */
|
|
26
|
+
authorizationProvider?: () => string | undefined;
|
|
18
27
|
};
|
|
19
28
|
export declare function registerByKaranteliTools(server: McpServer, options?: RegisterOptions): void;
|
package/dist/tools.js
CHANGED
|
@@ -10,6 +10,13 @@ export function registerByKaranteliTools(server, options) {
|
|
|
10
10
|
const PUBLIC_URL = (options?.publicUrl ?? process.env.BYKARANTELI_PUBLIC_URL ?? "https://bykaranteli.com").replace(/\/+$/, "");
|
|
11
11
|
const USER_AGENT = `bykaranteli-mcp/${options?.version ?? "dev"} (+https://github.com/bykarantelicom/bykaranteli-mcp)`;
|
|
12
12
|
const TIMEOUT_MS = 15_000;
|
|
13
|
+
const STATIC_KEY = (options?.apiKey ?? process.env.BYKARANTELI_API_KEY ?? "").trim();
|
|
14
|
+
const authorizationFor = () => {
|
|
15
|
+
const forwarded = options?.authorizationProvider?.();
|
|
16
|
+
if (forwarded)
|
|
17
|
+
return forwarded;
|
|
18
|
+
return STATIC_KEY ? `Bearer ${STATIC_KEY}` : undefined;
|
|
19
|
+
};
|
|
13
20
|
// Read-only GET tools over an open-world public API, all of them.
|
|
14
21
|
const READ_ONLY = { readOnlyHint: true, openWorldHint: true };
|
|
15
22
|
/** Invalid tool input (not a network problem): no retry hint in the error. */
|
|
@@ -19,9 +26,14 @@ export function registerByKaranteliTools(server, options) {
|
|
|
19
26
|
const controller = new AbortController();
|
|
20
27
|
const timer = setTimeout(() => controller.abort(new Error(`${path} timed out after ${TIMEOUT_MS / 1000}s`)), TIMEOUT_MS);
|
|
21
28
|
try {
|
|
29
|
+
const authorization = authorizationFor();
|
|
22
30
|
const res = await fetch(`${BASE_URL}${path}`, {
|
|
23
31
|
signal: controller.signal,
|
|
24
|
-
headers: {
|
|
32
|
+
headers: {
|
|
33
|
+
accept: "application/json",
|
|
34
|
+
"user-agent": USER_AGENT,
|
|
35
|
+
...(authorization ? { authorization } : {}),
|
|
36
|
+
},
|
|
25
37
|
});
|
|
26
38
|
if (!res.ok) {
|
|
27
39
|
/* Carry the route's own error body (audit P3 #412): "HTTP 400" alone
|
|
@@ -43,8 +55,6 @@ export function registerByKaranteliTools(server, options) {
|
|
|
43
55
|
const PAGE_FOR_STEM = {
|
|
44
56
|
"/borrow-rates": "/borrow",
|
|
45
57
|
"/oi": "/oi-leaderboard",
|
|
46
|
-
"/recent": "/signals",
|
|
47
|
-
"/leaderboard": "/strategies",
|
|
48
58
|
"/venues/markets": "/venues",
|
|
49
59
|
"/venues/lead-lag": "/venues",
|
|
50
60
|
"/venues/profile": "/venues",
|
|
@@ -379,78 +389,6 @@ export function registerByKaranteliTools(server, options) {
|
|
|
379
389
|
return fail(err);
|
|
380
390
|
}
|
|
381
391
|
});
|
|
382
|
-
server.registerTool("get_recent_signals", {
|
|
383
|
-
title: "Recent closed trading signals with verified outcomes",
|
|
384
|
-
description: "Call this when the user asks how the ByKaranteli signal engine is doing today, or wants recent closed LONG/SHORT signals with real outcomes (TP1, SL or TIMEOUT) and net basis-point results. Includes a 24h summary (wins, losses, net bps). Every signal is published with a SHA-256 receipt and results are net of fees, slippage and funding; live signals only, never backtests.",
|
|
385
|
-
inputSchema: {},
|
|
386
|
-
annotations: READ_ONLY,
|
|
387
|
-
}, async () => {
|
|
388
|
-
try {
|
|
389
|
-
const d = (await fetchJson("/api/public/recent"));
|
|
390
|
-
return ok({ ...d, source: `${PUBLIC_URL}/signals` });
|
|
391
|
-
}
|
|
392
|
-
catch (err) {
|
|
393
|
-
return fail(err);
|
|
394
|
-
}
|
|
395
|
-
});
|
|
396
|
-
server.registerTool("get_symbol_performance", {
|
|
397
|
-
title: "Per-symbol signal performance and recent trades",
|
|
398
|
-
description: "Call this when the user asks how signals performed on a specific coin (win rate, profit factor, net PnL, best/worst trade) or wants that coin's recent closed signals. Data is the live verified track record for one Binance USDT-M perp over a 30, 90 or 180 day window.",
|
|
399
|
-
inputSchema: {
|
|
400
|
-
symbol: z.string().describe("The symbol, e.g. BTCUSDT, or a coin name like BTC."),
|
|
401
|
-
window_days: z
|
|
402
|
-
.preprocess((v) => (typeof v === "string" && v.trim() !== "" && Number.isFinite(Number(v)) ? Number(v) : v), z.number().int().min(1).max(365))
|
|
403
|
-
.optional()
|
|
404
|
-
.describe("Optional lookback window in days, 1 to 365 (the API accepts any integer in that range). Default 90."),
|
|
405
|
-
},
|
|
406
|
-
annotations: READ_ONLY,
|
|
407
|
-
}, async ({ symbol, window_days }) => {
|
|
408
|
-
try {
|
|
409
|
-
const want = normalizeSymbol(symbol);
|
|
410
|
-
const w = window_days ?? 90;
|
|
411
|
-
let d;
|
|
412
|
-
try {
|
|
413
|
-
d = (await fetchJson(`/api/v1/public/symbols/${want}?window=${w}`));
|
|
414
|
-
}
|
|
415
|
-
catch (err) {
|
|
416
|
-
// The API 404s when the symbol has no closed signals in the chosen
|
|
417
|
-
// window (data-dependent, not an invalid request). Say so plainly.
|
|
418
|
-
if (err instanceof Error && err.message.includes("HTTP 404")) {
|
|
419
|
-
return ok({
|
|
420
|
-
symbol: want,
|
|
421
|
-
window_days: w,
|
|
422
|
-
note: `No closed signals recorded for ${want} in the last ${w} days (or the symbol is not tracked). Try window_days: 180, or check ${PUBLIC_URL}/symbols/${want}.`,
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
throw err;
|
|
426
|
-
}
|
|
427
|
-
// daily_points can be long; the stats + recent signals carry the answer.
|
|
428
|
-
const daily = d.daily_points;
|
|
429
|
-
return ok({
|
|
430
|
-
...d,
|
|
431
|
-
daily_points: Array.isArray(daily) ? daily.slice(-30) : daily,
|
|
432
|
-
daily_points_truncated: Array.isArray(daily) ? daily.length > 30 : false,
|
|
433
|
-
source: `${PUBLIC_URL}/symbols/${want}`,
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
catch (err) {
|
|
437
|
-
return fail(err);
|
|
438
|
-
}
|
|
439
|
-
});
|
|
440
|
-
server.registerTool("get_strategy_leaderboard", {
|
|
441
|
-
title: "Strategy leaderboard with verified live results",
|
|
442
|
-
description: "Call this when the user asks which trading strategies are performing best, or wants win rate, profit factor, drawdown and Sharpe per strategy. Rankings are computed from live closed signals only (no backtests), net of fees.",
|
|
443
|
-
inputSchema: {},
|
|
444
|
-
annotations: READ_ONLY,
|
|
445
|
-
}, async () => {
|
|
446
|
-
try {
|
|
447
|
-
const d = (await fetchJson("/api/v1/public/leaderboard"));
|
|
448
|
-
return ok({ ...d, source: `${PUBLIC_URL}/leaderboard` });
|
|
449
|
-
}
|
|
450
|
-
catch (err) {
|
|
451
|
-
return fail(err);
|
|
452
|
-
}
|
|
453
|
-
});
|
|
454
392
|
server.registerTool("get_cot_positioning", {
|
|
455
393
|
title: "CME futures positioning (weekly COT report, BTC + ETH)",
|
|
456
394
|
description: "Call this when the user asks how hedge funds or institutions are positioned in Bitcoin or Ethereum, or about the CFTC Commitments of Traders report. Returns net positions in contracts, week-over-week changes, open interest and notable extremes/streaks, from official CFTC data updated every Friday. Note: a large share of hedge fund shorts is the market-neutral basis trade, so the weekly change carries more signal than the level.",
|
|
@@ -823,7 +761,7 @@ export function registerByKaranteliTools(server, options) {
|
|
|
823
761
|
server.registerTool("get_new_listings", {
|
|
824
762
|
title: "New and delisted perpetual contracts",
|
|
825
763
|
description: "Call this when the user asks what new perpetuals were listed, which exchange listed a coin first, or about delistings. Returns listings and delistings across six exchanges from the hourly scan.",
|
|
826
|
-
inputSchema: { days: z.number().int().min(1).max(30).optional().describe("Window in days, 1-30 (default 30). Longer listing history is the
|
|
764
|
+
inputSchema: { days: z.number().int().min(1).max(30).optional().describe("Window in days, 1-30 (default 30). Longer listing history is the listings dataset at bykaranteli.com/data.") },
|
|
827
765
|
annotations: READ_ONLY,
|
|
828
766
|
}, async (args) => {
|
|
829
767
|
try {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bykaranteli-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MCP server for live crypto derivatives data from bykaranteli.com: funding rates, funding arbitrage, open interest pressure, Fear & Greed
|
|
3
|
+
"version": "0.26.0",
|
|
4
|
+
"description": "MCP server for live crypto derivatives data from bykaranteli.com: funding rates, funding arbitrage, open interest pressure, liquidations, options, ETF flows, Fear & Greed and BTC dominance. Free, no API key.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"bykaranteli-mcp": "dist/index.js"
|