bykaranteli-mcp 0.35.0 → 0.36.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/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  Notable changes to the `bykaranteli-mcp` package. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Dates are UTC and come from the git tag of each release (the version commit where no tag exists). The tool count is the number of tools the server registers in that release.
4
4
 
5
+ ## [0.36.0] - 2026-10-15
6
+
7
+ 68 tools.
8
+
9
+ ### Added
10
+
11
+ - `get_desk_notes`: the desk notes, short dated observations the ByKaranteli desk writer publishes from the platform's own recorded derivatives data, newest first, with publish time, news value, the board each reads from, the coins it names and a permanent URL; one UTC day (`day`), a window of up to 7 days (`since`), one card type (`type`), the text in zh, ru or ko (`lang`).
12
+
13
+ ## [0.35.1] - 2026-10-11
14
+
15
+ 67 tools.
16
+
17
+ ### Changed
18
+
19
+ - Every tool carries `annotations.title`, the same text as its top-level `title`: directory portals (the Claude Connectors Directory among them) read the display name there. The read-only, destructive, idempotent and open-world hints are unchanged.
20
+ - Descriptions name plans, not keys: depth and limits follow the account's plan whether the client signed in with OAuth or sends an account key (`get_liqmap`, `get_series`, `get_options_chain`, `get_solana_perps`, the account tools).
21
+ - `get_series` returns the newest 300 bars when neither `from` nor `limit` is given (Builder and higher plans received 1,000 by default, 64,700 characters for price); `limit` and `from`/`to` still return up to 5,000.
22
+
5
23
  ## [0.35.0] - 2026-10-11
6
24
 
7
25
  67 tools.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
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
- 67 read-only and account tools over the public JSON API of [bykaranteli.com](https://bykaranteli.com/developers): the market data tools only read, and the alert and watchlist tools act on your own account through your key ([Account tools](#account-tools-alerts-and-watchlist)). Since 2026-09-10 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 and 15,000 a month, public depth), and the Builder, Business and Scale plans raise the rate and the monthly fair use and unlock member depth (LiqMap on seven timeframes, 5-minute series) and a monthly allowance of x402 catalog calls within each plan's history window ([Plans and paid depth](#plans-and-paid-depth)). Set it as `BYKARANTELI_API_KEY`. Data covers Binance USDT-M perpetuals; funding arbitrage, liquidations, order book depth, options, positioning and insurance funds add the other venues each board lists on bykaranteli.com/coverage.
5
+ 68 read-only and account tools over the public JSON API of [bykaranteli.com](https://bykaranteli.com/developers): the market data tools only read, and the alert and watchlist tools act on your own account through your key ([Account tools](#account-tools-alerts-and-watchlist)). Since 2026-09-10 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 and 15,000 a month, public depth), and the Builder, Business and Scale plans raise the rate and the monthly fair use and unlock member depth (LiqMap on seven timeframes, 5-minute series) and a monthly allowance of x402 catalog calls within each plan's history window ([Plans and paid depth](#plans-and-paid-depth)). Set it as `BYKARANTELI_API_KEY`. Data covers Binance USDT-M perpetuals; funding arbitrage, liquidations, order book depth, options, positioning and insurance funds add the other venues each board lists on bykaranteli.com/coverage.
6
6
 
7
7
  ## Hosted endpoint (no install)
8
8
 
@@ -108,6 +108,7 @@ Requires Node.js 18 or newer.
108
108
  | `get_orderbook_depth` | "Where is the biggest BTC bid wall? How deep is ETH within 2% on Coinbase vs Binance?" |
109
109
  | `get_jupiter_perps` | "How much long vs short OI is on Jupiter SOL perps? Who topped Jupiter this week? What is the JLP APR?" |
110
110
  | `get_solana_perps` | "Which Solana perp DEX has the most open interest? What is Pacifica's BTC funding and 24h volume? Phoenix SOL open interest? GM Trade versus Jupiter?" |
111
+ | `get_desk_notes` | "What did the desk observe in the derivatives data today? What happened on 14 October? Give me a dated, quotable sentence with its number and time." |
111
112
  | `get_turkey_premium` | "What do lira buyers pay for bitcoin above the world price? What is the Turkey Premium Index and its score right now? Which Turkish exchange is dearest? What is USDT/TRY against the official rate?" |
112
113
  | `get_data_proof` | "Can I verify a ByKaranteli number was not changed later? Show the on-chain proof for BTC funding right now. Which Solana transaction sealed the newest epoch?" |
113
114
  | `get_cycle_indicators` | "Has the Pi Cycle crossed? Mayer Multiple and Puell today?" |
package/dist/tools.d.ts CHANGED
@@ -25,4 +25,4 @@ export type RegisterOptions = {
25
25
  * (the hosted endpoint). Takes precedence over apiKey when it returns one. */
26
26
  authorizationProvider?: () => string | undefined;
27
27
  };
28
- export declare function registerByKaranteliTools(server: McpServer, options?: RegisterOptions): void;
28
+ export declare function registerByKaranteliTools(target: McpServer, options?: RegisterOptions): void;
package/dist/tools.js CHANGED
@@ -6,7 +6,11 @@
6
6
  */
7
7
  import { z } from "zod/v4";
8
8
  import { buildProvenance, pageForApiPath } from "./provenance.js";
9
- export function registerByKaranteliTools(server, options) {
9
+ export function registerByKaranteliTools(target, options) {
10
+ const withTitle = (def) => def.title && !(def.annotations && "title" in def.annotations) ? { ...def, annotations: { ...(def.annotations ?? {}), title: def.title } } : def;
11
+ const server = {
12
+ registerTool: (name, def, handler) => target.registerTool.call(target, name, withTitle(def), handler),
13
+ };
10
14
  const BASE_URL = (options?.baseUrl ?? process.env.BYKARANTELI_BASE_URL ?? "https://bykaranteli.com").replace(/\/+$/, "");
11
15
  const PUBLIC_URL = (options?.publicUrl ?? process.env.BYKARANTELI_PUBLIC_URL ?? "https://bykaranteli.com").replace(/\/+$/, "");
12
16
  const USER_AGENT = `bykaranteli-mcp/${options?.version ?? "dev"} (+https://github.com/bykarantelicom/bykaranteli-mcp)`;
@@ -1152,7 +1156,7 @@ export function registerByKaranteliTools(server, options) {
1152
1156
  });
1153
1157
  server.registerTool("get_liqmap", {
1154
1158
  title: "LiqMap: estimated liquidation clusters with real prints overlaid",
1155
- 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 LiqMap snapshot for one symbol: modeled liquidation levels by price, zone aggregates and real liquidation prints from every liquidation venue ByKaranteli counts (listed on bykaranteli.com/coverage). Without an account key (or on the Free plan) the 24h view; with a Builder or higher key (BYKARANTELI_API_KEY) every timeframe from 1h to 30d. By default the 30 real levels nearest the price and the 30 newest real prints; pass detail=true for all of them.",
1159
+ 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 LiqMap snapshot for one symbol: modeled liquidation levels by price, zone aggregates and real liquidation prints from every liquidation venue ByKaranteli counts (listed on bykaranteli.com/coverage). On the Free plan the 24h view; on Builder and higher plans every timeframe from 1h to 30d. By default the 30 real levels nearest the price and the 30 newest real prints; pass detail=true for all of them.",
1156
1160
  inputSchema: {
1157
1161
  symbol: z
1158
1162
  .string()
@@ -1164,7 +1168,7 @@ export function registerByKaranteliTools(server, options) {
1164
1168
  timeframe: z
1165
1169
  .enum(["1h", "4h", "12h", "24h", "3d", "1w", "30d"])
1166
1170
  .optional()
1167
- .describe("Model window. Default 24h, the only one served without a Builder or higher key."),
1171
+ .describe("Model window. Default 24h, the only one on the Free plan; Builder and higher plans get every window."),
1168
1172
  detail: z.boolean().optional().describe("Optional. true: every real level and every real print (default false: the 30 nearest levels, the 30 newest prints)."),
1169
1173
  },
1170
1174
  annotations: READ_ONLY,
@@ -1373,6 +1377,38 @@ export function registerByKaranteliTools(server, options) {
1373
1377
  return fail(err);
1374
1378
  }
1375
1379
  });
1380
+ server.registerTool("get_desk_notes", {
1381
+ title: "Desk notes: short dated observations the ByKaranteli desk wrote from its own recorded derivatives data",
1382
+ description: "Call this when the user asks what happened in crypto derivatives today or on a date, what the desk observed, what moved in funding, open interest, liquidations, options, ETF flows or exchange premiums, or wants a dated, quotable sentence with its number and time. Returns the desk's notes newest first: each is one observation written by the desk writer (an AI model) from the platform's own recorded data and checked against it before publishing, with its publish time in UTC, the card's data time, the desk's 0 to 10 news value, the board it read from, the coins it names and its permanent URL. Information about the data, never advice. Default the last 24 hours; pass day for one UTC day, since for a window up to 7 days back, type for one card type (funding-arb, liqmap-btc, event-liq-burst, ...), lang for zh, ru or ko text.",
1383
+ inputSchema: {
1384
+ day: z.string().trim().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe("One UTC day, YYYY-MM-DD"),
1385
+ since: z.string().trim().max(40).optional().describe("ISO time; notes published at or after it, at most 7 days back (ignored with day)"),
1386
+ type: z.string().trim().toLowerCase().regex(/^[a-z0-9][a-z0-9-]{0,60}$/).optional().describe("One card type, e.g. funding-arb, liqmap-btc, event-liq-burst"),
1387
+ lang: z.enum(["en", "zh", "ru", "ko"]).optional().describe("Text language (default en); a note without that translation comes back in English"),
1388
+ limit: z.number().int().min(1).max(100).optional().describe("Notes to return, 1..100 (default 50)"),
1389
+ },
1390
+ annotations: READ_ONLY,
1391
+ }, async ({ day, since, type, lang, limit }) => {
1392
+ try {
1393
+ const q = new URLSearchParams();
1394
+ if (day)
1395
+ q.set("day", day);
1396
+ else if (since)
1397
+ q.set("since", since);
1398
+ if (type)
1399
+ q.set("type", type);
1400
+ if (lang && lang !== "en")
1401
+ q.set("lang", lang);
1402
+ if (limit)
1403
+ q.set("limit", String(limit));
1404
+ const qs = q.toString();
1405
+ const path = `/api/public/desk${qs ? `?${qs}` : ""}`;
1406
+ return ok(withProvenance(await fetchJson(path), path));
1407
+ }
1408
+ catch (err) {
1409
+ return fail(err);
1410
+ }
1411
+ });
1376
1412
  server.registerTool("get_turkey_premium", {
1377
1413
  title: "Turkey Premium Index: what lira buyers pay above the world price, with TRY reference prices from Turkish venues",
1378
1414
  description: "Call this when the user asks about Bitcoin, Ether or USDT prices in Turkish lira, the Turkey premium, the USDT/TRY rate or dollar premium in Turkey, or which Turkish exchanges (BtcTurk, Bitlo, CoinTR, OKX TR, Binance TR, Bybit TR, Bitexen; KuCoin TR contributes the USDT pairs only) trade above or below the global price. Returns the live board: the Turkey Premium Index (what a lira buyer pays for bitcoin against the global dollar price at the official exchange rate, in bps) with its dollar leg and crypto leg, a 0-100 score (50 = world price) and regime, 24h and 7d averages and the same-sign streak; then five reference prices (median of eligible order books), per-venue book status, spread, depth and each venue's implied premium. Pass pair and history_days for 15-minute history of one pair. Without pair, the daily rows cover the last 7 days; pass pair, or daily_days (up to 30) for more.",
@@ -1484,12 +1520,12 @@ export function registerByKaranteliTools(server, options) {
1484
1520
  });
1485
1521
  server.registerTool("get_options_chain", {
1486
1522
  title: "Options chain hour by hour: open interest and IV per expiry and strike, the change over 1h and 24h, the ATM IV path",
1487
- description: "Call this when the user asks how the BTC or ETH option chain moved today or over the last day: open interest and mark IV per expiry and strike from ByKaranteli's own hourly capture of every listed venue, the change over the last hour and the last 24 hours, and the front expiry's ATM IV hour by hour. Anonymous depth lists the largest strikes; a key with member depth lists every strike. Recorded from 2026-09-30, so the first days carry a short history.",
1523
+ description: "Call this when the user asks how the BTC or ETH option chain moved today or over the last day: open interest and mark IV per expiry and strike from ByKaranteli's own hourly capture of every listed venue, the change over the last hour and the last 24 hours, and the front expiry's ATM IV hour by hour. The Free plan lists the largest strikes; Builder and higher plans list every strike. Recorded from 2026-09-30, so the first days carry a short history.",
1488
1524
  inputSchema: {
1489
1525
  currency: z.enum(["BTC", "ETH"]).optional().describe("BTC or ETH (default BTC)"),
1490
1526
  venue: z.enum(["all", "deribit", "bybit", "binance", "okx", "delta"]).optional().describe("One venue or all (default all)"),
1491
1527
  expiry: z.string().trim().toUpperCase().regex(/^\d{1,2}[A-Z]{3}\d{2}$/).optional().describe("Expiry as DDMONYY, e.g. 31OCT26 (default: every expiry)"),
1492
- strikes: z.enum(["top", "all"]).optional().describe("top (largest strikes) or all (member depth)"),
1528
+ strikes: z.enum(["top", "all"]).optional().describe("top (largest strikes) or all (Builder and higher plans)"),
1493
1529
  },
1494
1530
  annotations: READ_ONLY,
1495
1531
  }, async ({ currency, venue, expiry, strikes }) => {
@@ -1588,7 +1624,7 @@ export function registerByKaranteliTools(server, options) {
1588
1624
  });
1589
1625
  server.registerTool("get_solana_perps", {
1590
1626
  title: "Solana Perps board: open interest, 24h volume and hourly rates across six Solana perpetual venues (Jupiter, Pacifica, Phoenix, GM Trade, Velocity, Bullet)",
1591
- description: "Call this when the user asks about perpetuals on Solana as a whole, which Solana perp DEX has the most open interest or volume, a market on Pacifica, Phoenix, GM Trade (GMX on Solana), Velocity (the Drift relaunch) or Bullet (funding, open interest, 24h volume, mark), or how Jupiter compares with the order-book venues. Returns the board read every 10 minutes: per-venue totals (one-sided open interest, both sides on pool venues, 24h volume, market count, median hourly rate, as_of), every market of every venue largest first with instrument type (perpetual, equity, index, commodity, fx), and optional hourly history of one market on any venue but Jupiter (7 days free, 30 with member depth; Jupiter history is get_jupiter_perps). Without venue, the 30 largest markets; pass venue, or limit (up to 300) for more.",
1627
+ description: "Call this when the user asks about perpetuals on Solana as a whole, which Solana perp DEX has the most open interest or volume, a market on Pacifica, Phoenix, GM Trade (GMX on Solana), Velocity (the Drift relaunch) or Bullet (funding, open interest, 24h volume, mark), or how Jupiter compares with the order-book venues. Returns the board read every 10 minutes: per-venue totals (one-sided open interest, both sides on pool venues, 24h volume, market count, median hourly rate, as_of), every market of every venue largest first with instrument type (perpetual, equity, index, commodity, fx), and optional hourly history of one market on any venue but Jupiter (7 days on the Free plan, 30 on Builder and higher plans; Jupiter history is get_jupiter_perps). Without venue, the 30 largest markets; pass venue, or limit (up to 300) for more.",
1592
1628
  inputSchema: {
1593
1629
  venue: z.string().trim().toLowerCase().regex(/^(jupiter|pacifica|phoenix|gmtrade|velocity|bullet)$/).optional().describe("Venue filter: jupiter, pacifica, phoenix, gmtrade, velocity or bullet"),
1594
1630
  /* Passed as typed: Pacifica and Phoenix list mixed-case markets (kBONK, kPEPE, kSHIB) and the route matches the
@@ -1779,7 +1815,7 @@ export function registerByKaranteliTools(server, options) {
1779
1815
  /* ---- 0.31.0: recorded series, alert text, alert recipes, watchlists ---- */
1780
1816
  server.registerTool("get_series", {
1781
1817
  title: "Recorded series: bars or points of one metric for one perpetual (price, OI, funding, CVD, liquidations, long/short, RSI and more)",
1782
- description: `Call this when the user wants the history of one recorded metric for one perpetual as a time series: price candles, volume, perp or spot CVD, open interest, funding (one venue, or OI-weighted across every venue as funding_agg), liquidations, long/short ratios, RSI, the Coinbase premium, US spot ETF flows, borrow rates or Hyperliquid whale net flow, for charting, backtesting or "what did X do over the last N days". Returns the /api/series answer (points as [t, v], or [t, o, h, l, c, v] for price, with unit, kind, source and source_kind, the bars served and whether member depth applied) plus provenance. metric is one of: ${SERIES_METRIC_KEYS.join(", ")} (unit, finest period and venue support of each: https://bykaranteli.com/api/series/metrics). Public depth serves fewer bars and no bars under 15 minutes (1m, 3m, 5m, 10m); a Builder key and above get member depth; the bar limits are in the same list. The answer names the venue it was read from (venue) and every venue a market-wide series sums (venues). Pass from and to (ISO) for a window, or limit for the newest bars.`,
1818
+ description: `Call this when the user wants the history of one recorded metric for one perpetual as a time series: price candles, volume, perp or spot CVD, open interest, funding (one venue, or OI-weighted across every venue as funding_agg), liquidations, long/short ratios, RSI, the Coinbase premium, US spot ETF flows, borrow rates or Hyperliquid whale net flow, for charting, backtesting or "what did X do over the last N days". Returns the /api/series answer (points as [t, v], or [t, o, h, l, c, v] for price, with unit, kind, source and source_kind, the bars served and whether member depth applied) plus provenance. metric is one of: ${SERIES_METRIC_KEYS.join(", ")} (unit, finest period and venue support of each: https://bykaranteli.com/api/series/metrics). The Free plan gets public depth: fewer bars and no bars under 15 minutes (1m, 3m, 5m, 10m); Builder and higher plans get member depth; the bar limits are in the same list. The answer names the venue it was read from (venue) and every venue a market-wide series sums (venues). Without from or limit, the newest 300 bars; pass from and to (ISO) for a window, or limit for more of the newest bars.`,
1783
1819
  inputSchema: {
1784
1820
  metric: z.string().describe("string, metric key, e.g. price, oi, funding, liquidations (list: /api/series/metrics)"),
1785
1821
  symbol: z.string().optional().describe("string, optional Binance USDT-M perp or coin, e.g. BTCUSDT or BTC (default BTCUSDT)"),
@@ -1787,7 +1823,7 @@ export function registerByKaranteliTools(server, options) {
1787
1823
  venue: z.string().optional().describe("string, optional venue id for price, oi, funding or borrow, e.g. okx (default binance)"),
1788
1824
  from: z.string().optional().describe("string, optional ISO start, e.g. 2026-09-01T00:00:00Z"),
1789
1825
  to: z.string().optional().describe("string, optional ISO end (default now)"),
1790
- limit: z.number().optional().describe(`number, optional newest bars, 10..${SERIES_MEMBER_BAR_LIMIT}; the key's depth caps it`),
1826
+ limit: z.number().optional().describe(`number, optional newest bars, 10..${SERIES_MEMBER_BAR_LIMIT}; the plan's depth caps it (default 300 without from)`),
1791
1827
  },
1792
1828
  annotations: READ_ONLY,
1793
1829
  }, async (args = {}) => {
@@ -1809,6 +1845,9 @@ export function registerByKaranteliTools(server, options) {
1809
1845
  const bars = from ? Math.ceil((end.getTime() - from.getTime()) / PERIOD_MS[period]) : undefined;
1810
1846
  if (bars !== undefined)
1811
1847
  limit = Math.min(limit ?? bars, bars);
1848
+ /* 0.35.1: the newest 300 bars when neither from nor limit is given (the route gives members 1000 by default). */
1849
+ if (limit === undefined)
1850
+ limit = 300;
1812
1851
  if (limit !== undefined)
1813
1852
  limit = Math.max(10, Math.min(SERIES_MEMBER_BAR_LIMIT, limit));
1814
1853
  const q = new URLSearchParams({ metric, symbol, period });
@@ -1839,7 +1878,7 @@ export function registerByKaranteliTools(server, options) {
1839
1878
  });
1840
1879
  server.registerTool("list_alert_recipes", {
1841
1880
  title: "Your alert recipes: every alert on your account with its conditions, scope, channels and when it last fired",
1842
- description: "Call this when the user asks which alerts they have, whether an alert fired, or before deleting or changing one. Returns the account's alert recipes (id, name, scope, symbols, conditions, cooldown in hours, enabled, last fired, fire count, channels). Needs the account key; reads nothing but this account.",
1881
+ description: "Call this when the user asks which alerts they have, whether an alert fired, or before deleting or changing one. Returns the account's alert recipes (id, name, scope, symbols, conditions, cooldown in hours, enabled, last fired, fire count, channels). Needs a signed-in account (OAuth sign-in or account key); reads nothing but this account.",
1843
1882
  inputSchema: {},
1844
1883
  annotations: ACCOUNT_READ,
1845
1884
  }, async () => {
@@ -1848,7 +1887,7 @@ export function registerByKaranteliTools(server, options) {
1848
1887
  });
1849
1888
  server.registerTool("create_alert_recipe", {
1850
1889
  title: "Create an alert recipe (writes to your account)",
1851
- description: `Call this when the user asks to be alerted when a metric crosses a threshold and has agreed to the exact condition (parse_alert_text turns their words into one). Saves an alert recipe on the account: it fires when every condition holds, delivers by Telegram first with email as fallback unless channels says otherwise, and waits cooldown_hours before it fires again for the same symbol. field is one of: ${RECIPE_FIELD_KEYS.join(", ")}; op is one of ${RECIPE_OPS.join(" ")}; percent fields take percent values (0.05 means 0.05%). Pass field, op and threshold for one condition, or conditions for up to ${RECIPE_LIMITS.MAX_CONDITIONS}. scope: watchlist (default), any, or symbols with symbols. The plan sets how many recipes an account keeps; past it the tool answers with the limit. Writes are rate limited per key and each one is recorded on the account.`,
1890
+ description: `Call this when the user asks to be alerted when a metric crosses a threshold and has agreed to the exact condition (parse_alert_text turns their words into one). Saves an alert recipe on the account: it fires when every condition holds, delivers by Telegram first with email as fallback unless channels says otherwise, and waits cooldown_hours before it fires again for the same symbol. field is one of: ${RECIPE_FIELD_KEYS.join(", ")}; op is one of ${RECIPE_OPS.join(" ")}; percent fields take percent values (0.05 means 0.05%). Pass field, op and threshold for one condition, or conditions for up to ${RECIPE_LIMITS.MAX_CONDITIONS}. scope: watchlist (default), any, or symbols with symbols. The plan sets how many recipes an account keeps; past it the tool answers with the limit. Writes are rate limited per connection (sign-in or key) and each one is recorded on the account.`,
1852
1891
  inputSchema: {
1853
1892
  field: z.string().optional().describe("string, one condition's metric, e.g. funding_rate_pct"),
1854
1893
  op: z.enum(RECIPE_OPS).optional().describe(`string, one condition's comparison: ${RECIPE_OPS.join(" | ")}`),
@@ -1910,7 +1949,7 @@ export function registerByKaranteliTools(server, options) {
1910
1949
  });
1911
1950
  server.registerTool("delete_alert_recipe", {
1912
1951
  title: "Delete one of your alert recipes (writes to your account)",
1913
- description: "Call this when the user asks to remove an alert. Deletes the alert recipe with this id from the account (list_alert_recipes shows the ids); an id that is not one of the account's recipes changes nothing and says so. Writes are rate limited per key and each one is recorded on the account.",
1952
+ description: "Call this when the user asks to remove an alert. Deletes the alert recipe with this id from the account (list_alert_recipes shows the ids); an id that is not one of the account's recipes changes nothing and says so. Writes are rate limited per connection (sign-in or key) and each one is recorded on the account.",
1914
1953
  inputSchema: {
1915
1954
  id: z.string().describe("string, the recipe id from list_alert_recipes"),
1916
1955
  },
@@ -1928,7 +1967,7 @@ export function registerByKaranteliTools(server, options) {
1928
1967
  });
1929
1968
  server.registerTool("list_watchlists", {
1930
1969
  title: "Your watchlists and the symbols on each",
1931
- description: "Call this when the user asks what is on their watchlist, which lists they have, or before adding or removing a symbol. Returns the account's watchlists (id, name, symbol count) and, unless include_symbols is false, the symbols on each list in order. Needs the account key; reads nothing but this account.",
1970
+ description: "Call this when the user asks what is on their watchlist, which lists they have, or before adding or removing a symbol. Returns the account's watchlists (id, name, symbol count) and, unless include_symbols is false, the symbols on each list in order. Needs a signed-in account (OAuth sign-in or account key); reads nothing but this account.",
1932
1971
  inputSchema: {
1933
1972
  include_symbols: z.boolean().optional().describe("boolean, optional: include each list's symbols (default true)"),
1934
1973
  },
@@ -1951,7 +1990,7 @@ export function registerByKaranteliTools(server, options) {
1951
1990
  });
1952
1991
  server.registerTool("add_watchlist_symbol", {
1953
1992
  title: "Add a symbol to your watchlist (writes to your account)",
1954
- description: "Call this when the user asks to watch, follow or add a coin to their watchlist. Adds the symbol to the list named by watchlist_id, else to the default list (or the only list the account has); a symbol already on the list stays once. Returns the list's symbols after the change. Writes are rate limited per key and each one is recorded on the account.",
1993
+ description: "Call this when the user asks to watch, follow or add a coin to their watchlist. Adds the symbol to the list named by watchlist_id, else to the default list (or the only list the account has); a symbol already on the list stays once. Returns the list's symbols after the change. Writes are rate limited per connection (sign-in or key) and each one is recorded on the account.",
1955
1994
  inputSchema: {
1956
1995
  symbol: z.string().describe("string, a Binance USDT-M perp or coin, e.g. SOLUSDT or SOL"),
1957
1996
  watchlist_id: z.string().optional().describe("string, optional list id from list_watchlists (default: the default list)"),
@@ -1971,7 +2010,7 @@ export function registerByKaranteliTools(server, options) {
1971
2010
  });
1972
2011
  server.registerTool("remove_watchlist_symbol", {
1973
2012
  title: "Remove a symbol from your watchlist (writes to your account)",
1974
- description: "Call this when the user asks to stop watching a coin or remove it from their watchlist. Removes the symbol from the list named by watchlist_id, else from the default list (or the only list the account has); a symbol that is not on the list changes nothing. Returns the list's symbols after the change. Writes are rate limited per key and each one is recorded on the account.",
2013
+ description: "Call this when the user asks to stop watching a coin or remove it from their watchlist. Removes the symbol from the list named by watchlist_id, else from the default list (or the only list the account has); a symbol that is not on the list changes nothing. Returns the list's symbols after the change. Writes are rate limited per connection (sign-in or key) and each one is recorded on the account.",
1975
2014
  inputSchema: {
1976
2015
  symbol: z.string().describe("string, the symbol to remove, e.g. SOLUSDT or SOL"),
1977
2016
  watchlist_id: z.string().optional().describe("string, optional list id from list_watchlists (default: the default list)"),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bykaranteli-mcp",
3
- "version": "0.35.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. 67 read-only and account tools (the alert and watchlist tools act on your own account), free account key, paid depth via plans or x402.",
3
+ "version": "0.36.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. 68 read-only and account tools (the alert and watchlist tools act on your own account), free account key, paid depth via plans or x402.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "bykaranteli-mcp": "dist/index.js"