@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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAyB9D,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,OAAO,EAAE,SAAS,CAAC;IACnB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAsCD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,CAyThF"}
package/dist/server.js ADDED
@@ -0,0 +1,266 @@
1
+ /**
2
+ * The Sharpe MCP server, independent of transport: the stdio entry point
3
+ * (index.ts) and the hosted Streamable HTTP endpoint (/api/mcp on
4
+ * www.sharpe.ai) both build their server here, so the two cannot drift.
5
+ */
6
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
+ import { z } from "zod/v3";
8
+ import { freshnessOf } from "./api-client.js";
9
+ import { TOOL_DEFS } from "./tools.js";
10
+ import { analyzeCoin, marketBriefing, findOpportunities, } from "./composite-tools.js";
11
+ import { FUTURES_CHARTS, EXCHANGES_DATA, NARRATIVE_SLUGS, ECOSYSTEM_SLUGS, } from "./resources.js";
12
+ import { API_TOOL_OUTPUT_SCHEMA, READ_ONLY_MARKET_DATA_TOOL_ANNOTATIONS, TEXT_TOOL_OUTPUT_SCHEMA, toTextToolResult, toToolErrorResult, splitPaginated, toToolResult, truncateResponse, withFreshness, } from "./tool-runtime.js";
13
+ /** Sent at initialize: how an agent should pick among the 40 tools. */
14
+ const SERVER_INSTRUCTIONS = [
15
+ "Sharpe provides crypto derivatives and market data covering funding rates across 32 venues, futures across 10 exchanges, arbitrage, listings, narratives, ecosystems, and news.",
16
+ "",
17
+ "Workflow patterns:",
18
+ "- Quick market check: get_market_overview",
19
+ "- Coin analysis: analyze_coin (or get_funding_rates -> get_futures_data)",
20
+ "- Derivatives health: get_global_overview -> get_futures_data",
21
+ "- Sector rotation: get_narratives -> get_ecosystems",
22
+ "- Arbitrage scan: find_opportunities (or get_arbitrage_spot_perp + get_arbitrage_cross_exchange)",
23
+ "- Full briefing: market_briefing",
24
+ "- Memecoin analysis: get_memecoins",
25
+ "- Token discovery: get_gem_finder",
26
+ "",
27
+ "Always start with get_market_overview or market_briefing for general questions.",
28
+ "Use analyze_coin for questions about a specific coin.",
29
+ "Use get_api_coverage to discover available chart types before querying specific charts.",
30
+ "Use resources (sharpe://charts/futures, etc.) for valid IDs.",
31
+ "get_token_scanner, get_stablecoins and get_derivatives_overview need an API key; every other tool works without one.",
32
+ "",
33
+ "Data freshness: current funding rates refresh every 5 minutes; futures datasets refresh every 10 minutes to 6 hours depending on the metric; narrative/ecosystem market data refreshes every 2 hours and mindshare every 12 hours.",
34
+ "Each result says how fresh its data is in `data_freshness` (as_of, stale_after, freshness_status, runtime_status, warnings) whenever the API reports it: treat freshness_status `stale` or `unknown` and runtime_status `degraded` as caveats to state, not as current data.",
35
+ ].join("\n");
36
+ const COIN_PARAM_SCHEMA = {
37
+ coin: z.string().describe("Coin ticker (e.g. BTC, ETH, SOL)"),
38
+ };
39
+ function titleFromToolName(name) {
40
+ return name
41
+ .split("_")
42
+ .filter((part) => part !== "get")
43
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
44
+ .join(" ");
45
+ }
46
+ export function createSharpeMcpServer(options) {
47
+ const { callApi } = options;
48
+ const server = new McpServer({ name: "sharpe-mcp-server", version: options.version }, { instructions: SERVER_INSTRUCTIONS });
49
+ // Register each endpoint-backed tool from the definitions.
50
+ for (const def of TOOL_DEFS) {
51
+ const { name, description, schema, apiPath, fallbackPath, prepareArgs, postProcess, } = def;
52
+ const hasParams = Object.keys(schema).length > 0;
53
+ if (hasParams) {
54
+ server.registerTool(name, {
55
+ title: titleFromToolName(name),
56
+ description,
57
+ inputSchema: schema,
58
+ outputSchema: API_TOOL_OUTPUT_SCHEMA,
59
+ annotations: READ_ONLY_MARKET_DATA_TOOL_ANNOTATIONS,
60
+ }, async (args) => {
61
+ try {
62
+ const typedArgs = args;
63
+ const raw = await callApi(apiPath, fallbackPath, prepareArgs ? prepareArgs(typedArgs) : typedArgs);
64
+ // Filter and truncate the rows, then reattach pagination (and any
65
+ // metadata beside the page) so continuation cursors survive to
66
+ // the tool output.
67
+ const { rows, pagination, extras } = splitPaginated(raw);
68
+ const filtered = postProcess
69
+ ? postProcess(rows, typedArgs, { paginated: pagination !== null })
70
+ : rows;
71
+ const truncated = truncateResponse(filtered);
72
+ return toToolResult(withFreshness(pagination
73
+ ? { ...extras, data: truncated, pagination }
74
+ : truncated, freshnessOf(raw)));
75
+ }
76
+ catch (err) {
77
+ return toToolErrorResult(err);
78
+ }
79
+ });
80
+ }
81
+ else {
82
+ server.registerTool(name, {
83
+ title: titleFromToolName(name),
84
+ description,
85
+ outputSchema: API_TOOL_OUTPUT_SCHEMA,
86
+ annotations: READ_ONLY_MARKET_DATA_TOOL_ANNOTATIONS,
87
+ }, async () => {
88
+ try {
89
+ const raw = await callApi(apiPath, fallbackPath, {});
90
+ const { rows, pagination, extras } = splitPaginated(raw);
91
+ const filtered = postProcess
92
+ ? postProcess(rows, {}, { paginated: pagination !== null })
93
+ : rows;
94
+ const truncated = truncateResponse(filtered);
95
+ return toToolResult(withFreshness(pagination
96
+ ? { ...extras, data: truncated, pagination }
97
+ : truncated, freshnessOf(raw)));
98
+ }
99
+ catch (err) {
100
+ return toToolErrorResult(err);
101
+ }
102
+ });
103
+ }
104
+ }
105
+ // ── Composite tools ──────────────────────────────────────────────────
106
+ server.registerTool("analyze_coin", {
107
+ title: "Analyze Coin",
108
+ description: "Single-coin analysis in one view: funding rates, futures OI, and a deterministic directional score.",
109
+ inputSchema: COIN_PARAM_SCHEMA,
110
+ outputSchema: TEXT_TOOL_OUTPUT_SCHEMA,
111
+ annotations: READ_ONLY_MARKET_DATA_TOOL_ANNOTATIONS,
112
+ }, async (args) => {
113
+ try {
114
+ const coin = typeof args.coin === "string" ? args.coin : "BTC";
115
+ const text = await analyzeCoin(callApi, coin);
116
+ return toTextToolResult(text, { coin: coin.toUpperCase() });
117
+ }
118
+ catch (err) {
119
+ return toToolErrorResult(err);
120
+ }
121
+ });
122
+ server.registerTool("market_briefing", {
123
+ title: "Market Briefing",
124
+ description: "Market briefing with market overview, top narratives, and a funding rate summary.",
125
+ outputSchema: TEXT_TOOL_OUTPUT_SCHEMA,
126
+ annotations: READ_ONLY_MARKET_DATA_TOOL_ANNOTATIONS,
127
+ }, async () => {
128
+ try {
129
+ const text = await marketBriefing(callApi);
130
+ return toTextToolResult(text);
131
+ }
132
+ catch (err) {
133
+ return toToolErrorResult(err);
134
+ }
135
+ });
136
+ server.registerTool("find_opportunities", {
137
+ title: "Find Opportunities",
138
+ description: "Scan all exchanges for the best funding rate arbitrage opportunities across spot-perp basis trades and cross-exchange funding arb.",
139
+ outputSchema: TEXT_TOOL_OUTPUT_SCHEMA,
140
+ annotations: READ_ONLY_MARKET_DATA_TOOL_ANNOTATIONS,
141
+ }, async () => {
142
+ try {
143
+ const text = await findOpportunities(callApi);
144
+ return toTextToolResult(text);
145
+ }
146
+ catch (err) {
147
+ return toToolErrorResult(err);
148
+ }
149
+ });
150
+ // ── Resources ─────────────────────────────────────────────────────────
151
+ server.registerResource("futures-charts", "sharpe://charts/futures", {
152
+ description: "List of all 24 valid futures chart IDs with descriptions. Use these IDs with get_futures_data.",
153
+ mimeType: "application/json",
154
+ }, async (uri) => ({
155
+ contents: [
156
+ {
157
+ uri: uri.href,
158
+ mimeType: "application/json",
159
+ text: JSON.stringify(FUTURES_CHARTS, null, 2),
160
+ },
161
+ ],
162
+ }));
163
+ server.registerResource("exchanges", "sharpe://exchanges", {
164
+ description: "Supported exchanges per product (funding rates, futures).",
165
+ mimeType: "application/json",
166
+ }, async (uri) => ({
167
+ contents: [
168
+ {
169
+ uri: uri.href,
170
+ mimeType: "application/json",
171
+ text: JSON.stringify(EXCHANGES_DATA, null, 2),
172
+ },
173
+ ],
174
+ }));
175
+ server.registerResource("narratives", "sharpe://narratives", {
176
+ description: "All 30 narrative slugs for use with get_narratives. Pass slug as the 'narrative' parameter.",
177
+ mimeType: "application/json",
178
+ }, async (uri) => ({
179
+ contents: [
180
+ {
181
+ uri: uri.href,
182
+ mimeType: "application/json",
183
+ text: JSON.stringify(NARRATIVE_SLUGS, null, 2),
184
+ },
185
+ ],
186
+ }));
187
+ server.registerResource("ecosystems", "sharpe://ecosystems", {
188
+ description: "All 23 ecosystem slugs for use with get_ecosystems. Pass slug as the 'ecosystem' parameter.",
189
+ mimeType: "application/json",
190
+ }, async (uri) => ({
191
+ contents: [
192
+ {
193
+ uri: uri.href,
194
+ mimeType: "application/json",
195
+ text: JSON.stringify(ECOSYSTEM_SLUGS, null, 2),
196
+ },
197
+ ],
198
+ }));
199
+ // ── Prompts ───────────────────────────────────────────────────────────
200
+ server.registerPrompt("market_analysis", {
201
+ title: "Market Analysis",
202
+ description: "A guided prompt template for a crypto market analysis.",
203
+ }, async () => ({
204
+ messages: [
205
+ {
206
+ role: "user",
207
+ content: {
208
+ type: "text",
209
+ text: "Perform a comprehensive crypto market analysis using Sharpe data.\n\n" +
210
+ "Follow these steps:\n\n" +
211
+ "1. Market overview: call market_briefing to get the current state of the market.\n" +
212
+ " Summarize: total market cap trend, BTC dominance, Fear & Greed, and top movers.\n\n" +
213
+ "2. Derivatives health: call get_derivatives_overview.\n" +
214
+ " Analyze: total OI trend, funding rate skew, and leverage levels.\n\n" +
215
+ "3. Sector rotation: call get_narratives to see which sectors are leading/lagging.\n" +
216
+ " Identify: top 3 outperforming and bottom 3 underperforming narratives.\n\n" +
217
+ "4. Ecosystem flows: call get_ecosystems to compare chain activity.\n" +
218
+ " Highlight: which chains are gaining TVL and volume.\n\n" +
219
+ "5. Opportunities: call find_opportunities for the best arb trades.\n" +
220
+ " List: top 3 highest-APR opportunities with risk notes.\n\n" +
221
+ "6. Synthesis: combine all signals into a coherent market thesis.\n" +
222
+ " Deliver: 1-paragraph summary + bullish/bearish/neutral verdict + key risks.\n\n" +
223
+ "Format the output as a structured report with headers and bullet points.",
224
+ },
225
+ },
226
+ ],
227
+ }));
228
+ server.registerPrompt("coin_deep_dive", {
229
+ title: "Coin Deep Dive",
230
+ description: "A guided prompt template for analyzing a specific coin in depth.",
231
+ argsSchema: COIN_PARAM_SCHEMA,
232
+ }, async (args) => {
233
+ const coin = typeof args.coin === "string" ? args.coin : "BTC";
234
+ return {
235
+ messages: [
236
+ {
237
+ role: "user",
238
+ content: {
239
+ type: "text",
240
+ text: `Perform a deep-dive analysis on ${coin.toUpperCase()} using Sharpe data.\n\n` +
241
+ "Follow these steps:\n\n" +
242
+ `1. Quick analysis: call analyze_coin with coin='${coin.toUpperCase()}' for a consolidated view.\n\n` +
243
+ `2. Futures deep dive: call get_futures_data for ${coin.toUpperCase()} with these charts:\n` +
244
+ " - oi-stacked (OI trend across exchanges)\n" +
245
+ " - long-short-ratio (positioning)\n" +
246
+ " - liquidations (if available)\n" +
247
+ " - annualized-basis (rolling 3M dated basis)\n" +
248
+ " Analyze: Is OI rising with price? Are traders net long or short? Is 3M basis elevated?\n\n" +
249
+ `3. Funding history: call get_funding_rates with type='history', coin='${coin.toUpperCase()}', days=30.\n` +
250
+ " Analyze: Is funding persistently positive/negative? Any recent spikes?\n\n" +
251
+ `4. Correlation: call get_correlation_matrix to see how ${coin.toUpperCase()} correlates with BTC, ETH, and TradFi.\n\n` +
252
+ "5. Directional heuristic: call get_price_prediction for the deterministic signal score and its input breakdown.\n\n" +
253
+ "6. Synthesis: combine all signals:\n" +
254
+ ` - Overall bias for ${coin.toUpperCase()} (bullish/bearish/neutral)\n` +
255
+ " - Key levels to watch (support/resistance from price action)\n" +
256
+ " - Risk factors (high leverage, extreme funding, vol crush potential)\n" +
257
+ " - Recommended trades (if any arb opportunities exist)\n\n" +
258
+ "Format as a structured research note with headers, key metrics in bold, and a summary box.",
259
+ },
260
+ },
261
+ ],
262
+ };
263
+ });
264
+ return server;
265
+ }
266
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,64 @@
1
1
  import type { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
2
2
  import type { ZodRawShapeCompat } from "@modelcontextprotocol/sdk/server/zod-compat.js";
3
+ import type { DataFreshness } from "./api-client.ts";
3
4
  export declare const MAX_ITEMS = 200;
4
5
  export declare const CHARACTER_LIMIT = 25000;
5
6
  export declare const READ_ONLY_MARKET_DATA_TOOL_ANNOTATIONS: ToolAnnotations;
6
7
  export declare const API_TOOL_OUTPUT_SCHEMA: ZodRawShapeCompat;
8
+ /**
9
+ * Splits a client result into rows + pagination. The api-client preserves
10
+ * the pagination envelope for paginated endpoints (funding/rates,
11
+ * gem-finder/data); filtering and truncation operate on the rows, and the
12
+ * pagination block is reattached to the final payload so callers can pass
13
+ * the cursor onward. Metadata riding beside a page (a futures chart's
14
+ * `chart`/`coverage`/`source`) comes back as `extras` so it is reattached
15
+ * too rather than dropped with the envelope.
16
+ */
17
+ export declare function splitPaginated(result: unknown): {
18
+ rows: unknown;
19
+ pagination: unknown | null;
20
+ extras: Record<string, unknown>;
21
+ };
22
+ /**
23
+ * Client-side paging for a free route that ignores limit/cursor and returns
24
+ * every row. Mirrors the v1 `paginateData` contract (src/lib/api/response.ts):
25
+ * the cursor is the base64url-encoded next offset, so a keyless caller walks
26
+ * the same pages an authenticated one would.
27
+ */
28
+ export declare function paginateRows(rows: unknown[], limit: number, cursor?: string): {
29
+ data: unknown[];
30
+ pagination: {
31
+ cursor: string | null;
32
+ has_more: boolean;
33
+ total: number;
34
+ };
35
+ };
36
+ /**
37
+ * A row's time in epoch ms, read from the keys the futures routes sort on
38
+ * (`snapshot_at ?? settled_at ?? timestamp`). Null when absent or unparseable.
39
+ */
40
+ export declare function rowTimeMs(row: unknown): number | null;
7
41
  export declare const TEXT_TOOL_OUTPUT_SCHEMA: ZodRawShapeCompat;
42
+ /**
43
+ * Client-side pagination for the free Gem Finder fallback, whose raw payload
44
+ * contains the complete `coins` array. Cursor shape matches the v1 endpoint so
45
+ * agents do not silently restart from offset zero when no API key is set.
46
+ */
47
+ export declare function paginateSnapshotPayload(payload: Record<string, unknown>, limit: number, cursor?: string): {
48
+ data: unknown[];
49
+ pagination: {
50
+ cursor: string | null;
51
+ has_more: boolean;
52
+ total: number;
53
+ };
54
+ };
8
55
  export declare function truncateResponse(data: unknown): unknown;
56
+ /**
57
+ * The result with the API's freshness envelope beside it (engine L5 WP-S12): an object gains `data_freshness`
58
+ * (dataset, `as_of`, `stale_after`, `freshness_status`, `runtime_status`, `warnings`); anything else is wrapped as
59
+ * `{ data, data_freshness }`, the shape a paged answer already has. Nothing changes when the API said nothing.
60
+ */
61
+ export declare function withFreshness(result: unknown, freshness: DataFreshness | null): unknown;
9
62
  export declare function toToolResult(result: unknown): {
10
63
  structuredContent: {
11
64
  result: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-runtime.d.ts","sourceRoot":"","sources":["../src/tool-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AAGxF,eAAO,MAAM,SAAS,MAAM,CAAC;AAC7B,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,eAAO,MAAM,sCAAsC,EAAE,eAKpD,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAQnB,iBAAiB,CAAC;AAElC,eAAO,MAAM,uBAAuB,EAGpB,iBAAiB,CAAC;AAKlC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAyCvD;AAqDD,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO;;;;;;;;EAU3C;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;EAWhC;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO;;;;;;;;;EAY/C"}
1
+ {"version":3,"file":"tool-runtime.d.ts","sourceRoot":"","sources":["../src/tool-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AAExF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,eAAO,MAAM,SAAS,MAAM,CAAC;AAC7B,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,eAAO,MAAM,sCAAsC,EAAE,eAKpD,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAQnB,iBAAiB,CAAC;AAElC;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG;IAC/C,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAYA;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,OAAO,EAAE,EACf,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,GACd;IACD,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CACzE,CAcA;AAUD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAOrD;AAwBD,eAAO,MAAM,uBAAuB,EAOpB,iBAAiB,CAAC;AAgClC;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,GACd;IACD,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,QAAQ,EAAE,OAAO,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CAiCA;AAKD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAoBvD;AAmLD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,aAAa,GAAG,IAAI,GAC9B,OAAO,CAKT;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO;;;;;;;;EAY3C;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;EAWhC;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO;;;;;;;;;EAY/C"}