bsv-mcp 0.0.36 → 0.2.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 (78) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +233 -4
  3. package/dist/index.js +120082 -54669
  4. package/index.ts +1196 -88
  5. package/next-env.d.ts +6 -0
  6. package/package.json +58 -15
  7. package/prompts/bsvSdk/index.ts +5 -5
  8. package/prompts/bsvSdk/transaction.ts +2 -2
  9. package/prompts/bsvSdk/wallet.ts +1 -1
  10. package/prompts/index.ts +1 -1
  11. package/resources/bitcom.ts +132 -0
  12. package/resources/resources.ts +7 -3
  13. package/smithery.yaml +3 -0
  14. package/test-mcp-server.ts +157 -0
  15. package/tools/a2b/discover.ts +13 -13
  16. package/tools/bap/friend.ts +266 -0
  17. package/tools/bap/generate.test.ts +350 -0
  18. package/tools/bap/generate.ts +431 -0
  19. package/tools/bap/getCurrentAddress.ts +69 -0
  20. package/tools/bap/getId.test.ts +121 -0
  21. package/tools/bap/getId.ts +169 -0
  22. package/tools/bap/index.ts +111 -0
  23. package/tools/bap/types.ts +66 -0
  24. package/tools/bap/utils.ts +33 -0
  25. package/tools/bsocial/bmapFollow.ts +121 -0
  26. package/tools/bsocial/bmapLikes.ts +111 -0
  27. package/tools/bsocial/bmapReadPosts.ts +148 -0
  28. package/tools/bsocial/createPost.ts +136 -0
  29. package/tools/bsocial/index.ts +45 -0
  30. package/tools/bsocial/readPosts.ts +255 -0
  31. package/tools/bsv/decodeTransaction.ts +7 -6
  32. package/tools/bsv/explore.ts +2 -3
  33. package/tools/bsv/getPrice.ts +1 -9
  34. package/tools/bsv/token.ts +14 -26
  35. package/tools/constants.ts +21 -0
  36. package/tools/index.ts +91 -18
  37. package/tools/mnee/getBalance.ts +2 -4
  38. package/tools/mnee/index.ts +8 -0
  39. package/tools/mnee/parseTx.ts +4 -4
  40. package/tools/mnee/sendMnee.ts +6 -6
  41. package/tools/ordinals/getInscription.ts +2 -3
  42. package/tools/ordinals/getTokenByIdOrTicker.ts +6 -3
  43. package/tools/ordinals/marketListings.ts +2 -18
  44. package/tools/ordinals/marketSales.ts +2 -4
  45. package/tools/ordinals/searchInscriptions.ts +2 -4
  46. package/tools/utils/aip.ts +46 -0
  47. package/tools/utils/conversion.ts +1 -0
  48. package/tools/utils/errorHandler.ts +76 -0
  49. package/tools/utils/index.ts +56 -14
  50. package/tools/utils/installAgentMaster.ts +84 -0
  51. package/tools/utils/logger.ts +20 -0
  52. package/tools/utils/toolConfig.ts +80 -0
  53. package/tools/utils/toolRegistration.ts +66 -0
  54. package/tools/utils/transactionBuilder.ts +196 -0
  55. package/tools/wallet/a2bPublishAgent.ts +25 -30
  56. package/tools/wallet/a2bPublishMcp.ts +43 -44
  57. package/tools/wallet/createOrdinals.ts +13 -20
  58. package/tools/wallet/fetchPaymentUtxos.ts +48 -39
  59. package/tools/wallet/gatherCollectionInfo.ts +370 -0
  60. package/tools/wallet/getAddress.ts +14 -30
  61. package/tools/wallet/getBalance.ts +54 -0
  62. package/tools/wallet/getBalanceDroplet.ts +48 -0
  63. package/tools/wallet/getPublicKey.ts +3 -16
  64. package/tools/wallet/integratedWallet.ts +120 -0
  65. package/tools/wallet/mintCollection.ts +373 -0
  66. package/tools/wallet/purchaseListing.ts +21 -31
  67. package/tools/wallet/refreshUtxos.ts +2 -14
  68. package/tools/wallet/schemas.ts +18 -249
  69. package/tools/wallet/sendOrdinals.ts +14 -21
  70. package/tools/wallet/sendToAddress.ts +2 -18
  71. package/tools/wallet/setupDroplet.ts +161 -0
  72. package/tools/wallet/tools.ts +55 -210
  73. package/tools/wallet/transactionHelper.ts +121 -0
  74. package/tools/wallet/transferOrdToken.ts +19 -24
  75. package/tools/wallet/utxo.ts +62 -0
  76. package/tools/wallet/wallet.ts +237 -234
  77. package/vite.config.ts +15 -0
  78. package/tools/a2b/call.ts +0 -32
package/next-env.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+ import "./.next/types/routes.d.ts";
4
+
5
+ // NOTE: This file should not be edited
6
+ // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "bsv-mcp",
3
3
  "module": "dist/index.js",
4
4
  "type": "module",
5
- "version": "0.0.36",
5
+ "version": "0.2.7",
6
6
  "license": "MIT",
7
7
  "author": "satchmo",
8
8
  "description": "A collection of Bitcoin SV (BSV) tools for the Model Context Protocol (MCP) framework",
@@ -41,26 +41,69 @@
41
41
  },
42
42
  "private": false,
43
43
  "devDependencies": {
44
- "@biomejs/biome": "^1.9.4",
45
- "@types/bun": "latest"
44
+ "@biomejs/biome": "^2.4.6",
45
+ "@radix-ui/react-dialog": "^1.1.15",
46
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
47
+ "@radix-ui/react-label": "^2.1.8",
48
+ "@radix-ui/react-separator": "^1.1.8",
49
+ "@radix-ui/react-slot": "^1.2.4",
50
+ "@radix-ui/react-tabs": "^1.1.13",
51
+ "@radix-ui/react-toast": "^1.2.15",
52
+ "@radix-ui/react-tooltip": "^1.2.8",
53
+ "@radix-ui/themes": "^3.3.0",
54
+ "@tailwindcss/postcss": "^4.2.1",
55
+ "@tanstack/react-query": "^5.90.21",
56
+ "@types/bun": "^1.3.10",
57
+ "@types/node": "^25.3.5",
58
+ "@types/react": "^19.2.14",
59
+ "@types/react-dom": "^19.2.3",
60
+ "autoprefixer": "^10.4.27",
61
+ "bun": "^1.3.10",
62
+ "class-variance-authority": "^0.7.1",
63
+ "clsx": "^2.1.1",
64
+ "lucide-react": "0.577.0",
65
+ "next": "^16.1.6",
66
+ "next-themes": "^0.4.6",
67
+ "postcss": "^8.5.8",
68
+ "react": "^19.2.4",
69
+ "react-dom": "^19.2.4",
70
+ "sonner": "^2.0.7",
71
+ "tailwind-merge": "^3.5.0",
72
+ "tailwindcss": "^4.2.1",
73
+ "tailwindcss-animate": "^1.0.7",
74
+ "vite": "^7.3.1",
75
+ "vite-plugin-singlefile": "^2.3.0"
46
76
  },
47
77
  "peerDependencies": {
48
- "typescript": "^5.8.3"
78
+ "typescript": "^5.9.3"
49
79
  },
50
80
  "dependencies": {
51
- "@bsv/sdk": "^1.4.20",
52
- "@modelcontextprotocol/sdk": "^1.10.2",
53
- "@types/node": "^22.15.2",
54
- "bun": "^1.2.10",
55
- "js-1sat-ord": "^0.1.81",
56
- "mnee": "^2.0.0",
57
- "satoshi-token": "^0.0.4",
58
- "sigma-protocol": "^0.1.6",
59
- "zod": "^3.24.3"
81
+ "@bsv/sdk": "^2.0.6",
82
+ "@modelcontextprotocol/ext-apps": "^1.2.0",
83
+ "@modelcontextprotocol/sdk": "^1.27.1",
84
+ "bitcoin-auth": "^0.0.7",
85
+ "bitcoin-backup": "0.0.7",
86
+ "bmap-api-types": "0.0.9",
87
+ "bsv-bap": "0.1.23",
88
+ "jose": "^6.2.0",
89
+ "js-1sat-ord": "^0.1.91",
90
+ "mcp-handler": "^1.0.7",
91
+ "mnee": "^3.1.0",
92
+ "satoshi-token": "^0.0.7",
93
+ "schema-dts": "^1.1.5",
94
+ "sigma-protocol": "^0.1.9",
95
+ "zod": "^4.3.6"
60
96
  },
61
97
  "scripts": {
62
- "build": "bun build ./index.ts --outdir ./dist --target node",
98
+ "build": "bun run ./scripts/build.ts",
99
+ "build:view": "vite build",
100
+ "build:all": "bun run build:view && bun run build",
101
+ "dev": "next dev",
102
+ "build:next": "next build",
103
+ "start:next": "next start",
63
104
  "lint": "biome check .",
64
- "lint:fix": "biome check . --write"
105
+ "lint:fix": "biome check . --write",
106
+ "deploy": "vercel --prod",
107
+ "deploy:preview": "vercel"
65
108
  }
66
109
  }
@@ -24,11 +24,11 @@ export function registerAllBsvSdkPrompts(server: McpServer): void {
24
24
  registerPrimitivesPrompt(server);
25
25
  }
26
26
 
27
- // Export all prompts
28
- export { registerOverviewPrompt } from "./overview";
29
- export { registerWalletPrompt } from "./wallet";
30
- export { registerTransactionPrompt } from "./transaction";
31
27
  export { registerAuthPrompt } from "./auth";
32
28
  export { registerCryptographyPrompt } from "./cryptography";
33
- export { registerScriptPrompt } from "./script";
29
+ // Export all prompts
30
+ export { registerOverviewPrompt } from "./overview";
34
31
  export { registerPrimitivesPrompt } from "./primitives";
32
+ export { registerScriptPrompt } from "./script";
33
+ export { registerTransactionPrompt } from "./transaction";
34
+ export { registerWalletPrompt } from "./wallet";
@@ -69,7 +69,7 @@ tx.addOutput({
69
69
  });
70
70
 
71
71
  // Add a data (OP_RETURN) output
72
- const dataScript = LockingScript.fromData(Buffer.from("Hello, Bitcoin!"));
72
+ const dataScript = LockingScript.fromData(Utils.toArray("Hello, Bitcoin!", "utf8"));
73
73
  tx.addOutput({
74
74
  lockingScript: dataScript,
75
75
  satoshis: 0 // OP_RETURN outputs typically have 0 value
@@ -205,7 +205,7 @@ import { Script, OpCodes } from "@bsv/sdk";
205
205
  const customScript = new Script();
206
206
  customScript.add(OpCodes.OP_DUP);
207
207
  customScript.add(OpCodes.OP_HASH160);
208
- customScript.add(Buffer.from("public_key_hash", "hex"));
208
+ customScript.add(Utils.toArray("public_key_hash", "hex"));
209
209
  customScript.add(OpCodes.OP_EQUALVERIFY);
210
210
  customScript.add(OpCodes.OP_CHECKSIG);
211
211
 
@@ -54,7 +54,7 @@ const privateKey = PrivateKey.fromRandom();
54
54
  const importedKey = PrivateKey.fromWif("your-wif-string");
55
55
 
56
56
  // Generate from a seed
57
- const seedKey = PrivateKey.fromSeed(Buffer.from("your-seed-data"));
57
+ const seedKey = PrivateKey.fromSeed(Utils.toArray("your-seed-data", "utf8"));
58
58
 
59
59
  // Get the corresponding public key
60
60
  const publicKey = privateKey.toPublicKey();
package/prompts/index.ts CHANGED
@@ -16,8 +16,8 @@ export function registerAllPrompts(server: McpServer): void {
16
16
  // Add more prompts registration here as needed
17
17
  }
18
18
 
19
+ export * from "./bsvSdk";
19
20
  /**
20
21
  * Export all prompt constants
21
22
  */
22
23
  export * from "./ordinals";
23
- export * from "./bsvSdk";
@@ -0,0 +1,132 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+
4
+ // Store protocol documentation
5
+ // Source AIP: https://raw.githubusercontent.com/b-open-io/AIP/refs/heads/main/README.md
6
+ // Source MAP: https://raw.githubusercontent.com/rohenaz/MAP/refs/heads/master/README.md
7
+ // Source SIGMA: User provided text
8
+ const bitcomProtocols = {
9
+ AIP: {
10
+ name: "Author Identity Protocol (AIP)",
11
+ prefix: "15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva",
12
+ description:
13
+ "A simple and flexible method to sign arbitrary OP_RETURN data with Bitcoin ECDSA signatures, decoupling the signing address from the funding source.",
14
+ structure: `
15
+ OP_RETURN
16
+ [Data]
17
+ [Media Type]
18
+ [Encoding]
19
+ [Filename]
20
+ |
21
+ 15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva (AIP Prefix)
22
+ [Signing Algorithm] (e.g., BITCOIN_ECDSA)
23
+ [Signing Address]
24
+ [Signature] (Base64 Encoded)
25
+ [Field Index 0] (Optional, 0 = OP_RETURN 0x6a)
26
+ [Field Index 1] (Optional)
27
+ ... (If indexes are omitted, all fields left of '|' are signed)
28
+ `,
29
+ reference:
30
+ "https://raw.githubusercontent.com/b-open-io/AIP/refs/heads/main/README.md",
31
+ },
32
+ MAP: {
33
+ name: "Magic Attribute Protocol (MAP)",
34
+ prefix: "1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5",
35
+ description:
36
+ "A simple protocol for associating data in a single transaction by defining key-value pairs, often used for mapping content (like B:// protocol data) to identifiers or actions.",
37
+ structure: `
38
+ OP_RETURN
39
+ ... (Optional Input Data Protocol, e.g., B://)
40
+ |
41
+ 1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5 (MAP Prefix)
42
+ 'SET'
43
+ [Key 1] (UTF8 String)
44
+ [Value 1] (UTF8 String)
45
+ [Key 2] (Optional UTF8 String)
46
+ [Value 2] (Optional UTF8 String)
47
+ ...
48
+ `,
49
+ notes:
50
+ "Can be used standalone or chained after other protocols (like B). Keys can represent attributes (url, type, coordinates.lat) or actions (like, follow.user).",
51
+ reference:
52
+ "https://raw.githubusercontent.com/rohenaz/MAP/refs/heads/master/README.md",
53
+ },
54
+ SIGMA: {
55
+ name: "Sigma Protocol",
56
+ prefix: "SIGMA", // As per user text, though often represented by a Bitcom address
57
+ description:
58
+ "Enhances transaction security by signing custom output scripts, incorporating input txid and output data hashes to mitigate replay attacks.",
59
+ structure: `
60
+ <locking script>
61
+ OP_RETURN
62
+ [Additional Data] (Optional)
63
+ | (Optional Separator)
64
+ SIGMA (Protocol Identifier)
65
+ [Signing Algorithm] (e.g., ECDSA)
66
+ [Signing Address]
67
+ [Signature] (Base64 Encoded in lib, Hex in script)
68
+ [VIN] (Index of input whose txid is included in signature, -1 for corresponding input)
69
+ `,
70
+ reference: "User provided text (Abstract/Introduction)",
71
+ },
72
+ // BAP could be added here if spec is provided
73
+ } as const; // Use 'as const' for stricter type inference
74
+
75
+ type ProtocolName = keyof typeof bitcomProtocols;
76
+
77
+ // Define the MCP resource
78
+ const bitcomResourceTemplate = new ResourceTemplate(
79
+ "bitcom://protocol/{protocolName}",
80
+ { list: undefined }, // Required options object with list: undefined
81
+ );
82
+
83
+ /**
84
+ * Register the Bitcom protocol documentation resource
85
+ * @param server McpServer instance
86
+ */
87
+ export function registerBitcomResource(server: McpServer): void {
88
+ server.resource(
89
+ "bitcom_protocol",
90
+ bitcomResourceTemplate,
91
+ async (uri, params) => {
92
+ const protocolName = params.protocolName as ProtocolName;
93
+
94
+ if (!protocolName || !(protocolName in bitcomProtocols)) {
95
+ const available = Object.keys(bitcomProtocols).join(", ");
96
+ return {
97
+ code: -32602, // Invalid params
98
+ message: `Invalid or missing protocol name. Available: ${available}`,
99
+ contents: [],
100
+ };
101
+ }
102
+
103
+ const proto = bitcomProtocols[protocolName];
104
+ const notesString =
105
+ "notes" in proto && proto.notes ? `\\nNotes:\\n${proto.notes}\\n` : "";
106
+
107
+ const textContent = `
108
+ Protocol: ${proto.name}
109
+ Prefix: ${proto.prefix || "N/A"}
110
+ Reference: ${proto.reference}
111
+
112
+ Description:
113
+ ${proto.description}
114
+
115
+ Structure:
116
+ \`\`\`
117
+ ${proto.structure.trim()}
118
+ \`\`\`
119
+ ${notesString} `.trim();
120
+
121
+ return {
122
+ contents: [
123
+ {
124
+ uri: uri.href,
125
+ text: textContent,
126
+ mimeType: "text/plain",
127
+ },
128
+ ],
129
+ };
130
+ },
131
+ );
132
+ }
@@ -1,7 +1,8 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { registerBRCsResources } from "./brcs";
3
- import { registerChangelogResource } from "./changelog";
4
- import { registerJungleBusResource } from "./junglebus";
2
+ import { registerBitcomResource } from "./bitcom.js";
3
+ import { registerBRCsResources } from "./brcs.js";
4
+ import { registerChangelogResource } from "./changelog.js";
5
+ import { registerJungleBusResource } from "./junglebus.js";
5
6
 
6
7
  /**
7
8
  * Register all resources with the MCP server
@@ -17,5 +18,8 @@ export function registerResources(server: McpServer): void {
17
18
  // Register JungleBus API documentation resource
18
19
  registerJungleBusResource(server);
19
20
 
21
+ // Register Bitcom resource
22
+ registerBitcomResource(server);
23
+
20
24
  // Add more resource categories here as needed
21
25
  }
package/smithery.yaml CHANGED
@@ -55,6 +55,9 @@ startCommand:
55
55
  (config) => {
56
56
  const env = {};
57
57
 
58
+ // Set stdio transport for MCP
59
+ env.TRANSPORT = 'stdio';
60
+
58
61
  // Add private key if provided
59
62
  if (config.privateKeyWif) {
60
63
  env.PRIVATE_KEY_WIF = config.privateKeyWif;
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env bun
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
+
5
+ async function testMCPServer() {
6
+ console.log("🧪 Testing BSV MCP Server...\n");
7
+
8
+ // Create transport
9
+ const transport = new StdioClientTransport({
10
+ command: "bun",
11
+ args: ["run", "./index.ts"],
12
+ env: {
13
+ ...process.env,
14
+ TRANSPORT: "stdio",
15
+ DISABLE_BROADCASTING: "true", // Don't broadcast test transactions
16
+ USE_DROPLET_API: "false", // Use local mode to test BSocial
17
+ },
18
+ });
19
+
20
+ // Create client
21
+ const client = new Client(
22
+ { name: "test-client", version: "1.0.0" },
23
+ {
24
+ capabilities: {},
25
+ },
26
+ );
27
+
28
+ try {
29
+ // Connect
30
+ console.log("📡 Connecting to server...");
31
+ await client.connect(transport);
32
+ console.log("✅ Connected successfully\n");
33
+
34
+ // List available tools
35
+ console.log("🔧 Available tools:");
36
+ const tools = await client.listTools();
37
+ console.log(`Found ${tools.tools.length} tools:`);
38
+
39
+ // Group tools by category
40
+ const categories = new Map<string, string[]>();
41
+ for (const tool of tools.tools) {
42
+ const prefix = tool.name.split("_")[0];
43
+ if (!categories.has(prefix)) {
44
+ categories.set(prefix, []);
45
+ }
46
+ const categoryTools = categories.get(prefix);
47
+ if (categoryTools) {
48
+ categoryTools.push(tool.name);
49
+ }
50
+ }
51
+
52
+ // Display by category
53
+ for (const [category, toolNames] of categories) {
54
+ console.log(`\n${category}:`);
55
+ for (const name of toolNames) {
56
+ console.log(` - ${name}`);
57
+ }
58
+ }
59
+
60
+ // Test a few tools
61
+ console.log("\n🧪 Testing tools:\n");
62
+
63
+ // 1. Test BSV price tool
64
+ console.log("1. Testing bsv_getPrice:");
65
+ try {
66
+ const priceResult = await client.callTool({
67
+ name: "bsv_getPrice",
68
+ arguments: {},
69
+ });
70
+ const content = priceResult.content[0] as { text: string };
71
+ console.log("✅", content.text);
72
+ } catch (error) {
73
+ console.log("❌ Error:", error);
74
+ }
75
+
76
+ // 2. Test utils conversion
77
+ console.log("\n2. Testing utils_convertData:");
78
+ try {
79
+ const convertResult = await client.callTool({
80
+ name: "utils_convertData",
81
+ arguments: {
82
+ args: {
83
+ data: "Hello BSV!",
84
+ from: "utf8",
85
+ to: "hex",
86
+ },
87
+ },
88
+ });
89
+ const content = convertResult.content[0] as { text: string };
90
+ console.log("✅ Converted:", content.text);
91
+ } catch (error) {
92
+ console.log("❌ Error:", error);
93
+ }
94
+
95
+ // 3. Test bsocial_readPosts
96
+ console.log("\n3. Testing bsocial_readPosts:");
97
+ try {
98
+ const postsResult = await client.callTool({
99
+ name: "bsocial_readPosts",
100
+ arguments: {
101
+ args: {
102
+ limit: 5,
103
+ },
104
+ },
105
+ });
106
+ const content = postsResult.content[0] as { text: string };
107
+ console.log("✅ Read posts (showing first 200 chars):");
108
+ console.log(`${content.text.substring(0, 200)}...`);
109
+ } catch (error) {
110
+ console.log("❌ Error:", error);
111
+ }
112
+
113
+ // 4. Test ordinals search
114
+ console.log("\n4. Testing ordinals_searchInscriptions:");
115
+ try {
116
+ const ordinalsResult = await client.callTool({
117
+ name: "ordinals_searchInscriptions",
118
+ arguments: {
119
+ args: {
120
+ query: "test",
121
+ limit: 3,
122
+ },
123
+ },
124
+ });
125
+ const content = ordinalsResult.content[0] as { text: string };
126
+ const response = JSON.parse(content.text);
127
+ console.log(`✅ Found ${response.total || 0} inscriptions`);
128
+ } catch (error) {
129
+ console.log("❌ Error:", error);
130
+ }
131
+
132
+ // List resources
133
+ console.log("\n📚 Available resources:");
134
+ const resources = await client.listResources();
135
+ console.log(`Found ${resources.resources.length} resources`);
136
+ for (const resource of resources.resources) {
137
+ console.log(` - ${resource.name}`);
138
+ }
139
+
140
+ // List prompts
141
+ console.log("\n💭 Available prompts:");
142
+ const prompts = await client.listPrompts();
143
+ console.log(`Found ${prompts.prompts.length} prompts`);
144
+ for (const prompt of prompts.prompts) {
145
+ console.log(` - ${prompt.name}`);
146
+ }
147
+ } catch (error) {
148
+ console.error("❌ Test failed:", error);
149
+ } finally {
150
+ console.log("\n🔌 Disconnecting...");
151
+ await client.close();
152
+ process.exit(0);
153
+ }
154
+ }
155
+
156
+ // Run the test
157
+ testMCPServer().catch(console.error);
@@ -121,37 +121,37 @@ export function registerA2bDiscoverTool(server: McpServer) {
121
121
  server.tool(
122
122
  "a2b_discover",
123
123
  "Search on-chain agent and MCP tool records. Use 'agent' to search for agents, 'tool' to search for MCP tools.",
124
- { args: a2bDiscoverArgsSchema },
124
+ { ...a2bDiscoverArgsSchema.shape },
125
125
  async (
126
- { args }: { args: A2bDiscoverArgs },
126
+ { queryType, query, limit, offset, fromBlock, toBlock },
127
127
  extra: RequestHandlerExtra<ServerRequest, ServerNotification>,
128
128
  ) => {
129
129
  try {
130
130
  const params = new URLSearchParams();
131
131
 
132
132
  // Set query type (agent, tool, or all)
133
- params.set("type", args.queryType);
133
+ params.set("type", queryType);
134
134
 
135
135
  // Use enhanced search for better relevance scoring
136
136
  let searchEndpoint = "/search/enhanced";
137
137
 
138
138
  // For empty queries, use the regular search endpoint
139
- if (!args.query || !args.query.trim()) {
139
+ if (!query || !query.trim()) {
140
140
  searchEndpoint = "/search";
141
141
  } else {
142
- params.set("q", args.query); // enhanced search uses 'q' parameter
142
+ params.set("q", query); // enhanced search uses 'q' parameter
143
143
  }
144
144
 
145
145
  // Add pagination parameters
146
- params.set("limit", args.limit?.toString() ?? "10");
147
- params.set("offset", args.offset?.toString() ?? "0");
146
+ params.set("limit", limit?.toString() ?? "10");
147
+ params.set("offset", offset?.toString() ?? "0");
148
148
 
149
149
  // Add block range if specified
150
- if (args.fromBlock) {
151
- params.set("fromBlock", args.fromBlock.toString());
150
+ if (fromBlock) {
151
+ params.set("fromBlock", fromBlock.toString());
152
152
  }
153
- if (args.toBlock) {
154
- params.set("toBlock", args.toBlock.toString());
153
+ if (toBlock) {
154
+ params.set("toBlock", toBlock.toString());
155
155
  }
156
156
 
157
157
  // Construct the full URL
@@ -178,7 +178,7 @@ export function registerA2bDiscoverTool(server: McpServer) {
178
178
  let result = "";
179
179
 
180
180
  if (data?.items?.length > 0) {
181
- result = `Found ${data.items.length} ${args.queryType}(s):\n\n`;
181
+ result = `Found ${data.items.length} ${queryType}(s):\n\n`;
182
182
 
183
183
  data.items.forEach((item: A2BDiscoveryItem, index: number) => {
184
184
  // Server name and description
@@ -217,7 +217,7 @@ export function registerA2bDiscoverTool(server: McpServer) {
217
217
  result += "\n";
218
218
  });
219
219
  } else {
220
- result = `No ${args.queryType} results found.`;
220
+ result = `No ${queryType} results found.`;
221
221
  }
222
222
 
223
223
  return {