@cryptoquant_official/mcp 0.0.4 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +308 -39
  2. package/dist/ai-sdk/execute.d.ts +35 -0
  3. package/dist/ai-sdk/execute.d.ts.map +1 -0
  4. package/dist/ai-sdk/execute.js +531 -0
  5. package/dist/ai-sdk/execute.js.map +1 -0
  6. package/dist/ai-sdk/index.d.ts +51 -0
  7. package/dist/ai-sdk/index.d.ts.map +1 -0
  8. package/dist/ai-sdk/index.js +54 -0
  9. package/dist/ai-sdk/index.js.map +1 -0
  10. package/dist/ai-sdk/prompts.d.ts +34 -0
  11. package/dist/ai-sdk/prompts.d.ts.map +1 -0
  12. package/dist/ai-sdk/prompts.js +74 -0
  13. package/dist/ai-sdk/prompts.js.map +1 -0
  14. package/dist/ai-sdk/schemas.d.ts +66 -0
  15. package/dist/ai-sdk/schemas.d.ts.map +1 -0
  16. package/dist/ai-sdk/schemas.js +136 -0
  17. package/dist/ai-sdk/schemas.js.map +1 -0
  18. package/dist/ai-sdk/tools.d.ts +165 -0
  19. package/dist/ai-sdk/tools.d.ts.map +1 -0
  20. package/dist/ai-sdk/tools.js +152 -0
  21. package/dist/ai-sdk/tools.js.map +1 -0
  22. package/dist/ai-sdk/types.d.ts +149 -0
  23. package/dist/ai-sdk/types.d.ts.map +1 -0
  24. package/dist/ai-sdk/types.js +5 -0
  25. package/dist/ai-sdk/types.js.map +1 -0
  26. package/dist/core/auth/storage.d.ts.map +1 -0
  27. package/dist/core/auth/storage.js.map +1 -0
  28. package/dist/core/cache/storage.d.ts +110 -0
  29. package/dist/core/cache/storage.d.ts.map +1 -0
  30. package/dist/core/cache/storage.js +356 -0
  31. package/dist/core/cache/storage.js.map +1 -0
  32. package/dist/core/cache/summary.d.ts.map +1 -0
  33. package/dist/core/cache/summary.js.map +1 -0
  34. package/dist/{cache → core/cache}/types.d.ts +25 -0
  35. package/dist/{cache → core/cache}/types.d.ts.map +1 -1
  36. package/dist/core/cache/types.js.map +1 -0
  37. package/dist/core/config.d.ts.map +1 -0
  38. package/dist/core/config.js.map +1 -0
  39. package/dist/core/discovery.d.ts.map +1 -0
  40. package/dist/{discovery.js → core/discovery.js} +14 -2
  41. package/dist/core/discovery.js.map +1 -0
  42. package/dist/core/index.d.ts +16 -0
  43. package/dist/core/index.d.ts.map +1 -0
  44. package/dist/core/index.js +19 -0
  45. package/dist/core/index.js.map +1 -0
  46. package/dist/{permissions.d.ts → core/permissions.d.ts} +2 -2
  47. package/dist/core/permissions.d.ts.map +1 -0
  48. package/dist/{permissions.js → core/permissions.js} +38 -14
  49. package/dist/core/permissions.js.map +1 -0
  50. package/dist/core/plan-limits.d.ts.map +1 -0
  51. package/dist/core/plan-limits.js.map +1 -0
  52. package/dist/{utils.d.ts → core/utils.d.ts} +13 -0
  53. package/dist/core/utils.d.ts.map +1 -0
  54. package/dist/{utils.js → core/utils.js} +34 -0
  55. package/dist/core/utils.js.map +1 -0
  56. package/dist/data/metrics.toon +8 -5
  57. package/dist/http/chat-proxy.d.ts +32 -0
  58. package/dist/http/chat-proxy.d.ts.map +1 -0
  59. package/dist/http/chat-proxy.js +305 -0
  60. package/dist/http/chat-proxy.js.map +1 -0
  61. package/dist/http/index.d.ts +16 -0
  62. package/dist/http/index.d.ts.map +1 -0
  63. package/dist/http/index.js +26 -0
  64. package/dist/http/index.js.map +1 -0
  65. package/dist/http/server.d.ts +20 -0
  66. package/dist/http/server.d.ts.map +1 -0
  67. package/dist/http/server.js +204 -0
  68. package/dist/http/server.js.map +1 -0
  69. package/dist/index.d.ts +8 -16
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +19 -29
  72. package/dist/index.js.map +1 -1
  73. package/dist/mcp/index.d.ts +6 -0
  74. package/dist/mcp/index.d.ts.map +1 -0
  75. package/dist/mcp/index.js +6 -0
  76. package/dist/mcp/index.js.map +1 -0
  77. package/dist/mcp/tools/auth.d.ts +3 -0
  78. package/dist/mcp/tools/auth.d.ts.map +1 -0
  79. package/dist/{tools → mcp/tools}/auth.js +38 -12
  80. package/dist/mcp/tools/auth.js.map +1 -0
  81. package/dist/mcp/tools/core.d.ts +3 -0
  82. package/dist/mcp/tools/core.d.ts.map +1 -0
  83. package/dist/{tools → mcp/tools}/core.js +122 -162
  84. package/dist/mcp/tools/core.js.map +1 -0
  85. package/dist/shared/metrics-data.generated.d.ts +176 -0
  86. package/dist/shared/metrics-data.generated.d.ts.map +1 -0
  87. package/dist/shared/metrics-data.generated.js +3077 -0
  88. package/dist/shared/metrics-data.generated.js.map +1 -0
  89. package/package.json +44 -5
  90. package/dist/auth/storage.d.ts.map +0 -1
  91. package/dist/auth/storage.js.map +0 -1
  92. package/dist/cache/storage.d.ts +0 -47
  93. package/dist/cache/storage.d.ts.map +0 -1
  94. package/dist/cache/storage.js +0 -140
  95. package/dist/cache/storage.js.map +0 -1
  96. package/dist/cache/summary.d.ts.map +0 -1
  97. package/dist/cache/summary.js.map +0 -1
  98. package/dist/cache/types.js.map +0 -1
  99. package/dist/config.d.ts.map +0 -1
  100. package/dist/config.js.map +0 -1
  101. package/dist/discovery.d.ts.map +0 -1
  102. package/dist/discovery.js.map +0 -1
  103. package/dist/permissions.d.ts.map +0 -1
  104. package/dist/permissions.js.map +0 -1
  105. package/dist/plan-limits.d.ts.map +0 -1
  106. package/dist/plan-limits.js.map +0 -1
  107. package/dist/tools/auth.d.ts +0 -3
  108. package/dist/tools/auth.d.ts.map +0 -1
  109. package/dist/tools/auth.js.map +0 -1
  110. package/dist/tools/core.d.ts +0 -3
  111. package/dist/tools/core.d.ts.map +0 -1
  112. package/dist/tools/core.js.map +0 -1
  113. package/dist/utils.d.ts.map +0 -1
  114. package/dist/utils.js.map +0 -1
  115. /package/dist/{auth → core/auth}/storage.d.ts +0 -0
  116. /package/dist/{auth → core/auth}/storage.js +0 -0
  117. /package/dist/{cache → core/cache}/summary.d.ts +0 -0
  118. /package/dist/{cache → core/cache}/summary.js +0 -0
  119. /package/dist/{cache → core/cache}/types.js +0 -0
  120. /package/dist/{config.d.ts → core/config.d.ts} +0 -0
  121. /package/dist/{config.js → core/config.js} +0 -0
  122. /package/dist/{discovery.d.ts → core/discovery.d.ts} +0 -0
  123. /package/dist/{plan-limits.d.ts → core/plan-limits.d.ts} +0 -0
  124. /package/dist/{plan-limits.js → core/plan-limits.js} +0 -0
@@ -1,12 +1,10 @@
1
1
  import { z } from "zod";
2
- import { readFileSync } from "fs";
3
- import { join, dirname } from "path";
4
- import { fileURLToPath } from "url";
5
- import { getPermissionState } from "../permissions.js";
6
- import { isDiscoveryLoaded, searchEndpoints, getEndpointByPath, getDiscoverySummary, getEndpointCatalog, validateEndpointParams, getParameterOptions, } from "../discovery.js";
7
- import { hasEndpointAccess, getEndpointWindowLimits, validateDateRange, getRequiredPlan, getPlanLimitsState, parseDurationToDate, } from "../plan-limits.js";
8
- import { getApiBaseUrl } from "../config.js";
9
- import { jsonResponse, errorResponse, getPlanNote, capitalizeFirst } from "../utils.js";
2
+ import { METRIC_DEFINITIONS, getAvailableMetrics, } from "../../shared/metrics-data.generated.js";
3
+ import { getApiBaseUrl } from "../../core/config.js";
4
+ import { getDiscoverySummary, getEndpointByPath, getEndpointCatalog, getParameterOptions, isDiscoveryLoaded, searchEndpoints, validateEndpointParams, } from "../../core/discovery.js";
5
+ import { getPermissionState } from "../../core/permissions.js";
6
+ import { getEndpointWindowLimits, getPlanLimitsState, getRequiredPlan, hasEndpointAccess, parseDurationToDate, validateDateRange, } from "../../core/plan-limits.js";
7
+ import { capitalizeFirst, errorResponse, getPlanNote, jsonResponse, logger, } from "../../core/utils.js";
10
8
  function buildRateLimitInfo(response) {
11
9
  const limit = response.headers.get("X-RateLimit-Limit");
12
10
  const remaining = response.headers.get("X-RateLimit-Remaining");
@@ -45,38 +43,62 @@ const queryDataSchema = {
45
43
  .describe("API endpoint path (e.g., /v1/btc/market-data/mvrv)"),
46
44
  params: z
47
45
  .object({
48
- window: z.string().optional().describe("Time window granularity (hour, day, block, etc.)"),
49
- limit: z.number().optional().describe("Number of data points to return (max 1000)"),
46
+ window: z
47
+ .string()
48
+ .optional()
49
+ .describe("Time window granularity (hour, day, block, etc.)"),
50
+ limit: z
51
+ .number()
52
+ .optional()
53
+ .describe("Number of data points to return (max 1000)"),
50
54
  from: z.string().optional().describe("Start date (ISO 8601 format)"),
51
55
  to: z.string().optional().describe("End date (ISO 8601 format)"),
52
- exchange: z.string().optional().describe("Exchange filter (for exchange-specific data)"),
53
- symbol: z.string().optional().describe("Trading symbol (e.g., btc_usd, btc_usdt)"),
56
+ exchange: z
57
+ .string()
58
+ .optional()
59
+ .describe("Exchange filter (for exchange-specific data)"),
60
+ symbol: z
61
+ .string()
62
+ .optional()
63
+ .describe("Trading symbol (e.g., btc_usd, btc_usdt)"),
54
64
  market: z.string().optional().describe("Market type (spot, perpetual)"),
55
- token: z.string().optional().describe("Token filter (for alt/erc20 data)"),
65
+ token: z
66
+ .string()
67
+ .optional()
68
+ .describe("Token filter (for alt/erc20 data)"),
56
69
  miner: z.string().optional().describe("Miner filter (for miner data)"),
57
- type: z.string().optional().describe("Entity type filter (e.g., exchange, entity, miner, bank)"),
70
+ type: z
71
+ .string()
72
+ .optional()
73
+ .describe("Entity type filter (e.g., exchange, entity, miner, bank)"),
58
74
  })
59
75
  .optional()
60
76
  .describe("Query parameters"),
61
77
  };
62
78
  const getEndpointInfoSchema = {
63
- endpoint: z
64
- .string()
65
- .describe("API endpoint path to get information about"),
79
+ endpoint: z.string().describe("API endpoint path to get information about"),
66
80
  };
67
81
  function requireAuth() {
68
82
  const state = getPermissionState();
69
83
  if (!state.authenticated) {
70
- return errorResponse("Not authenticated", { action: "Call initialize() first to authenticate with your API key" });
84
+ return errorResponse("Not authenticated", {
85
+ action: "Call initialize() first to authenticate with your API key",
86
+ });
71
87
  }
72
88
  return null;
73
89
  }
74
90
  export function registerCoreTools(server) {
75
91
  server.tool("discover_endpoints", "Discover available API endpoints for a specific asset and category. Call initialize() first to get valid asset/category combinations. Returns endpoint paths and parameter options (e.g., window: ['day', 'hour']). Use returned paths with query_data().", discoverEndpointsSchema, async (params) => {
92
+ logger.debug("[discover_endpoints] called with:", {
93
+ asset: params.asset || "all",
94
+ category: params.category || "all",
95
+ query: params.query || null,
96
+ });
76
97
  const authError = requireAuth();
77
98
  if (authError)
78
99
  return authError;
79
100
  if (!isDiscoveryLoaded()) {
101
+ logger.debug("[discover_endpoints] discovery not loaded");
80
102
  return errorResponse("Discovery data not loaded", {
81
103
  action: "Discovery may have failed during initialization. Try reset_session() and initialize() again.",
82
104
  });
@@ -86,6 +108,7 @@ export function registerCoreTools(server) {
86
108
  category: params.category,
87
109
  query: params.query,
88
110
  });
111
+ logger.debug("[discover_endpoints] found", endpoints.length, "endpoints");
89
112
  const grouped = {};
90
113
  for (const ep of endpoints) {
91
114
  grouped[ep.asset] ??= {};
@@ -104,7 +127,9 @@ export function registerCoreTools(server) {
104
127
  const planInfo = planState.loaded
105
128
  ? {
106
129
  accessible,
107
- ...(Object.keys(windowLimits).length > 0 && { date_limits: windowLimits }),
130
+ ...(Object.keys(windowLimits).length > 0 && {
131
+ date_limits: windowLimits,
132
+ }),
108
133
  ...(!accessible && {
109
134
  required_plan: requiredPlan,
110
135
  upgrade_hint: `Upgrade to ${capitalizeFirst(requiredPlan)} for access`,
@@ -132,19 +157,26 @@ export function registerCoreTools(server) {
132
157
  matched_endpoints: endpoints.length,
133
158
  total_available: summary?.total_endpoints || 0,
134
159
  ...(planState.loaded && {
135
- plan_info: { your_plan: planState.plan, note: getPlanNote(planState.plan) },
160
+ plan_info: {
161
+ your_plan: planState.plan,
162
+ note: getPlanNote(planState.plan),
163
+ },
136
164
  }),
137
165
  catalog,
138
166
  tip: "Use get_endpoint_info(endpoint) to see available parameter values for a specific endpoint",
139
167
  });
140
168
  });
141
169
  server.tool("get_endpoint_info", "Get detailed information about a specific API endpoint including available parameter values.", getEndpointInfoSchema, async (params) => {
170
+ logger.debug("[get_endpoint_info] lookup:", params.endpoint);
142
171
  const authError = requireAuth();
143
172
  if (authError)
144
173
  return authError;
145
174
  const endpoint = getEndpointByPath(params.endpoint);
146
175
  if (!endpoint) {
147
- const searchResults = searchEndpoints({ query: params.endpoint.split("/").pop() || "" });
176
+ logger.debug("[get_endpoint_info] endpoint not found:", params.endpoint);
177
+ const searchResults = searchEndpoints({
178
+ query: params.endpoint.split("/").pop() || "",
179
+ });
148
180
  return errorResponse(`Endpoint not found: ${params.endpoint}`, {
149
181
  suggestions: searchResults.slice(0, 5).map((ep) => ep.path),
150
182
  tip: "Use discover_endpoints() to browse available endpoints",
@@ -159,7 +191,9 @@ export function registerCoreTools(server) {
159
191
  const earliestDate = parseDurationToDate(limit);
160
192
  dateLimitsInfo[window] = {
161
193
  limit,
162
- earliest_date: earliestDate ? earliestDate.toISOString().split("T")[0] : null,
194
+ earliest_date: earliestDate
195
+ ? earliestDate.toISOString().split("T")[0]
196
+ : null,
163
197
  };
164
198
  }
165
199
  return jsonResponse({
@@ -176,14 +210,21 @@ export function registerCoreTools(server) {
176
210
  plan_access: {
177
211
  accessible,
178
212
  your_plan: planState.plan,
179
- ...(Object.keys(dateLimitsInfo).length > 0 && { date_limits: dateLimitsInfo }),
180
- ...(!accessible && { required_plan: requiredPlan, upgrade_url: "https://cryptoquant.com/pricing" }),
213
+ ...(Object.keys(dateLimitsInfo).length > 0 && {
214
+ date_limits: dateLimitsInfo,
215
+ }),
216
+ ...(!accessible && {
217
+ required_plan: requiredPlan,
218
+ upgrade_url: "https://cryptoquant.com/pricing",
219
+ }),
181
220
  },
182
221
  }),
183
222
  example_query: buildExampleQuery(endpoint),
184
223
  });
185
224
  });
186
225
  server.tool("query_data", "Query raw data from CryptoQuant API. Workflow: initialize() → discover_endpoints(asset, category) → query_data(endpoint, params). Use endpoint paths and parameter values from discover_endpoints response.", queryDataSchema, async (params) => {
226
+ logger.debug("[query_data] called with endpoint:", params.endpoint);
227
+ logger.debug("[query_data] params:", params.params);
187
228
  const authError = requireAuth();
188
229
  if (authError)
189
230
  return authError;
@@ -224,7 +265,9 @@ export function registerCoreTools(server) {
224
265
  return errorResponse(dateValidation.error || "Date range exceeds plan limit", {
225
266
  your_plan: planState.plan,
226
267
  ...(dateValidation.limit && { limit: dateValidation.limit }),
227
- ...(dateValidation.earliest_allowed && { earliest_allowed: dateValidation.earliest_allowed }),
268
+ ...(dateValidation.earliest_allowed && {
269
+ earliest_allowed: dateValidation.earliest_allowed,
270
+ }),
228
271
  upgrade_url: "https://cryptoquant.com/pricing",
229
272
  suggestion: "Upgrade to Premium for unlimited historical data access",
230
273
  });
@@ -233,7 +276,9 @@ export function registerCoreTools(server) {
233
276
  }
234
277
  const apiKey = state.api_key;
235
278
  if (!apiKey) {
236
- return errorResponse("API key not available", { action: "Re-initialize with your API key" });
279
+ return errorResponse("API key not available", {
280
+ action: "Re-initialize with your API key",
281
+ });
237
282
  }
238
283
  try {
239
284
  const urlParams = new URLSearchParams();
@@ -248,10 +293,12 @@ export function registerCoreTools(server) {
248
293
  urlParams.set("source", "mcp");
249
294
  const apiUrl = getApiBaseUrl();
250
295
  const fullUrl = `${apiUrl}${params.endpoint}?${urlParams.toString()}`;
296
+ logger.debug("[query_data] API request:", fullUrl);
251
297
  const response = await fetch(fullUrl, {
252
298
  method: "GET",
253
299
  headers: { Authorization: `Bearer ${apiKey}` },
254
300
  });
301
+ logger.debug("[query_data] API response status:", response.status, response.statusText);
255
302
  if (!response.ok) {
256
303
  const errorBody = await response.text();
257
304
  return errorResponse(`API request failed: ${response.status} ${response.statusText}`, {
@@ -261,10 +308,12 @@ export function registerCoreTools(server) {
261
308
  }
262
309
  let data;
263
310
  try {
264
- data = await response.json();
311
+ data = (await response.json());
265
312
  }
266
313
  catch {
267
- return errorResponse("Failed to parse API response", { endpoint: params.endpoint });
314
+ return errorResponse("Failed to parse API response", {
315
+ endpoint: params.endpoint,
316
+ });
268
317
  }
269
318
  const rateLimitInfo = buildRateLimitInfo(response);
270
319
  return jsonResponse({
@@ -276,7 +325,9 @@ export function registerCoreTools(server) {
276
325
  });
277
326
  }
278
327
  catch (error) {
279
- return errorResponse(`Network error: ${error}`, { endpoint: params.endpoint });
328
+ return errorResponse(`Network error: ${error}`, {
329
+ endpoint: params.endpoint,
330
+ });
280
331
  }
281
332
  });
282
333
  server.tool("list_assets", "List all supported assets (cryptocurrencies) with their available data categories.", {}, async () => {
@@ -292,7 +343,12 @@ export function registerCoreTools(server) {
292
343
  const note = state.authenticated
293
344
  ? "Discovery data not loaded. Try reset_session() and initialize() again."
294
345
  : "Call initialize() to load full endpoint catalog";
295
- return jsonResponse({ success: true, authenticated: state.authenticated, assets: defaultAssets, note });
346
+ return jsonResponse({
347
+ success: true,
348
+ authenticated: state.authenticated,
349
+ assets: defaultAssets,
350
+ note,
351
+ });
296
352
  }
297
353
  const summary = getDiscoverySummary();
298
354
  const catalog = getEndpointCatalog();
@@ -318,140 +374,41 @@ export function registerCoreTools(server) {
318
374
  });
319
375
  });
320
376
  server.tool("describe_metric", "Get detailed description for a specific metric. Use only when user asks 'what is X?' or metric is unfamiliar. Returns thresholds, interpretation guidance, and category info.", {
321
- metric_id: z.string().describe("The metric ID to describe (e.g., 'mvrv', 'sopr', 'netflow')"),
377
+ metric_id: z
378
+ .string()
379
+ .describe("The metric ID to describe (e.g., 'mvrv', 'sopr', 'netflow')"),
322
380
  }, async (params) => {
323
- try {
324
- const metrics = parseToonMetrics();
325
- const searchLower = params.metric_id.toLowerCase();
326
- const metric = metrics.find((m) => m.id.toLowerCase() === searchLower);
327
- if (!metric) {
328
- const suggestions = metrics
329
- .filter((m) => m.id.toLowerCase().includes(searchLower) || m.name.toLowerCase().includes(searchLower))
330
- .slice(0, 5)
331
- .map((m) => m.id);
332
- return errorResponse(`Unknown metric: ${params.metric_id}`, {
333
- suggestions: suggestions.length > 0 ? suggestions : undefined,
334
- tip: "Use discover_endpoints() to find available metrics",
335
- });
336
- }
337
- return jsonResponse({
338
- success: true,
339
- metric: {
340
- id: metric.id,
341
- name: metric.name,
342
- category: metric.category,
343
- asset: metric.asset,
344
- description: metric.description,
345
- thresholds: metric.thresholds,
346
- interpretation: metric.interpretation,
347
- },
381
+ logger.debug("[describe_metric] looking up metric:", params.metric_id);
382
+ const searchLower = params.metric_id.toLowerCase();
383
+ const metric = METRIC_DEFINITIONS[searchLower];
384
+ if (!metric) {
385
+ logger.debug("[describe_metric] metric not found:", params.metric_id);
386
+ const allMetrics = getAvailableMetrics();
387
+ const suggestions = allMetrics
388
+ .filter((id) => id.includes(searchLower))
389
+ .slice(0, 5);
390
+ return errorResponse(`Unknown metric: ${params.metric_id}`, {
391
+ suggestions: suggestions.length > 0 ? suggestions : undefined,
392
+ tip: "Use discover_endpoints() to find available metrics",
348
393
  });
349
394
  }
350
- catch (error) {
351
- return errorResponse(`Failed to load metric data: ${error}`);
352
- }
395
+ logger.debug("[describe_metric] found metric:", metric.id, "-", metric.name);
396
+ return jsonResponse({
397
+ success: true,
398
+ metric: {
399
+ id: metric.id,
400
+ name: metric.name,
401
+ category: metric.category,
402
+ asset: metric.asset,
403
+ definition: metric.definition,
404
+ interpretation: metric.interpretation,
405
+ thresholds: metric.thresholds,
406
+ keyInsights: metric.keyInsights,
407
+ endpoint: metric.endpoint,
408
+ },
409
+ });
353
410
  });
354
411
  }
355
- function parseToonMetrics() {
356
- const __filename = fileURLToPath(import.meta.url);
357
- const __dirname = dirname(__filename);
358
- const toonPath = join(__dirname, "..", "data", "metrics.toon");
359
- let content;
360
- try {
361
- content = readFileSync(toonPath, "utf-8");
362
- }
363
- catch {
364
- return getBuiltInMetrics();
365
- }
366
- const metrics = [];
367
- const lines = content.split("\n");
368
- let schemaFields = [];
369
- let dataStartIndex = -1;
370
- for (let i = 0; i < lines.length; i++) {
371
- const line = lines[i].trim();
372
- if (line.startsWith("metrics[") && line.includes("{") && line.includes("}:")) {
373
- const match = line.match(/\{([^}]+)\}/);
374
- if (match) {
375
- schemaFields = match[1].split(",").map((f) => f.trim());
376
- dataStartIndex = i + 1;
377
- break;
378
- }
379
- }
380
- }
381
- if (schemaFields.length === 0 || dataStartIndex === -1) {
382
- return getBuiltInMetrics();
383
- }
384
- for (let i = dataStartIndex; i < lines.length; i++) {
385
- const line = lines[i].trim();
386
- if (!line || line.startsWith("#"))
387
- continue;
388
- const values = line.split(",").map((p) => p.trim());
389
- if (values.length >= schemaFields.length) {
390
- const metric = {
391
- id: values[0] || "",
392
- name: values[1] || "",
393
- category: values[2] || "",
394
- asset: values[3] || "",
395
- description: values[4] || "",
396
- thresholds: values[5] || "",
397
- interpretation: values[6] || "",
398
- };
399
- if (metric.id) {
400
- metrics.push(metric);
401
- }
402
- }
403
- }
404
- return metrics.length > 0 ? metrics : getBuiltInMetrics();
405
- }
406
- function getBuiltInMetrics() {
407
- return [
408
- {
409
- id: "mvrv",
410
- name: "Market Value to Realized Value",
411
- category: "market-indicator",
412
- asset: "btc",
413
- description: "Compares current market cap to realized cap (aggregate cost basis)",
414
- thresholds: "<1 undervalued|1-2.5 neutral|2.5-3.7 overheated|>3.7 extreme",
415
- interpretation: "Primary cycle indicator. Values below 1 historically mark accumulation zones.",
416
- },
417
- {
418
- id: "sopr",
419
- name: "Spent Output Profit Ratio",
420
- category: "market-indicator",
421
- asset: "btc",
422
- description: "Ratio of price sold to price paid for coins moved on-chain",
423
- thresholds: "<1 selling at loss|=1 breakeven|>1 selling at profit",
424
- interpretation: "Real-time profit/loss behavior. SOPR=1 often acts as support/resistance.",
425
- },
426
- {
427
- id: "nupl",
428
- name: "Net Unrealized Profit/Loss",
429
- category: "market-indicator",
430
- asset: "btc",
431
- description: "Percentage of coins in profit or loss relative to total market cap",
432
- thresholds: "<0 capitulation|0-0.25 hope|0.25-0.5 belief|0.5-0.75 optimism|>0.75 euphoria",
433
- interpretation: "Sentiment gauge. Extreme values often precede major reversals.",
434
- },
435
- {
436
- id: "netflow",
437
- name: "Exchange Netflow",
438
- category: "exchange-flows",
439
- asset: "btc",
440
- description: "Net flow of BTC into (positive) or out of (negative) exchanges",
441
- thresholds: "positive sell pressure|negative accumulation",
442
- interpretation: "Key supply dynamics indicator. Sustained outflows suggest accumulation.",
443
- },
444
- {
445
- id: "funding-rates",
446
- name: "Funding Rates",
447
- category: "market-data",
448
- asset: "btc",
449
- description: "Periodic payment between long and short perpetual swap holders",
450
- thresholds: "<0 bearish|0-0.03% neutral|>0.1% extreme bullish",
451
- interpretation: "Leverage sentiment. Extreme positive rates often precede corrections.",
452
- },
453
- ];
454
- }
455
412
  function buildExampleQuery(endpoint) {
456
413
  const params = [];
457
414
  for (const required of endpoint.required_parameters) {
@@ -460,14 +417,17 @@ function buildExampleQuery(endpoint) {
460
417
  params.push(`${required}=${values[0]}`);
461
418
  }
462
419
  }
463
- if (endpoint.parameters.window && !endpoint.required_parameters.includes("window")) {
420
+ if (endpoint.parameters.window &&
421
+ !endpoint.required_parameters.includes("window")) {
464
422
  params.push(`window=${endpoint.parameters.window[0]}`);
465
423
  }
466
424
  params.push("limit=100");
467
- const paramStr = params.map((p) => {
425
+ const paramStr = params
426
+ .map((p) => {
468
427
  const [key, val] = p.split("=");
469
428
  return `"${key}": "${val}"`;
470
- }).join(", ");
429
+ })
430
+ .join(", ");
471
431
  return `query_data(endpoint="${endpoint.path}", params={${paramStr}})`;
472
432
  }
473
433
  //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/mcp/tools/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY
3
+ *
4
+ * Generated by: npm run sync-skills
5
+ * Source files:
6
+ * - skills/crypto/INTERPRETATION.md
7
+ * - mcp-server/src/data/metrics.toon
8
+ *
9
+ * To update, edit the source files and run: npm run sync-skills
10
+ */
11
+ export interface MetricThreshold {
12
+ range: string;
13
+ signal: "bullish" | "neutral" | "caution" | "bearish";
14
+ emoji: string;
15
+ meaning: string;
16
+ }
17
+ export interface ScoringRule {
18
+ condition: (value: number) => boolean;
19
+ score: number;
20
+ }
21
+ export interface MetricScoring {
22
+ weight: number;
23
+ rules: ScoringRule[];
24
+ }
25
+ export interface MetricDefinition {
26
+ id: string;
27
+ name: string;
28
+ category: string;
29
+ asset: string;
30
+ definition: string;
31
+ interpretation: string;
32
+ thresholds: MetricThreshold[];
33
+ keyInsights: string[];
34
+ endpoint: string;
35
+ scoring?: MetricScoring;
36
+ }
37
+ export declare const SIGNAL_LEGEND: {
38
+ readonly bullish: {
39
+ readonly emoji: "🟢";
40
+ readonly label: "Bullish / Buy opportunity";
41
+ readonly action: "Consider accumulating";
42
+ };
43
+ readonly neutral: {
44
+ readonly emoji: "🟡";
45
+ readonly label: "Neutral";
46
+ readonly action: "Hold / Wait for clearer signal";
47
+ };
48
+ readonly caution: {
49
+ readonly emoji: "🟠";
50
+ readonly label: "Caution";
51
+ readonly action: "Be cautious, potential reversal";
52
+ };
53
+ readonly bearish: {
54
+ readonly emoji: "🔴";
55
+ readonly label: "Bearish / Sell signal";
56
+ readonly action: "Consider reducing exposure";
57
+ };
58
+ };
59
+ export declare const METRIC_DEFINITIONS: Record<string, MetricDefinition>;
60
+ export declare const SCORING_RULES: Record<string, MetricScoring>;
61
+ /**
62
+ * Get metric definition by ID
63
+ */
64
+ export declare function getMetricDefinition(metricId: string): MetricDefinition | undefined;
65
+ /**
66
+ * Get all available metric IDs
67
+ */
68
+ export declare function getAvailableMetrics(): string[];
69
+ /**
70
+ * Calculate score for a metric value
71
+ */
72
+ export declare function calculateScore(metricId: string, value: number): number;
73
+ /**
74
+ * Calculate weighted trading signal score
75
+ */
76
+ export declare function calculateTradingSignal(metrics: Record<string, number>): {
77
+ score: number;
78
+ signal: string;
79
+ confidence: number;
80
+ };
81
+ /**
82
+ * Get signal for a metric value
83
+ */
84
+ export declare function getMetricSignal(metricId: string, value: number): {
85
+ signal: string;
86
+ emoji: string;
87
+ meaning: string;
88
+ } | null;
89
+ export declare const MARKET_THRESHOLDS: {
90
+ mvrv: {
91
+ bullish: {
92
+ max: number;
93
+ };
94
+ neutral: {
95
+ min: number;
96
+ max: number;
97
+ };
98
+ bearish: {
99
+ min: number;
100
+ };
101
+ };
102
+ sopr: {
103
+ bullish: {
104
+ max: number;
105
+ };
106
+ neutral: {
107
+ min: number;
108
+ max: number;
109
+ };
110
+ bearish: {
111
+ min: number;
112
+ };
113
+ };
114
+ netflow: {
115
+ bullish: {
116
+ max: number;
117
+ };
118
+ neutral: {
119
+ min: number;
120
+ max: number;
121
+ };
122
+ bearish: {
123
+ min: number;
124
+ };
125
+ };
126
+ };
127
+ export declare const WHALE_THRESHOLDS: {
128
+ ratio: {
129
+ retail: {
130
+ max: number;
131
+ };
132
+ mixed: {
133
+ min: number;
134
+ max: number;
135
+ };
136
+ whaleHeavy: {
137
+ min: number;
138
+ max: number;
139
+ };
140
+ whaleDominated: {
141
+ min: number;
142
+ max: number;
143
+ };
144
+ extreme: {
145
+ min: number;
146
+ };
147
+ };
148
+ };
149
+ export declare const CYCLE_PHASES: {
150
+ accumulation: {
151
+ name: string;
152
+ mvrv: string;
153
+ sopr: string;
154
+ netflow: string;
155
+ };
156
+ markupEarlyBull: {
157
+ name: string;
158
+ mvrv: string;
159
+ sopr: string;
160
+ netflow: string;
161
+ };
162
+ distribution: {
163
+ name: string;
164
+ mvrv: string;
165
+ sopr: string;
166
+ netflow: string;
167
+ };
168
+ markdownBear: {
169
+ name: string;
170
+ mvrv: string;
171
+ sopr: string;
172
+ netflow: string;
173
+ };
174
+ };
175
+ export declare const INTERPRETATION_SYSTEM_PROMPT = "\nYou are a crypto market analyst with access to CryptoQuant on-chain data.\n\n## Key Metrics Interpretation\n\n### Valuation (MVRV)\n- < 1.0: \uD83D\uDFE2 Undervalued (buy zone)\n- 1.0-2.5: \uD83D\uDFE1 Fair value\n- > 3.5: \uD83D\uDD34 Overheated (sell zone)\n\n### Profit Behavior (SOPR)\n- < 0.95: \uD83D\uDFE2 Capitulation (contrarian buy)\n- 0.95-1.05: \uD83D\uDFE1 Normal\n- > 1.10: \uD83D\uDD34 Heavy profit taking\n\n### Exchange Flows (Netflow)\n- < -1,000 BTC: \uD83D\uDFE2 Accumulation\n- \u00B11,000 BTC: \uD83D\uDFE1 Neutral\n- > +5,000 BTC: \uD83D\uDD34 Distribution\n\n### Funding Rate\n- < -0.03%: \uD83D\uDFE2 Shorts overcrowded\n- \u00B10.01%: \uD83D\uDFE1 Neutral\n- > 0.05%: \uD83D\uDD34 Longs overcrowded\n\n## Trading Signal Weights\n- MVRV: 30%\n- SOPR: 25%\n- Netflow: 25%\n- Funding: 20%\n\nScore > 70: BUY | 40-70: HOLD | < 40: SELL\n\n## Important Notes\n- No single metric is definitive - use multiple confirmations\n- Context matters - same values mean different things in bull vs bear\n- This is not financial advice - metrics are informational only\n";
176
+ //# sourceMappingURL=metrics-data.generated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-data.generated.d.ts","sourceRoot":"","sources":["../../src/shared/metrics-data.generated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAMD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;CAKhB,CAAC;AAMX,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA8yF/D,CAAC;AAWF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CA0CvD,CAAC;AAMF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAElF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAUtE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAwBvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAO3D;AAMD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAI7B,CAAC;AAMF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;CAQ5B,CAAC;AAMF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;CAKxB,CAAC;AAMF,eAAO,MAAM,4BAA4B,+jCAqCxC,CAAC"}