{"version":3,"file":"mcp2.mjs","names":[],"sources":["../../src/mcp.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { UnsupportedOperationError } from \"./core/errors.js\";\nimport { resolveAddresses, resolveInput } from \"./core/input.js\";\nimport type { Provider } from \"./core/provider.js\";\nimport { listProviders } from \"./core/registry.js\";\nimport { withProvider } from \"./core/resolve.js\";\nimport type { ProviderContext } from \"./core/resolve.js\";\nimport { clampMaxResults, normalizeChain } from \"./core/types.js\";\nimport type { ContractInfo, ProviderCapabilities, Transaction } from \"./core/types.js\";\nimport { version } from \"./version.js\";\n\nconst providerInput = {\n  chain: z.string().trim().min(1).optional().describe(\"Chain name or alias\"),\n  provider: z.string().trim().min(1).optional().describe(\"Explorer provider key\"),\n};\nconst rawInput = {\n  raw: z\n    .boolean()\n    .optional()\n    .describe(\n      \"Include the provider's own transaction record as raw, for fields the normalized shape leaves out, such as every input and output of a Bitcoin transaction. Defaults to false.\",\n    ),\n};\n/** Holdings one tokens call lists unless asked for more; a busy wallet holds thousands. */\nconst TOKEN_HOLDINGS_LIMIT = 50;\nconst contractPayloadInput = {\n  abi: z\n    .boolean()\n    .optional()\n    .describe(\"Include the ABI of a verified contract as a JSON string. Defaults to false.\"),\n  sourceCode: z\n    .boolean()\n    .optional()\n    .describe(\"Include the source code of a verified contract. Defaults to false.\"),\n};\ntype ProviderOperation =\n  | \"getBalance\"\n  | \"getTxHistory\"\n  | \"getTxDetail\"\n  | \"getUtxos\"\n  | \"getContractInfo\"\n  | \"getTokenBalances\"\n  | \"getTokenTransfers\"\n  | \"getGasData\"\n  | \"getBlockInfo\";\nconst OPERATION_CAPABILITIES = {\n  getBalance: \"balances\",\n  getTxHistory: \"txHistory\",\n  getTxDetail: \"txDetail\",\n  getUtxos: \"utxos\",\n  getContractInfo: \"contractInfo\",\n  getTokenBalances: \"tokenBalances\",\n  getTokenTransfers: \"tokenTransfers\",\n  getGasData: \"gasData\",\n  getBlockInfo: \"blockInfo\",\n} as const satisfies Record<ProviderOperation, keyof ProviderCapabilities>;\n\nfunction withSelectedProvider<T>(\n  providerName: string | undefined,\n  chainName: string | undefined,\n  operation: ProviderOperation,\n  /* oxlint-disable-next-line typescript/prefer-readonly-parameter-types */\n  run: (selected: ProviderContext) => Promise<T>,\n): Promise<T> {\n  const requestedChain = chainName === undefined ? undefined : normalizeChain(chainName);\n  return withProvider(providerName, requestedChain, run, OPERATION_CAPABILITIES[operation]);\n}\n\nfunction result(value: unknown): CallToolResult {\n  return {\n    content: [{ type: \"text\", text: JSON.stringify(value, null, 2) }],\n  };\n}\n\nfunction providerResult(provider: string, value: unknown): CallToolResult {\n  return result({ provider, data: value });\n}\n\n/* The provider's record dwarfs the normalized fields, so it travels only when asked for. */\n/* oxlint-disable-next-line typescript/prefer-readonly-parameter-types */\nfunction trimTransaction(transaction: Transaction, keepRaw = false): Transaction {\n  if (keepRaw) return transaction;\n  const { raw: _raw, ...trimmed } = transaction;\n  return trimmed;\n}\n\n/* ABI and source run to tens of kilobytes; a caller after verification or proxy status skips them. */\nfunction trimContract(\n  info: Readonly<ContractInfo>,\n  requested: Readonly<{ abi?: boolean; sourceCode?: boolean }>,\n): ContractInfo {\n  const { abi, sourceCode, ...trimmed } = info;\n  const contract: ContractInfo = trimmed;\n  if (requested.abi) contract.abi = abi;\n  if (requested.sourceCode) contract.sourceCode = sourceCode;\n  return contract;\n}\n\nasync function addressForChain(address: string, chain: Parameters<typeof resolveInput>[1]) {\n  return (await resolveInput(address, chain)).address;\n}\n\nfunction requireOperation<K extends ProviderOperation>(\n  /* oxlint-disable-next-line typescript/prefer-readonly-parameter-types */\n  provider: Provider,\n  operation: K,\n): NonNullable<Provider[K]> {\n  const method = provider[operation];\n  if (!provider.capabilities[OPERATION_CAPABILITIES[operation]] || typeof method !== \"function\") {\n    throw new UnsupportedOperationError(operation, provider.name);\n  }\n  return method.bind(provider) as NonNullable<Provider[K]>;\n}\n\n/**\n * Create an MCP server exposing the normalized explorer operations.\n *\n * @returns {McpServer} The resulting value.\n */\nexport function createMcpServer(): McpServer {\n  const server = new McpServer({ name: \"explorers\", version });\n\n  server.registerTool(\n    \"explorers_providers\",\n    {\n      description:\n        \"List registered block explorer providers with the chains they serve, their capabilities, and their public endpoints\",\n      annotations: { readOnlyHint: true },\n    },\n    () => result(listProviders()),\n  );\n\n  server.registerTool(\n    \"explorers_balance\",\n    {\n      description: \"Get the native-token balance for one or more blockchain addresses or ENS names\",\n      inputSchema: {\n        address: z\n          .union([z.string().trim().min(1), z.array(z.string().trim().min(1)).min(1).max(20)])\n          .describe(\"Blockchain address or ENS name, or a list of them\"),\n        ...providerInput,\n      },\n      annotations: { readOnlyHint: true },\n    },\n    async ({ address, chain, provider }) => {\n      const requestedChain = chain === undefined ? undefined : normalizeChain(chain);\n      return withProvider(\n        provider,\n        requestedChain,\n        async (selected) => {\n          const resolvedAddresses = await resolveAddresses(address, selected.chain);\n          const getBalance = requireOperation(selected.provider, \"getBalance\");\n          const balances = await Promise.all(\n            resolvedAddresses.map((resolvedAddress) => getBalance(resolvedAddress, selected.chain)),\n          );\n          return providerResult(\n            selected.name,\n            typeof address === \"string\" ? balances[0] : balances,\n          );\n        },\n        \"balances\",\n      );\n    },\n  );\n\n  server.registerTool(\n    \"explorers_tx_history\",\n    {\n      description: \"List normalized transactions involving a blockchain address\",\n      inputSchema: {\n        address: z.string().min(1),\n        ...providerInput,\n        startBlock: z.number().int().nonnegative().optional(),\n        endBlock: z.number().int().nonnegative().optional(),\n        sort: z.enum([\"asc\", \"desc\"]).optional(),\n        limit: z.number().int().positive().max(100).optional(),\n        page: z.number().int().positive().optional(),\n        ...rawInput,\n      },\n      annotations: { readOnlyHint: true },\n    },\n    async ({ address, chain, provider, raw, ...options }) =>\n      withSelectedProvider(provider, chain, \"getTxHistory\", async (selected) => {\n        const resolvedAddress = await addressForChain(address, selected.chain);\n        const getTxHistory = requireOperation(selected.provider, \"getTxHistory\");\n        const transactions = await getTxHistory(resolvedAddress, selected.chain, options);\n        return providerResult(\n          selected.name,\n          transactions.map((transaction) => trimTransaction(transaction, raw)),\n        );\n      }),\n  );\n\n  server.registerTool(\n    \"explorers_tx_detail\",\n    {\n      description:\n        \"Get one normalized transaction by hash, with OP_RETURN messages when the provider is mempool\",\n      inputSchema: { hash: z.string().min(1), ...providerInput, ...rawInput },\n      annotations: { readOnlyHint: true },\n    },\n    async ({ hash, chain, provider, raw }) =>\n      withSelectedProvider(provider, chain, \"getTxDetail\", async (selected) => {\n        const getTxDetail = requireOperation(selected.provider, \"getTxDetail\");\n        return providerResult(\n          selected.name,\n          trimTransaction(await getTxDetail(hash, selected.chain), raw),\n        );\n      }),\n  );\n\n  server.registerTool(\n    \"explorers_utxos\",\n    {\n      description:\n        \"List the unspent outputs a Bitcoin-like address still controls, each as txid and vout with its value in base units and confirmation state\",\n      inputSchema: { address: z.string().min(1), ...providerInput },\n      annotations: { readOnlyHint: true },\n    },\n    async ({ address, chain, provider }) =>\n      withSelectedProvider(provider, chain, \"getUtxos\", async (selected) => {\n        const resolvedAddress = await addressForChain(address, selected.chain);\n        const getUtxos = requireOperation(selected.provider, \"getUtxos\");\n        return providerResult(selected.name, await getUtxos(resolvedAddress, selected.chain));\n      }),\n  );\n\n  server.registerTool(\n    \"explorers_contract\",\n    {\n      description:\n        \"Get verification, compiler, creator, proxy and token metadata for a contract, plus its ABI and source on request\",\n      inputSchema: { address: z.string().min(1), ...providerInput, ...contractPayloadInput },\n      annotations: { readOnlyHint: true },\n    },\n    async ({ address, chain, provider, ...requested }) =>\n      withSelectedProvider(provider, chain, \"getContractInfo\", async (selected) => {\n        const getContractInfo = requireOperation(selected.provider, \"getContractInfo\");\n        const resolvedAddress = await addressForChain(address, selected.chain);\n        return providerResult(\n          selected.name,\n          trimContract(await getContractInfo(resolvedAddress, selected.chain), requested),\n        );\n      }),\n  );\n\n  server.registerTool(\n    \"explorers_tokens\",\n    {\n      description:\n        \"List token holdings for a blockchain address: the first 50 in the explorer's order unless limit says otherwise; total counts every holding the list was cut from. Zero balances are dropped unless nonZeroOnly is false.\",\n      inputSchema: {\n        address: z.string().min(1),\n        ...providerInput,\n        nonZeroOnly: z\n          .boolean()\n          .optional()\n          .default(true)\n          .describe(\"Drop holdings whose balance is zero. Defaults to true.\"),\n        limit: z\n          .number()\n          .int()\n          .positive()\n          .max(100)\n          .optional()\n          .default(TOKEN_HOLDINGS_LIMIT)\n          .describe(\n            \"Holdings to list, at most 100; total still counts every holding. Defaults to 50.\",\n          ),\n      },\n      annotations: { readOnlyHint: true },\n    },\n    async ({ address, chain, provider, nonZeroOnly, limit }) =>\n      withSelectedProvider(provider, chain, \"getTokenBalances\", async (selected) => {\n        const resolvedAddress = await addressForChain(address, selected.chain);\n        const getTokenBalances = requireOperation(selected.provider, \"getTokenBalances\");\n        const holdings = await getTokenBalances(resolvedAddress, selected.chain, {\n          nonZeroOnly: nonZeroOnly ?? true,\n        });\n        return result({\n          provider: selected.name,\n          total: holdings.length,\n          data: holdings.slice(0, clampMaxResults(limit ?? TOKEN_HOLDINGS_LIMIT)),\n        });\n      }),\n  );\n\n  server.registerTool(\n    \"explorers_token_transfers\",\n    {\n      description:\n        \"List fungible-token transfers involving a blockchain address, including transfers sent to it by third parties that never show up in its native transaction history\",\n      inputSchema: {\n        address: z.string().min(1),\n        ...providerInput,\n        token: z\n          .string()\n          .trim()\n          .min(1)\n          .optional()\n          .describe(\"Only transfers of this token contract\"),\n        startBlock: z.number().int().nonnegative().optional(),\n        endBlock: z.number().int().nonnegative().optional(),\n        sort: z.enum([\"asc\", \"desc\"]).optional(),\n        limit: z.number().int().positive().max(100).optional(),\n        page: z.number().int().positive().optional(),\n      },\n      annotations: { readOnlyHint: true },\n    },\n    async ({ address, chain, provider, ...options }) =>\n      withSelectedProvider(provider, chain, \"getTokenTransfers\", async (selected) => {\n        const resolvedAddress = await addressForChain(address, selected.chain);\n        const getTokenTransfers = requireOperation(selected.provider, \"getTokenTransfers\");\n        return providerResult(\n          selected.name,\n          await getTokenTransfers(resolvedAddress, selected.chain, options),\n        );\n      }),\n  );\n\n  server.registerTool(\n    \"explorers_gas\",\n    {\n      description: \"Get current gas or fee-market suggestions\",\n      inputSchema: providerInput,\n      annotations: { readOnlyHint: true },\n    },\n    async ({ chain, provider }) =>\n      withSelectedProvider(provider, chain, \"getGasData\", async (selected) => {\n        const getGasData = requireOperation(selected.provider, \"getGasData\");\n        return providerResult(selected.name, await getGasData(selected.chain));\n      }),\n  );\n\n  server.registerTool(\n    \"explorers_block\",\n    {\n      description: \"Get normalized block information by block number\",\n      inputSchema: {\n        blockNumber: z.number().int().nonnegative(),\n        ...providerInput,\n      },\n      annotations: { readOnlyHint: true },\n    },\n    async ({ blockNumber, chain, provider }) =>\n      withSelectedProvider(provider, chain, \"getBlockInfo\", async (selected) => {\n        const getBlockInfo = requireOperation(selected.provider, \"getBlockInfo\");\n        return providerResult(selected.name, await getBlockInfo(blockNumber, selected.chain));\n      }),\n  );\n\n  return server;\n}\n"],"mappings":"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"}