UNPKG

@trishchuk/ai-think-gate-mcp

Version:

Model Context Protocol (MCP) server that provides AI-powered thinking and code architecture tools

165 lines (164 loc) 5.57 kB
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { logService } from '../services/logging-service.js'; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { toolRegistry } from './registry.js'; import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"; /** * MCP server implementation */ export class MCPServer { constructor() { this.server = new Server({ name: "thinkgate-mcp", version: "1.0.0", }, { capabilities: { tools: {}, } }); } /** * Start the MCP server */ async start() { try { // Connect to transport const transport = new StdioServerTransport(); await this.server.connect(transport); // Set up request handlers this.setupRequestHandlers(); logService.log(`ThinkGate-MCP server started`); } catch (error) { logService.error(`Failed to start MCP server: ${error}`); throw error; } } /** * Set up request handlers for the server */ setupRequestHandlers() { // Handle tools listing request this.server.setRequestHandler(ListToolsRequestSchema, async () => { logService.debug("Handling tools/list request"); // Convert to expected type format using type assertion const tools = toolRegistry.getAllTools(); return { tools }; }); // Handle tool call request this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args, _meta } = request.params; logService.log(`Handling tools/call request for ${name}`); const tool = toolRegistry.getToolByName(name); if (!tool) { return this.createErrorResponse(`Tool '${name}' not found`); } try { const result = await this.executeToolWithProgress(tool, args, _meta?.progressToken); return { content: result.content, isError: result.isError }; } catch (error) { logService.error(`Error executing tool ${name}: ${error}`); return this.createErrorResponse(`Error executing tool ${name}: ${error?.message || 'Unknown error'}`); } }); } /** * Execute a tool with progress updates */ async executeToolWithProgress(tool, args, progressToken) { try { // Send initial progress if token is provided if (progressToken) { await this.sendProgressNotification(progressToken, 0, 100, `Starting ${tool.name}...`); } // Execute the tool const result = await tool.execute(args); // Send completion progress if token is provided if (progressToken) { await this.sendProgressNotification(progressToken, 100, 100, `Completed ${tool.name}`); } return result; } catch (error) { // Send error progress if token is provided if (progressToken) { await this.sendProgressNotification(progressToken, 100, 100, `Error in ${tool.name}: ${error?.message || 'Unknown error'}`); } throw error; } } /** * Send a progress notification */ async sendProgressNotification(progressToken, progress, total, message) { try { await this.server.notification({ method: "notifications/progress", params: { progressToken, progress, total, message } }); } catch (error) { logService.warn(`Failed to send progress notification: ${error}`); } } /** * Create an error response */ createErrorResponse(errorMessage) { return { content: [{ type: "text", text: errorMessage, annotations: { priority: 1.0, audience: ["user", "assistant"] } }], isError: true }; } /** * Send a notification that tools have changed */ async sendToolsChangedNotification() { // Debounce notification to avoid sending too many if (this.notifyTimeout) { clearTimeout(this.notifyTimeout); } this.notifyTimeout = setTimeout(async () => { try { await this.server.notification({ method: "notifications/tools/changed", params: {} }); logService.debug("Sent tools changed notification"); } catch (error) { logService.warn(`Failed to send tools changed notification: ${error}`); } }, 500); } /** * Stop the MCP server */ async stop() { try { await this.server.close(); logService.log("MCP server stopped"); } catch (error) { logService.error(`Error stopping MCP server: ${error}`); } } } // Export a singleton instance export const mcpServer = new MCPServer();