bsv-mcp 0.0.9 → 0.0.10

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.
package/package.json CHANGED
@@ -2,7 +2,31 @@
2
2
  "name": "bsv-mcp",
3
3
  "module": "index.ts",
4
4
  "type": "module",
5
- "version": "0.0.9",
5
+ "version": "0.0.10",
6
+ "license": "MIT",
7
+ "author": "satchmo",
8
+ "description": "A collection of Bitcoin SV (BSV) tools for the Model Context Protocol (MCP) framework",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/b-open-io/bsv-mcp"
12
+ },
13
+ "keywords": [
14
+ "bitcoin",
15
+ "bsv",
16
+ "bitcoin-sv",
17
+ "mcp",
18
+ "model-context-protocol",
19
+ "wallet",
20
+ "ordinals",
21
+ "blockchain"
22
+ ],
23
+ "files": [
24
+ "index.ts",
25
+ "tools/**/*.ts",
26
+ "LICENSE",
27
+ "README.md",
28
+ "smithery.yaml"
29
+ ],
6
30
  "bin": {
7
31
  "bsv-mcp": "./index.ts"
8
32
  },
@@ -20,7 +44,6 @@
20
44
  "@types/node": "^22.14.1",
21
45
  "js-1sat-ord": "^0.1.80",
22
46
  "satoshi-token": "^0.0.4",
23
- "tsx": "^4.19.3",
24
47
  "zod": "^3.24.2"
25
48
  },
26
49
  "scripts": {
package/Dockerfile DELETED
@@ -1,20 +0,0 @@
1
- # Use the official Bun image
2
- FROM oven/bun:1
3
-
4
- # Set working directory
5
- WORKDIR /app
6
-
7
- # Copy all application code first
8
- COPY . .
9
-
10
- # Install dependencies
11
- RUN bun install --frozen-lockfile
12
-
13
- # Set user for security
14
- USER bun
15
-
16
- # Expose port (if needed)
17
- EXPOSE 3000
18
-
19
- # Run the application
20
- CMD ["bun", "run", "index.ts"]
package/biome.json DELETED
@@ -1,30 +0,0 @@
1
- {
2
- "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3
- "vcs": {
4
- "enabled": false,
5
- "clientKind": "git",
6
- "useIgnoreFile": false
7
- },
8
- "files": {
9
- "ignoreUnknown": false,
10
- "ignore": []
11
- },
12
- "formatter": {
13
- "enabled": true,
14
- "indentStyle": "tab"
15
- },
16
- "organizeImports": {
17
- "enabled": true
18
- },
19
- "linter": {
20
- "enabled": true,
21
- "rules": {
22
- "recommended": true
23
- }
24
- },
25
- "javascript": {
26
- "formatter": {
27
- "quoteStyle": "double"
28
- }
29
- }
30
- }
@@ -1,216 +0,0 @@
1
- import { expect, test } from "bun:test";
2
- import { PrivateKey } from "@bsv/sdk";
3
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
- import { z } from "zod";
5
- import { registerWalletTools } from "../../tools/wallet/tools";
6
- import { Wallet } from "../../tools/wallet/wallet";
7
-
8
- // List of expected wallet tool names
9
- const EXPECTED_WALLET_TOOLS = [
10
- "wallet_getPublicKey",
11
- "wallet_createSignature",
12
- "wallet_verifySignature",
13
- "wallet_encrypt",
14
- "wallet_decrypt",
15
- "wallet_createAction",
16
- "wallet_signAction",
17
- "wallet_listActions",
18
- "wallet_listOutputs",
19
- "wallet_getNetwork",
20
- "wallet_getVersion",
21
- "wallet_revealCounterpartyKeyLinkage",
22
- "wallet_revealSpecificKeyLinkage",
23
- "wallet_createHmac",
24
- "wallet_verifyHmac",
25
- "wallet_abortAction",
26
- "wallet_internalizeAction",
27
- "wallet_relinquishOutput",
28
- "wallet_acquireCertificate",
29
- "wallet_listCertificates",
30
- "wallet_proveCertificate",
31
- "wallet_relinquishCertificate",
32
- "wallet_discoverByIdentityKey",
33
- "wallet_discoverByAttributes",
34
- "wallet_isAuthenticated",
35
- "wallet_waitForAuthentication",
36
- "wallet_getHeaderForHeight",
37
- ];
38
-
39
- // Mock wallet with test responses
40
- class TestWallet extends Wallet {
41
- constructor() {
42
- super(PrivateKey.fromRandom());
43
- }
44
-
45
- // Override with test implementations that actually return something
46
- async getPublicKey() {
47
- return { publicKey: "mockPublicKey123" };
48
- }
49
-
50
- // Note: other methods will still return 'not implemented' errors
51
- }
52
-
53
- test("MCP server registers all expected wallet tools", async () => {
54
- // Create an MCP server
55
- const server = new McpServer({
56
- name: "Wallet Server Test",
57
- version: "0.0.1",
58
- });
59
-
60
- // Create test wallet and register tools
61
- const wallet = new TestWallet();
62
- const handlers = registerWalletTools(server, wallet);
63
-
64
- // Check that we have all expected tool handlers
65
- for (const toolName of EXPECTED_WALLET_TOOLS) {
66
- expect(handlers[toolName as keyof typeof handlers]).toBeDefined();
67
- expect(typeof handlers[toolName as keyof typeof handlers]).toBe("function");
68
- }
69
-
70
- // Check that we don't have any unexpected handlers
71
- const actualToolNames = Object.keys(handlers);
72
- expect(actualToolNames.length).toBe(EXPECTED_WALLET_TOOLS.length);
73
-
74
- for (const toolName of actualToolNames) {
75
- expect(EXPECTED_WALLET_TOOLS).toContain(toolName);
76
- }
77
- });
78
-
79
- test("MCP server with wallet tools", async () => {
80
- // Create an MCP server
81
- const server = new McpServer({
82
- name: "Wallet Server Test",
83
- version: "0.0.1",
84
- });
85
-
86
- // Create test wallet and register tools
87
- const wallet = new TestWallet();
88
- const handlers = registerWalletTools(server, wallet);
89
-
90
- // Mock the request handler extra
91
- const mockExtra = {
92
- signal: new AbortController().signal,
93
- };
94
-
95
- // Test the overridden getPublicKey handler which should return data
96
- const getPublicKeyHandler = handlers.wallet_getPublicKey;
97
- const getPublicKeyResult = await getPublicKeyHandler({ args: {} }, mockExtra);
98
-
99
- // Check the success result based on the actual structure
100
- expect(getPublicKeyResult.content).toBeDefined();
101
- expect(getPublicKeyResult.content?.[0]?.type).toBe("text");
102
-
103
- const publicKeyContent = getPublicKeyResult.content?.[0]?.text;
104
- if (typeof publicKeyContent === "string") {
105
- expect(JSON.parse(publicKeyContent)).toEqual({
106
- publicKey: "mockPublicKey123",
107
- });
108
- }
109
- });
110
-
111
- // For a more complete integration test, we could create a real HTTP server
112
- // and use fetch to make requests to it
113
- test.skip("MCP server with HTTP requests", async () => {
114
- // Create MCP server
115
- const server = new McpServer({
116
- name: "Wallet Server Test",
117
- version: "0.0.1",
118
- });
119
-
120
- // Register wallet tools
121
- const wallet = new TestWallet();
122
- const handlers = registerWalletTools(server, wallet);
123
-
124
- // Define expected request type
125
- type ToolCallRequest = {
126
- type: string;
127
- name: string;
128
- args?: Record<string, unknown>;
129
- };
130
-
131
- // Create a simple HTTP server
132
- const httpServer = Bun.serve({
133
- port: 0, // Use random available port
134
- async fetch(req) {
135
- if (req.method === "POST") {
136
- const bodyText = await req.text();
137
- let body: unknown;
138
-
139
- try {
140
- body = JSON.parse(bodyText);
141
- } catch (err) {
142
- return new Response("Invalid JSON", { status: 400 });
143
- }
144
-
145
- // Type guard for the request body
146
- const isToolCallRequest = (obj: unknown): obj is ToolCallRequest => {
147
- return (
148
- typeof obj === "object" &&
149
- obj !== null &&
150
- "type" in obj &&
151
- "name" in obj &&
152
- typeof (obj as ToolCallRequest).type === "string" &&
153
- typeof (obj as ToolCallRequest).name === "string"
154
- );
155
- };
156
-
157
- // Handle MCP requests by calling the appropriate tool
158
- if (
159
- isToolCallRequest(body) &&
160
- body.type === "tool_call" &&
161
- body.name.startsWith("wallet_")
162
- ) {
163
- // Get handler from our handlers object
164
- const toolName = body.name as keyof typeof handlers;
165
- const handler = handlers[toolName];
166
- if (handler) {
167
- const result = await handler(
168
- { args: body.args || {} },
169
- {
170
- signal: new AbortController().signal,
171
- },
172
- );
173
-
174
- return new Response(JSON.stringify(result), {
175
- headers: { "Content-Type": "application/json" },
176
- });
177
- }
178
- }
179
- }
180
-
181
- return new Response("Not found", { status: 404 });
182
- },
183
- });
184
-
185
- try {
186
- const port = httpServer.port;
187
- const baseUrl = `http://localhost:${port}`;
188
-
189
- // Test calling the getPublicKey tool
190
- const response = await fetch(`${baseUrl}`, {
191
- method: "POST",
192
- headers: { "Content-Type": "application/json" },
193
- body: JSON.stringify({
194
- type: "tool_call",
195
- name: "wallet_getPublicKey",
196
- args: {},
197
- }),
198
- });
199
-
200
- const resultData = (await response.json()) as {
201
- isError?: boolean;
202
- content?: Array<{ type: string; text: string }>;
203
- };
204
-
205
- expect(resultData.content).toBeDefined();
206
- expect(resultData.content?.[0]?.type).toBe("text");
207
-
208
- if (resultData.content?.[0]?.text) {
209
- const parsedContent = JSON.parse(resultData.content[0].text);
210
- expect(parsedContent).toEqual({ publicKey: "mockPublicKey123" });
211
- }
212
- } finally {
213
- // Shutdown the server
214
- httpServer.stop();
215
- }
216
- });
package/tsconfig.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- // Environment setup & latest features
4
- "lib": ["ESNext"],
5
- "target": "ESNext",
6
- "module": "ESNext",
7
- "moduleDetection": "force",
8
- "jsx": "react-jsx",
9
- "allowJs": true,
10
-
11
- // Bundler mode
12
- "moduleResolution": "bundler",
13
- "allowImportingTsExtensions": true,
14
- "verbatimModuleSyntax": true,
15
- "noEmit": true,
16
-
17
- // Best practices
18
- "strict": true,
19
- "skipLibCheck": true,
20
- "noFallthroughCasesInSwitch": true,
21
- "noUncheckedIndexedAccess": true,
22
-
23
- // Some stricter flags (disabled by default)
24
- "noUnusedLocals": false,
25
- "noUnusedParameters": false,
26
- "noPropertyAccessFromIndexSignature": false
27
- }
28
- }