Skip to main content
Glama
tools.ts6.95 kB
import type { PrivateKey } from "@bsv/sdk"; import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { ToolCallback } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js"; import type { CallToolResult, ServerNotification, ServerRequest, } from "@modelcontextprotocol/sdk/types.js"; import type { z } from "zod"; import { type a2bPublishMcpArgsSchema, registerA2bPublishMcpTool, } from "./a2bPublishMcp"; import { type createOrdinalsArgsSchema, registerCreateOrdinalsTool, } from "./createOrdinals"; import { registerGatherCollectionInfoTool } from "./gatherCollectionInfo"; import { registerGetAddressTool } from "./getAddress"; import { registerWalletGetBalanceTool } from "./getBalance"; import { registerGetPublicKeyTool } from "./getPublicKey"; import { registerMintCollectionTool } from "./mintCollection"; import { registerPurchaseListingTool } from "./purchaseListing"; import { registerRefreshUtxosTool } from "./refreshUtxos"; import { type emptyArgsSchema, type getAddressArgsSchema, type getPublicKeyArgsSchema, type purchaseListingArgsSchema, type sendToAddressArgsSchema, walletEncryptionArgsSchema, } from "./schemas"; import { registerSendToAddressTool } from "./sendToAddress"; import { registerTransferOrdTokenTool, type transferOrdTokenArgsSchema, } from "./transferOrdToken"; import type { Wallet } from "./wallet"; // Define mapping from tool names to argument schemas type ToolArgSchemas = { wallet_getPublicKey: typeof getPublicKeyArgsSchema; wallet_encryption: typeof walletEncryptionArgsSchema; wallet_getAddress: typeof getAddressArgsSchema; wallet_sendToAddress: typeof sendToAddressArgsSchema; wallet_purchaseListing: typeof purchaseListingArgsSchema; wallet_transferOrdToken: typeof transferOrdTokenArgsSchema; wallet_a2bPublish: typeof a2bPublishMcpArgsSchema; wallet_createOrdinals: typeof createOrdinalsArgsSchema; wallet_refreshUtxos: typeof emptyArgsSchema; wallet_getBalance: typeof emptyArgsSchema; }; // Define a type for the handler function with proper argument types type ToolHandler = ( params: { args: unknown }, extra: RequestHandlerExtra<ServerRequest, ServerNotification>, ) => Promise<CallToolResult>; // Define a map type for tool name to handler functions type ToolHandlerMap = { [K in keyof ToolArgSchemas]: ToolHandler; }; export function registerWalletTools( server: McpServer, wallet: Wallet, config: { disableBroadcasting: boolean; enableA2bTools: boolean; identityPk?: PrivateKey; }, ): ToolHandlerMap { const handlers = {} as ToolHandlerMap; // Handle tools registration with properly typed parameters function registerTool<T extends z.ZodType>( name: keyof ToolArgSchemas, description: string, schema: { args: T }, handler: ToolCallback<{ args: T }>, ): void { // Register all tools normally server.tool(name, description, schema, handler); handlers[name] = handler as ToolHandler; } // Register the wallet_sendToAddress tool registerSendToAddressTool(server, wallet); // Register the wallet_getAddress tool registerGetAddressTool(server, wallet); // Register the wallet_getPublicKey tool registerGetPublicKeyTool(server, wallet); // Register the wallet_purchaseListing tool registerPurchaseListingTool(server, wallet); // Register the wallet_transferOrdToken tool registerTransferOrdTokenTool(server, wallet); // Register the wallet_refreshUtxos tool registerRefreshUtxosTool(server, wallet); // Register the wallet_getBalance tool registerWalletGetBalanceTool(server, wallet); // A2B tools have to be explicitly enabled if (config.enableA2bTools) { // Register the wallet_a2bPublishMcp tool registerA2bPublishMcpTool(server, wallet, config.identityPk, { disableBroadcasting: config.disableBroadcasting, }); } // Register combined wallet_encryption tool registerTool( "wallet_encryption", "Combined tool for encrypting and decrypting data using the wallet's cryptographic keys.\n\n" + "PARAMETERS:\n" + '- mode: (required) Either "encrypt" to encrypt plaintext or "decrypt" to decrypt ciphertext\n' + "- data: (required) Text string or array of numbers to process\n" + "- encoding: (optional) For text input, the encoding format (utf8, hex, base64) - default is utf8\n" + "- recipientPublicKeyHex: (optional) Hexadecimal representation of the recipient's public key (required for encrypt mode)\n\n" + "EXAMPLES:\n" + "1. Encrypt text data:\n" + " {\n" + ' "mode": "encrypt",\n' + ' "data": "Hello World",\n' + ' "encoding": "utf8",\n' + ' "recipientPublicKeyHex": "020202020202020202020202020202020202020202020202020202020202020202"\n' + " }\n\n" + "2. Decrypt previously encrypted data:\n" + " {\n" + ' "mode": "decrypt",\n' + ' "data": [encrypted bytes from previous response]\n' + " }", { args: walletEncryptionArgsSchema }, async ( { args }: { args: z.infer<typeof walletEncryptionArgsSchema> }, extra: RequestHandlerExtra<ServerRequest, ServerNotification>, ) => { try { const { mode, data, encoding, recipientPublicKeyHex } = args; let inputBuffer: Buffer; if (typeof data === "string") { inputBuffer = Buffer.from(data, encoding || "utf8"); } else { inputBuffer = Buffer.from(Uint8Array.from(data)); } // let resultBuffer: Buffer; // let resultOutput: string | number[]; if (mode === "encrypt") { // recipientPublicKeyHex is validated by Zod schema to be present for encrypt mode // The schema ensures recipientPublicKeyHex is defined here. // resultBuffer = await wallet.encrypt({ // data: inputBuffer, // recipientPublicKeyHex: recipientPublicKeyHex as string, // Still needs type assertion if Zod optional isn't fully narrowed // }); throw new Error("Encrypt method not yet implemented in wallet"); // if (encoding === "utf8") { // resultOutput = Array.from(resultBuffer); // } else { // resultOutput = resultBuffer.toString(encoding || "base64"); // } } // mode === "decrypt" // resultBuffer = await wallet.decrypt({ data: inputBuffer }); throw new Error("Decrypt method not yet implemented in wallet"); // return { // content: [ // { type: "text", text: JSON.stringify({ data: resultOutput }) }, // ], // }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [ { type: "text", text: `Error during ${args.mode}: ${errorMessage}`, }, ], isError: true, }; } }, ); // Register createOrdinals tool registerCreateOrdinalsTool(server, wallet); // Register collection tools registerGatherCollectionInfoTool(server, wallet); registerMintCollectionTool(server, wallet); return handlers; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/b-open-io/bsv-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server