bc_resource_mcp-beta
Version:
MCP server for Baichuan resource
139 lines (138 loc) • 5.47 kB
JavaScript
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;