bsv-mcp 0.0.24 → 0.0.26

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/README.md CHANGED
@@ -38,6 +38,8 @@ This server implements the [Model Context Protocol](https://modelcontextprotocol
38
38
 
39
39
  ![MCP Configuration Example](docs/images/mcp-config-example.png)
40
40
 
41
+ > **Note:** The PRIVATE_KEY_WIF environment variable is now optional. Without it, the server runs in limited mode with educational resources and non-wallet tools available. Wallet and MNEE token operations require a valid private key.
42
+
41
43
  ### Cursor
42
44
 
43
45
  To use the BSV MCP server with [Cursor](https://cursor.sh/):
@@ -282,6 +284,11 @@ A collection of prompts providing detailed information about the Bitcoin SV SDK:
282
284
 
283
285
  The server also provides access to Bitcoin Request for Comments (BRC) specifications and documentation:
284
286
 
287
+ #### Changelog Resource
288
+ - **Identifier**: `bsv-mcp-changelog`
289
+ - **Description**: Version history and changelog for the BSV MCP server.
290
+ - **Usage**: "Show me the BSV MCP changelog" or "What's new in the latest version?"
291
+
285
292
  #### BRC Resources
286
293
  - **BRCs Overview**
287
294
  - **Identifier**: `brcs_readme`
@@ -333,6 +340,49 @@ When you interact with an MCP-enabled AI assistant:
333
340
  4. The results are returned to the AI assistant
334
341
  5. The assistant presents the information in a natural, conversational way
335
342
 
343
+ ## Customization Options
344
+
345
+ The BSV MCP server can be customized using environment variables to enable or disable specific components:
346
+
347
+ ### Component Configuration
348
+
349
+ | Environment Variable | Default | Description |
350
+ | -------------------- | ------- | ----------- |
351
+ | `DISABLE_PROMPTS` | `false` | Set to `true` to disable all educational prompts |
352
+ | `DISABLE_RESOURCES` | `false` | Set to `true` to disable all resources (BRCs, changelog) |
353
+ | `DISABLE_TOOLS` | `false` | Set to `true` to disable all tools |
354
+
355
+ ### Tool-Specific Configuration
356
+
357
+ | Environment Variable | Default | Description |
358
+ | -------------------- | ------- | ----------- |
359
+ | `DISABLE_WALLET_TOOLS` | `false` | Set to `true` to disable Bitcoin wallet tools |
360
+ | `DISABLE_MNEE_TOOLS` | `false` | Set to `true` to disable MNEE token tools |
361
+ | `DISABLE_BSV_TOOLS` | `false` | Set to `true` to disable BSV blockchain tools |
362
+ | `DISABLE_ORDINALS_TOOLS` | `false` | Set to `true` to disable Ordinals/NFT tools |
363
+ | `DISABLE_UTILS_TOOLS` | `false` | Set to `true` to disable utility tools |
364
+ | `DISABLE_A2B_TOOLS` | `false` | Set to `true` to disable agent-to-blockchain tools |
365
+
366
+ ### Examples
367
+
368
+ Run with only educational resources and prompts, no tools:
369
+
370
+ ```bash
371
+ DISABLE_TOOLS=true bunx bsv-mcp@latest
372
+ ```
373
+
374
+ Run with only BSV tools, no wallet or other functionality:
375
+
376
+ ```bash
377
+ DISABLE_PROMPTS=true DISABLE_RESOURCES=true DISABLE_WALLET_TOOLS=true DISABLE_MNEE_TOOLS=true DISABLE_ORDINALS_TOOLS=true DISABLE_UTILS_TOOLS=true bunx bsv-mcp@latest
378
+ ```
379
+
380
+ Use all tools except wallet operations:
381
+
382
+ ```bash
383
+ DISABLE_WALLET_TOOLS=true bunx bsv-mcp@latest
384
+ ```
385
+
336
386
  ## Troubleshooting
337
387
 
338
388
  If you're having issues with the BSV MCP server:
@@ -392,7 +442,7 @@ The tool supports the following endpoint categories and specific endpoints:
392
442
 
393
443
  | Endpoint | Description | Required Parameters | Example Response |
394
444
  | -------------------- | ----------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------- |
395
- | `chain_info` | Network statistics, difficulty, and chain work | None | `{"chain":"main","blocks":826458,"headers":826458,"bestblockhash":"000000000000..."}` |
445
+ | `chain_info` | Network statistics, difficulty, and chain work | None | `{"chain":"main","blocks":826458,"headers":826458,"bestblockhash":"0000000000..."}` |
396
446
  | `chain_tips` | Current chain tips including heights and states | None | `[{"height":826458,"hash":"000000000000...","branchlen":0,"status":"active"}]` |
397
447
  | `circulating_supply` | Current BSV circulating supply | None | `{"bsv":21000000}` |
398
448
  | `peer_info` | Connected peer statistics | None | `[{"addr":"1.2.3.4:8333","services":"000000000000...","lastsend":1621234567}]` |
package/index.ts CHANGED
@@ -7,46 +7,70 @@ import { registerResources } from "./resources/resources";
7
7
  import { registerAllTools } from "./tools";
8
8
  import { registerWalletTools } from "./tools/wallet/tools";
9
9
  import { Wallet } from "./tools/wallet/wallet";
10
+ import { registerMneeTools } from "./tools/mnee";
10
11
 
11
12
  /**
12
- * Validate the private key from environment variables
13
- * Exits the process with an error message if validation fails
13
+ * Configuration options from environment variables
14
14
  */
15
- function validatePrivateKey(): PrivateKey {
15
+ const CONFIG = {
16
+ // Whether to load various components
17
+ loadPrompts: process.env.DISABLE_PROMPTS !== "true",
18
+ loadResources: process.env.DISABLE_RESOURCES !== "true",
19
+ loadTools: process.env.DISABLE_TOOLS !== "true",
20
+
21
+ // Fine-grained tool category control
22
+ loadWalletTools: process.env.DISABLE_WALLET_TOOLS !== "true",
23
+ loadMneeTools: process.env.DISABLE_MNEE_TOOLS !== "true",
24
+ loadBsvTools: process.env.DISABLE_BSV_TOOLS !== "true",
25
+ loadOrdinalsTools: process.env.DISABLE_ORDINALS_TOOLS !== "true",
26
+ loadUtilsTools: process.env.DISABLE_UTILS_TOOLS !== "true",
27
+ loadA2bTools: process.env.DISABLE_A2B_TOOLS !== "true",
28
+ };
29
+
30
+ /**
31
+ * Try to initialize the private key from environment variables
32
+ * Returns the private key if valid, or undefined if not present or invalid
33
+ */
34
+ function initializePrivateKey(): PrivateKey | undefined {
16
35
  const privateKeyWif = process.env.PRIVATE_KEY_WIF;
17
36
 
18
37
  // Check if private key is set
19
38
  if (!privateKeyWif) {
20
- console.error(
21
- "\x1b[31mError: PRIVATE_KEY_WIF environment variable is not set\x1b[0m",
39
+ console.warn(
40
+ "\x1b[33mWarning: PRIVATE_KEY_WIF environment variable is not set\x1b[0m",
22
41
  );
23
- console.error(
24
- "Please set this variable with a valid Bitcoin SV private key in WIF format",
42
+ console.warn(
43
+ "The server will run, but wallet operations requiring a private key will return errors.",
25
44
  );
26
- console.error(
45
+ console.warn(
46
+ "Set this variable with a valid Bitcoin SV private key in WIF format to enable all features:",
47
+ );
48
+ console.warn(
27
49
  "Example: PRIVATE_KEY_WIF=your_private_key_wif bun run index.ts",
28
50
  );
29
- process.exit(1);
51
+ return undefined;
30
52
  }
31
53
 
32
54
  // Validate the private key format
33
55
  try {
34
56
  return PrivateKey.fromWif(privateKeyWif);
35
57
  } catch (error) {
36
- console.error("\x1b[31mError: Invalid private key format\x1b[0m");
37
- console.error(
38
- "The PRIVATE_KEY_WIF provided is not a valid Bitcoin SV private key in WIF format",
58
+ console.warn("\x1b[33mWarning: Invalid private key format\x1b[0m");
59
+ console.warn(
60
+ "The PRIVATE_KEY_WIF provided is not a valid Bitcoin SV private key in WIF format.",
61
+ );
62
+ console.warn(
63
+ "The server will run, but wallet operations requiring a private key will return errors.",
39
64
  );
40
- console.error("Please check your key and try again");
41
- process.exit(1);
65
+ return undefined;
42
66
  }
43
67
  }
44
68
 
45
- // Validate private key early before starting the server
46
- const privKey = validatePrivateKey();
69
+ // Try to initialize private key but don't stop the server if missing or invalid
70
+ const privKey = initializePrivateKey();
47
71
 
48
72
  const server = new McpServer(
49
- { name: "Bitcoin SV", version: "0.0.24" },
73
+ { name: "Bitcoin SV", version: "0.0.26" },
50
74
  // {
51
75
  // // Advertise only what you actually implement
52
76
  // capabilities: {
@@ -65,20 +89,46 @@ const server = new McpServer(
65
89
  // },
66
90
  );
67
91
 
68
- // Initialize wallet with the validated private key
69
- const wallet = new Wallet(privKey);
92
+ // Initialize wallet and register tools based on configuration
93
+ let wallet: Wallet | null = null;
70
94
 
71
- // Register wallet tools separately (needs wallet instance)
72
- registerWalletTools(server, wallet);
95
+ if (CONFIG.loadTools) {
96
+ if (privKey) {
97
+ // Register MNEE tools if enabled
98
+ if (CONFIG.loadMneeTools) {
99
+ console.log("Registering MNEE tools");
100
+ registerMneeTools(server);
101
+ }
73
102
 
74
- // Register all other tools (BSV, Ordinals, Utils, etc.)
75
- registerAllTools(server);
103
+ // Initialize wallet with the private key if wallet tools are enabled
104
+ if (CONFIG.loadWalletTools) {
105
+ console.log("Initializing wallet and registering wallet tools");
106
+ wallet = new Wallet(privKey);
107
+ registerWalletTools(server, wallet);
108
+ }
109
+ }
76
110
 
77
- // Register resources
78
- registerResources(server);
111
+ // Register all other tools based on configuration
112
+ console.log("Registering other tools");
113
+ registerAllTools(server, {
114
+ enableBsvTools: CONFIG.loadBsvTools,
115
+ enableOrdinalsTools: CONFIG.loadOrdinalsTools,
116
+ enableUtilsTools: CONFIG.loadUtilsTools,
117
+ enableA2bTools: CONFIG.loadA2bTools,
118
+ });
119
+ }
79
120
 
80
- // Register prompts
81
- registerAllPrompts(server);
121
+ // Register resources if enabled
122
+ if (CONFIG.loadResources) {
123
+ console.log("Registering resources");
124
+ registerResources(server);
125
+ }
126
+
127
+ // Register prompts if enabled
128
+ if (CONFIG.loadPrompts) {
129
+ console.log("Registering prompts");
130
+ registerAllPrompts(server);
131
+ }
82
132
 
83
133
  // Connect to the transport
84
134
  const transport = new StdioServerTransport();
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "bsv-mcp",
3
3
  "module": "index.ts",
4
4
  "type": "module",
5
- "version": "0.0.24",
5
+ "version": "0.0.26",
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",
package/tools/index.ts CHANGED
@@ -2,32 +2,69 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { registerA2aCallTool } from "./a2b/call";
3
3
  import { registerA2bDiscoverTool } from "./a2b/discover";
4
4
  import { registerBsvTools } from "./bsv";
5
- import { registerMneeTools } from "./mnee";
6
5
  import { registerOrdinalsTools } from "./ordinals";
7
6
  import { registerUtilsTools } from "./utils";
8
7
 
9
8
  /**
10
- * Register all tools with the MCP server
9
+ * Configuration options for tools
10
+ *
11
+ * These options can be controlled through environment variables:
12
+ * - enableBsvTools: controlled by DISABLE_BSV_TOOLS
13
+ * - enableOrdinalsTools: controlled by DISABLE_ORDINALS_TOOLS
14
+ * - enableUtilsTools: controlled by DISABLE_UTILS_TOOLS
15
+ * - enableA2bTools: controlled by DISABLE_A2B_TOOLS
16
+ */
17
+ export interface ToolsConfig {
18
+ enableBsvTools?: boolean;
19
+ enableOrdinalsTools?: boolean;
20
+ enableUtilsTools?: boolean;
21
+ enableA2bTools?: boolean;
22
+ }
23
+
24
+ /**
25
+ * Register all tools with the MCP server based on configuration
11
26
  * @param server The MCP server instance
27
+ * @param config Configuration options
12
28
  */
13
- export function registerAllTools(server: McpServer): void {
29
+ export function registerAllTools(
30
+ server: McpServer,
31
+ config: ToolsConfig = {
32
+ enableBsvTools: true,
33
+ enableOrdinalsTools: true,
34
+ enableUtilsTools: true,
35
+ enableA2bTools: true
36
+ }
37
+ ): void {
38
+ const {
39
+ enableBsvTools = true,
40
+ enableOrdinalsTools = true,
41
+ enableUtilsTools = true,
42
+ enableA2bTools = true
43
+ } = config;
44
+
14
45
  // Register BSV-related tools
15
- registerBsvTools(server);
46
+ if (enableBsvTools) {
47
+ registerBsvTools(server);
48
+ }
16
49
 
17
50
  // Register Ordinals-related tools
18
- registerOrdinalsTools(server);
51
+ if (enableOrdinalsTools) {
52
+ registerOrdinalsTools(server);
53
+ }
19
54
 
20
55
  // Register utility tools
21
- registerUtilsTools(server);
22
-
23
- // Register agent-to-blockchain discovery tool
24
- registerA2bDiscoverTool(server);
56
+ if (enableUtilsTools) {
57
+ registerUtilsTools(server);
58
+ }
25
59
 
26
- // Register agent-to-agent call tool
27
- // registerA2aCallTool(server);
60
+ // Register agent-to-blockchain tools
61
+ if (enableA2bTools) {
62
+ // Register agent-to-blockchain discovery tool
63
+ registerA2bDiscoverTool(server);
28
64
 
29
- // Register MNEE tools
30
- registerMneeTools(server);
65
+ // Register agent-to-agent call tool
66
+ // registerA2aCallTool(server);
67
+ }
31
68
 
32
69
  // Add more tool categories as needed
33
70
  }
@@ -61,7 +61,19 @@ export function registerSendMneeTool(server: McpServer, mnee: Mnee): void {
61
61
  // Get WIF from environment
62
62
  const wif = process.env.PRIVATE_KEY_WIF;
63
63
  if (!wif) {
64
- throw new Error("PRIVATE_KEY_WIF environment variable is not set");
64
+ return {
65
+ content: [
66
+ {
67
+ type: "text",
68
+ text: JSON.stringify({
69
+ success: false,
70
+ error: "No private key available",
71
+ message: "Please set PRIVATE_KEY_WIF environment variable with a valid Bitcoin SV private key in WIF format.",
72
+ }, null, 2),
73
+ },
74
+ ],
75
+ isError: true,
76
+ };
65
77
  }
66
78
 
67
79
  const result: TransferResponse = await mnee.transfer(
@@ -21,7 +21,22 @@ export function registerGetAddressTool(server: McpServer): void {
21
21
  async () => {
22
22
  try {
23
23
  const wif = process.env.PRIVATE_KEY_WIF;
24
- if (!wif) throw new Error("PRIVATE_KEY_WIF env var not set");
24
+ if (!wif) {
25
+ return {
26
+ content: [
27
+ {
28
+ type: "text",
29
+ text: JSON.stringify({
30
+ error: "No private key available",
31
+ message: "Please set PRIVATE_KEY_WIF environment variable with a valid Bitcoin SV private key in WIF format.",
32
+ status: "error"
33
+ }),
34
+ },
35
+ ],
36
+ isError: true,
37
+ };
38
+ }
39
+
25
40
  const privKey = PrivateKey.fromWif(wif);
26
41
  const address = privKey.toAddress();
27
42
  return {
@@ -35,7 +50,14 @@ export function registerGetAddressTool(server: McpServer): void {
35
50
  } catch (err: unknown) {
36
51
  const msg = err instanceof Error ? err.message : String(err);
37
52
  return {
38
- content: [{ type: "text", text: msg }],
53
+ content: [{
54
+ type: "text",
55
+ text: JSON.stringify({
56
+ error: "Invalid private key",
57
+ message: msg,
58
+ status: "error"
59
+ })
60
+ }],
39
61
  isError: true,
40
62
  };
41
63
  }