@cryptoquant_official/mcp 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +88 -0
  2. package/dist/auth/server.d.ts +3 -0
  3. package/dist/auth/server.d.ts.map +1 -0
  4. package/dist/auth/server.js +405 -0
  5. package/dist/auth/server.js.map +1 -0
  6. package/dist/auth/storage.d.ts +11 -0
  7. package/dist/auth/storage.d.ts.map +1 -0
  8. package/dist/auth/storage.js +53 -0
  9. package/dist/auth/storage.js.map +1 -0
  10. package/dist/cache/storage.d.ts +47 -0
  11. package/dist/cache/storage.d.ts.map +1 -0
  12. package/dist/cache/storage.js +140 -0
  13. package/dist/cache/storage.js.map +1 -0
  14. package/dist/cache/summary.d.ts +16 -0
  15. package/dist/cache/summary.d.ts.map +1 -0
  16. package/dist/cache/summary.js +85 -0
  17. package/dist/cache/summary.js.map +1 -0
  18. package/dist/cache/types.d.ts +76 -0
  19. package/dist/cache/types.d.ts.map +1 -0
  20. package/dist/cache/types.js +6 -0
  21. package/dist/cache/types.js.map +1 -0
  22. package/dist/config.d.ts +18 -0
  23. package/dist/config.d.ts.map +1 -0
  24. package/dist/config.js +23 -0
  25. package/dist/config.js.map +1 -0
  26. package/dist/data/metrics.toon +58 -0
  27. package/dist/discovery.d.ts +70 -0
  28. package/dist/discovery.d.ts.map +1 -0
  29. package/dist/discovery.js +159 -0
  30. package/dist/discovery.js.map +1 -0
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +23 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/permissions.d.ts +36 -0
  36. package/dist/permissions.d.ts.map +1 -0
  37. package/dist/permissions.js +135 -0
  38. package/dist/permissions.js.map +1 -0
  39. package/dist/plan-limits.d.ts +71 -0
  40. package/dist/plan-limits.d.ts.map +1 -0
  41. package/dist/plan-limits.js +400 -0
  42. package/dist/plan-limits.js.map +1 -0
  43. package/dist/tools/auth.d.ts +3 -0
  44. package/dist/tools/auth.d.ts.map +1 -0
  45. package/dist/tools/auth.js +157 -0
  46. package/dist/tools/auth.js.map +1 -0
  47. package/dist/tools/core.d.ts +3 -0
  48. package/dist/tools/core.d.ts.map +1 -0
  49. package/dist/tools/core.js +472 -0
  50. package/dist/tools/core.js.map +1 -0
  51. package/dist/utils.d.ts +32 -0
  52. package/dist/utils.d.ts.map +1 -0
  53. package/dist/utils.js +42 -0
  54. package/dist/utils.js.map +1 -0
  55. package/package.json +62 -0
@@ -0,0 +1,400 @@
1
+ const DEFAULT_STATE = {
2
+ loaded: false,
3
+ limits: null,
4
+ plan: "unknown",
5
+ statics: [],
6
+ apiRateLimit: null,
7
+ fetched_at: null,
8
+ };
9
+ let planLimitsState = { ...DEFAULT_STATE };
10
+ /**
11
+ * Normalize plan name from API (e.g., "PROFESSIONAL") to UserPlan type
12
+ */
13
+ function normalizePlanName(apiPlanName) {
14
+ const normalized = apiPlanName.toLowerCase();
15
+ switch (normalized) {
16
+ case "basic":
17
+ return "basic";
18
+ case "advanced":
19
+ return "advanced";
20
+ case "professional":
21
+ return "professional";
22
+ case "premium":
23
+ return "premium";
24
+ case "custom":
25
+ return "custom";
26
+ default:
27
+ return "unknown";
28
+ }
29
+ }
30
+ export async function fetchPlanLimits(apiKey, apiUrl) {
31
+ try {
32
+ const discoveryUrl = apiUrl.replace(/\/v1$/, "") + "/v1/my/discovery/endpoints?source=mcp";
33
+ const response = await fetch(discoveryUrl, {
34
+ method: "GET",
35
+ headers: { Authorization: `Bearer ${apiKey}` },
36
+ });
37
+ if (response.status === 403 || response.status === 500) {
38
+ planLimitsState = { ...DEFAULT_STATE, loaded: true, plan: "basic", fetched_at: Date.now() };
39
+ return {
40
+ success: true,
41
+ plan: "basic",
42
+ parsed: { limits: null, statics: [], apiRateLimit: null },
43
+ };
44
+ }
45
+ if (!response.ok) {
46
+ return { success: false, error: `Plan limits API failed: ${response.status} ${response.statusText}` };
47
+ }
48
+ let data;
49
+ try {
50
+ data = await response.json();
51
+ }
52
+ catch {
53
+ return { success: false, error: "Failed to parse plan limits response" };
54
+ }
55
+ const parsed = parseApiResponse(data);
56
+ // Prefer direct plan name from API, fallback to detection from limits
57
+ const plan = parsed.planName
58
+ ? normalizePlanName(parsed.planName)
59
+ : detectPlanFromLimits(parsed.limits);
60
+ planLimitsState = {
61
+ loaded: true,
62
+ limits: parsed.limits,
63
+ plan,
64
+ statics: parsed.statics,
65
+ apiRateLimit: parsed.apiRateLimit,
66
+ fetched_at: Date.now(),
67
+ };
68
+ return {
69
+ success: true,
70
+ rawResponse: data,
71
+ parsed: {
72
+ limits: parsed.limits,
73
+ statics: parsed.statics,
74
+ apiRateLimit: parsed.apiRateLimit,
75
+ },
76
+ plan,
77
+ };
78
+ }
79
+ catch (error) {
80
+ return { success: false, error: `Plan limits fetch error: ${error}` };
81
+ }
82
+ }
83
+ function parseApiResponse(data) {
84
+ const result = {
85
+ limits: null,
86
+ statics: [],
87
+ apiRateLimit: null,
88
+ planName: null,
89
+ };
90
+ if (!data || typeof data !== "object")
91
+ return result;
92
+ const obj = data;
93
+ // Parse plan.name directly from response (new format)
94
+ if (obj.plan && typeof obj.plan === "object") {
95
+ const plan = obj.plan;
96
+ if (typeof plan.name === "string") {
97
+ result.planName = plan.name;
98
+ }
99
+ }
100
+ // Parse apiEndpoint (the main limits data)
101
+ if (obj.apiEndpoint && typeof obj.apiEndpoint === "object") {
102
+ const apiEndpoint = obj.apiEndpoint;
103
+ const limits = {};
104
+ for (const [asset, categories] of Object.entries(apiEndpoint)) {
105
+ // Skip non-asset keys like "statics"
106
+ if (asset === "statics" || typeof categories !== "object" || categories === null) {
107
+ continue;
108
+ }
109
+ limits[asset] = {};
110
+ for (const [category, metrics] of Object.entries(categories)) {
111
+ if (typeof metrics !== "object" || metrics === null)
112
+ continue;
113
+ limits[asset][category] = {};
114
+ for (const [metric, metricData] of Object.entries(metrics)) {
115
+ if (typeof metricData !== "object" || metricData === null)
116
+ continue;
117
+ const md = metricData;
118
+ // New format: metric data is directly { windowType: duration }
119
+ // e.g., { "day": "P1Y" } instead of { window: { "day": "P1Y" }, limit: 1000 }
120
+ const windowLimits = {};
121
+ let hasValidWindow = false;
122
+ for (const [key, value] of Object.entries(md)) {
123
+ if (typeof value === "string" && /^P\d+[YMWD]$/.test(value)) {
124
+ windowLimits[key] = value;
125
+ hasValidWindow = true;
126
+ }
127
+ }
128
+ if (hasValidWindow) {
129
+ limits[asset][category][metric] = { window: windowLimits };
130
+ }
131
+ }
132
+ }
133
+ }
134
+ // Extract statics from apiEndpoint if present
135
+ if (apiEndpoint.statics && Array.isArray(apiEndpoint.statics)) {
136
+ result.statics = apiEndpoint.statics;
137
+ }
138
+ result.limits = Object.keys(limits).length > 0 ? limits : null;
139
+ }
140
+ // Parse apiRateLimit
141
+ if (obj.apiRateLimit && typeof obj.apiRateLimit === "object") {
142
+ const rl = obj.apiRateLimit;
143
+ if (typeof rl.token === "number" && typeof rl.window === "string") {
144
+ result.apiRateLimit = {
145
+ token: rl.token,
146
+ window: rl.window,
147
+ };
148
+ }
149
+ }
150
+ return result;
151
+ }
152
+ function collectDurationCounts(limits) {
153
+ const counts = { p0d: 0, p3y: 0, p1d: 0, total: 0 };
154
+ for (const categories of Object.values(limits)) {
155
+ if (!categories)
156
+ continue;
157
+ for (const metrics of Object.values(categories)) {
158
+ if (!metrics)
159
+ continue;
160
+ for (const metricLimits of Object.values(metrics)) {
161
+ if (!metricLimits?.window)
162
+ continue;
163
+ for (const duration of Object.values(metricLimits.window)) {
164
+ counts.total++;
165
+ if (duration === "P0D")
166
+ counts.p0d++;
167
+ else if (duration === "P3Y")
168
+ counts.p3y++;
169
+ else if (duration === "P1D")
170
+ counts.p1d++;
171
+ }
172
+ }
173
+ }
174
+ }
175
+ return counts;
176
+ }
177
+ export function detectPlanFromLimits(limits) {
178
+ if (!limits)
179
+ return "basic";
180
+ const counts = collectDurationCounts(limits);
181
+ if (counts.total === 0)
182
+ return "basic";
183
+ const p1dRatio = counts.p1d / counts.total;
184
+ const p0dRatio = counts.p0d / counts.total;
185
+ const p3yRatio = counts.p3y / counts.total;
186
+ // P1D (1 day only) with low limits = basic plan
187
+ if (p1dRatio > 0.5)
188
+ return "basic";
189
+ // P0D (unlimited) on most endpoints = premium
190
+ if (p0dRatio > 0.5)
191
+ return "premium";
192
+ // P3Y (3 years) on many endpoints = professional
193
+ if (p3yRatio > 0.3)
194
+ return "professional";
195
+ return "advanced";
196
+ }
197
+ export function getPlanLimitsState() {
198
+ return planLimitsState;
199
+ }
200
+ function parseEndpointPath(endpointPath) {
201
+ const parts = endpointPath.split("/");
202
+ if (parts.length < 5)
203
+ return null;
204
+ return { asset: parts[2], category: parts[3], metric: parts.slice(4).join("/") };
205
+ }
206
+ function getMetricLimits(endpointPath) {
207
+ if (!planLimitsState.limits)
208
+ return null;
209
+ const parsed = parseEndpointPath(endpointPath);
210
+ if (!parsed)
211
+ return null;
212
+ const { asset, category, metric } = parsed;
213
+ return planLimitsState.limits[asset]?.[category]?.[metric] ?? null;
214
+ }
215
+ export function getPlanLimit(endpointPath, windowType) {
216
+ const metricLimits = getMetricLimits(endpointPath);
217
+ if (!metricLimits?.window)
218
+ return null;
219
+ if (windowType && metricLimits.window[windowType]) {
220
+ return metricLimits.window[windowType];
221
+ }
222
+ // Return first available window limit
223
+ const windows = Object.keys(metricLimits.window);
224
+ return windows.length > 0 ? metricLimits.window[windows[0]] : null;
225
+ }
226
+ export function getEndpointResultLimit(_endpointPath) {
227
+ // Note: The new API response format no longer includes result limits per endpoint
228
+ // Return null to indicate no specific limit is set
229
+ return null;
230
+ }
231
+ export function getEndpointWindowLimits(endpointPath) {
232
+ const metricLimits = getMetricLimits(endpointPath);
233
+ return metricLimits?.window ?? {};
234
+ }
235
+ export function hasEndpointAccess(endpointPath) {
236
+ if (!planLimitsState.loaded || planLimitsState.plan === "unknown") {
237
+ return true;
238
+ }
239
+ // Check if it's a static endpoint (always accessible)
240
+ if (planLimitsState.statics.includes(endpointPath)) {
241
+ return true;
242
+ }
243
+ if (planLimitsState.plan === "basic" && !planLimitsState.limits) {
244
+ return false;
245
+ }
246
+ return getPlanLimit(endpointPath) !== null;
247
+ }
248
+ export function parseDurationToDate(duration) {
249
+ if (duration === "P0D")
250
+ return null; // Unlimited
251
+ const match = duration.match(/^P(\d+)([YMWD])$/);
252
+ if (!match)
253
+ return null;
254
+ const value = parseInt(match[1], 10);
255
+ const unit = match[2];
256
+ const date = new Date();
257
+ switch (unit) {
258
+ case "Y":
259
+ date.setFullYear(date.getFullYear() - value);
260
+ break;
261
+ case "M":
262
+ date.setMonth(date.getMonth() - value);
263
+ break;
264
+ case "W":
265
+ date.setDate(date.getDate() - value * 7);
266
+ break;
267
+ case "D":
268
+ date.setDate(date.getDate() - value);
269
+ break;
270
+ default:
271
+ return null;
272
+ }
273
+ return date;
274
+ }
275
+ export function getEarliestAllowedDate(endpointPath, windowType) {
276
+ const limit = getPlanLimit(endpointPath, windowType);
277
+ if (!limit)
278
+ return new Date();
279
+ return parseDurationToDate(limit);
280
+ }
281
+ export function validateDateRange(endpointPath, fromDate, windowType) {
282
+ if (!planLimitsState.loaded || planLimitsState.plan === "unknown") {
283
+ return { valid: true };
284
+ }
285
+ if (!hasEndpointAccess(endpointPath)) {
286
+ return { valid: false, error: "Endpoint not accessible on your plan" };
287
+ }
288
+ if (!fromDate) {
289
+ return { valid: true };
290
+ }
291
+ const limit = getPlanLimit(endpointPath, windowType);
292
+ if (!limit) {
293
+ return { valid: false, error: "No access to this endpoint/window combination" };
294
+ }
295
+ if (limit === "P0D") {
296
+ return { valid: true };
297
+ }
298
+ const earliestDate = parseDurationToDate(limit);
299
+ if (!earliestDate) {
300
+ return { valid: true };
301
+ }
302
+ const requestedDate = new Date(fromDate);
303
+ if (isNaN(requestedDate.getTime())) {
304
+ return { valid: false, error: "Invalid date format" };
305
+ }
306
+ if (requestedDate < earliestDate) {
307
+ return {
308
+ valid: false,
309
+ error: "Date range exceeds plan limit",
310
+ earliest_allowed: earliestDate.toISOString().split("T")[0],
311
+ limit,
312
+ };
313
+ }
314
+ return { valid: true };
315
+ }
316
+ export function getRequiredPlan(endpointPath) {
317
+ // TODO: Sync endpoint-to-plan mapping with actual CryptoQuant pricing data
318
+ // Plan hierarchy: basic < advanced < professional < premium < custom
319
+ if (!planLimitsState.limits)
320
+ return "professional";
321
+ const limit = getPlanLimit(endpointPath);
322
+ switch (limit) {
323
+ case null:
324
+ return "professional";
325
+ case "P0D":
326
+ case "P1D":
327
+ return "basic";
328
+ default:
329
+ return "professional";
330
+ }
331
+ }
332
+ export function getApiRateLimit() {
333
+ return planLimitsState.apiRateLimit;
334
+ }
335
+ export function getStaticEndpoints() {
336
+ return planLimitsState.statics;
337
+ }
338
+ export function resetPlanLimits() {
339
+ planLimitsState = { ...DEFAULT_STATE };
340
+ }
341
+ /**
342
+ * Load plan limits state from cached data (no API call).
343
+ */
344
+ export function loadPlanLimitsFromCache(limits, statics, apiRateLimit, plan) {
345
+ planLimitsState = {
346
+ loaded: true,
347
+ limits,
348
+ plan,
349
+ statics,
350
+ apiRateLimit,
351
+ fetched_at: Date.now(),
352
+ };
353
+ }
354
+ export function getAccessibleEndpointsSummary() {
355
+ const state = planLimitsState;
356
+ if (!state.loaded) {
357
+ return { count: 0 };
358
+ }
359
+ // For basic plan without limits data, no endpoints are accessible
360
+ if (state.plan === "basic" && !state.limits) {
361
+ return { count: 0, endpoints: [] };
362
+ }
363
+ let count = 0;
364
+ const endpoints = [];
365
+ if (state.limits) {
366
+ for (const asset of Object.keys(state.limits)) {
367
+ const categories = state.limits[asset];
368
+ if (!categories)
369
+ continue;
370
+ for (const category of Object.keys(categories)) {
371
+ const metrics = categories[category];
372
+ if (!metrics)
373
+ continue;
374
+ for (const metric of Object.keys(metrics)) {
375
+ const metricLimits = metrics[metric];
376
+ if (!metricLimits?.window)
377
+ continue;
378
+ count++;
379
+ // For basic/advanced plans, include detailed endpoint info
380
+ if (state.plan === "basic" || state.plan === "advanced") {
381
+ const dayLimit = metricLimits.window["day"] || Object.values(metricLimits.window)[0];
382
+ endpoints.push({
383
+ path: `/v1/${asset}/${category}/${metric}`,
384
+ date_limit: dayLimit,
385
+ });
386
+ }
387
+ }
388
+ }
389
+ }
390
+ }
391
+ // Include static endpoints in count
392
+ count += state.statics.length;
393
+ const result = { count };
394
+ // Only include endpoints list for basic/advanced plans
395
+ if ((state.plan === "basic" || state.plan === "advanced") && endpoints.length > 0) {
396
+ result.endpoints = endpoints;
397
+ }
398
+ return result;
399
+ }
400
+ //# sourceMappingURL=plan-limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-limits.js","sourceRoot":"","sources":["../src/plan-limits.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerAuthTools(server: McpServer): void;
3
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAuCpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiKzD"}
@@ -0,0 +1,157 @@
1
+ import { z } from "zod";
2
+ import { initializePermissions, resetPermissions, getDiscoverySummary, getPermissionState, clearDiscoveryCache, getDiscoveryCachePath, getCachedDiscovery, } from "../permissions.js";
3
+ import { getAssetCategoryMap } from "../discovery.js";
4
+ import { getStoredApiKey, clearCredentials, getCredentialsPath, updateValidatedAt, } from "../auth/storage.js";
5
+ import { startAuthServer, getAuthUrl } from "../auth/server.js";
6
+ import { getPlanLimitsState, getAccessibleEndpointsSummary } from "../plan-limits.js";
7
+ import { getApiUrl } from "../config.js";
8
+ import { jsonResponse, getPlanNote } from "../utils.js";
9
+ const initializeSchema = {
10
+ api_key: z.string().optional().describe("API key (optional if CRYPTOQUANT_API_KEY env var is set)"),
11
+ };
12
+ function resolveApiKey(paramKey) {
13
+ if (paramKey)
14
+ return paramKey;
15
+ const envKey = process.env.CRYPTOQUANT_API_KEY;
16
+ const isEnvKeyValid = envKey && envKey.trim() && !envKey.startsWith("${");
17
+ if (isEnvKeyValid)
18
+ return envKey;
19
+ return getStoredApiKey() ?? undefined;
20
+ }
21
+ export function registerAuthTools(server) {
22
+ server.tool("initialize", "Initialize CryptoQuant session. MUST be called first before any other CryptoQuant tools. Returns available assets (btc, eth, etc.), metric categories per asset (e.g., market-indicator, network-indicator), and your plan. Use the returned asset_categories to know which discover_endpoints() calls are valid.", initializeSchema, async (params) => {
23
+ let apiKey = resolveApiKey(params.api_key);
24
+ if (!apiKey) {
25
+ try {
26
+ apiKey = await startAuthServer();
27
+ updateValidatedAt();
28
+ }
29
+ catch (error) {
30
+ const errorMessage = error instanceof Error ? error.message : String(error);
31
+ return jsonResponse({
32
+ success: false,
33
+ error: `Browser authentication failed: ${errorMessage}`,
34
+ help: {
35
+ manual_url: getAuthUrl(),
36
+ get_api_key: "https://cryptoquant.com/settings/api",
37
+ alternative: "Or call initialize(api_key='your_key') directly",
38
+ },
39
+ });
40
+ }
41
+ }
42
+ const apiUrl = getApiUrl();
43
+ const result = await initializePermissions(apiKey, apiUrl);
44
+ if (!result.success) {
45
+ return jsonResponse({
46
+ success: false,
47
+ error: result.error,
48
+ help: {
49
+ check_key: "Check your API key at https://cryptoquant.com/dashboard/api",
50
+ browser_auth: "Or use start_browser_auth() to re-authenticate",
51
+ },
52
+ });
53
+ }
54
+ if (!params.api_key && !process.env.CRYPTOQUANT_API_KEY) {
55
+ updateValidatedAt();
56
+ }
57
+ const discovery = getDiscoverySummary();
58
+ const assetCategories = getAssetCategoryMap();
59
+ const permState = getPermissionState();
60
+ const planState = getPlanLimitsState();
61
+ const cachedDiscovery = getCachedDiscovery();
62
+ const accessibleSummary = getAccessibleEndpointsSummary();
63
+ // Build session info with cache status
64
+ const sessionInfo = {
65
+ plan: permState.plan,
66
+ cache_status: result.cache_status,
67
+ ...(planState.apiRateLimit && {
68
+ rate_limit: `${planState.apiRateLimit.token}/${planState.apiRateLimit.window}`,
69
+ }),
70
+ };
71
+ // Build scope info (compact summary)
72
+ const scopeInfo = {
73
+ total_endpoints: discovery?.total_endpoints || cachedDiscovery?.summary.total_endpoints || 0,
74
+ accessible: accessibleSummary.count,
75
+ note: "Use discover_endpoints(asset, category) for details",
76
+ };
77
+ // Add asset breakdown from cache summary if available
78
+ if (cachedDiscovery?.summary.assets) {
79
+ const assets = {};
80
+ for (const assetInfo of cachedDiscovery.summary.assets) {
81
+ assets[assetInfo.name] = {
82
+ endpoints: assetInfo.endpoint_count,
83
+ categories: assetInfo.categories.length,
84
+ };
85
+ }
86
+ scopeInfo.assets = assets;
87
+ }
88
+ else if (discovery) {
89
+ // Fallback to discovery data
90
+ const assets = {};
91
+ for (const assetInfo of discovery.assets) {
92
+ assets[assetInfo.name] = {
93
+ endpoints: assetInfo.count,
94
+ categories: assetCategories?.[assetInfo.name]?.length || 0,
95
+ };
96
+ }
97
+ scopeInfo.assets = assets;
98
+ }
99
+ const planInfo = {
100
+ plan: permState.plan,
101
+ plan_limits_loaded: planState.loaded,
102
+ accessible_endpoints: accessibleSummary.count,
103
+ // Only include endpoint details for basic/advanced plans (limited access)
104
+ ...(accessibleSummary.endpoints && { accessible_list: accessibleSummary.endpoints }),
105
+ fetched_at: planState.fetched_at ? new Date(planState.fetched_at).toISOString() : null,
106
+ note: getPlanNote(permState.plan),
107
+ };
108
+ return jsonResponse({
109
+ success: true,
110
+ session: sessionInfo,
111
+ scope: scopeInfo,
112
+ discovery: discovery
113
+ ? {
114
+ total_endpoints: discovery.total_endpoints,
115
+ assets: discovery.assets.map((a) => a.name),
116
+ categories: discovery.categories.map((c) => c.name),
117
+ asset_categories: assetCategories,
118
+ fetched_at: discovery.fetched_at,
119
+ }
120
+ : null,
121
+ plan_info: planInfo,
122
+ ...(result.discovery_error && { warning: `Discovery partial: ${result.discovery_error}` }),
123
+ });
124
+ });
125
+ server.tool("reset_session", "Clear session and optionally stored credentials. Use cases: (1) Switch accounts - clear_stored=true then initialize(), (2) API key expired - clear_stored=true then initialize(), (3) Refresh session - clear_stored=false. After clearing, initialize() will auto-open browser for new API key.", {
126
+ clear_stored: z
127
+ .boolean()
128
+ .optional()
129
+ .describe("If true, also clears stored credentials from ~/.cryptoquant/credentials"),
130
+ clear_cache: z
131
+ .boolean()
132
+ .optional()
133
+ .describe("If true, also clears discovery cache (forces fresh API fetch on next initialize)"),
134
+ }, async (params) => {
135
+ resetPermissions();
136
+ const apiUrl = getApiUrl();
137
+ const clearedItems = ["session"];
138
+ if (params.clear_stored) {
139
+ clearCredentials();
140
+ clearedItems.push("credentials");
141
+ }
142
+ if (params.clear_cache) {
143
+ clearDiscoveryCache(apiUrl);
144
+ clearedItems.push("discovery cache");
145
+ }
146
+ const message = clearedItems.length === 1
147
+ ? "Session cleared (credentials and cache preserved)"
148
+ : `Cleared: ${clearedItems.join(", ")}`;
149
+ return jsonResponse({
150
+ success: true,
151
+ message,
152
+ ...(params.clear_stored && { credentials_path: getCredentialsPath() }),
153
+ ...(params.clear_cache && { cache_path: getDiscoveryCachePath(apiUrl) }),
154
+ });
155
+ });
156
+ }
157
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerCoreTools(server: McpServer): void;
3
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/tools/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsGpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiVzD"}