bsv-mcp 0.0.5 → 0.0.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.
package/README.md CHANGED
@@ -14,16 +14,6 @@ To install dependencies:
14
14
  bun install
15
15
  ```
16
16
 
17
- For global installation (recommended for MCP client integration):
18
-
19
- ```bash
20
- # Install globally with bun
21
- bun install -g bsv-mcp
22
-
23
- # Or with npm
24
- npm install -g bsv-mcp
25
- ```
26
-
27
17
  ## External Dependencies
28
18
 
29
19
  For full functionality of all tools, the following additional dependencies are installed:
@@ -38,11 +28,7 @@ js-1sat-ord
38
28
  Start the MCP server:
39
29
 
40
30
  ```bash
41
- # If installed locally
42
31
  bun run index.ts
43
-
44
- # If installed globally
45
- bunx bsv-mcp
46
32
  ```
47
33
 
48
34
  ## Connecting to MCP Clients
@@ -54,7 +40,7 @@ This server implements the [Model Context Protocol](https://modelcontextprotocol
54
40
  To use the BSV MCP server with [Cursor](https://cursor.sh/):
55
41
 
56
42
  1. Install Cursor if you haven't already
57
- 2. Install this package globally: `bun install -g bsv-mcp`
43
+ 2. Clone this repository and run `bun install` in the project directory
58
44
  3. Open Cursor and navigate to Settings → Extensions → Model Context Protocol
59
45
  4. Click "Add a new global MCP server"
60
46
  5. Enter the following configuration in JSON format:
@@ -65,15 +51,17 @@ To use the BSV MCP server with [Cursor](https://cursor.sh/):
65
51
  "command": "env",
66
52
  "args": [
67
53
  "PRIVATE_KEY_WIF=<your_private_key_wif>",
68
- "bunx",
69
- "bsv-mcp"
54
+ "bun",
55
+ "run",
56
+ "<path_to_project>/index.ts"
70
57
  ]
71
58
  }
72
59
  }
73
60
  ```
74
61
 
75
62
  6. Replace `<your_private_key_wif>` with your actual private key WIF (keep this secure!)
76
- 7. Click "Save"
63
+ 7. Replace `<path_to_project>` with the full path to where you cloned this repository
64
+ 8. Click "Save"
77
65
 
78
66
  The BSV tools will now be available to Cursor's AI assistant under the "Bitcoin SV" namespace.
79
67
 
@@ -82,7 +70,7 @@ The BSV tools will now be available to Cursor's AI assistant under the "Bitcoin
82
70
  To connect this server to Claude for Desktop:
83
71
 
84
72
  1. Ensure you have [Claude for Desktop](https://claude.ai/desktop) installed and updated to the latest version
85
- 2. Install this package globally: `bun install -g bsv-mcp`
73
+ 2. Clone this repository and run `bun install` in the project directory
86
74
  3. Open your Claude for Desktop configuration file:
87
75
  ```bash
88
76
  # macOS/Linux
@@ -99,16 +87,18 @@ To connect this server to Claude for Desktop:
99
87
  "command": "env",
100
88
  "args": [
101
89
  "PRIVATE_KEY_WIF=<your_private_key_wif>",
102
- "bunx",
103
- "bsv-mcp"
90
+ "bun",
91
+ "run",
92
+ "<path_to_project>/index.ts"
104
93
  ]
105
94
  }
106
95
  }
107
96
  }
108
97
  ```
109
98
  5. Replace `<your_private_key_wif>` with your actual private key WIF
110
- 6. Save the file and restart Claude for Desktop
111
- 7. The BSV tools will appear when you click the tools icon (hammer) in Claude for Desktop
99
+ 6. Replace `<path_to_project>` with the full path to where you cloned this repository
100
+ 7. Save the file and restart Claude for Desktop
101
+ 8. The BSV tools will appear when you click the tools icon (hammer) in Claude for Desktop
112
102
 
113
103
  ### Generic MCP Client Integration
114
104
 
@@ -120,8 +110,9 @@ For other MCP clients that support JSON configuration:
120
110
  "command": "env",
121
111
  "args": [
122
112
  "PRIVATE_KEY_WIF=<your_private_key_wif>",
123
- "bunx",
124
- "bsv-mcp"
113
+ "bun",
114
+ "run",
115
+ "<path_to_project>/index.ts"
125
116
  ]
126
117
  }
127
118
  }
@@ -134,7 +125,7 @@ If running the server directly:
134
125
  export PRIVATE_KEY_WIF=<your_private_key_wif>
135
126
 
136
127
  # Then run the server
137
- bunx bsv-mcp
128
+ bun run index.ts
138
129
  ```
139
130
 
140
131
  ## Available Tools
@@ -225,7 +216,7 @@ When you interact with an MCP-enabled AI assistant:
225
216
 
226
217
  If you're having issues connecting to the server:
227
218
 
228
- 1. Ensure the package is properly installed: `bun install -g bsv-mcp`
219
+ 1. Ensure the package dependencies are properly installed: `bun install`
229
220
  2. Verify your WIF private key is correctly set in the environment
230
221
  3. Check that your client supports MCP and is properly configured
231
222
  4. Look for error messages in the client's console output
@@ -254,18 +245,7 @@ This project was created using `bun init` in bun v1.2.9. [Bun](https://bun.sh) i
254
245
 
255
246
  ### Package Configuration
256
247
 
257
- To ensure the package can be run with `bunx bsv-mcp`, make sure your `package.json` includes:
258
-
259
- ```json
260
- {
261
- "name": "bsv-mcp",
262
- "bin": {
263
- "bsv-mcp": "./index.ts"
264
- },
265
- "type": "module"
266
- // ...other configuration
267
- }
268
- ```
248
+ The main entry point for this package is `index.ts`.
269
249
 
270
250
  ### Running Tests
271
251
 
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.5",
5
+ "version": "0.0.7",
6
6
  "bin": {
7
7
  "bsv-mcp": "./index.ts"
8
8
  },
package/smithery.yaml ADDED
@@ -0,0 +1,21 @@
1
+ startCommand:
2
+ type: stdio
3
+ configSchema:
4
+ type: object
5
+ required:
6
+ - privateKeyWif
7
+ properties:
8
+ privateKeyWif:
9
+ type: string
10
+ description: "Your private key WIF (Wallet Import Format) for Bitcoin SV transactions. This key is used to sign transactions and is required for wallet operations."
11
+ commandFunction: |
12
+ (config) => ({
13
+ "command": "bun",
14
+ "args": [
15
+ "run",
16
+ "index.ts"
17
+ ],
18
+ "env": {
19
+ "PRIVATE_KEY_WIF": config.privateKeyWif
20
+ }
21
+ })
@@ -118,6 +118,7 @@ function isTxid(str: string): boolean {
118
118
  export function registerDecodeTransactionTool(server: McpServer): void {
119
119
  server.tool(
120
120
  "bsv_decodeTransaction",
121
+ "Decodes and analyzes Bitcoin SV transactions to provide detailed insights. This powerful tool accepts either a transaction ID or raw transaction data and returns comprehensive information including inputs, outputs, fee calculations, script details, and blockchain context. Supports both hex and base64 encoded transactions and automatically fetches additional on-chain data when available.",
121
122
  {
122
123
  args: decodeTransactionArgsSchema,
123
124
  },
@@ -8,8 +8,9 @@ import { z } from "zod";
8
8
  export function registerGetPriceTool(server: McpServer): void {
9
9
  server.tool(
10
10
  "bsv_getPrice",
11
+ "Retrieves the current price of Bitcoin SV (BSV) in USD from a reliable exchange API. This tool provides real-time market data that can be used for calculating transaction values, monitoring market conditions, or converting between BSV and fiat currencies.",
11
12
  {
12
- args: z.object({}).optional(),
13
+ args: z.object({}).optional().describe("No parameters required - simply returns the current BSV price in USD"),
13
14
  },
14
15
  async () => {
15
16
  try {
@@ -40,6 +40,7 @@ interface InscriptionResponse {
40
40
  export function registerGetInscriptionTool(server: McpServer): void {
41
41
  server.tool(
42
42
  "ordinals_getInscription",
43
+ "Retrieves detailed information about a specific ordinal inscription by its outpoint. Returns complete inscription data including content type, file information, inscription origin, and current status. Useful for verifying NFT authenticity or retrieving metadata about digital artifacts.",
43
44
  {
44
45
  args: getInscriptionArgsSchema,
45
46
  },
@@ -0,0 +1,109 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
3
+ import { z } from "zod";
4
+
5
+ // Schema for get token by ID or ticker arguments
6
+ export const getTokenByIdOrTickerArgsSchema = z.object({
7
+ id: z.string().optional().describe("BSV20 token ID in outpoint format (txid_vout)"),
8
+ tick: z.string().optional().describe("BSV20 token ticker symbol"),
9
+ }).refine(data => data.id || data.tick, {
10
+ message: "Either id or tick must be provided",
11
+ });
12
+
13
+ export type GetTokenByIdOrTickerArgs = z.infer<typeof getTokenByIdOrTickerArgsSchema>;
14
+
15
+ // BSV20 token response type
16
+ interface TokenResponse {
17
+ id: string;
18
+ tick?: string;
19
+ sym?: string;
20
+ max?: string;
21
+ lim?: string;
22
+ dec?: number;
23
+ supply?: string;
24
+ amt?: string;
25
+ status?: number;
26
+ icon?: string;
27
+ height?: number;
28
+ [key: string]: unknown;
29
+ }
30
+
31
+ /**
32
+ * Register the BSV20 token lookup tool
33
+ */
34
+ export function registerGetTokenByIdOrTickerTool(server: McpServer): void {
35
+ server.tool(
36
+ "ordinals_getTokenByIdOrTicker",
37
+ "Retrieves detailed information about a specific BSV-20 token by its ID or ticker symbol. Returns complete token data including ticker symbol, supply information, decimals, and current status. This tool is useful for verifying token authenticity or checking supply metrics.",
38
+ {
39
+ args: getTokenByIdOrTickerArgsSchema,
40
+ },
41
+ async (
42
+ { args }: { args: GetTokenByIdOrTickerArgs },
43
+ extra: RequestHandlerExtra,
44
+ ) => {
45
+ try {
46
+ const { id, tick } = args;
47
+
48
+ // Validate that at least one of id or tick is provided
49
+ if (!id && !tick) {
50
+ throw new Error("Either token ID or ticker symbol must be provided");
51
+ }
52
+
53
+ // Validate ID format if provided
54
+ if (id && !/^[0-9a-f]{64}_\d+$/i.test(id)) {
55
+ throw new Error("Invalid BSV20 ID format. Expected 'txid_vout'");
56
+ }
57
+
58
+ // Determine which endpoint to use based on provided parameters
59
+ let endpoint: string;
60
+ if (id) {
61
+ endpoint = `https://ordinals.gorillapool.io/api/bsv20/id/${id}`;
62
+ } else {
63
+ endpoint = `https://ordinals.gorillapool.io/api/bsv20/tick/${tick}`;
64
+ }
65
+
66
+ // Fetch BSV20 token data from GorillaPool API
67
+ const response = await fetch(endpoint);
68
+
69
+ if (response.status === 404) {
70
+ return {
71
+ content: [
72
+ {
73
+ type: "text",
74
+ text: JSON.stringify({ error: "BSV20 token not found" }),
75
+ },
76
+ ],
77
+ };
78
+ }
79
+
80
+ if (!response.ok) {
81
+ throw new Error(
82
+ `API error: ${response.status} ${response.statusText}`,
83
+ );
84
+ }
85
+
86
+ const data = (await response.json()) as TokenResponse;
87
+
88
+ return {
89
+ content: [
90
+ {
91
+ type: "text",
92
+ text: JSON.stringify(data, null, 2),
93
+ },
94
+ ],
95
+ };
96
+ } catch (error) {
97
+ return {
98
+ content: [
99
+ {
100
+ type: "text",
101
+ text: error instanceof Error ? error.message : String(error),
102
+ },
103
+ ],
104
+ isError: true,
105
+ };
106
+ }
107
+ },
108
+ );
109
+ }
@@ -1,6 +1,6 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { registerGetBsv20ByIdTool } from "./getBsv20ById";
3
2
  import { registerGetInscriptionTool } from "./getInscription";
3
+ import { registerGetTokenByIdOrTickerTool } from "./getTokenByIdOrTicker";
4
4
  import { registerMarketListingsTool } from "./marketListings";
5
5
  import { registerMarketSalesTool } from "./marketSales";
6
6
  import { registerSearchInscriptionsTool } from "./searchInscriptions";
@@ -15,5 +15,5 @@ export function registerOrdinalsTools(server: McpServer): void {
15
15
  registerSearchInscriptionsTool(server);
16
16
  registerMarketListingsTool(server);
17
17
  registerMarketSalesTool(server);
18
- registerGetBsv20ByIdTool(server);
18
+ registerGetTokenByIdOrTickerTool(server);
19
19
  }
@@ -89,6 +89,7 @@ interface MarketListingResponse {
89
89
  export function registerMarketListingsTool(server: McpServer): void {
90
90
  server.tool(
91
91
  "ordinals_marketListings",
92
+ "Retrieves current marketplace listings for Bitcoin SV ordinals with flexible filtering. Supports multiple asset types (NFTs, BSV-20 tokens, BSV-21 tokens) through a unified interface. Results include listing prices, details about the assets, and seller information.",
92
93
  {
93
94
  args: marketListingsArgsSchema,
94
95
  },
@@ -67,6 +67,7 @@ interface MarketSaleResponse {
67
67
  export function registerMarketSalesTool(server: McpServer): void {
68
68
  server.tool(
69
69
  "ordinals_marketSales",
70
+ "Retrieves recent sales data for BSV-20 and BSV-21 tokens on the ordinals marketplace. This tool provides insights into market activity, including sale prices, transaction details, and token information. Supports filtering by token ID, ticker symbol, or seller address to help analyze market trends and track specific token sales.",
70
71
  {
71
72
  args: marketSalesArgsSchema,
72
73
  },
@@ -57,6 +57,7 @@ interface InscriptionSearchResponse {
57
57
  export function registerSearchInscriptionsTool(server: McpServer): void {
58
58
  server.tool(
59
59
  "ordinals_searchInscriptions",
60
+ "Searches for Bitcoin SV ordinal inscriptions using flexible criteria. This powerful search tool supports filtering by address, inscription content, MIME type, MAP fields, and other parameters. Results include detailed information about each matched inscription. Ideal for discovering NFTs and exploring the ordinals ecosystem.",
60
61
  {
61
62
  args: searchInscriptionsArgsSchema,
62
63
  },
@@ -11,11 +11,12 @@ const encodingSchema = z.enum(["utf8", "hex", "base64", "binary"]);
11
11
  export function registerUtilsTools(server: McpServer): void {
12
12
  server.tool(
13
13
  "utils_convertData",
14
+ "Converts data between different encodings (utf8, hex, base64, binary). Useful for transforming data formats when working with blockchain data, encryption, or file processing.",
14
15
  {
15
16
  args: z.object({
16
- data: z.string(),
17
- from: encodingSchema,
18
- to: encodingSchema,
17
+ data: z.string().describe("The data string to be converted"),
18
+ from: encodingSchema.describe("Source encoding format (utf8, hex, base64, or binary)"),
19
+ to: encodingSchema.describe("Target encoding format to convert to (utf8, hex, base64, or binary)"),
19
20
  }),
20
21
  },
21
22
  async ({ args }) => {
@@ -37,6 +37,7 @@ export type CreateOrdinalsArgs = z.infer<typeof createOrdinalsArgsSchema>;
37
37
  export function registerCreateOrdinalsTool(server: McpServer, wallet: Wallet) {
38
38
  server.tool(
39
39
  "wallet_createOrdinals",
40
+ "Creates and inscribes ordinals (NFTs) on the Bitcoin SV blockchain. This tool lets you mint new digital artifacts by encoding data directly into the blockchain. Supports various content types including images, text, JSON, and HTML. The tool handles transaction creation, fee calculation, and broadcasting.",
40
41
  { args: createOrdinalsArgsSchema },
41
42
  async (
42
43
  { args }: { args: CreateOrdinalsArgs },
@@ -9,8 +9,9 @@ import { z } from "zod";
9
9
  export function registerGetAddressTool(server: McpServer): void {
10
10
  server.tool(
11
11
  "wallet_getAddress",
12
+ "Retrieves the current wallet's Bitcoin SV address. This address can be used to receive BSV, ordinals, or tokens, and is derived from the wallet's private key.",
12
13
  {
13
- args: z.object({}).optional(),
14
+ args: z.object({}).optional().describe("No parameters required - simply returns the current wallet address"),
14
15
  },
15
16
  async () => {
16
17
  try {
@@ -61,13 +61,17 @@ interface OrdUtxo {
61
61
  /**
62
62
  * Register the purchaseListing tool
63
63
  *
64
- * This tool:
64
+ * This tool enables purchasing listed ordinals (NFTs or tokens) from the marketplace:
65
65
  * 1. Parses the listing outpoint to get the txid and vout
66
66
  * 2. Fetches the listing UTXO from the ordinals API
67
67
  * 3. Gets the wallet's payment UTXOs (using the wallet's internal UTXO management)
68
68
  * 4. Uses purchaseOrdListing or purchaseOrdTokenListing based on the listing type
69
- * 5. Broadcasts the transaction
70
- * 6. Returns the transaction details
69
+ * 5. For NFTs, automatically detects and processes royalty payments to original creators
70
+ * 6. Broadcasts the transaction
71
+ * 7. Returns the transaction details including success status and txid
72
+ *
73
+ * The tool supports both NFT and token listings with appropriate type-specific handling.
74
+ * Royalty payments are supported for NFT purchases only (based on creator-defined metadata).
71
75
  */
72
76
  export function registerPurchaseListingTool(server: McpServer, wallet: Wallet) {
73
77
  // Store a reference to check if wallet is persistent
@@ -75,6 +79,7 @@ export function registerPurchaseListingTool(server: McpServer, wallet: Wallet) {
75
79
 
76
80
  server.tool(
77
81
  "wallet_purchaseListing",
82
+ "Purchases a listing from the Bitcoin SV ordinals marketplace. Supports both NFT purchases (with royalty payments to original creators) and BSV-20/BSV-21 token purchases. The tool handles all aspects of the transaction - from fetching listing details, calculating fees, creating and broadcasting the transaction.",
78
83
  { args: purchaseListingArgsSchema },
79
84
  async (
80
85
  { args }: { args: z.infer<typeof purchaseListingArgsSchema> },
@@ -200,7 +205,7 @@ Please fund this wallet address with enough BSV to cover the purchase price
200
205
  satoshis: 1, // TokenUtxo's satoshis must be exactly 1
201
206
  amt: listingData.data.bsv20.amt,
202
207
  id: args.tokenID,
203
- payout: listingData.data.list.payout,
208
+ payout: listingData.data.list.payout,
204
209
  };
205
210
 
206
211
  transaction = await purchaseOrdTokenListing({
@@ -229,6 +234,9 @@ Please fund this wallet address with enough BSV to cover the purchase price
229
234
  };
230
235
 
231
236
  // Check for royalties in the NFT origin data
237
+ // Royalties are only supported for NFTs, not for tokens
238
+ // The royalties are defined by the original creator as a JSON string
239
+ // in the NFT's metadata and parsed into a Royalty[] array
232
240
  let royalties: Royalty[] = [];
233
241
  if (listingData.origin?.data?.map?.royalties) {
234
242
  try {
@@ -291,7 +291,7 @@ export const purchaseListingArgsSchema = z.object({
291
291
  .string()
292
292
  .optional()
293
293
  .describe("Optional description for the transaction"),
294
- });
294
+ }).describe("Schema for the wallet_purchaseListing tool arguments (purchase NFTs or tokens), with detailed field descriptions.");
295
295
 
296
296
  // Export types
297
297
  export type SendToAddressArgs = z.infer<typeof sendToAddressArgsSchema>;
@@ -26,6 +26,7 @@ export type SendOrdinalsArgs = z.infer<typeof sendOrdinalsArgsSchema>;
26
26
  export function registerSendOrdinalsTool(server: McpServer, wallet: Wallet) {
27
27
  server.tool(
28
28
  "wallet_sendOrdinals",
29
+ "Transfers ordinals (NFTs) from your wallet to another address on the Bitcoin SV blockchain. This tool enables sending inscriptions you own to any valid BSV address. The transaction is created, signed, and broadcast automatically, with appropriate fee calculation and change handling.",
29
30
  { args: sendOrdinalsArgsSchema },
30
31
  async (
31
32
  { args }: { args: SendOrdinalsArgs },
@@ -42,6 +42,7 @@ export type SendToAddressArgs = z.infer<typeof sendToAddressArgsSchema>;
42
42
  export function registerSendToAddressTool(server: McpServer, wallet: Wallet) {
43
43
  server.tool(
44
44
  "wallet_sendToAddress",
45
+ "Sends Bitcoin SV (BSV) to a specified address. This tool supports payments in both BSV and USD amounts (with automatic conversion using current exchange rates). Transaction fees are automatically calculated and a confirmation with transaction ID is returned upon success.",
45
46
  {
46
47
  args: sendToAddressArgsSchema,
47
48
  },
@@ -1,94 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
3
- import { z } from "zod";
4
-
5
- // Schema for get BSV20 by ID arguments
6
- export const getBsv20ByIdArgsSchema = z.object({
7
- id: z.string().describe("BSV20 token ID in outpoint format (txid_vout)"),
8
- });
9
-
10
- export type GetBsv20ByIdArgs = z.infer<typeof getBsv20ByIdArgsSchema>;
11
-
12
- // BSV20 token response type
13
- interface Bsv20TokenResponse {
14
- id: string;
15
- tick?: string;
16
- sym?: string;
17
- max?: string;
18
- lim?: string;
19
- dec?: number;
20
- supply?: string;
21
- amt?: string;
22
- status?: number;
23
- icon?: string;
24
- height?: number;
25
- [key: string]: unknown;
26
- }
27
-
28
- /**
29
- * Register the BSV20 token lookup tool
30
- */
31
- export function registerGetBsv20ByIdTool(server: McpServer): void {
32
- server.tool(
33
- "ordinals_getBsv20ById",
34
- {
35
- args: getBsv20ByIdArgsSchema,
36
- },
37
- async (
38
- { args }: { args: GetBsv20ByIdArgs },
39
- extra: RequestHandlerExtra,
40
- ) => {
41
- try {
42
- const { id } = args;
43
-
44
- // Validate ID format (should be in outpoint format)
45
- if (!/^[0-9a-f]{64}_\d+$/i.test(id)) {
46
- throw new Error("Invalid BSV20 ID format. Expected 'txid_vout'");
47
- }
48
-
49
- // Fetch BSV20 token data from GorillaPool API
50
- const response = await fetch(
51
- `https://ordinals.gorillapool.io/api/bsv20/id/${id}`,
52
- );
53
-
54
- if (response.status === 404) {
55
- return {
56
- content: [
57
- {
58
- type: "text",
59
- text: JSON.stringify({ error: "BSV20 token not found" }),
60
- },
61
- ],
62
- };
63
- }
64
-
65
- if (!response.ok) {
66
- throw new Error(
67
- `API error: ${response.status} ${response.statusText}`,
68
- );
69
- }
70
-
71
- const data = (await response.json()) as Bsv20TokenResponse;
72
-
73
- return {
74
- content: [
75
- {
76
- type: "text",
77
- text: JSON.stringify(data, null, 2),
78
- },
79
- ],
80
- };
81
- } catch (error) {
82
- return {
83
- content: [
84
- {
85
- type: "text",
86
- text: error instanceof Error ? error.message : String(error),
87
- },
88
- ],
89
- isError: true,
90
- };
91
- }
92
- },
93
- );
94
- }