UNPKG

@solana-agent-kit/adapter-mcp

Version:
108 lines (107 loc) 3.13 kB
// src/index.ts import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; function isZodOptional(schema) { return schema instanceof z.ZodOptional; } function isZodObject(schema) { return schema instanceof z.ZodObject || schema?._def?.typeName === "ZodObject"; } function zodToMCPShape(schema) { if (!isZodObject(schema)) { throw new Error("MCP tools require an object schema at the top level"); } const shape = schema.shape; const result = {}; for (const [key, value] of Object.entries(shape)) { result[key] = isZodOptional(value) ? value.unwrap() : value; } return { result, keys: Object.keys(result) }; } function createMcpServer(actions, solanaAgentKit, options) { const server = new McpServer({ name: options.name, version: options.version }); for (const [_key, action] of Object.entries(actions)) { const { result } = zodToMCPShape(action.schema); server.tool(action.name, action.description, result, async (params) => { try { const result2 = await action.handler(solanaAgentKit, params); return { content: [ { type: "text", text: JSON.stringify(result2, null, 2) } ] }; } catch (error) { console.error("error", error); return { isError: true, content: [ { type: "text", text: error instanceof Error ? error.message : "Unknown error occurred" } ] }; } }); if (action.examples && action.examples.length > 0) { server.prompt( `${action.name}-examples`, { showIndex: z.string().optional().describe("Example index to show (number)") }, (args) => { const showIndex = args.showIndex ? parseInt(args.showIndex) : void 0; const examples = action.examples.flat(); const selectedExamples = typeof showIndex === "number" ? [examples[showIndex]] : examples; const exampleText = selectedExamples.map( (ex, idx) => ` Example ${idx + 1}: Input: ${JSON.stringify(ex.input, null, 2)} Output: ${JSON.stringify(ex.output, null, 2)} Explanation: ${ex.explanation} ` ).join("\n"); return { messages: [ { role: "user", content: { type: "text", text: `Examples for ${action.name}: ${exampleText}` } } ] }; } ); } } return server; } async function startMcpServer(actions, solanaAgentKit, options) { try { const server = createMcpServer(actions, solanaAgentKit, options); const transport = new StdioServerTransport(); await server.connect(transport); return server; } catch (error) { console.error("Error starting MCP server", error); throw error; } } export { createMcpServer, startMcpServer, zodToMCPShape };