UNPKG

bc_resource_mcp-beta

Version:

MCP server for Baichuan resource

139 lines (138 loc) 5.47 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { APIServerMCP } from "./server.js"; import { createToolHandlers } from "./toolRegistery.js"; import * as tools from "./tools.js"; import { z } from "zod"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import * as dotenv from "dotenv"; import { MAIN_OVERFLOW_PROMPT } from "./prompts.js"; dotenv.config(); // const appId = process.env.APP_ID; // const sn = process.env.SN; // const nonce = process.env.NONCE; // const timestamp = process.env.TIMESTAMP; // const sign = process.env.SIGN; // const token = process.env.TOKEN; const moduleId = process.env.MODULE_ID; if (!moduleId) { console.error("MODULE_ID environment variable is required"); process.exit(1); } const client = new APIServerMCP({ moduleId: moduleId }); const toolHandlers = createToolHandlers(client.getAPIServer()); const getHandler = (name) => { const handler = toolHandlers.get(name); if (!handler) { throw new Error(`Tool ${name} not found`); } return handler; }; const server = new McpServer({ name: "bc_resource_mcp", version: "0.0.1", }); const dictionaryHandler = getHandler(tools.TOOL_DICTIONARY); server.tool(dictionaryHandler.name, dictionaryHandler.getToolDescription().description, { subject: z.string().optional().describe(dictionaryHandler.getToolDescription().inputSchema.properties.subject.description), grade: z.string().optional().describe(dictionaryHandler.getToolDescription().inputSchema.properties.grade.description), volume: z.string().optional().describe(dictionaryHandler.getToolDescription().inputSchema.properties.volume.description), press: z.string().optional().describe(dictionaryHandler.getToolDescription().inputSchema.properties.press.description), }, async (args) => { const result = await client.runTool(dictionaryHandler.name, args); const content = result[0]; if (content.type === "text") { return { content: [ { type: "text", text: content.text, }, ], }; } throw new Error("Unexpected result type from tool"); }); const listBooksHandler = getHandler(tools.TOOL_LIST_BOOKS); server.tool(listBooksHandler.name, listBooksHandler.getToolDescription().description, { subject: z.string().optional().describe(listBooksHandler.getToolDescription().inputSchema.properties.subject.description), grade: z.number().optional().describe(listBooksHandler.getToolDescription().inputSchema.properties.grade.description), volume: z.number().optional().describe(listBooksHandler.getToolDescription().inputSchema.properties.volume.description), press: z.number().optional().describe(listBooksHandler.getToolDescription().inputSchema.properties.press.description), }, async (args) => { const result = await client.runTool(listBooksHandler.name, args); const content = result[0]; if (content.type === "text") { return { content: [ { type: "text", text: content.text, }, ], }; } throw new Error("Unexpected result type from tool"); }); const listChaptersHandler = getHandler(tools.TOOL_LIST_CHAPTERS); server.tool(listChaptersHandler.name, listChaptersHandler.getToolDescription().description, { bookId: z.string().describe(listChaptersHandler.getToolDescription().inputSchema.properties.bookId.description), }, async (args) => { const result = await client.runTool(listChaptersHandler.name, args); const content = result[0]; if (content.type === "text") { return { content: [ { type: "text", text: content.text, }, ], }; } throw new Error("Unexpected result type from tool"); }); const fetchResourceHandler = getHandler(tools.TOOL_FETCH_RESOURCE); server.tool(fetchResourceHandler.name, fetchResourceHandler.getToolDescription().description, { id: z.string().describe(fetchResourceHandler.getToolDescription().inputSchema.properties.id.description), }, async (args) => { const result = await client.runTool(fetchResourceHandler.name, args); const content = result[0]; if (content.type === "text") { return { content: [ { type: "text", text: content.text, }, ], }; } throw new Error("Unexpected result type from tool"); }); server.prompt(MAIN_OVERFLOW_PROMPT.name, { user_input: z.string().describe("The content of user input") }, ({ user_input }) => { const promptText = MAIN_OVERFLOW_PROMPT.promptText.replace("{{user_input}}", user_input); return { messages: [ { role: "user", content: { type: "text", text: promptText, }, }, ], }; }); export async function startServer() { try { const transport = new StdioServerTransport(); console.error("Starting MCP server..."); await server.connect(transport); console.error("MCP Server connected and ready."); } catch (error) { console.error("Failed to start MCP server:", error); process.exit(1); } } export default server;