@sharpe-terminal/mcp-server 1.2.0 → 1.5.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 +65 -163
- package/dist/api-client.d.ts +40 -0
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +244 -9
- package/dist/api-client.js.map +1 -1
- package/dist/composite-tools.d.ts +49 -3
- package/dist/composite-tools.d.ts.map +1 -1
- package/dist/composite-tools.js +452 -380
- package/dist/composite-tools.js.map +1 -1
- package/dist/index.js +9 -226
- package/dist/index.js.map +1 -1
- package/dist/resources.d.ts +44 -5
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +61 -5
- package/dist/resources.js.map +1 -1
- package/dist/server.d.ts +15 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +266 -0
- package/dist/server.js.map +1 -0
- package/dist/tool-runtime.d.ts +53 -0
- package/dist/tool-runtime.d.ts.map +1 -1
- package/dist/tool-runtime.js +277 -52
- package/dist/tool-runtime.js.map +1 -1
- package/dist/tools.d.ts +143 -76
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +403 -116
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
package/dist/tools.js
CHANGED
|
@@ -1,7 +1,55 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { FUTURES_CHARTS } from "./resources.js";
|
|
3
|
+
import { MAX_ITEMS, paginateRows, paginateSnapshotPayload, rowTimeMs, } from "./tool-runtime.js";
|
|
3
4
|
// -- Tool schemas (Zod shapes for McpServer.tool()) --
|
|
4
5
|
const FUTURES_CHART_IDS = FUTURES_CHARTS.map((chart) => chart.id);
|
|
6
|
+
const pageCursorSchema = z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Pagination cursor returned by the previous page. Only meaningful alongside limit.");
|
|
10
|
+
export const globalOverviewSchema = {
|
|
11
|
+
tab: z
|
|
12
|
+
.enum(["crypto", "equity", "preipo", "etf", "index", "commodity", "fx"])
|
|
13
|
+
.default("crypto")
|
|
14
|
+
.describe("Universe to return rows for. 'crypto' = crypto perps; the rest are RWA perp classes. The market-wide metric block is identical on every tab. The 'basket' asset class has no tab and is rejected."),
|
|
15
|
+
limit: z
|
|
16
|
+
.number()
|
|
17
|
+
.int()
|
|
18
|
+
.min(1)
|
|
19
|
+
.max(1000)
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("Rows per page (1-1000). A paged response is { data, pagination } holding only the ranked rows; the market-wide metric block comes back on unpaged calls. Responses are additionally capped at 200 items, so pass limit together with cursor to page through every row."),
|
|
22
|
+
cursor: pageCursorSchema,
|
|
23
|
+
};
|
|
24
|
+
export const rwaPerpRatesSchema = {
|
|
25
|
+
type: z
|
|
26
|
+
.enum(["current", "history", "stats"])
|
|
27
|
+
.default("current")
|
|
28
|
+
.describe("Type of rwa-perp data. 'current' = latest funding/rollover snapshot per venue market, 'history' = session-tagged settlement time-series for one symbol (Hyperliquid + Kraken), 'stats' = best carry, top cross-venue spread, weekend premium, and tracked open interest."),
|
|
29
|
+
symbol: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.describe("Underlying equity ticker (e.g. TSLA, NVDA, MSTR). Required for type=history. GOOG (Ostium) and GOOGL (Hyperliquid/Kraken) are distinct share classes."),
|
|
33
|
+
venue: z
|
|
34
|
+
.string()
|
|
35
|
+
.optional()
|
|
36
|
+
.describe("Filter results to a single venue, e.g. Binance, Bybit, OKX, Bitget, Gate, Kraken, Coinbase, Aster, Lighter, Extended, GRVT, ApeX, Pacifica, Orderly, Ostium, Avantis, or a Hyperliquid HIP-3 builder market (Hyperliquid, Felix, Kinetiq, dreamcash, Paragon, Ventuals). Free-form because the venue list is registry-driven and grows."),
|
|
37
|
+
days: z
|
|
38
|
+
.number()
|
|
39
|
+
.min(1)
|
|
40
|
+
.max(90)
|
|
41
|
+
.default(7)
|
|
42
|
+
.optional()
|
|
43
|
+
.describe("Days of settlement history to retrieve (type=history only). Range: 1-90."),
|
|
44
|
+
limit: z
|
|
45
|
+
.number()
|
|
46
|
+
.int()
|
|
47
|
+
.min(1)
|
|
48
|
+
.max(5000)
|
|
49
|
+
.optional()
|
|
50
|
+
.describe("Rows per page for type=current and type=history (1-5000); a paged response is { data, pagination }. Responses are additionally capped at 200 items, so pass limit together with cursor to page through every row."),
|
|
51
|
+
cursor: pageCursorSchema,
|
|
52
|
+
};
|
|
5
53
|
export const fundingRatesSchema = {
|
|
6
54
|
type: z
|
|
7
55
|
.enum(["current", "accumulated", "history"])
|
|
@@ -10,7 +58,19 @@ export const fundingRatesSchema = {
|
|
|
10
58
|
coin: z
|
|
11
59
|
.string()
|
|
12
60
|
.optional()
|
|
13
|
-
.describe("
|
|
61
|
+
.describe("Coin ticker, lot spelling or full name (e.g. BTC, PEPE, 1000PEPE, kPEPE, bitcoin). Returns every contract of that asset across all exchanges, whatever its base_coin spelling: PEPE also returns the 1000PEPE and KPEPE lot contracts (read lot_multiplier). Required for type=history; optional for current/accumulated."),
|
|
62
|
+
exchange: z
|
|
63
|
+
.string()
|
|
64
|
+
.optional()
|
|
65
|
+
.describe("Filter to a single venue. Values are title case exactly as returned in the `exchange` field (e.g. Binance, Bybit, OKX, Gate.io, Hyperliquid, Kraken, Aster, Lighter, dYdX, Crypto.com, edgeX, tradeXYZ); lowercase slugs such as 'gate-io' also resolve. Free-form because the venue list is registry-driven and grows. Read sharpe://exchanges for the current list."),
|
|
66
|
+
margin: z
|
|
67
|
+
.enum(["linear", "inverse"])
|
|
68
|
+
.optional()
|
|
69
|
+
.describe("Collateral convention: 'linear' = quote-margined (USDT/USDC), 'inverse' = coin-margined. Unfiltered by default."),
|
|
70
|
+
asset_class: z
|
|
71
|
+
.enum(["crypto", "equity", "commodity", "fx", "index"])
|
|
72
|
+
.optional()
|
|
73
|
+
.describe("Underlying category of the perpetual. Unfiltered by default, so tokenized-equity, commodity, index and FX perps are returned alongside crypto; pass 'crypto' to rank crypto only."),
|
|
14
74
|
days: z
|
|
15
75
|
.number()
|
|
16
76
|
.min(1)
|
|
@@ -18,6 +78,66 @@ export const fundingRatesSchema = {
|
|
|
18
78
|
.default(30)
|
|
19
79
|
.optional()
|
|
20
80
|
.describe("Number of days of history to retrieve (type=history only). Range: 1-1095."),
|
|
81
|
+
limit: z
|
|
82
|
+
.number()
|
|
83
|
+
.int()
|
|
84
|
+
.min(1)
|
|
85
|
+
.max(5000)
|
|
86
|
+
.optional()
|
|
87
|
+
.describe("Maximum rows to return. Responses are additionally capped at 200 items to protect the agent context window, so pass limit together with cursor to page through the whole book."),
|
|
88
|
+
cursor: z
|
|
89
|
+
.string()
|
|
90
|
+
.optional()
|
|
91
|
+
.describe("Pagination cursor returned by the previous page. Only meaningful alongside limit."),
|
|
92
|
+
sort: z
|
|
93
|
+
.enum(["open_interest", "-open_interest"])
|
|
94
|
+
.optional()
|
|
95
|
+
.describe("type=current only: order the rows by their open_interest, ascending, or descending with the leading '-'. Rows with unknown open interest come last either way. Applied before limit/cursor."),
|
|
96
|
+
extremes: z
|
|
97
|
+
.number()
|
|
98
|
+
.int()
|
|
99
|
+
.min(1)
|
|
100
|
+
.max(100)
|
|
101
|
+
.optional()
|
|
102
|
+
.describe("type=current only: answer with the N highest and N lowest markets by rate_8h (extremes.highest, extremes.lowest, each row with rate_8h and apr) among fresh rows with a usable interval, and how many rows each check left out (extremes.omitted: stale, no_interval, below_floor). The other filters narrow the rows first. Returns an object instead of rows: do not pass limit, cursor or sort with it."),
|
|
103
|
+
min_oi_usd: z
|
|
104
|
+
.number()
|
|
105
|
+
.min(0)
|
|
106
|
+
.optional()
|
|
107
|
+
.describe("With extremes only: leave out markets whose open interest in USD is below this floor. A market with unknown open interest fails a floor above 0."),
|
|
108
|
+
stats: z
|
|
109
|
+
.enum(["1"])
|
|
110
|
+
.optional()
|
|
111
|
+
.describe("type=current only: '1' answers with the whole book's funding (market.funding_apr_mean and market.funding_apr_oi_weighted, APR fractions over one primary contract per venue and asset with a fresh rate; market.positive and market.negative counts). Returns an object instead of rows; cannot be combined with coin, exchange, margin, asset_class, limit, cursor or sort."),
|
|
112
|
+
summary: z
|
|
113
|
+
.enum(["1"])
|
|
114
|
+
.optional()
|
|
115
|
+
.describe("type=current with coin only: '1' answers with the coin's funding across venues, one summary entry per base_coin spelling and asset class: funding_avg_8h (the funding grid's Avg Rate: open-interest-weighted over each venue's fresh primary contract, or their median; funding_method says which), funding_median_8h, funding_venues_used, funding_venues_stale, funding_all_stale. Returns an object instead of rows; cannot be combined with limit, cursor or sort."),
|
|
116
|
+
};
|
|
117
|
+
export const fundingSettlementSchema = {
|
|
118
|
+
window: z
|
|
119
|
+
.enum(["current", "1d", "3d", "7d"])
|
|
120
|
+
.default("current")
|
|
121
|
+
.describe("Settlement window. 'current' is the next settlement, priced live off open interest and the forward-looking rate (predicted_rate when a venue publishes one, else the in-progress rate) -- always estimated, never realised yet. '1d'/'3d'/'7d' are realised windows; one whose coverage is below 90% carries partial: true in its window value because its history is still accruing, not a completed total."),
|
|
122
|
+
class: z
|
|
123
|
+
.enum(["all", "crypto", "rwa"])
|
|
124
|
+
.default("all")
|
|
125
|
+
.describe("Asset universe. 'rwa' = tokenized equity, commodity, FX and index perps. crypto + rwa always equal the all totals."),
|
|
126
|
+
coin: z
|
|
127
|
+
.string()
|
|
128
|
+
.optional()
|
|
129
|
+
.describe("Comma-separated base coin tickers (e.g. 'BTC' or 'BTC,ETH,SOL') to filter rows to. `totals` stays scoped to the selected class regardless of this filter -- read a filtered coin's own row for its number, not totals."),
|
|
130
|
+
exchange: z
|
|
131
|
+
.string()
|
|
132
|
+
.optional()
|
|
133
|
+
.describe("Keep only coins that have a contract on this venue. Each row's windows and open interest stay all-venue totals, not this venue's own figures. Free-form because the venue list is registry-driven and grows; an unresolvable value is rejected rather than silently returning an empty book."),
|
|
134
|
+
limit: z
|
|
135
|
+
.number()
|
|
136
|
+
.int()
|
|
137
|
+
.min(1)
|
|
138
|
+
.max(1000)
|
|
139
|
+
.optional()
|
|
140
|
+
.describe("Maximum rows to return, in market-cap rank order (unranked coins follow alphabetically). Defaults to 100."),
|
|
21
141
|
};
|
|
22
142
|
export const futuresDataSchema = {
|
|
23
143
|
chart: z
|
|
@@ -37,6 +157,14 @@ export const futuresDataSchema = {
|
|
|
37
157
|
.string()
|
|
38
158
|
.optional()
|
|
39
159
|
.describe("Comma-separated list of exchanges to include (e.g. Binance,Bybit,OKX,Deribit,Hyperliquid)."),
|
|
160
|
+
limit: z
|
|
161
|
+
.number()
|
|
162
|
+
.int()
|
|
163
|
+
.min(1)
|
|
164
|
+
.max(10000)
|
|
165
|
+
.optional()
|
|
166
|
+
.describe("Rows per page (1-10000), oldest first, returned with a pagination cursor. Paged rows are raw chart rows, oi-snapshot included. Responses are additionally capped at 200 items, so pass limit together with cursor to page through the full window."),
|
|
167
|
+
cursor: pageCursorSchema,
|
|
40
168
|
};
|
|
41
169
|
export const futuresCoinsSchema = {};
|
|
42
170
|
export const correlationMatrixSchema = {
|
|
@@ -48,7 +176,7 @@ export const correlationMatrixSchema = {
|
|
|
48
176
|
ids: z
|
|
49
177
|
.string()
|
|
50
178
|
.optional()
|
|
51
|
-
.describe("Comma-separated
|
|
179
|
+
.describe("Comma-separated asset IDs. Use CoinGecko IDs for crypto (e.g. bitcoin,ethereum) and Sharpe IDs for TradFi (e.g. sp500,gold,nvda). If omitted, returns the default mixed set."),
|
|
52
180
|
};
|
|
53
181
|
export const arbitrageSpotPerpSchema = {
|
|
54
182
|
exchange: z
|
|
@@ -60,13 +188,38 @@ export const arbitrageSpotPerpSchema = {
|
|
|
60
188
|
.enum(["all", "long", "short"])
|
|
61
189
|
.default("all")
|
|
62
190
|
.optional()
|
|
63
|
-
.describe("Filter by
|
|
191
|
+
.describe("Filter by perpetual-leg direction: short for positive funding capture, long for negative funding capture."),
|
|
192
|
+
minOiUsd: z
|
|
193
|
+
.number()
|
|
194
|
+
.min(0)
|
|
195
|
+
.optional()
|
|
196
|
+
.describe("Minimum open interest in USD on the perp leg (perpOpenInterestUsd). A row whose open interest is unknown fails a floor above 0. Default 0 (no floor). The board order is kept."),
|
|
64
197
|
};
|
|
65
198
|
export const arbitrageCrossExchangeSchema = {
|
|
66
199
|
exchanges: z
|
|
67
200
|
.string()
|
|
68
201
|
.optional()
|
|
69
|
-
.describe("Comma-separated list of
|
|
202
|
+
.describe("Comma-separated list of venues to compare (e.g. Binance,Bybit,Hyperliquid). Omit for all 32 funding venues."),
|
|
203
|
+
minOiUsd: z
|
|
204
|
+
.number()
|
|
205
|
+
.min(0)
|
|
206
|
+
.optional()
|
|
207
|
+
.describe("Minimum open interest in USD on the smaller leg. Legs with unknown OI fail the floor. Default 0 (no floor)."),
|
|
208
|
+
minVolUsd: z
|
|
209
|
+
.number()
|
|
210
|
+
.min(0)
|
|
211
|
+
.optional()
|
|
212
|
+
.describe("Minimum 24h volume in USD on the smaller leg. Legs with unknown volume fail the floor. Default 0 (no floor)."),
|
|
213
|
+
assetClass: z
|
|
214
|
+
.enum(["all", "crypto", "rwa"])
|
|
215
|
+
.optional()
|
|
216
|
+
.describe('Underlying filter: "all" (default), "crypto", or "rwa" (equity, commodity, FX and index perps). Pairs never cross asset classes.'),
|
|
217
|
+
limit: z
|
|
218
|
+
.number()
|
|
219
|
+
.int()
|
|
220
|
+
.min(1)
|
|
221
|
+
.optional()
|
|
222
|
+
.describe("At most this many rows, the first ones in the board's order (executable first). Default: every row."),
|
|
70
223
|
};
|
|
71
224
|
export const arbitrageScannerSchema = {
|
|
72
225
|
coin: z
|
|
@@ -80,17 +233,26 @@ export const arbitrageScannerSchema = {
|
|
|
80
233
|
minApr: z
|
|
81
234
|
.number()
|
|
82
235
|
.optional()
|
|
83
|
-
.describe("Minimum
|
|
236
|
+
.describe("Minimum product-specific fee-adjusted net APR in percentage points."),
|
|
84
237
|
minOiUsd: z
|
|
85
238
|
.number()
|
|
86
239
|
.min(0)
|
|
87
240
|
.optional()
|
|
88
241
|
.describe("Minimum open interest in USD."),
|
|
242
|
+
minVolumeUsd: z
|
|
243
|
+
.number()
|
|
244
|
+
.min(0)
|
|
245
|
+
.optional()
|
|
246
|
+
.describe("Minimum 24-hour volume in USD."),
|
|
89
247
|
minDepthUsd: z
|
|
90
248
|
.number()
|
|
91
249
|
.min(0)
|
|
92
250
|
.optional()
|
|
93
251
|
.describe("Minimum executable depth in USD when available."),
|
|
252
|
+
marginType: z
|
|
253
|
+
.enum(["linear", "inverse", "both"])
|
|
254
|
+
.optional()
|
|
255
|
+
.describe("Futures margin type filter."),
|
|
94
256
|
notional: z
|
|
95
257
|
.number()
|
|
96
258
|
.positive()
|
|
@@ -112,7 +274,10 @@ export const arbitrageScannerSchema = {
|
|
|
112
274
|
export const cexSpotTransferScannerSchema = {
|
|
113
275
|
coin: arbitrageScannerSchema.coin,
|
|
114
276
|
exchanges: arbitrageScannerSchema.exchanges,
|
|
115
|
-
minApr:
|
|
277
|
+
minApr: z
|
|
278
|
+
.number()
|
|
279
|
+
.optional()
|
|
280
|
+
.describe("Minimum fee-adjusted transfer profit in percentage points (legacy parameter name)."),
|
|
116
281
|
minDepthUsd: arbitrageScannerSchema.minDepthUsd,
|
|
117
282
|
notional: arbitrageScannerSchema.notional,
|
|
118
283
|
limit: arbitrageScannerSchema.limit,
|
|
@@ -128,21 +293,7 @@ export const heatmapSchema = {
|
|
|
128
293
|
.string()
|
|
129
294
|
.default("top-100")
|
|
130
295
|
.optional()
|
|
131
|
-
.describe("
|
|
132
|
-
};
|
|
133
|
-
export const dexScreenerDataSchema = {
|
|
134
|
-
category: z
|
|
135
|
-
.enum(["volume", "trending", "gainers", "losers", "new_pairs"])
|
|
136
|
-
.default("trending")
|
|
137
|
-
.optional()
|
|
138
|
-
.describe("DEX Screener category."),
|
|
139
|
-
network: z.string().optional().describe("Optional chain/network slug."),
|
|
140
|
-
phrase: z.string().optional().describe("Optional search phrase."),
|
|
141
|
-
limit: z.number().min(1).max(100).default(50).optional(),
|
|
142
|
-
};
|
|
143
|
-
export const dexScreenerSecuritySchema = {
|
|
144
|
-
address: z.string().describe("Token contract address."),
|
|
145
|
-
chainId: z.number().int().positive().describe("Codex network ID."),
|
|
296
|
+
.describe("One of 34 category slugs (e.g. top-100, defi, layer-1, memes). The legacy top-100 slug returns the Top 50 universe."),
|
|
146
297
|
};
|
|
147
298
|
export const tokenScannerSchema = {
|
|
148
299
|
mode: z
|
|
@@ -156,18 +307,30 @@ export const tokenScannerSchema = {
|
|
|
156
307
|
.describe("Comma-separated Dexscreener chain IDs."),
|
|
157
308
|
chain: z.string().optional().describe("Single chain for top-new mode."),
|
|
158
309
|
profile: z
|
|
159
|
-
.enum(["discovery", "balanced", "strict"
|
|
310
|
+
.enum(["discovery", "balanced", "strict"])
|
|
160
311
|
.optional()
|
|
161
312
|
.describe("Scanner profile."),
|
|
162
|
-
|
|
313
|
+
days: z.number().min(1).optional().describe("Top-new lookback in days."),
|
|
314
|
+
limit: z.number().min(1).max(72).default(50).optional(),
|
|
163
315
|
minLiquidityUsd: z.number().min(0).optional(),
|
|
164
316
|
minVolumeH24: z.number().min(0).optional(),
|
|
165
317
|
minTxnsH1: z.number().min(0).optional(),
|
|
318
|
+
minTxnsH24: z.number().min(0).optional(),
|
|
166
319
|
maxAgeHours: z.number().min(0).optional(),
|
|
320
|
+
includeUnknownAge: z.boolean().optional(),
|
|
321
|
+
sortBy: z.enum(["score", "readiness", "rs", "volume", "momentum"]).optional(),
|
|
322
|
+
minBreakoutReadiness: z.number().min(0).optional(),
|
|
323
|
+
minRelativeStrength: z.number().optional(),
|
|
324
|
+
maxVolLiqRatio: z.number().min(0).optional(),
|
|
325
|
+
minPriceChangeH1: z.number().optional(),
|
|
167
326
|
};
|
|
168
327
|
export const rugCheckSecuritySchema = {
|
|
169
328
|
address: z.string().describe("Token contract address."),
|
|
170
|
-
chainId: z
|
|
329
|
+
chainId: z
|
|
330
|
+
.number()
|
|
331
|
+
.int()
|
|
332
|
+
.positive()
|
|
333
|
+
.describe("EVM chain ID (1 Ethereum, 56 BNB Smart Chain, 8453 Base, 42161 Arbitrum, 137 Polygon, 10 Optimism, 43114 Avalanche, 146 Sonic, 80094 Berachain, and 29 more), or 1399811149 for Solana and 728126428 for Tron. An unsupported chain returns 400."),
|
|
171
334
|
};
|
|
172
335
|
export const rugCheckTrendingSchema = {
|
|
173
336
|
limit: z.number().min(1).max(100).default(50).optional(),
|
|
@@ -205,7 +368,7 @@ export const webTrafficSchema = {
|
|
|
205
368
|
.optional()
|
|
206
369
|
.describe("Entity type."),
|
|
207
370
|
mode: z
|
|
208
|
-
.enum(["rankings", "
|
|
371
|
+
.enum(["rankings", "snapshots", "market"])
|
|
209
372
|
.optional()
|
|
210
373
|
.describe("Payload mode."),
|
|
211
374
|
tf: z
|
|
@@ -218,23 +381,40 @@ export const webTrafficSchema = {
|
|
|
218
381
|
.optional()
|
|
219
382
|
.describe("Market sub-mode when mode=market."),
|
|
220
383
|
};
|
|
221
|
-
export const katanaSchema = {};
|
|
222
384
|
export const narrativesSchema = {
|
|
223
385
|
narrative: z
|
|
224
386
|
.string()
|
|
225
387
|
.optional()
|
|
226
|
-
.describe("Narrative
|
|
388
|
+
.describe("Narrative to filter by, as the id the API matches (layer-1, layer-2, defi, ai-agents, defai, depin, desci, gaming, dex, cex, lending, memes, nfts, oracles, privacy, rwa, stablecoins, restaking, liquid-staking, modular, socialfi, intent, prediction-markets, perps, bridges, account-abstraction, tap-to-earn, telegram-apps, zk, yield-farming). Page slugs such as dex-tokens or cex-tokens return no coins; use dex or cex. Omit for all narratives."),
|
|
227
389
|
correlation: z
|
|
228
390
|
.string()
|
|
229
391
|
.optional()
|
|
230
392
|
.describe('Set to "true" to include correlation data between the narrative\'s tokens.'),
|
|
231
393
|
timeframe: z.string().optional().describe("Timeframe for correlation data."),
|
|
394
|
+
sort: z
|
|
395
|
+
.enum(["-change24h", "change24h"])
|
|
396
|
+
.optional()
|
|
397
|
+
.describe("Order the narratives list by 24h change: '-change24h' highest first, 'change24h' lowest first. A narrative without a 24h change comes last either way."),
|
|
398
|
+
top: z
|
|
399
|
+
.number()
|
|
400
|
+
.int()
|
|
401
|
+
.min(1)
|
|
402
|
+
.max(50)
|
|
403
|
+
.optional()
|
|
404
|
+
.describe("Add `top`: the N narratives with the highest 24h change, highest first. A narrative without a 24h change is never ranked."),
|
|
405
|
+
bottom: z
|
|
406
|
+
.number()
|
|
407
|
+
.int()
|
|
408
|
+
.min(1)
|
|
409
|
+
.max(50)
|
|
410
|
+
.optional()
|
|
411
|
+
.describe("Add `bottom`: the N narratives with the lowest 24h change, lowest first. A narrative without a 24h change is never ranked."),
|
|
232
412
|
};
|
|
233
413
|
export const ecosystemsSchema = {
|
|
234
414
|
ecosystem: z
|
|
235
415
|
.string()
|
|
236
416
|
.optional()
|
|
237
|
-
.describe("Ecosystem
|
|
417
|
+
.describe("Ecosystem to filter by, as the id the API matches (e.g. ethereum, solana, bnb, arbitrum, base, bitcoin, avalanche, optimism, cosmos, polkadot, sui, aptos, ton, tron); read sharpe://ecosystems for all of them. Page slugs such as bnb-chain or toncoin return no coins; use bnb or ton. Omit for all ecosystems."),
|
|
238
418
|
excludeNative: z
|
|
239
419
|
.string()
|
|
240
420
|
.optional()
|
|
@@ -291,6 +471,13 @@ export const newsSchema = {
|
|
|
291
471
|
.string()
|
|
292
472
|
.optional()
|
|
293
473
|
.describe("ISO 8601 timestamp. Only return articles published after this time."),
|
|
474
|
+
q: z
|
|
475
|
+
.string()
|
|
476
|
+
.trim()
|
|
477
|
+
.min(1)
|
|
478
|
+
.max(200)
|
|
479
|
+
.optional()
|
|
480
|
+
.describe("Search article titles across the stored news corpus."),
|
|
294
481
|
offset: z
|
|
295
482
|
.number()
|
|
296
483
|
.int()
|
|
@@ -298,36 +485,19 @@ export const newsSchema = {
|
|
|
298
485
|
.optional()
|
|
299
486
|
.describe("Offset for pagination; skip this many articles before returning results."),
|
|
300
487
|
};
|
|
301
|
-
export const curatedNewsSchema = {
|
|
302
|
-
limit: z
|
|
303
|
-
.number()
|
|
304
|
-
.min(1)
|
|
305
|
-
.max(100)
|
|
306
|
-
.default(20)
|
|
307
|
-
.optional()
|
|
308
|
-
.describe("Maximum number of curated stories to return (1-100)."),
|
|
309
|
-
category: z
|
|
310
|
-
.enum(["all", "crypto", "ai", "markets", "geopolitics"])
|
|
311
|
-
.optional()
|
|
312
|
-
.describe("Filter by category: all, crypto, ai, markets, geopolitics."),
|
|
313
|
-
cursor: z
|
|
314
|
-
.string()
|
|
315
|
-
.optional()
|
|
316
|
-
.describe("Pagination cursor (ISO date or 'date|id') from a previous response."),
|
|
317
|
-
};
|
|
318
488
|
export const marketOverviewSchema = {};
|
|
319
489
|
export const pricePredictionSchema = {
|
|
320
490
|
coin: z
|
|
321
491
|
.string()
|
|
322
492
|
.optional()
|
|
323
|
-
.describe("
|
|
493
|
+
.describe("Ticker or canonical coin slug (e.g. BTC, bitcoin, solana). Omit for all coins."),
|
|
324
494
|
};
|
|
325
495
|
export const searchMarketCapSchema = {
|
|
326
496
|
q: z
|
|
327
497
|
.string()
|
|
328
498
|
.min(2)
|
|
329
499
|
.max(100)
|
|
330
|
-
.describe("
|
|
500
|
+
.describe("Crypto or supported TradFi asset name/symbol (2-100 characters)."),
|
|
331
501
|
};
|
|
332
502
|
export const gemFinderSchema = {
|
|
333
503
|
limit: z
|
|
@@ -337,6 +507,10 @@ export const gemFinderSchema = {
|
|
|
337
507
|
.default(100)
|
|
338
508
|
.optional()
|
|
339
509
|
.describe("Maximum number of tokens to return (1-1000)."),
|
|
510
|
+
cursor: z
|
|
511
|
+
.string()
|
|
512
|
+
.optional()
|
|
513
|
+
.describe("Snapshot-bound pagination cursor returned by the previous Gem Finder page."),
|
|
340
514
|
};
|
|
341
515
|
export const derivativesOverviewSchema = {};
|
|
342
516
|
export const apiCoverageSchema = {};
|
|
@@ -375,15 +549,25 @@ const listingExchangeIds = [
|
|
|
375
549
|
"dydx",
|
|
376
550
|
"aevo",
|
|
377
551
|
];
|
|
552
|
+
// /listings/data validates only the legacy compatibility venues
|
|
553
|
+
// (legacyListingExchangeIds in src/lib/api/schemas.ts) and 400s the rest;
|
|
554
|
+
// the recent/events feeds accept every id in listingExchangeIds.
|
|
555
|
+
const legacyListingExchangeIds = [
|
|
556
|
+
"binance",
|
|
557
|
+
"okx",
|
|
558
|
+
"bybit",
|
|
559
|
+
"gateio",
|
|
560
|
+
"mexc",
|
|
561
|
+
];
|
|
378
562
|
export const listingsDataSchema = {
|
|
379
563
|
narrative: z
|
|
380
564
|
.string()
|
|
381
565
|
.optional()
|
|
382
566
|
.describe("Filter to a single narrative slug (e.g. 'ai-agents', 'memes', 'layer-1', 'rwa', 'defi'). Uses the Sharpe narrative taxonomy."),
|
|
383
567
|
exchange: z
|
|
384
|
-
.enum(
|
|
568
|
+
.enum(legacyListingExchangeIds)
|
|
385
569
|
.optional()
|
|
386
|
-
.describe("Filter to a single exchange."),
|
|
570
|
+
.describe("Filter to a single exchange. The aggregate hub covers the compatibility venues only; use get_recent_listings or get_listing_events for the other venues."),
|
|
387
571
|
};
|
|
388
572
|
export const listingsRecentSchema = {
|
|
389
573
|
narrative: z
|
|
@@ -531,6 +715,10 @@ export const listingsExchangesSchema = {
|
|
|
531
715
|
.optional()
|
|
532
716
|
.describe("Filter to enabled or disabled connectors."),
|
|
533
717
|
};
|
|
718
|
+
const signalCoinParam = z
|
|
719
|
+
.string()
|
|
720
|
+
.optional()
|
|
721
|
+
.describe("One coin's row by its CoinGecko id (e.g. bitcoin, pepe), exactly as the scorer wrote it: a coin that stopped qualifying answers score null with its sub-scores cleared instead of being absent; an unknown id answers no rows. limit, min_score and phase do not apply to it.");
|
|
534
722
|
export const signalScoreSchema = {
|
|
535
723
|
limit: z
|
|
536
724
|
.number()
|
|
@@ -547,6 +735,7 @@ export const signalScoreSchema = {
|
|
|
547
735
|
.default(0)
|
|
548
736
|
.optional()
|
|
549
737
|
.describe("Minimum 0-10 risk/pressure score to include."),
|
|
738
|
+
coin: signalCoinParam,
|
|
550
739
|
};
|
|
551
740
|
// get_pump_dump adds a manipulation-lifecycle phase filter on top of the shared
|
|
552
741
|
// signal-score params. get_insider_selling stays on signalScoreSchema (no phase).
|
|
@@ -572,63 +761,173 @@ export const pumpDumpSchema = {
|
|
|
572
761
|
.enum(["setup", "markup", "distribution", "dump", "dumping"])
|
|
573
762
|
.optional()
|
|
574
763
|
.describe("Filter to one manipulation lifecycle phase."),
|
|
764
|
+
coin: signalCoinParam,
|
|
575
765
|
};
|
|
766
|
+
// -- Keyless-path post-processing helpers --
|
|
767
|
+
function isRecord(value) {
|
|
768
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
769
|
+
}
|
|
770
|
+
function cursorArg(args) {
|
|
771
|
+
return typeof args.cursor === "string" && args.cursor
|
|
772
|
+
? args.cursor
|
|
773
|
+
: undefined;
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* oi-snapshot is documented as current open interest by exchange, but both
|
|
777
|
+
* routes return the whole ascending window (up to 5,000 raw rows). Keep each
|
|
778
|
+
* exchange's newest reading, largest first, so "current" means current.
|
|
779
|
+
*/
|
|
780
|
+
export function latestRowPerExchange(rows) {
|
|
781
|
+
const latest = new Map();
|
|
782
|
+
for (const row of rows) {
|
|
783
|
+
const at = rowTimeMs(row);
|
|
784
|
+
if (!isRecord(row) || at == null)
|
|
785
|
+
continue;
|
|
786
|
+
const exchange = String(row.exchange ?? "");
|
|
787
|
+
const prev = latest.get(exchange);
|
|
788
|
+
if (!prev || at >= prev.at)
|
|
789
|
+
latest.set(exchange, { row, at });
|
|
790
|
+
}
|
|
791
|
+
const oiOf = (row) => {
|
|
792
|
+
const value = Number(row.open_interest_value);
|
|
793
|
+
return Number.isFinite(value) ? value : Number.NEGATIVE_INFINITY;
|
|
794
|
+
};
|
|
795
|
+
return [...latest.values()]
|
|
796
|
+
.map((entry) => entry.row)
|
|
797
|
+
.sort((a, b) => oiOf(b) - oiOf(a));
|
|
798
|
+
}
|
|
576
799
|
export const TOOL_DEFS = [
|
|
800
|
+
{
|
|
801
|
+
name: "get_global_overview",
|
|
802
|
+
description: "Get the whole-market derivatives board in one call: total open interest with its crypto-versus-RWA split, 24h liquidations, average Wilder RSI(14) across the top 100 crypto perps by market cap, the Altcoin Season Index (share of the top 50 by market cap beating BTC over 90 days, excluding stablecoins and wrapped/staked derivatives), open interest broken down by asset class, and a ranked per-asset row table. The tab parameter selects the universe: crypto, equity, preipo, etf, index, commodity or fx. Rows carry price, 24h price change, funding rate (interval-true, never assumed 8h), 24h volume, market cap, open interest with 1h and 24h changes, plus liquidations on crypto or a venue count on RWA tabs. Ranks are by open interest descending. Liquidations are crypto-only because no RWA venue publishes a liquidation feed. Use this for 'what is the market doing' questions; use get_funding_rates for per-venue crypto funding detail and get_rwa_perp_funding for RWA carry and cross-venue spreads.",
|
|
803
|
+
schema: globalOverviewSchema,
|
|
804
|
+
apiPath: "/api/v1/global/overview",
|
|
805
|
+
fallbackPath: "/api/global/overview",
|
|
806
|
+
// The free route ignores limit/cursor and always returns every row with
|
|
807
|
+
// the metric block. Page its rows into the v1 paged shape ({ data,
|
|
808
|
+
// pagination }, rows only) so a keyless caller can reach all of them.
|
|
809
|
+
postProcess: (data, args, context) => {
|
|
810
|
+
if (context?.paginated || typeof args.limit !== "number")
|
|
811
|
+
return data;
|
|
812
|
+
if (!isRecord(data) || !Array.isArray(data.rows))
|
|
813
|
+
return data;
|
|
814
|
+
return paginateRows(data.rows, args.limit, cursorArg(args));
|
|
815
|
+
},
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
name: "get_rwa_perp_funding",
|
|
819
|
+
description: "Get funding and carry for real-world-asset perpetuals (RWA perps: stocks, pre-IPO, ETFs, indices, commodities, FX) across 19 venues: CEXs (Binance, Bybit, OKX, Bitget, Gate, Kraken xStocks, Coinbase INTX), perp DEXs (Aster, Lighter, Extended, GRVT, ApeX, Pacifica, Orderly), Hyperliquid HIP-3 builder markets, and the rollover venues Ostium and Avantis. Rates are interval-true and mechanism-true: funding_apr annualizes each venue's own settlement interval (never an assumed 8h), and a both-sides rollover is reported separately as borrow_apr_annual (a cost, never mixed into funding spreads). Marks more than 2% off the cross-venue median are flagged is_price_suspect and excluded from stats and spreads. type=history returns session-tagged settlements (market/after_hours/weekend/holiday); type=stats returns best carry, top cross-venue spread, weekend premium, and open interest.",
|
|
820
|
+
schema: rwaPerpRatesSchema,
|
|
821
|
+
apiPath: "/api/v1/rwa-perps/rates",
|
|
822
|
+
fallbackPath: "/api/rwa-perps/rates",
|
|
823
|
+
// The free route returns current/history rows as a bare array and
|
|
824
|
+
// ignores limit/cursor; page it the way v1 does. type=stats is an object
|
|
825
|
+
// and passes through.
|
|
826
|
+
postProcess: (data, args, context) => {
|
|
827
|
+
if (context?.paginated || typeof args.limit !== "number")
|
|
828
|
+
return data;
|
|
829
|
+
if (!Array.isArray(data))
|
|
830
|
+
return data;
|
|
831
|
+
return paginateRows(data, args.limit, cursorArg(args));
|
|
832
|
+
},
|
|
833
|
+
},
|
|
577
834
|
{
|
|
578
835
|
name: "get_funding_rates",
|
|
579
|
-
description: "Get perpetual funding rates across
|
|
836
|
+
description: "Get perpetual funding rates across every supported venue (see sharpe://exchanges for the current list). Returns current snapshots, accumulated rates over multiple windows, or per-coin historical rates. Units: `rate` is a decimal fraction settled over that row's own `interval_hours` (1h, 2h, 4h, 8h or 24h depending on venue and market). It is not a percent and never implicitly 8h, so compare or rank venues on the served rate_8h (rate × 8 / interval_hours) or apr (rate × 8760 / interval_hours), both null when the row has no usable interval. Accumulated rows carry realized sums (acc_1d/acc_7d/acc_30d/acc_90d/acc_1y) instead of a per-interval rate. Filter with coin, exchange, margin (linear/inverse) and asset_class; asset_class is unfiltered by default, so tokenized-equity, commodity, index and FX perps are included alongside crypto. `coin` names an asset: PEPE returns every PEPE contract, the 1000PEPE and KPEPE lot contracts included. Current and accumulated rows carry asset_id, asset_symbol, lot_multiplier (asset units per contract unit, e.g. 1000 on 1000PEPEUSDT), instrument_status (the venue's own status) and is_live (null = unknown). Page the full book with limit and cursor, or order it by open interest with sort. For type=current the API also answers with aggregates instead of rows: extremes (the highest and lowest markets by rate_8h above an optional min_oi_usd floor), stats (the whole book's mean and OI-weighted funding APR and the positive/negative counts) and summary (with coin: the coin's average and median funding across venues, the funding grid's Avg Rate).",
|
|
580
837
|
schema: fundingRatesSchema,
|
|
581
838
|
apiPath: "/api/v1/funding/rates",
|
|
582
839
|
fallbackPath: "/api/funding/rates",
|
|
583
|
-
// The
|
|
584
|
-
//
|
|
585
|
-
//
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
840
|
+
// The unpaged book is ~13,000 rows (6MB) of which MAX_ITEMS survive
|
|
841
|
+
// truncation: page it server-side instead, so the rows come with a cursor
|
|
842
|
+
// (0.3s instead of 1.8s, 2026-09-26). A coin filter or history is small,
|
|
843
|
+
// and an aggregate (extremes, stats, summary) answers without rows and
|
|
844
|
+
// refuses a page. The API scopes every filter itself: the rows are served
|
|
845
|
+
// as it answered them, never re-filtered here.
|
|
846
|
+
prepareArgs: (args) => args.limit == null &&
|
|
847
|
+
args.coin == null &&
|
|
848
|
+
args.type !== "history" &&
|
|
849
|
+
args.extremes == null &&
|
|
850
|
+
args.stats == null &&
|
|
851
|
+
args.summary == null
|
|
852
|
+
? { ...args, limit: MAX_ITEMS }
|
|
853
|
+
: args,
|
|
854
|
+
},
|
|
855
|
+
{
|
|
856
|
+
name: "get_funding_settlement",
|
|
857
|
+
description: "Get the dollar value of funding actually paid at each settlement -- not just the rate -- and which side, longs or shorts, paid it. Every response carries both the per-coin row breakdown and a totals block (net/long_paid/short_paid) for the requested window and class, so 'who paid funding today' is read directly from totals rather than summed from a page of rows; totals always reflects the full requested class regardless of any coin/exchange filter on the rows. window=current (the default) is the next settlement, priced live off open interest and the forward-looking rate -- always estimated, never realised. 1d/3d/7d are realised windows; one whose coverage is below 90% carries partial: true (complete: false) because its history is still accruing, not a completed total, and halted_within_window says a contract stopped settling inside the window (listed_within_window is always null: no listing time is known). Sign convention: a window's net = long_paid - short_paid; positive means longs paid more than they received (a cost to longs), negative means shorts paid more. Both long_paid and short_paid are always non-negative magnitudes. Missing is null, never 0. class splits crypto perps from RWA perps (tokenized equity, commodity, FX, index); crypto + rwa totals always equal the all totals.",
|
|
858
|
+
schema: fundingSettlementSchema,
|
|
859
|
+
apiPath: "/api/v1/funding/settlement",
|
|
860
|
+
fallbackPath: "/api/funding/settlement",
|
|
861
|
+
// The v1 payload nests rows/totals/settlementMeta inside the envelope's
|
|
862
|
+
// `data` field; the free fallback puts the row array directly under
|
|
863
|
+
// `data` with `totals` riding alongside it (api-client.ts preserves that
|
|
864
|
+
// sibling instead of discarding it). Normalize both shapes into one
|
|
865
|
+
// `{ rows, totals, meta }` result so callers never branch on which tier
|
|
866
|
+
// answered, and `totals` is always the API's own aggregate -- never
|
|
867
|
+
// recomputed from a possibly-truncated page of rows.
|
|
868
|
+
postProcess: (data) => {
|
|
869
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
593
870
|
return data;
|
|
594
871
|
}
|
|
595
|
-
const
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
872
|
+
const obj = data;
|
|
873
|
+
const result = {
|
|
874
|
+
rows: obj.rows ?? obj.data,
|
|
875
|
+
totals: obj.totals,
|
|
876
|
+
};
|
|
877
|
+
const meta = obj.settlementMeta ?? obj.meta;
|
|
878
|
+
if (meta !== undefined)
|
|
879
|
+
result.meta = meta;
|
|
880
|
+
return result;
|
|
599
881
|
},
|
|
600
882
|
},
|
|
601
883
|
{
|
|
602
884
|
name: "get_futures_data",
|
|
603
|
-
description: "Get futures chart data including open interest, volume, funding rate history, liquidations, long/short ratios, basis, term structure, and OHLCV.",
|
|
885
|
+
description: "Get futures chart data including open interest, volume, funding rate history, liquidations, long/short ratios, basis, term structure, and OHLCV. Time series are oldest-first; when one exceeds the response cap its newest rows are kept (truncated_fields marks kept: latest). Without limit, oi-snapshot returns each exchange's latest reading; pass limit/cursor to page raw rows oldest-first.",
|
|
604
886
|
schema: futuresDataSchema,
|
|
605
887
|
apiPath: "/api/v1/futures/data",
|
|
606
888
|
fallbackPath: "/api/futures/data",
|
|
889
|
+
postProcess: (data, args, context) => {
|
|
890
|
+
if (context?.paginated || !isRecord(data) || !Array.isArray(data.data)) {
|
|
891
|
+
return data;
|
|
892
|
+
}
|
|
893
|
+
if (typeof args.limit === "number") {
|
|
894
|
+
// The free route ignores limit/cursor: page the same oldest-first
|
|
895
|
+
// rows v1 pages.
|
|
896
|
+
return {
|
|
897
|
+
...data,
|
|
898
|
+
...paginateRows(data.data, args.limit, cursorArg(args)),
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
if (args.chart === "oi-snapshot") {
|
|
902
|
+
return { ...data, data: latestRowPerExchange(data.data) };
|
|
903
|
+
}
|
|
904
|
+
return data;
|
|
905
|
+
},
|
|
607
906
|
},
|
|
608
907
|
{
|
|
609
908
|
name: "get_futures_coins",
|
|
610
|
-
description: "Get
|
|
909
|
+
description: "Get up to 1,000 coins with futures data, including funding, open-interest, liquidation, long/short, CVD, and dated-basis capability flags plus observed venue coverage and market-cap rank.",
|
|
611
910
|
schema: futuresCoinsSchema,
|
|
612
911
|
apiPath: "/api/v1/futures/coins",
|
|
613
912
|
fallbackPath: "/api/futures/coins",
|
|
614
913
|
},
|
|
615
914
|
{
|
|
616
915
|
name: "get_correlation_matrix",
|
|
617
|
-
description: "Get a price correlation matrix for crypto assets over a specified period. Useful for portfolio analysis and diversification.",
|
|
916
|
+
description: "Get a price correlation matrix for crypto and supported TradFi assets over a specified calendar period. Useful for portfolio analysis and diversification.",
|
|
618
917
|
schema: correlationMatrixSchema,
|
|
619
918
|
apiPath: "/api/v1/correlation/matrix",
|
|
620
919
|
fallbackPath: "/api/correlation/matrix",
|
|
621
920
|
},
|
|
622
921
|
{
|
|
623
922
|
name: "get_arbitrage_spot_perp",
|
|
624
|
-
description: "Get
|
|
923
|
+
description: "Get structurally executable spot-perpetual funding-capture rows with live funding, verified spot or margin availability, diagnostic basis, gross APR, and fee-adjusted net APR, in the board's order (rows with a net APR first by net APR, then by gross APR). Each row carries perpSymbol, perpOpenInterestUsd, fundingIsStale, executionStatus, pairStatus (price_gap when the spot and perp prices are more than 20% apart: no net APR), fundingAsOf and pricesAsOf. minOiUsd floors the perp leg's open interest (unknown fails a positive floor).",
|
|
625
924
|
schema: arbitrageSpotPerpSchema,
|
|
626
925
|
apiPath: "/api/v1/arbitrage/spot-perp",
|
|
627
926
|
fallbackPath: "/api/arbitrage/spot-perp",
|
|
628
927
|
},
|
|
629
928
|
{
|
|
630
929
|
name: "get_arbitrage_cross_exchange",
|
|
631
|
-
description: "Get cross-exchange
|
|
930
|
+
description: "Get cross-exchange funding arbitrage across every funding venue and asset class (crypto plus RWA perps: equity, commodity, FX, index — pairs never cross classes), ranked with executable rows (book-priced netApr) first by netApr, then indicative rows by gross annualized funding differential (apr); pairs whose two legs' prices differ by more than 20% are indicative (likely different instruments). Spread uses real books where available (spreadSource: book) or reference prices (reference); netApr is present only on book-priced rows; unknown spread/OI/volume are null, never zero. Rows carry pairStatus, fundingAsOf (the older leg's funding write) and pricesAsOf; limit keeps the first N rows of the board.",
|
|
632
931
|
schema: arbitrageCrossExchangeSchema,
|
|
633
932
|
apiPath: "/api/v1/arbitrage/cross-exchange",
|
|
634
933
|
fallbackPath: "/api/arbitrage/cross-exchange",
|
|
@@ -656,42 +955,28 @@ export const TOOL_DEFS = [
|
|
|
656
955
|
},
|
|
657
956
|
{
|
|
658
957
|
name: "get_arbitrage_cex_spot_transfer",
|
|
659
|
-
description: "Get live CEX spot-transfer arbitrage rows after common network, fee, status, depth, slippage, and spread-lifetime checks.",
|
|
958
|
+
description: "Get live CEX spot-transfer arbitrage rows after common network and token-contract matching, fee, status, depth, slippage, and spread-lifetime checks.",
|
|
660
959
|
schema: cexSpotTransferScannerSchema,
|
|
661
960
|
apiPath: "/api/v1/arbitrage/cex-spot-transfer",
|
|
662
961
|
fallbackPath: "/api/arbitrage/cex-spot-transfer",
|
|
663
962
|
},
|
|
664
963
|
{
|
|
665
964
|
name: "get_heatmap",
|
|
666
|
-
description: "Get market heatmap data for coins, narratives, or ecosystems.
|
|
965
|
+
description: "Get market heatmap data for coins, narratives, or ecosystems. The legacy top-100 slug returns the Top 50 universe; aggregate modes expose complete or partial category coverage.",
|
|
667
966
|
schema: heatmapSchema,
|
|
668
967
|
apiPath: "/api/v1/heatmap/data",
|
|
669
968
|
fallbackPath: "/api/heatmap/data",
|
|
670
969
|
},
|
|
671
|
-
{
|
|
672
|
-
name: "get_dexscreener_data",
|
|
673
|
-
description: "Get live DEX Screener rows by category, network, or search phrase. Use this for pair-level discovery across DEX markets. Requires API key (SHARPE_API_KEY) — not available on the free tier.",
|
|
674
|
-
schema: dexScreenerDataSchema,
|
|
675
|
-
apiPath: "/api/v1/dexscreener/data",
|
|
676
|
-
fallbackPath: "/api/v1/dexscreener/data",
|
|
677
|
-
},
|
|
678
|
-
{
|
|
679
|
-
name: "get_dexscreener_security",
|
|
680
|
-
description: "Get token contract security signals for a DEX Screener token by address and chain ID.",
|
|
681
|
-
schema: dexScreenerSecuritySchema,
|
|
682
|
-
apiPath: "/api/v1/dexscreener/security",
|
|
683
|
-
fallbackPath: "/api/dexscreener/security",
|
|
684
|
-
},
|
|
685
970
|
{
|
|
686
971
|
name: "get_token_scanner",
|
|
687
|
-
description: "Run read-only token scanner modes
|
|
972
|
+
description: "Run read-only token scanner modes for hot tokens, new runners, alpha drops, AI tokens, and top-new pairs. Responses expose source coverage; valuation and risk fields stay null when unavailable. Requires an API key (SHARPE_API_KEY; the free tier works). No keyless fallback.",
|
|
688
973
|
schema: tokenScannerSchema,
|
|
689
974
|
apiPath: "/api/v1/token-scanner/scan",
|
|
690
975
|
fallbackPath: "/api/v1/token-scanner/scan",
|
|
691
976
|
},
|
|
692
977
|
{
|
|
693
978
|
name: "get_rug_check_security",
|
|
694
|
-
description: "Get rug-check token contract security and liquidity risk signals.",
|
|
979
|
+
description: "Get rug-check token contract security and liquidity risk signals, and the Rug Check score the /rug-check page shows, computed by the API: score.value (0-100, higher is safer; null only when no provider answered), score.verdict, score.data_completeness and score.engine_version, with the checks[] behind it.",
|
|
695
980
|
schema: rugCheckSecuritySchema,
|
|
696
981
|
apiPath: "/api/v1/rug-check/security",
|
|
697
982
|
fallbackPath: "/api/rug-check/security",
|
|
@@ -705,7 +990,7 @@ export const TOOL_DEFS = [
|
|
|
705
990
|
},
|
|
706
991
|
{
|
|
707
992
|
name: "get_narratives",
|
|
708
|
-
description: "Get narrative-level market data (L1, L2, DeFi, AI Agents, DePIN, RWA, Gaming, etc.) including market cap, volume, performance, and social metrics.",
|
|
993
|
+
description: "Get narrative-level market data (L1, L2, DeFi, AI Agents, DePIN, RWA, Gaming, etc.) including market cap, volume, performance, and social metrics. sort orders the list by 24h change and top/bottom add the N highest and lowest narratives by 24h change (a narrative without one is never ranked).",
|
|
709
994
|
schema: narrativesSchema,
|
|
710
995
|
apiPath: "/api/v1/narratives/data",
|
|
711
996
|
fallbackPath: "/api/narratives/data",
|
|
@@ -726,14 +1011,14 @@ export const TOOL_DEFS = [
|
|
|
726
1011
|
},
|
|
727
1012
|
{
|
|
728
1013
|
name: "get_memecoin_launches",
|
|
729
|
-
description: "Get recently launched memecoin
|
|
1014
|
+
description: "Get recently launched tokens from recognized memecoin launchpads, screened by age, liquidity, volume, and transactions. Generic new DEX pairs are excluded; response includes complete/partial chain coverage.",
|
|
730
1015
|
schema: memecoinLaunchesSchema,
|
|
731
1016
|
apiPath: "/api/v1/memecoins/launches",
|
|
732
1017
|
fallbackPath: "/api/memecoins/launches",
|
|
733
1018
|
},
|
|
734
1019
|
{
|
|
735
1020
|
name: "get_stablecoins",
|
|
736
|
-
description: "Get stablecoin overview, detail, or yield data including
|
|
1021
|
+
description: "Get stablecoin overview, detail, or yield data including nominal supply at peg, marked value, nullable peg metrics, mechanism mix, chain supply, velocity coverage, freshness, and APY risk flags. Requires an API key (SHARPE_API_KEY; the free tier works). No keyless fallback.",
|
|
737
1022
|
schema: stablecoinsSchema,
|
|
738
1023
|
apiPath: "/api/v1/stablecoins/data",
|
|
739
1024
|
fallbackPath: "/api/v1/stablecoins/data",
|
|
@@ -747,63 +1032,65 @@ export const TOOL_DEFS = [
|
|
|
747
1032
|
},
|
|
748
1033
|
{
|
|
749
1034
|
name: "get_web_traffic",
|
|
750
|
-
description: "Get attention rankings,
|
|
1035
|
+
description: "Get attention rankings, social snapshots, or market-level signals for coins and narratives, plus CoinGecko trust-score rankings for exchanges.",
|
|
751
1036
|
schema: webTrafficSchema,
|
|
752
1037
|
apiPath: "/api/v1/web-traffic/data",
|
|
753
1038
|
fallbackPath: "/api/web-traffic/data",
|
|
754
1039
|
},
|
|
755
|
-
{
|
|
756
|
-
name: "get_katana",
|
|
757
|
-
description: "Get Katana Network TVL, token, holder, sentiment, pool, mover, and ecosystem analytics.",
|
|
758
|
-
schema: katanaSchema,
|
|
759
|
-
apiPath: "/api/v1/katana/data",
|
|
760
|
-
fallbackPath: "/api/products/katana/data",
|
|
761
|
-
},
|
|
762
1040
|
{
|
|
763
1041
|
name: "get_news",
|
|
764
|
-
description: "Get aggregated crypto news articles from multiple sources, with optional filtering by category or coin. Articles are deduplicated so only the best source per story is shown.",
|
|
1042
|
+
description: "Get aggregated crypto news articles from multiple sources, with optional title search and filtering by category or coin. Articles are deduplicated so only the best source per story is shown.",
|
|
765
1043
|
schema: newsSchema,
|
|
766
1044
|
apiPath: "/api/v1/news/feed",
|
|
767
1045
|
fallbackPath: "/api/news/feed",
|
|
768
1046
|
},
|
|
769
|
-
{
|
|
770
|
-
name: "get_curated_news",
|
|
771
|
-
description: "Get AI-curated crypto news highlights across crypto, AI, markets, and geopolitics. Updated every 15 minutes.",
|
|
772
|
-
schema: curatedNewsSchema,
|
|
773
|
-
apiPath: "/api/v1/news/curated",
|
|
774
|
-
fallbackPath: "/api/news/curated",
|
|
775
|
-
},
|
|
776
1047
|
{
|
|
777
1048
|
name: "get_market_overview",
|
|
778
|
-
description: "Get
|
|
1049
|
+
description: "Get BTC and ETH price/change, total crypto market cap and 24h volume, BTC dominance, market-cap change, and the Fear & Greed Index. Auxiliary source fields may be null when unavailable.",
|
|
779
1050
|
schema: marketOverviewSchema,
|
|
780
1051
|
apiPath: "/api/v1/tracker/market-overview",
|
|
781
1052
|
fallbackPath: "/api/tracker/market-overview",
|
|
782
1053
|
},
|
|
783
1054
|
{
|
|
784
1055
|
name: "get_price_prediction",
|
|
785
|
-
description: "Get
|
|
1056
|
+
description: "Get deterministic directional scores and sub-signal breakdowns for a coin. Optional 7D/30D values are volatility-scaled heuristic scenarios, not calibrated targets or probabilities.",
|
|
786
1057
|
schema: pricePredictionSchema,
|
|
787
1058
|
apiPath: "/api/v1/price-prediction/data",
|
|
788
1059
|
fallbackPath: "/api/price-prediction/data",
|
|
789
1060
|
},
|
|
790
1061
|
{
|
|
791
1062
|
name: "search_market_cap",
|
|
792
|
-
description: "Search
|
|
1063
|
+
description: "Search crypto and supported TradFi assets by name or ticker. Returns matching assets with asset class, market cap, and nullable price, 24h change, FDV, ATH, and estimated ATH market cap fields.",
|
|
793
1064
|
schema: searchMarketCapSchema,
|
|
794
1065
|
apiPath: "/api/v1/market-cap/search",
|
|
795
1066
|
fallbackPath: "/api/market-cap/search",
|
|
796
1067
|
},
|
|
797
1068
|
{
|
|
798
1069
|
name: "get_gem_finder",
|
|
799
|
-
description: "Get
|
|
1070
|
+
description: "Get market-ranked token rows with market cap, volume, price and market-cap change, circulating supply, ATH and ATL history, nullable FDV/MCap, the preferred chain plus every supported chain the asset is deployed on (chainSlugs), observed exchange availability, quote freshness, and enrichment coverage. Delisted or halted markets whose upstream quote is over 24 hours old are excluded rather than reporting a weeks-old price change as current. Ambiguous same-ticker assets do not receive symbol-only exchange attribution. No wallet signal or proprietary score is returned.",
|
|
800
1071
|
schema: gemFinderSchema,
|
|
801
1072
|
apiPath: "/api/v1/gem-finder/data",
|
|
802
1073
|
fallbackPath: "/api/gem-finder/data",
|
|
1074
|
+
postProcess: (data, args) => {
|
|
1075
|
+
// Authenticated v1 calls are already an array with pagination reattached
|
|
1076
|
+
// by the runtime. The free fallback returns the complete cache payload,
|
|
1077
|
+
// so apply the same snapshot-bound paging semantics client-side.
|
|
1078
|
+
if (!data ||
|
|
1079
|
+
typeof data !== "object" ||
|
|
1080
|
+
Array.isArray(data) ||
|
|
1081
|
+
!Array.isArray(data.coins)) {
|
|
1082
|
+
return data;
|
|
1083
|
+
}
|
|
1084
|
+
const limit = typeof args.limit === "number" && Number.isInteger(args.limit)
|
|
1085
|
+
? args.limit
|
|
1086
|
+
: 100;
|
|
1087
|
+
const cursor = typeof args.cursor === "string" ? args.cursor : undefined;
|
|
1088
|
+
return paginateSnapshotPayload(data, limit, cursor);
|
|
1089
|
+
},
|
|
803
1090
|
},
|
|
804
1091
|
{
|
|
805
1092
|
name: "get_derivatives_overview",
|
|
806
|
-
description: "Get a derivatives market overview including aggregated open interest, funding rates,
|
|
1093
|
+
description: "Get a derivatives market overview including aggregated open interest, 8-hour-equivalent funding rates, top coins by open interest (each top_coins_oi entry is an asset, its lot spellings included), and exchange/coin counts. Requires an API key (SHARPE_API_KEY; the free tier works). No keyless fallback.",
|
|
807
1094
|
schema: derivativesOverviewSchema,
|
|
808
1095
|
apiPath: "/api/v1/market/derivatives-overview",
|
|
809
1096
|
fallbackPath: "/api/v1/market/derivatives-overview",
|
|
@@ -817,21 +1104,21 @@ export const TOOL_DEFS = [
|
|
|
817
1104
|
},
|
|
818
1105
|
{
|
|
819
1106
|
name: "get_exchange_listings",
|
|
820
|
-
description: "Get the New Listings hub payload
|
|
1107
|
+
description: "Get the New Listings hub payload: weekly + monthly aggregated counts by narrative and exchange, plus the last-90-day recent listings. Optionally filter by narrative slug or single exchange. Useful for tracking where venues are adding listing slots.",
|
|
821
1108
|
schema: listingsDataSchema,
|
|
822
1109
|
apiPath: "/api/v1/listings/data",
|
|
823
1110
|
fallbackPath: "/api/listings/data",
|
|
824
1111
|
},
|
|
825
1112
|
{
|
|
826
1113
|
name: "get_recent_listings",
|
|
827
|
-
description: "Get a flat feed of recent token listings. Defaults remain backward-compatible with the legacy spot listing feed
|
|
1114
|
+
description: "Get a flat feed of recent token listings. Defaults remain backward-compatible with the legacy spot listing feed. Event filters add source-observation freshness, partial status, and provider coverage so agents can reject incomplete opportunity scans.",
|
|
828
1115
|
schema: listingsRecentSchema,
|
|
829
1116
|
apiPath: "/api/v1/listings/recent",
|
|
830
1117
|
fallbackPath: "/api/listings/recent",
|
|
831
1118
|
},
|
|
832
1119
|
{
|
|
833
1120
|
name: "get_listing_events",
|
|
834
|
-
description: "Get canonical listing lifecycle events across CEXs and Perp DEXs, including
|
|
1121
|
+
description: "Get canonical listing lifecycle events across CEXs and Perp DEXs, including source URLs, confidence, real source-observation freshness, partial status, and per-provider coverage. Pass the opaque cursor through unchanged.",
|
|
835
1122
|
schema: listingsEventsSchema,
|
|
836
1123
|
apiPath: "/api/v1/listings/events",
|
|
837
1124
|
fallbackPath: "/api/listings/events",
|
|
@@ -845,14 +1132,14 @@ export const TOOL_DEFS = [
|
|
|
845
1132
|
},
|
|
846
1133
|
{
|
|
847
1134
|
name: "get_insider_selling",
|
|
848
|
-
description: "Get insider selling pressure signals across crypto assets. Scores require cross-venue negative funding and combine OI, basis, CVD, sell-side flow, and supporting wallet/supply context.",
|
|
1135
|
+
description: "Get insider selling pressure signals across crypto assets. Scores require cross-venue negative funding and combine OI, basis, CVD, sell-side flow, and supporting wallet/supply context; read signal_coverage_pct because partial-input scores are conservative lower bounds. coin returns one coin's row as the scorer wrote it (score null once it stopped qualifying).",
|
|
849
1136
|
schema: signalScoreSchema,
|
|
850
1137
|
apiPath: "/api/v1/insider-selling/data",
|
|
851
1138
|
fallbackPath: "/api/insider-selling/data",
|
|
852
1139
|
},
|
|
853
1140
|
{
|
|
854
1141
|
name: "get_pump_dump",
|
|
855
|
-
description: "Get pump-and-dump manipulation risk signals across crypto assets. Scores combine derivatives pressure, holder concentration, liquidity quality, DEX flow, and price behavior.",
|
|
1142
|
+
description: "Get pump-and-dump manipulation risk signals across crypto assets. Scores combine derivatives pressure, holder concentration, liquidity quality, DEX flow, and price behavior; read signal_coverage_pct because partial-input scores are conservative lower bounds. coin returns one coin's row as the scorer wrote it (score null once it stopped qualifying).",
|
|
856
1143
|
schema: pumpDumpSchema,
|
|
857
1144
|
apiPath: "/api/v1/pump-dump/data",
|
|
858
1145
|
fallbackPath: "/api/pump-dump/data",
|