@fundtracer/mcp 1.0.2 → 1.0.4

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 (2) hide show
  1. package/fundtracer-mcp.js +83 -17
  2. package/package.json +2 -1
package/fundtracer-mcp.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ #!/usr/bin/env node
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
5
  var __esm = (fn, res) => function __init() {
@@ -219,6 +220,31 @@ var init_tools = __esm({
219
220
  }
220
221
  });
221
222
 
223
+ // src/mcp/mcpLogger.ts
224
+ import { getFirestore } from "../firebase.js";
225
+ async function logMcpRequest(entry) {
226
+ try {
227
+ const db = getFirestore();
228
+ if (!db) {
229
+ console.warn("[MCP-LOGGER] getFirestore() returned null");
230
+ return;
231
+ }
232
+ await db.collection("mcpLogs").add(entry);
233
+ console.log("[MCP-LOGGER] Logged:", entry.toolName, "for user:", entry.userId, "status:", entry.status);
234
+ } catch (err2) {
235
+ mcpLogWarnings++;
236
+ if (mcpLogWarnings <= 3 || mcpLogWarnings % 10 === 0) {
237
+ console.error("[MCP-LOGGER] Failed to log MCP request:", err2?.message || err2);
238
+ }
239
+ }
240
+ }
241
+ var mcpLogWarnings;
242
+ var init_mcpLogger = __esm({
243
+ "src/mcp/mcpLogger.ts"() {
244
+ mcpLogWarnings = 0;
245
+ }
246
+ });
247
+
222
248
  // src/mcp/api-handlers.ts
223
249
  var api_handlers_exports = {};
224
250
  __export(api_handlers_exports, {
@@ -233,19 +259,59 @@ function err(message) {
233
259
  }
234
260
  function api() {
235
261
  const key = process.env.FUNDTRACER_MCP_API_KEY || "";
262
+ const headers = {
263
+ Authorization: `Bearer ${key}`,
264
+ "Content-Type": "application/json"
265
+ };
266
+ if (_mcpCtx?.userId) {
267
+ headers["X-MCP-UserId"] = _mcpCtx.userId;
268
+ }
236
269
  return axios.create({
237
270
  baseURL: API_BASE,
238
271
  timeout: 6e4,
239
- headers: {
240
- Authorization: `Bearer ${key}`,
241
- "Content-Type": "application/json"
242
- }
272
+ headers
243
273
  });
244
274
  }
245
- var API_BASE, analyzeWallet, traceFunds, compareWallets, analyzeContract, detectSybilClusters, getPortfolio, getTransactions, lookupEntity, getGasPrices, getTokenInfo, TOOL_HANDLERS;
275
+ function withLogging(toolName, handler) {
276
+ return async (args, ctx) => {
277
+ _mcpCtx = ctx;
278
+ const start = Date.now();
279
+ try {
280
+ const result = await handler(args, ctx);
281
+ logMcpRequest({
282
+ userId: ctx.userId,
283
+ toolName,
284
+ args: JSON.stringify(args).substring(0, 500),
285
+ status: result.isError ? "error" : "success",
286
+ responsePreview: JSON.stringify(result).substring(0, 300),
287
+ duration: Date.now() - start,
288
+ createdAt: Date.now(),
289
+ keyPrefix: ctx.apiKeyPrefix
290
+ });
291
+ return result;
292
+ } catch (error) {
293
+ logMcpRequest({
294
+ userId: ctx.userId,
295
+ toolName,
296
+ args: JSON.stringify(args).substring(0, 500),
297
+ status: "error",
298
+ responsePreview: error.message.substring(0, 300),
299
+ duration: Date.now() - start,
300
+ createdAt: Date.now(),
301
+ keyPrefix: ctx.apiKeyPrefix
302
+ });
303
+ throw error;
304
+ } finally {
305
+ _mcpCtx = null;
306
+ }
307
+ };
308
+ }
309
+ var API_BASE, _mcpCtx, analyzeWallet, traceFunds, compareWallets, analyzeContract, detectSybilClusters, getPortfolio, getTransactions, lookupEntity, getGasPrices, getTokenInfo, TOOL_HANDLERS;
246
310
  var init_api_handlers = __esm({
247
311
  "src/mcp/api-handlers.ts"() {
312
+ init_mcpLogger();
248
313
  API_BASE = process.env.FUNDTRACER_API_URL || "https://api.fundtracer.xyz";
314
+ _mcpCtx = null;
249
315
  analyzeWallet = async (args, ctx) => {
250
316
  const { address, chainId, transactionLimit } = args;
251
317
  try {
@@ -399,16 +465,16 @@ var init_api_handlers = __esm({
399
465
  }
400
466
  };
401
467
  TOOL_HANDLERS = {
402
- analyze_wallet: analyzeWallet,
403
- trace_funds: traceFunds,
404
- compare_wallets: compareWallets,
405
- analyze_contract: analyzeContract,
406
- detect_sybil_clusters: detectSybilClusters,
407
- get_portfolio: getPortfolio,
408
- get_transactions: getTransactions,
409
- lookup_entity: lookupEntity,
410
- get_gas_prices: getGasPrices,
411
- get_token_info: getTokenInfo
468
+ analyze_wallet: withLogging("analyze_wallet", analyzeWallet),
469
+ trace_funds: withLogging("trace_funds", traceFunds),
470
+ compare_wallets: withLogging("compare_wallets", compareWallets),
471
+ analyze_contract: withLogging("analyze_contract", analyzeContract),
472
+ detect_sybil_clusters: withLogging("detect_sybil_clusters", detectSybilClusters),
473
+ get_portfolio: withLogging("get_portfolio", getPortfolio),
474
+ get_transactions: withLogging("get_transactions", getTransactions),
475
+ lookup_entity: withLogging("lookup_entity", lookupEntity),
476
+ get_gas_prices: withLogging("get_gas_prices", getGasPrices),
477
+ get_token_info: withLogging("get_token_info", getTokenInfo)
412
478
  };
413
479
  }
414
480
  });
@@ -430,8 +496,8 @@ async function validateMcpApiKey(rawKey) {
430
496
  return validateViaHttp(rawKey);
431
497
  }
432
498
  async function validateWithFirestore(rawKey) {
433
- const { getFirestore } = await import("../firebase.js");
434
- const db = getFirestore();
499
+ const { getFirestore: getFirestore2 } = await import("../firebase.js");
500
+ const db = getFirestore2();
435
501
  if (!db) return null;
436
502
  const keyDoc = await db.collection("apiKeys").doc(rawKey).get();
437
503
  if (keyDoc.exists) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fundtracer/mcp",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "FundTracer MCP Server — blockchain analysis for AI assistants (Claude Desktop, Claude Code, Cursor, etc.)",
5
5
  "type": "module",
6
6
  "main": "fundtracer-mcp.js",
@@ -12,6 +12,7 @@
12
12
  "package.json"
13
13
  ],
14
14
  "dependencies": {
15
+ "@cfworker/json-schema": "^4.1.1",
15
16
  "@modelcontextprotocol/server": "^2.0.0-alpha.2",
16
17
  "axios": "^1.7.0",
17
18
  "dotenv": "^16.3.1",