UNPKG

survey-mcp-server

Version:
126 lines (125 loc) 5.31 kB
#!/usr/bin/env node import dotenv from 'dotenv'; // Load environment variables from .env file dotenv.config(); import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { toolDefinitions } from "./tools/schemas.js"; import * as toolHandlers from "./tools/handlers.js"; import * as resourceHandlers from "./resources/handlers.js"; import { resourceDefinitions } from "./resources/resources.js"; import * as promptHandlers from "./prompts/handlers.js"; import { promptDefinitions } from "./prompts/prompts.js"; import fs from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Register tools export function registerTools(server) { Object.values(toolDefinitions).forEach((tool) => { const handler = toolHandlers[tool.name]; if (!handler) { throw new Error(`Handler not found for tool: ${tool.name}`); } server.tool(tool.name, tool.description, tool.schema, handler); }); } // Register resources export function registerResources(server) { Object.values(resourceDefinitions).forEach((resource) => { const handler = resourceHandlers[resource.method]; if (!handler) { throw new Error(`Handler not found for resource: ${resource.method}`); } console.error(`Registering resource: ${resource.name} at ${resource.uri}`); // Convert URI format from <param> to {param} for ResourceTemplate const templateUri = resource.uri.replace(/<([^>]+)>/g, '{$1}'); const template = new ResourceTemplate(templateUri, { list: undefined, // Not listing all resources }); try { server.resource(resource.name, template, { description: resource.description, mimeType: resource.mimeType, }, async (uri, variables) => { console.error(`Resource read requested: ${uri.toString()}`); console.error(`Variables:`, JSON.stringify(variables)); // Extract the identifier from the variables object // For "user://details/{user_id}", variables will contain { user_id: "..." } // For "vessel://managers/{imo}", variables will contain { imo: "..." } const userId = variables.user_id; const imo = variables.imo; const identifier = (Array.isArray(userId) ? userId[0] : userId) || (Array.isArray(imo) ? imo[0] : imo) || ''; console.error(`Calling handler with identifier: ${identifier}`); const result = await handler(identifier); return { contents: [ { uri: uri.toString(), mimeType: resource.mimeType, text: JSON.stringify(result, null, 2), }, ], }; }); console.error(`✓ Successfully registered resource: ${resource.name}`); } catch (error) { console.error(`✗ Failed to register resource: ${resource.name}`, error); throw error; } }); } // Register prompts export function registerPrompts(server) { promptDefinitions.forEach((prompt) => { const handler = promptHandlers[prompt.name]; if (!handler) { throw new Error(`Handler not found for prompt: ${prompt.name}`); } console.error(`Registering prompt: ${prompt.name}`); server.prompt(prompt.name, prompt.description, prompt.arguments, async (args) => { console.error(`Prompt requested: ${prompt.name}`); const content = await handler(args); return { messages: [ { role: "assistant", content: { type: "text", text: content, }, }, ], }; }); console.error(`✓ Successfully registered prompt: ${prompt.name}`); }); } // Create server instance const packageJson = fs.readFileSync(join(__dirname, '..', 'package.json'), 'utf8'); const packageJsonObject = JSON.parse(packageJson); const server = new McpServer({ name: packageJsonObject.name, version: packageJsonObject.version, }); // Register tools, resources, and prompts console.error("Registering tools..."); registerTools(server); console.error("Registering resources..."); registerResources(server); console.error(`Registered ${Object.keys(resourceDefinitions).length} resources`); console.error("Registering prompts..."); registerPrompts(server); console.error(`Registered ${promptDefinitions.length} prompts`); async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error(`${packageJsonObject.name} MCP Server running on stdio`); } main().catch((error) => { console.error("Fatal error in main():", error); process.exit(1); });