bsv-mcp 0.0.35 โ†’ 0.2.0

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 (71) hide show
  1. package/CHANGELOG.md +112 -1
  2. package/README.md +233 -4
  3. package/dist/index.js +111762 -0
  4. package/index.ts +804 -86
  5. package/next-env.d.ts +6 -0
  6. package/package.json +57 -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/bap/friend.ts +267 -0
  16. package/tools/bap/generate.test.ts +350 -0
  17. package/tools/bap/generate.ts +433 -0
  18. package/tools/bap/getCurrentAddress.ts +76 -0
  19. package/tools/bap/getId.test.ts +121 -0
  20. package/tools/bap/getId.ts +169 -0
  21. package/tools/bap/index.ts +111 -0
  22. package/tools/bap/types.ts +66 -0
  23. package/tools/bap/utils.ts +33 -0
  24. package/tools/bigblocks/components.ts +304 -0
  25. package/tools/bigblocks/docs.ts +488 -0
  26. package/tools/bigblocks/examples.ts +527 -0
  27. package/tools/bigblocks/generator.ts +485 -0
  28. package/tools/bigblocks/index.ts +23 -0
  29. package/tools/bsocial/bigblocksApiClient.ts +189 -0
  30. package/tools/bsocial/bmapFollow.ts +125 -0
  31. package/tools/bsocial/bmapLikes.ts +111 -0
  32. package/tools/bsocial/bmapReadPosts.ts +148 -0
  33. package/tools/bsocial/createPost.ts +136 -0
  34. package/tools/bsocial/index.ts +45 -0
  35. package/tools/bsocial/readPosts.ts +255 -0
  36. package/tools/bsv/decodeTransaction.ts +5 -1
  37. package/tools/constants.ts +21 -0
  38. package/tools/index.ts +103 -17
  39. package/tools/mnee/index.ts +8 -0
  40. package/tools/mnee/parseTx.ts +1 -1
  41. package/tools/mnee/sendMnee.ts +1 -1
  42. package/tools/utils/aip.ts +46 -0
  43. package/tools/utils/conversion.ts +1 -0
  44. package/tools/utils/errorHandler.ts +76 -0
  45. package/tools/utils/index.ts +45 -1
  46. package/tools/utils/installAgentMaster.ts +84 -0
  47. package/tools/utils/logger.ts +20 -0
  48. package/tools/utils/toolConfig.ts +80 -0
  49. package/tools/utils/toolRegistration.ts +66 -0
  50. package/tools/utils/transactionBuilder.ts +196 -0
  51. package/tools/wallet/a2bPublishAgent.ts +8 -4
  52. package/tools/wallet/a2bPublishMcp.ts +28 -24
  53. package/tools/wallet/createOrdinals.ts +4 -2
  54. package/tools/wallet/fetchPaymentUtxos.ts +44 -43
  55. package/tools/wallet/gatherCollectionInfo.ts +374 -0
  56. package/tools/wallet/getAddress.ts +13 -21
  57. package/tools/wallet/getBalance.ts +66 -0
  58. package/tools/wallet/getBalanceDroplet.ts +59 -0
  59. package/tools/wallet/integratedWallet.ts +120 -0
  60. package/tools/wallet/mintCollection.ts +378 -0
  61. package/tools/wallet/purchaseListing.ts +4 -4
  62. package/tools/wallet/schemas.ts +18 -249
  63. package/tools/wallet/sendOrdinals.ts +4 -2
  64. package/tools/wallet/sendToAddress.ts +5 -1
  65. package/tools/wallet/setupDroplet.ts +172 -0
  66. package/tools/wallet/tools.ts +71 -156
  67. package/tools/wallet/transactionHelper.ts +121 -0
  68. package/tools/wallet/transferOrdToken.ts +7 -4
  69. package/tools/wallet/utxo.ts +62 -0
  70. package/tools/wallet/wallet.ts +237 -234
  71. 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
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "bsv-mcp",
3
- "module": "index.ts",
3
+ "module": "dist/index.js",
4
4
  "type": "module",
5
- "version": "0.0.35",
5
+ "version": "0.2.0",
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",
@@ -22,6 +22,7 @@
22
22
  "block explorer"
23
23
  ],
24
24
  "files": [
25
+ "dist/**/*.js",
25
26
  "package.json",
26
27
  "*.ts",
27
28
  "tools/*.ts",
@@ -36,28 +37,69 @@
36
37
  "smithery.yaml"
37
38
  ],
38
39
  "bin": {
39
- "bsv-mcp": "./index.ts"
40
+ "bsv-mcp": "./dist/index.js"
40
41
  },
41
42
  "private": false,
42
43
  "devDependencies": {
43
- "@biomejs/biome": "^1.9.4",
44
- "@types/bun": "latest"
44
+ "@biomejs/biome": "^2.4.6",
45
+ "@tailwindcss/postcss": "^4.2.1",
46
+ "@types/bun": "^1.3.10",
47
+ "@types/node": "^25.3.5",
48
+ "bun": "^1.3.10",
49
+ "@types/react": "^19.2.14",
50
+ "@types/react-dom": "^19.2.3",
51
+ "autoprefixer": "^10.4.27",
52
+ "postcss": "^8.5.8",
53
+ "tailwindcss": "^4.2.1",
54
+ "tailwindcss-animate": "^1.0.7"
45
55
  },
46
56
  "peerDependencies": {
47
- "typescript": "^5.8.3"
57
+ "typescript": "^5.9.3"
48
58
  },
49
59
  "dependencies": {
50
- "@bsv/sdk": "^1.4.20",
51
- "@modelcontextprotocol/sdk": "^1.10.2",
52
- "@types/node": "^22.14.1",
53
- "js-1sat-ord": "^0.1.81",
54
- "mnee": "^2.0.0",
55
- "satoshi-token": "^0.0.4",
56
- "sigma-protocol": "^0.1.6",
57
- "zod": "^3.24.3"
60
+ "@bsv/sdk": "^2.0.6",
61
+ "@modelcontextprotocol/sdk": "^1.27.1",
62
+ "@radix-ui/react-dialog": "^1.1.15",
63
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
64
+ "@radix-ui/react-label": "^2.1.8",
65
+ "@radix-ui/react-separator": "^1.1.8",
66
+ "@radix-ui/react-slot": "^1.2.4",
67
+ "@radix-ui/react-tabs": "^1.1.13",
68
+ "@radix-ui/react-toast": "^1.2.15",
69
+ "@radix-ui/react-tooltip": "^1.2.8",
70
+ "@radix-ui/themes": "^3.3.0",
71
+ "@tanstack/react-query": "^5.90.21",
72
+ "bigblocks": "0.0.39",
73
+ "bitcoin-auth": "^0.0.7",
74
+ "bitcoin-backup": "0.0.7",
75
+ "bmap-api-types": "0.0.9",
76
+ "bsv-bap": "0.1.23",
77
+ "class-variance-authority": "^0.7.1",
78
+ "clsx": "^2.1.1",
79
+ "jose": "^6.2.0",
80
+ "js-1sat-ord": "^0.1.91",
81
+ "lucide-react": "0.577.0",
82
+ "mcp-handler": "^1.0.7",
83
+ "mnee": "^3.1.0",
84
+ "next": "^16.1.6",
85
+ "next-themes": "^0.4.6",
86
+ "react": "^19.2.4",
87
+ "react-dom": "^19.2.4",
88
+ "satoshi-token": "^0.0.7",
89
+ "schema-dts": "^1.1.5",
90
+ "sigma-protocol": "^0.1.9",
91
+ "sonner": "^2.0.7",
92
+ "tailwind-merge": "^3.5.0",
93
+ "zod": "^4.3.6"
58
94
  },
59
95
  "scripts": {
96
+ "build": "bun build ./index.ts --outdir ./dist --target node",
97
+ "dev": "next dev",
98
+ "build:next": "next build",
99
+ "start:next": "next start",
60
100
  "lint": "biome check .",
61
- "lint:fix": "biome check . --write"
101
+ "lint:fix": "biome check . --write",
102
+ "deploy": "vercel --prod",
103
+ "deploy:preview": "vercel"
62
104
  }
63
105
  }
@@ -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);