UNPKG

vibe-coder-mcp

Version:

Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.

116 lines (113 loc) 5.51 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import dotenv from "dotenv"; import logger from "./logger.js"; import './tools/index.js'; import './services/request-processor/index.js'; import { getAllTools, executeTool } from './services/routing/toolRegistry.js'; import { addInteraction } from './services/state/sessionState.js'; import { getUnifiedSecurityConfig } from "./tools/vibe-task-manager/security/unified-security-config.js"; dotenv.config(); export function createServer(loadedConfigParam) { logger.info({ receivedConfig: loadedConfigParam, hasMapping: Boolean(loadedConfigParam.llm_mapping), mappingKeys: loadedConfigParam.llm_mapping ? Object.keys(loadedConfigParam.llm_mapping) : [], mappingValues: loadedConfigParam.llm_mapping }, 'createServer received config object.'); try { const unifiedSecurityConfig = getUnifiedSecurityConfig(); unifiedSecurityConfig.initializeFromMCPConfig(loadedConfigParam); logger.info('Unified security configuration initialized from MCP client config'); } catch (error) { logger.warn({ err: error }, 'Failed to initialize unified security configuration from MCP client config'); } const server = new McpServer({ name: "vibe-coder-mcp", version: "1.0.0" }, { instructions: ` Vibe Coder MCP server provides tools for development automation: 1. Fullstack Starter Kit - Generates custom full-stack project starter kits 2. Research - Performs deep research using Perplexity Sonar 3. Generate Rules - Creates project-specific development rules 4. Generate PRD - Creates comprehensive product requirements documents 5. Generate User Stories - Creates detailed user stories 6. Generate Task List - Creates detailed development task lists All generated artifacts are stored in structured directories. ` }); logger.info('MCP Server initialized'); logger.info('Registering tools from Tool Registry...'); const allToolDefinitions = getAllTools(); if (allToolDefinitions.length === 0) { logger.warn('No tools found in the registry. Ensure tools register themselves via imports.'); } for (const definition of allToolDefinitions) { logger.debug(`Registering tool "${definition.name}" with MCP server.`); server.tool(definition.name, definition.description, definition.inputSchema, async (params, extra) => { logger.debug({ configInHandler: loadedConfigParam }, 'Tool handler closure using config object.'); let sessionId = 'placeholder-session-id'; let transportType = 'unknown'; if (extra && typeof extra === 'object') { if ('sessionId' in extra && typeof extra.sessionId === 'string') { sessionId = extra.sessionId; } else if ('req' in extra && extra.req && typeof extra.req === 'object') { const req = extra.req; if (req.query && req.query.sessionId) { sessionId = req.query.sessionId; } else if (req.body && req.body.session_id) { sessionId = req.body.session_id; } else if (req.headers && req.headers['x-session-id']) { sessionId = req.headers['x-session-id']; } } if ('transportType' in extra && typeof extra.transportType === 'string') { transportType = extra.transportType; } } if (sessionId === 'placeholder-session-id') { sessionId = 'stdio-session'; transportType = 'stdio'; logger.warn({ toolName: definition.name }, "Using stdio session ID. SSE notifications will be limited to polling."); } const context = { sessionId, transportType }; logger.debug({ toolName: definition.name, sessionId: context.sessionId, transportType: context.transportType }, "Server handler executing tool with context"); let executionConfig; try { const configToCopy = { ...loadedConfigParam, llm_mapping: loadedConfigParam.llm_mapping || {} }; executionConfig = JSON.parse(JSON.stringify(configToCopy)); logger.debug({ configForExecution: executionConfig }, 'Deep copied config for executeTool call.'); } catch (copyError) { logger.error({ err: copyError }, 'Failed to deep copy config in handler. Using original reference (may cause issues).'); executionConfig = loadedConfigParam; } const result = await executeTool(definition.name, params, executionConfig, context); const responseWithTimestamp = { ...result, timestamp: Date.now(), }; addInteraction(sessionId, { toolCall: { name: definition.name, params: params, timestamp: Date.now() }, response: responseWithTimestamp, }); return result; }); } logger.info(`Registered ${allToolDefinitions.length} tools dynamically with MCP server.`); return server; }