bsv-mcp 0.0.15 → 0.0.17
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 +2 -2
- package/index.ts +1 -1
- package/package.json +1 -1
- package/tools/index.ts +0 -0
- package/tools/utils/index.ts +14 -1
- package/tools/wallet/schemas.ts +5 -1
- package/tools/wallet/tools.ts +56 -29
package/README.md
CHANGED
|
@@ -143,7 +143,7 @@ Wallet tools provide core BSV wallet functionality:
|
|
|
143
143
|
| `wallet_getPublicKey` | Retrieves a public key for a specified protocol and key ID | `{"publicKey":"032d0c73eb9270e9e009fd1f9dd77e19cf764fbad5f799560c4e8fd414e40d6fc2"}` |
|
|
144
144
|
| `wallet_createSignature` | Creates a cryptographic signature for the provided data | `{"signature":[144,124,85,193,226,45,140,249,9,177,11,167,33,215,209,38,...]}` |
|
|
145
145
|
| `wallet_verifySignature` | Verifies a cryptographic signature against the provided data | `{"isValid":true}` |
|
|
146
|
-
| `wallet_encryption` | Combined tool for encrypting and decrypting data using the wallet's cryptographic keys
|
|
146
|
+
| `wallet_encryption` | Combined tool for encrypting and decrypting data using the wallet's cryptographic keys.<br><br>**Examples:**<br>1. Encrypt text: `"Encrypt this message: Hello World"`<br>2. Decrypt data: `"Decrypt this data that was previously encrypted for me"` | Encrypt: `{"ciphertext":[89,32,155,38,125,22,49,226,26,...]}` <br> Decrypt: `{"plaintext":"hello world"}` |
|
|
147
147
|
| `wallet_getAddress` | Returns a BSV address for the current wallet or a derived path | `{"address":"1ExampleBsvAddressXXXXXXXXXXXXXXXXX","status":"ok"}` |
|
|
148
148
|
| `wallet_sendToAddress` | Sends BSV to a specified address (supports BSV or USD amounts) | `{"status":"success","txid":"a1b2c3d4e5f6...","satoshis":1000000}` |
|
|
149
149
|
| `wallet_purchaseListing` | Purchases NFTs or BSV-20/BSV-21 tokens from marketplace listings | `{"status":"success","txid":"a1b2c3d4e5f6...","type":"nft","origin":"abcdef123456..."}` |
|
|
@@ -177,7 +177,7 @@ General-purpose utility functions:
|
|
|
177
177
|
|
|
178
178
|
| Tool Name | Description | Example Output |
|
|
179
179
|
|-----------|-------------|----------------|
|
|
180
|
-
| `utils_convertData` | Converts data between different
|
|
180
|
+
| `utils_convertData` | Converts data between different encoding formats (utf8, hex, base64, binary).<br><br>**Parameters:**<br>- `data` (required): The string to convert<br>- `from` (required): Source encoding format (utf8, hex, base64, or binary)<br>- `to` (required): Target encoding format (utf8, hex, base64, or binary)<br><br>**Examples:**<br>- UTF-8 to hex: `{"data": "hello world", "from": "utf8", "to": "hex"}` → `68656c6c6f20776f726c64`<br>- UTF-8 to base64: `{"data": "Hello World", "from": "utf8", "to": "base64"}` → `SGVsbG8gV29ybGQ=`<br>- base64 to UTF-8: `{"data": "SGVsbG8gV29ybGQ=", "from": "base64", "to": "utf8"}` → `Hello World`<br>- hex to base64: `{"data": "68656c6c6f20776f726c64", "from": "hex", "to": "base64"}` → `aGVsbG8gd29ybGQ=`<br><br>**Notes:**<br>- All parameters are required<br>- The tool returns the converted data as a string<br>- For binary conversion, data is represented as an array of byte values | `"SGVsbG8gV29ybGQ="` (UTF-8 "Hello World" converted to base64) |
|
|
181
181
|
|
|
182
182
|
## Using the Tools with MCP
|
|
183
183
|
|
package/index.ts
CHANGED
package/package.json
CHANGED
package/tools/index.ts
CHANGED
|
File without changes
|
package/tools/utils/index.ts
CHANGED
|
@@ -11,7 +11,20 @@ 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
|
+
"Converts data between different encodings (utf8, hex, base64, binary). Useful for transforming data formats when working with blockchain data, encryption, or file processing.\n\n" +
|
|
15
|
+
"Parameters:\n" +
|
|
16
|
+
"- data (required): The string to convert\n" +
|
|
17
|
+
"- from (required): Source encoding format (utf8, hex, base64, or binary)\n" +
|
|
18
|
+
"- to (required): Target encoding format (utf8, hex, base64, or binary)\n\n" +
|
|
19
|
+
"Example usage:\n" +
|
|
20
|
+
"- UTF-8 to hex: {\"data\": \"hello world\", \"from\": \"utf8\", \"to\": \"hex\"} → 68656c6c6f20776f726c64\n" +
|
|
21
|
+
"- UTF-8 to base64: {\"data\": \"Hello World\", \"from\": \"utf8\", \"to\": \"base64\"} → SGVsbG8gV29ybGQ=\n" +
|
|
22
|
+
"- base64 to UTF-8: {\"data\": \"SGVsbG8gV29ybGQ=\", \"from\": \"base64\", \"to\": \"utf8\"} → Hello World\n" +
|
|
23
|
+
"- hex to base64: {\"data\": \"68656c6c6f20776f726c64\", \"from\": \"hex\", \"to\": \"base64\"} → aGVsbG8gd29ybGQ=\n\n" +
|
|
24
|
+
"Notes:\n" +
|
|
25
|
+
"- All parameters are required\n" +
|
|
26
|
+
"- The tool returns the converted data as a string\n" +
|
|
27
|
+
"- For binary conversion, data is represented as an array of byte values",
|
|
15
28
|
{
|
|
16
29
|
args: z.object({
|
|
17
30
|
data: z.string().describe("The data string to be converted"),
|
package/tools/wallet/schemas.ts
CHANGED
|
@@ -75,7 +75,11 @@ export const walletDecryptArgsSchema = z.object({
|
|
|
75
75
|
// Combined wallet encryption/decryption args
|
|
76
76
|
export const walletEncryptionArgsSchema = z.object({
|
|
77
77
|
mode: z.enum(["encrypt", "decrypt"]).describe("Operation mode: 'encrypt' to encrypt data or 'decrypt' to decrypt data"),
|
|
78
|
-
data: z.
|
|
78
|
+
data: z.union([
|
|
79
|
+
z.string().describe("Text data (with encoding specified by the encoding parameter)"),
|
|
80
|
+
z.array(z.number()).describe("Binary data as an array of numbers")
|
|
81
|
+
]).describe("Data to process: plaintext for encryption or ciphertext for decryption"),
|
|
82
|
+
encoding: z.enum(["utf8", "hex", "base64"]).optional().default("utf8").describe("Encoding of text data (default: utf8)"),
|
|
79
83
|
protocolID: walletProtocolSchema.describe("Protocol identifier - common values are 'aes' for symmetric encryption or 'ecies' for asymmetric encryption"),
|
|
80
84
|
keyID: z.string().describe("Key identifier - use 'default' or 'primary' for the default wallet key"),
|
|
81
85
|
privilegedReason: z.string().optional().describe("Required reason for privileged operations"),
|
package/tools/wallet/tools.ts
CHANGED
|
@@ -39,6 +39,7 @@ import type { createOrdinalsArgsSchema } from "./createOrdinals";
|
|
|
39
39
|
import { registerGetAddressTool } from "./getAddress";
|
|
40
40
|
import { registerPurchaseListingTool } from "./purchaseListing";
|
|
41
41
|
import { registerSendToAddressTool } from "./sendToAddress";
|
|
42
|
+
import { Utils } from "@bsv/sdk";
|
|
42
43
|
|
|
43
44
|
// Define mapping from tool names to argument schemas
|
|
44
45
|
type ToolArgSchemas = {
|
|
@@ -176,24 +177,23 @@ export function registerWalletTools(
|
|
|
176
177
|
"Combined tool for encrypting and decrypting data using the wallet's cryptographic keys.\n\n" +
|
|
177
178
|
"PARAMETERS:\n" +
|
|
178
179
|
"- mode: (required) Either \"encrypt\" to encrypt plaintext or \"decrypt\" to decrypt ciphertext\n" +
|
|
179
|
-
"- data: (required)
|
|
180
|
-
"-
|
|
181
|
-
"-
|
|
182
|
-
"-
|
|
183
|
-
"- privileged: (optional) Boolean indicating if operation requires elevated privileges\n\n" +
|
|
180
|
+
"- data: (required) Text string or array of numbers to process (plaintext for encryption or ciphertext for decryption)\n" +
|
|
181
|
+
"- encoding: (optional) For text input, the encoding format (utf8, hex, base64) - default is utf8\n" +
|
|
182
|
+
"- protocolID: (required) Protocol identifier - common values are 'aes' for symmetric encryption or 'ecies' for asymmetric encryption\n" +
|
|
183
|
+
"- keyID: (required) Key identifier - use 'default' or 'primary' for the default wallet key\n\n" +
|
|
184
184
|
"EXAMPLES:\n" +
|
|
185
|
-
"1. Encrypt data:\n" +
|
|
185
|
+
"1. Encrypt text data:\n" +
|
|
186
186
|
" {\n" +
|
|
187
187
|
" \"mode\": \"encrypt\",\n" +
|
|
188
|
-
" \"data\":
|
|
189
|
-
" \"protocolID\": \"aes\",\n" +
|
|
188
|
+
" \"data\": \"Hello World\",\n" +
|
|
189
|
+
" \"protocolID\": [1, \"aes\"],\n" +
|
|
190
190
|
" \"keyID\": \"default\"\n" +
|
|
191
191
|
" }\n\n" +
|
|
192
192
|
"2. Decrypt previously encrypted data:\n" +
|
|
193
193
|
" {\n" +
|
|
194
194
|
" \"mode\": \"decrypt\",\n" +
|
|
195
195
|
" \"data\": [encrypted bytes from previous response],\n" +
|
|
196
|
-
" \"protocolID\": \"aes\",\n" +
|
|
196
|
+
" \"protocolID\": [1, \"aes\"],\n" +
|
|
197
197
|
" \"keyID\": \"default\"\n" +
|
|
198
198
|
" }",
|
|
199
199
|
{ args: walletEncryptionArgsSchema },
|
|
@@ -202,32 +202,59 @@ export function registerWalletTools(
|
|
|
202
202
|
extra: RequestHandlerExtra,
|
|
203
203
|
) => {
|
|
204
204
|
try {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
const { mode, data, protocolID, keyID, encoding } = args;
|
|
206
|
+
|
|
207
|
+
// Convert string data to binary if needed
|
|
208
|
+
let binaryData: number[];
|
|
209
|
+
if (Array.isArray(data)) {
|
|
210
|
+
binaryData = data;
|
|
211
|
+
} else {
|
|
212
|
+
// String data with encoding
|
|
213
|
+
const { toArray } = Utils;
|
|
214
|
+
binaryData = toArray(data, encoding || "utf8");
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let result: { ciphertext?: number[]; plaintext?: number[] } = {};
|
|
218
|
+
if (mode === "encrypt") {
|
|
208
219
|
result = await wallet.encrypt({
|
|
209
|
-
plaintext:
|
|
210
|
-
protocolID
|
|
211
|
-
keyID
|
|
212
|
-
privilegedReason: args.privilegedReason,
|
|
213
|
-
counterparty: args.counterparty,
|
|
214
|
-
privileged: args.privileged,
|
|
220
|
+
plaintext: binaryData,
|
|
221
|
+
protocolID,
|
|
222
|
+
keyID,
|
|
215
223
|
});
|
|
216
|
-
} else {
|
|
217
|
-
// For decryption, the data is treated as ciphertext
|
|
224
|
+
} else if (mode === "decrypt") {
|
|
218
225
|
result = await wallet.decrypt({
|
|
219
|
-
ciphertext:
|
|
220
|
-
protocolID
|
|
221
|
-
keyID
|
|
222
|
-
privilegedReason: args.privilegedReason,
|
|
223
|
-
counterparty: args.counterparty,
|
|
224
|
-
privileged: args.privileged,
|
|
226
|
+
ciphertext: binaryData,
|
|
227
|
+
protocolID,
|
|
228
|
+
keyID,
|
|
225
229
|
});
|
|
230
|
+
|
|
231
|
+
// For decryption, convert plaintext back to string if it's likely UTF-8 text
|
|
232
|
+
if (result.plaintext) {
|
|
233
|
+
try {
|
|
234
|
+
const { toUTF8 } = Utils;
|
|
235
|
+
const textResult = toUTF8(result.plaintext);
|
|
236
|
+
// If conversion succeeds and seems like valid text, return as string
|
|
237
|
+
if (textResult && textResult.length > 0) {
|
|
238
|
+
return {
|
|
239
|
+
content: [{
|
|
240
|
+
type: "text",
|
|
241
|
+
text: JSON.stringify({ plaintext: textResult })
|
|
242
|
+
}]
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
} catch (e) {
|
|
246
|
+
// If UTF-8 conversion fails, continue with binary result
|
|
247
|
+
}
|
|
248
|
+
}
|
|
226
249
|
}
|
|
250
|
+
|
|
227
251
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
228
|
-
} catch (
|
|
229
|
-
const
|
|
230
|
-
return {
|
|
252
|
+
} catch (error) {
|
|
253
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
254
|
+
return {
|
|
255
|
+
content: [{ type: "text", text: `Error during ${args.mode}: ${errorMessage}` }],
|
|
256
|
+
isError: true
|
|
257
|
+
};
|
|
231
258
|
}
|
|
232
259
|
},
|
|
233
260
|
);
|