bykaranteli-mcp 0.9.0 → 0.9.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.
Files changed (3) hide show
  1. package/README.md +17 -3
  2. package/dist/tools.js +48 -7
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  MCP (Model Context Protocol) server for **live crypto derivatives data**: funding rates, cross-exchange funding arbitrage, open interest pressure, Fear & Greed, BTC dominance and a verified signal track record.
4
4
 
5
- 20 read-only tools over the free, no-auth public JSON API of [bykaranteli.com](https://bykaranteli.com/developers). No API key, no account, no rate-limit registration. Data covers Binance USDT-M perpetuals (funding arbitrage additionally compares OKX, Bybit, Gate, HTX and BingX).
5
+ 34 read-only tools over the free, no-auth public JSON API of [bykaranteli.com](https://bykaranteli.com/developers). No API key, no account, no rate-limit registration. 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 23 tools, nothing to install, no key.
10
+ assistant. Same 34 tools, nothing to install, no key.
11
11
 
12
12
  ## Quick start
13
13
 
@@ -62,6 +62,20 @@ Requires Node.js 18 or newer.
62
62
  | `get_liquidation_cascades` | "What caused that flush?", "Who got liquidated this week?" |
63
63
  | `get_open_interest` | "Is leverage entering the market?", "Are shorts building in XRP?" |
64
64
  | `get_psi_charge` | "What liquidity state is the market in?", "Is parked money deploying?" |
65
+ | `get_theme_indices` | "Which crypto narrative is leading: AI, RWA, DePIN, memes, L2s, DeFi?" |
66
+ | `get_factor_board` | "Which indicators sit in an unusual band today, and what followed historically?" |
67
+ | `get_venue_markets` | "Total BTC open interest across exchanges?", "What is the DEX share of perp OI?", "Is USDT off peg anywhere?" |
68
+ | `get_lead_lag` | "Does Coinbase or Binance move first?" |
69
+ | `get_iv_surface` | "What is BTC implied vol by expiry?", "Is downside protection expensive (skew)?" |
70
+ | `get_whale_tape` | "Are whales buying or selling right now?" |
71
+ | `get_correlations` | "How correlated is SOL to BTC over 30 days?" |
72
+ | `get_new_listings` | "Which perpetuals were listed this week, and where first?" |
73
+ | `get_macro_liquidity` | "What is the Fed balance sheet / RRP / stablecoin supply doing?" |
74
+ | `get_network_health` | "Bitcoin hashrate, difficulty, fees, mempool right now?" |
75
+ | `get_altseason` | "Is it altseason?", "What is the altcoin season index?" |
76
+ | `get_metric_context` | "Is today's funding extreme historically?", "Where does this reading sit in its distribution?" |
77
+ | `get_quantum_exposure` | "How much Bitcoin is quantum-vulnerable?", "What is the P2PK exposure?" |
78
+ | `get_liqmap` | "Where are the BTC liquidation clusters?", "Where would leveraged longs get liquidated?" |
65
79
 
66
80
  All responses are JSON and carry a `generatedAt` timestamp plus a `source` URL to the human-readable page. Symbols accept both `BTCUSDT` and bare `BTC`.
67
81
 
@@ -91,7 +105,7 @@ MIT. Attribution appreciated: "ByKaranteli (bykaranteli.com)".
91
105
 
92
106
  ## Paid depth (optional)
93
107
 
94
- The 23 tools above are free and stay free. For recorded history and raw records
108
+ The 34 tools above are free and stay free. For recorded history and raw records
95
109
  beyond the live snapshots, bykaranteli.com also exposes pay-per-call x402
96
110
  endpoints (USDC on Solana or Base, priced per call, no account):
97
111
  <https://bykaranteli.com/developers#x402> · machine catalog:
package/dist/tools.js CHANGED
@@ -26,7 +26,7 @@ export function registerByKaranteliTools(server, options) {
26
26
  if (!res.ok) {
27
27
  /* Carry the route's own error body (audit P3 #412): "HTTP 400" alone
28
28
  * hid the actual reason (unknown metric, bad symbol...). */
29
- const body = (await res.text().catch(() => "")).replace(/\s+/g, " ").slice(0, 240);
29
+ const body = (await res.text().catch(() => "")).replace(/\s+/g, " ").slice(0, 2000);
30
30
  throw new Error(`${path} returned HTTP ${res.status}${body ? `: ${body}` : ""}`);
31
31
  }
32
32
  return await res.json();
@@ -106,7 +106,7 @@ export function registerByKaranteliTools(server, options) {
106
106
  });
107
107
  server.registerTool("get_liquidations", {
108
108
  title: "Crypto liquidations: daily long/short totals per symbol and exchange",
109
- description: "Call this when the user asks how much was liquidated in crypto futures, whether longs or shorts got flushed, or for liquidation history. Returns daily long and short liquidation totals in USD per symbol and exchange, recorded from ByKaranteli's own Binance, Bybit, OKX, Gate and HTX stream collectors (recorded events, a floor, not estimates). One row per finalized UTC day, symbol and exchange; history begins 2026-07-30 and grows daily.",
109
+ description: "Call this when the user asks how much was liquidated in crypto futures, whether longs or shorts got flushed, or for liquidation history. Returns daily long and short liquidation totals in USD per symbol and exchange, recorded from ByKaranteli's own Binance, Bybit, OKX, Gate, HTX and dYdX stream collectors (recorded events, a floor, not estimates). One row per finalized UTC day, symbol and exchange; history begins 2026-07-30 and grows daily.",
110
110
  inputSchema: {
111
111
  symbol: z
112
112
  .string()
@@ -209,9 +209,24 @@ export function registerByKaranteliTools(server, options) {
209
209
  const d = (await fetchJson("/api/v1/public/datasets/etf-flows.json"));
210
210
  const rows = Array.isArray(d.rows) ? d.rows : [];
211
211
  const filtered = rows.filter((r) => !asset || String(r.asset) === asset);
212
+ /* Window by DATE like get_liquidations (audit D14-03): the old row-count
213
+ * slice could cut one asset's day in half and reported no totals and no
214
+ * truncation flag, so partial sums read as full ones. */
215
+ const wantDays = days ?? 10;
216
+ const dates = [...new Set(filtered.map((r) => String(r.date)))].sort().reverse().slice(0, wantDays);
217
+ const dateSet = new Set(dates);
218
+ const windowed = filtered.filter((r) => dateSet.has(String(r.date)));
219
+ const totals = {};
220
+ for (const r of windowed) {
221
+ const a = String(r.asset);
222
+ totals[a] = (totals[a] ?? 0) + (Number(r.net_inflow_usd) || 0);
223
+ }
212
224
  return ok({
213
- rows: filtered.slice(0, (days ?? 10) * (asset ? 1 : 2)),
214
- note: "Finalized US trading days only; a positive net_inflow_usd means the funds bought more of the asset than they sold that day.",
225
+ rows: windowed,
226
+ window_days: dates.length,
227
+ window_net_inflow_usd: totals,
228
+ truncated: dates.length < new Set(filtered.map((r) => String(r.date))).size,
229
+ note: "Finalized US trading days only; a positive net_inflow_usd means the funds bought more of the asset than they sold that day. window_net_inflow_usd sums the returned window per asset.",
215
230
  source: `${PUBLIC_URL}/etf`,
216
231
  });
217
232
  }
@@ -377,6 +392,7 @@ export function registerByKaranteliTools(server, options) {
377
392
  return ok({
378
393
  ...d,
379
394
  daily_points: Array.isArray(daily) ? daily.slice(-30) : daily,
395
+ daily_points_truncated: Array.isArray(daily) ? daily.length > 30 : false,
380
396
  source: `${PUBLIC_URL}/symbols/${want}`,
381
397
  });
382
398
  }
@@ -669,7 +685,7 @@ export function registerByKaranteliTools(server, options) {
669
685
  server.registerTool("get_new_listings", {
670
686
  title: "New and delisted perpetual contracts",
671
687
  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.",
672
- inputSchema: { days: z.number().optional().describe("number, optional window in days, default 30") },
688
+ inputSchema: { days: z.number().int().min(1).max(30).optional().describe("Window in days, 1-30 (default 30). Longer listing history is the paid x402 dataset.") },
673
689
  annotations: READ_ONLY,
674
690
  }, async (args) => {
675
691
  try {
@@ -683,7 +699,7 @@ export function registerByKaranteliTools(server, options) {
683
699
  server.registerTool("get_macro_liquidity", {
684
700
  title: "Macro liquidity: Fed funds, 10y, balance sheet, RRP, stablecoin supply",
685
701
  description: "Call this when the user asks about macro liquidity, the Fed balance sheet, reverse repo, rates or stablecoin supply in relation to crypto. Returns the recorded daily series and latest values.",
686
- inputSchema: { days: z.number().optional().describe("number, optional window in days, default 365") },
702
+ inputSchema: { days: z.number().int().min(1).max(730).optional().describe("Window in days, 1-730 (default 365).") },
687
703
  annotations: READ_ONLY,
688
704
  }, async (args) => {
689
705
  try {
@@ -697,7 +713,7 @@ export function registerByKaranteliTools(server, options) {
697
713
  server.registerTool("get_network_health", {
698
714
  title: "Bitcoin network health from our own node",
699
715
  description: "Call this when the user asks about Bitcoin hashrate, difficulty, fees or mempool congestion. Returns the recorded daily series and latest values measured on ByKaranteli's own node.",
700
- inputSchema: { days: z.number().optional().describe("number, optional window in days, default 365") },
716
+ inputSchema: { days: z.number().int().min(1).max(730).optional().describe("Window in days, 1-730 (default 365).") },
701
717
  annotations: READ_ONLY,
702
718
  }, async (args) => {
703
719
  try {
@@ -708,4 +724,29 @@ export function registerByKaranteliTools(server, options) {
708
724
  return fail(err);
709
725
  }
710
726
  });
727
+ server.registerTool("get_liqmap", {
728
+ title: "LiqMap: estimated liquidation clusters with real prints overlaid",
729
+ description: "Call this when the user asks where liquidation clusters or liquidity pools sit for a perpetual, where leveraged longs/shorts would get liquidated, or for a liquidation heatmap reading. Returns the public LiqMap snapshot for one symbol: modeled liquidation levels by price, zone aggregates and real liquidation prints from six venues. Public tier serves the 24h view; other intervals are a member feature at the source page.",
730
+ inputSchema: {
731
+ symbol: z
732
+ .string()
733
+ .trim()
734
+ .toUpperCase()
735
+ .regex(/^[A-Z0-9]{2,20}$/)
736
+ .optional()
737
+ .describe("Symbol like BTCUSDT (bare BTC accepted). Default BTCUSDT."),
738
+ },
739
+ annotations: READ_ONLY,
740
+ }, async ({ symbol }) => {
741
+ try {
742
+ const raw = symbol ?? "BTCUSDT";
743
+ const sym = raw.endsWith("USDT") ? raw : `${raw}USDT`;
744
+ const path = `/api/liqmap/public?symbol=${encodeURIComponent(sym)}&timeframe=24h`;
745
+ const data = await fetchJson(path);
746
+ return ok({ ...data, source: `${PUBLIC_URL}/liqmap/${sym.replace(/USDT$/, "").toLowerCase()}` });
747
+ }
748
+ catch (err) {
749
+ return fail(err);
750
+ }
751
+ });
711
752
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bykaranteli-mcp",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "MCP server for live crypto derivatives data from bykaranteli.com: funding rates, funding arbitrage, open interest pressure, Fear & Greed, BTC dominance and verified signal performance. Free, no API key.",
5
5
  "type": "module",
6
6
  "bin": {