Skip to main content
Glama
server.ts25.7 kB
#!/usr/bin/env node /** * Code-MCP HTTP Server * Cloud-deployable version with HTTP transport and authentication */ import express, { Request, Response, NextFunction } from "express"; import cors from "cors"; import helmet from "helmet"; import rateLimit from "express-rate-limit"; import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { zodToJsonSchema } from "zod-to-json-schema"; // Import DB and Auth import { initDatabase, validateApiKey, UserRole } from "./db.js"; // Import Admin Tools import { generateApiKeySchema, generateApiKeyHandler, listApiKeysSchema, listApiKeysHandler, revokeApiKeySchema, revokeApiKeyHandler, } from "./tools/admin.js"; // Import all tools (same as index.ts) import { sequentialThinkingSchema, sequentialThinkingHandler, } from "./tools/thinking.js"; import { saveMemorySchema, readMemorySchema, listMemoriesSchema, clearMemorySchema, saveMemoryHandler, readMemoryHandler, listMemoriesHandler, clearMemoryHandler, } from "./tools/memory.js"; import { validateCodeSchema, validateCodeHandler } from "./tools/validator.js"; import { generateCursorRulesSchema, generateCursorRulesHandler, generateGeminiConfigSchema, generateGeminiConfigHandler, generateClaudeConfigSchema, generateClaudeConfigHandler, generateWindsurfConfigSchema, generateWindsurfConfigHandler, generateAiderConfigSchema, generateAiderConfigHandler, generateClineConfigSchema, generateClineConfigHandler, generateCopilotConfigSchema, generateCopilotConfigHandler, } from "./tools/aiconfigs.js"; import { planTaskSchema, planTaskHandler, reflectOnCodeSchema, reflectOnCodeHandler, analyzeArchitectureSchema, analyzeArchitectureHandler, debugProblemSchema, debugProblemHandler, brainstormSolutionsSchema, brainstormSolutionsHandler, compareApproachesSchema, compareApproachesHandler, estimateComplexitySchema, estimateComplexityHandler, generateTestsSchema, generateTestsHandler, explainCodeSchema, explainCodeHandler, } from "./tools/cognitive.js"; import { checkImportsSchema, checkImportsHandler, lintCodeSchema, lintCodeHandler, formatCodeSchema, formatCodeHandler, } from "./tools/linting.js"; import { generateContinueConfigSchema, generateContinueConfigHandler, generateTabnineConfigSchema, generateTabnineConfigHandler, generateVSCodeTasksSchema, generateVSCodeTasksHandler, generateVSCodeLaunchSchema, generateVSCodeLaunchHandler, generateJetBrainsConfigSchema, generateJetBrainsConfigHandler, } from "./tools/ideconfigs.js"; import { trackProjectSchema, trackProjectHandler, checkDependenciesSchema, checkDependenciesHandler, generateGitHubActionsSchema, generateGitHubActionsHandler, fullStackScaffoldSchema, fullStackScaffoldHandler, developerRulesSchema, developerRulesHandler, enforceProjectStandardsSchema, enforceProjectStandardsHandler, } from "./tools/fullstack.js"; import { generateClientConfigSchema, generateClientConfigHandler, } from "./tools/config_generator.js"; // Additional tools (syncing with index.ts) import { analyzePythonAstSchema, analyzePythonAstHandler, checkPythonDepsSchema, checkPythonDepsHandler, } from "./tools/python.js"; import { analyzeGoModSchema, analyzeGoModHandler, goStructHelperSchema, goStructHelperHandler, } from "./tools/go.js"; import { generateTerraformResourceSchema, generateTerraformResourceHandler, generateObservabilitySchema, generateObservabilityHandler, generateK8sManifestSchema, generateK8sManifestHandler, generateTerraformConfigSchema, generateTerraformConfigHandler, generateNginxConfigSchema, generateNginxConfigHandler, } from "./tools/infrastructure.js"; import { runTestsSafeSchema, runTestsSafeHandler, analyzeCoverageSchema, analyzeCoverageHandler, } from "./tools/testing.js"; import { generateSnippetSchema, generateSnippetHandler, regexBuilderSchema, regexBuilderHandler, } from "./tools/generators.js"; import { gitHelperSchema, gitHelperHandler, packageJsonSchema, packageJsonHandler, dockerfileSchema, dockerfileHandler, envTemplateSchema, envTemplateHandler, } from "./tools/utilities.js"; import { typescriptHelperSchema, typescriptHelperHandler, apiClientSchema, apiClientHandler, sqlHelperSchema, sqlHelperHandler, readmeGeneratorSchema, readmeGeneratorHandler, licenseGeneratorSchema, licenseGeneratorHandler, } from "./tools/advanced.js"; import { decisionMatrixSchema, decisionMatrixHandler, consequenceAnalysisSchema, consequenceAnalysisHandler, conceptAssociationSchema, conceptAssociationHandler, derivePatternsSchema, derivePatternsHandler, researchSynthesisSchema, researchSynthesisHandler, sixThinkingHatsSchema, sixThinkingHatsHandler, logicalFallacyCheckSchema, logicalFallacyCheckHandler, causalLoopDiagramSchema, causalLoopDiagramHandler, } from "./tools/agentic.js"; import { generateDiagramSchema, generateDiagramHandler, visualizeSystemSchema, visualizeSystemHandler, } from "./tools/visualization.js"; import { generateCommitMessageSchema, generateCommitMessageHandler, generatePRDescriptionSchema, generatePRDescriptionHandler, updateChangelogSchema, updateChangelogHandler, } from "./tools/communication.js"; import { suggestToolChainSchema, suggestToolChainHandler, projectProfilerSchema, projectProfilerHandler, } from "./tools/coordination.js"; import { analyzeComplexitySchema, analyzeComplexityHandler, securityScanSchema, securityScanHandler, } from "./tools/quality.js"; import { convertFormatSchema, convertFormatHandler, generateMockDataSchema, generateMockDataHandler, } from "./tools/data.js"; import { listFilesSchema, listFilesHandler, readFileSnippetSchema, readFileSnippetHandler, searchFilesSchema, searchFilesHandler, fileTreeSchema, fileTreeHandler, } from "./tools/filesystem.js"; import { summarizeFilesSchema, summarizeFilesHandler, aggregateContextSchema, aggregateContextHandler, } from "./tools/context.js"; import { defineUserStoriesSchema, defineUserStoriesHandler, createPersonasSchema, createPersonasHandler, marketAnalysisSchema, marketAnalysisHandler, } from "./tools/product.js"; import { getTemplateSchema, getTemplateHandler } from "./tools/templates.js"; import { generateOpenApiSpecSchema, generateOpenApiSpecHandler, usageStatsSchema, } from "./tools/api.js"; import { getUsageStats, logUsage } from "./db.js"; // Import new self-improvement tools import { generateDocumentationSchema, generateDocumentationHandler, } from "./tools/documentation.js"; import { dashboardGeneratorSchema, dashboardGeneratorHandler, } from "./tools/dashboard.js"; import { prompts, getPrompt } from "./prompts.js"; // Load registries import languagesRegistry from "./data/languages.json" with { type: "json" }; import databasesRegistry from "./data/databases.json" with { type: "json" }; import frameworksRegistry from "./data/frameworks.json" with { type: "json" }; // Extend Express Request to include User interface AuthenticatedRequest extends Request { user?: { id: number; role: UserRole; }; } const app = express(); // Security Headers app.use(helmet()); app.use(cors()); app.use(express.json()); // Initialize DB initDatabase().catch(console.error); // Rate Limiter (Users only, Admins exempt, configurable via env) const limiter = rateLimit({ windowMs: parseInt(process.env.RATE_LIMIT_WINDOW || "900000"), // Default: 15 minutes limit: parseInt(process.env.RATE_LIMIT_MAX || "100"), // Default: 100 requests standardHeaders: true, legacyHeaders: false, message: { error: "Too many requests, please try again later." }, skip: (req) => { // Skip rate limiting for admins const user = (req as AuthenticatedRequest).user; return user?.role === "admin"; }, }); // Auth Middleware (Async DB Check) const authMiddleware = async ( req: AuthenticatedRequest, res: Response, next: NextFunction, ) => { const key = req.headers["x-api-key"] as string; if (!key) { return res.status(401).json({ error: "Missing API Key" }); } const user = await validateApiKey(key); if (!user) { return res.status(401).json({ error: "Invalid API Key" }); } req.user = { id: user.id, role: user.role }; next(); }; // Tool registry const toolRegistry = new Map< string, { schema: any; handler: any; adminOnly?: boolean } >([ // Admin Tools [ "generate_api_key", { schema: generateApiKeySchema, handler: generateApiKeyHandler, adminOnly: true, }, ], [ "list_api_keys", { schema: listApiKeysSchema, handler: listApiKeysHandler, adminOnly: true }, ], [ "revoke_api_key", { schema: revokeApiKeySchema, handler: revokeApiKeyHandler, adminOnly: true, }, ], // Standard Tools [ "sequential_thinking", { schema: sequentialThinkingSchema, handler: sequentialThinkingHandler }, ], ["plan_task", { schema: planTaskSchema, handler: planTaskHandler }], [ "reflect_on_code", { schema: reflectOnCodeSchema, handler: reflectOnCodeHandler }, ], [ "analyze_architecture", { schema: analyzeArchitectureSchema, handler: analyzeArchitectureHandler }, ], [ "debug_problem", { schema: debugProblemSchema, handler: debugProblemHandler }, ], [ "brainstorm_solutions", { schema: brainstormSolutionsSchema, handler: brainstormSolutionsHandler }, ], [ "compare_approaches", { schema: compareApproachesSchema, handler: compareApproachesHandler }, ], [ "estimate_complexity", { schema: estimateComplexitySchema, handler: estimateComplexityHandler }, ], [ "generate_tests", { schema: generateTestsSchema, handler: generateTestsHandler }, ], ["explain_code", { schema: explainCodeSchema, handler: explainCodeHandler }], ["save_memory", { schema: saveMemorySchema, handler: saveMemoryHandler }], ["read_memory", { schema: readMemorySchema, handler: readMemoryHandler }], [ "list_memories", { schema: listMemoriesSchema, handler: listMemoriesHandler }, ], ["clear_memory", { schema: clearMemorySchema, handler: clearMemoryHandler }], [ "validate_code", { schema: validateCodeSchema, handler: validateCodeHandler }, ], [ "check_imports", { schema: checkImportsSchema, handler: checkImportsHandler }, ], ["lint_code", { schema: lintCodeSchema, handler: lintCodeHandler }], ["format_code", { schema: formatCodeSchema, handler: formatCodeHandler }], [ "generate_cursor_rules", { schema: generateCursorRulesSchema, handler: generateCursorRulesHandler }, ], [ "generate_gemini_config", { schema: generateGeminiConfigSchema, handler: generateGeminiConfigHandler, }, ], [ "generate_claude_config", { schema: generateClaudeConfigSchema, handler: generateClaudeConfigHandler, }, ], [ "generate_windsurf_config", { schema: generateWindsurfConfigSchema, handler: generateWindsurfConfigHandler, }, ], [ "generate_aider_config", { schema: generateAiderConfigSchema, handler: generateAiderConfigHandler }, ], [ "generate_cline_config", { schema: generateClineConfigSchema, handler: generateClineConfigHandler }, ], [ "generate_copilot_config", { schema: generateCopilotConfigSchema, handler: generateCopilotConfigHandler, }, ], [ "generate_continue_config", { schema: generateContinueConfigSchema, handler: generateContinueConfigHandler, }, ], [ "generate_tabnine_config", { schema: generateTabnineConfigSchema, handler: generateTabnineConfigHandler, }, ], [ "generate_vscode_tasks", { schema: generateVSCodeTasksSchema, handler: generateVSCodeTasksHandler }, ], [ "generate_vscode_launch", { schema: generateVSCodeLaunchSchema, handler: generateVSCodeLaunchHandler, }, ], [ "generate_jetbrains_config", { schema: generateJetBrainsConfigSchema, handler: generateJetBrainsConfigHandler, }, ], [ "track_project", { schema: trackProjectSchema, handler: trackProjectHandler }, ], [ "check_dependencies", { schema: checkDependenciesSchema, handler: checkDependenciesHandler }, ], [ "generate_github_actions", { schema: generateGitHubActionsSchema, handler: generateGitHubActionsHandler, }, ], [ "full_stack_scaffold", { schema: fullStackScaffoldSchema, handler: fullStackScaffoldHandler }, ], [ "developer_rules", { schema: developerRulesSchema, handler: developerRulesHandler }, ], [ "generate_client_config", { schema: generateClientConfigSchema, handler: generateClientConfigHandler, }, ], [ "enforce_project_standards", { schema: enforceProjectStandardsSchema, handler: enforceProjectStandardsHandler, }, ], // Python tools [ "analyze_python_ast", { schema: analyzePythonAstSchema, handler: analyzePythonAstHandler }, ], [ "check_python_deps", { schema: checkPythonDepsSchema, handler: checkPythonDepsHandler }, ], // Go tools [ "analyze_go_mod", { schema: analyzeGoModSchema, handler: analyzeGoModHandler }, ], [ "go_struct_helper", { schema: goStructHelperSchema, handler: goStructHelperHandler }, ], // Infrastructure tools [ "generate_terraform_resource", { schema: generateTerraformResourceSchema, handler: generateTerraformResourceHandler, }, ], [ "generate_observability_config", { schema: generateObservabilitySchema, handler: generateObservabilityHandler, }, ], [ "generate_k8s_manifest", { schema: generateK8sManifestSchema, handler: generateK8sManifestHandler }, ], [ "generate_terraform_config", { schema: generateTerraformConfigSchema, handler: generateTerraformConfigHandler, }, ], [ "generate_nginx_config", { schema: generateNginxConfigSchema, handler: generateNginxConfigHandler }, ], // Testing tools [ "run_tests_safe", { schema: runTestsSafeSchema, handler: runTestsSafeHandler }, ], [ "analyze_coverage", { schema: analyzeCoverageSchema, handler: analyzeCoverageHandler }, ], // Generator tools [ "generate_snippet", { schema: generateSnippetSchema, handler: generateSnippetHandler }, ], [ "regex_builder", { schema: regexBuilderSchema, handler: regexBuilderHandler }, ], // Utility tools ["git_helper", { schema: gitHelperSchema, handler: gitHelperHandler }], [ "generate_package_json", { schema: packageJsonSchema, handler: packageJsonHandler }, ], [ "generate_dockerfile", { schema: dockerfileSchema, handler: dockerfileHandler }, ], [ "generate_env_template", { schema: envTemplateSchema, handler: envTemplateHandler }, ], // Advanced tools [ "typescript_helper", { schema: typescriptHelperSchema, handler: typescriptHelperHandler }, ], [ "generate_api_client", { schema: apiClientSchema, handler: apiClientHandler }, ], ["sql_helper", { schema: sqlHelperSchema, handler: sqlHelperHandler }], [ "generate_readme", { schema: readmeGeneratorSchema, handler: readmeGeneratorHandler }, ], [ "generate_license", { schema: licenseGeneratorSchema, handler: licenseGeneratorHandler }, ], // Agentic tools [ "decision_matrix", { schema: decisionMatrixSchema, handler: decisionMatrixHandler }, ], [ "consequence_analysis", { schema: consequenceAnalysisSchema, handler: consequenceAnalysisHandler }, ], [ "concept_association", { schema: conceptAssociationSchema, handler: conceptAssociationHandler }, ], [ "derive_patterns", { schema: derivePatternsSchema, handler: derivePatternsHandler }, ], [ "research_synthesis", { schema: researchSynthesisSchema, handler: researchSynthesisHandler }, ], [ "six_thinking_hats", { schema: sixThinkingHatsSchema, handler: sixThinkingHatsHandler }, ], [ "logical_fallacy_check", { schema: logicalFallacyCheckSchema, handler: logicalFallacyCheckHandler }, ], [ "causal_loop_diagram", { schema: causalLoopDiagramSchema, handler: causalLoopDiagramHandler }, ], // Visualization tools [ "generate_diagram", { schema: generateDiagramSchema, handler: generateDiagramHandler }, ], [ "visualize_system", { schema: visualizeSystemSchema, handler: visualizeSystemHandler }, ], // Communication tools [ "generate_commit_message", { schema: generateCommitMessageSchema, handler: generateCommitMessageHandler, }, ], [ "generate_pr_description", { schema: generatePRDescriptionSchema, handler: generatePRDescriptionHandler, }, ], [ "update_changelog", { schema: updateChangelogSchema, handler: updateChangelogHandler }, ], // Coordination tools [ "suggest_tool_chain", { schema: suggestToolChainSchema, handler: suggestToolChainHandler }, ], [ "project_profiler", { schema: projectProfilerSchema, handler: projectProfilerHandler }, ], // Quality tools [ "analyze_complexity", { schema: analyzeComplexitySchema, handler: analyzeComplexityHandler }, ], [ "security_scan", { schema: securityScanSchema, handler: securityScanHandler }, ], // Data tools [ "convert_format", { schema: convertFormatSchema, handler: convertFormatHandler }, ], [ "generate_mock_data", { schema: generateMockDataSchema, handler: generateMockDataHandler }, ], // Filesystem tools ["list_files", { schema: listFilesSchema, handler: listFilesHandler }], [ "read_file_snippet", { schema: readFileSnippetSchema, handler: readFileSnippetHandler }, ], ["search_files", { schema: searchFilesSchema, handler: searchFilesHandler }], ["get_file_tree", { schema: fileTreeSchema, handler: fileTreeHandler }], // Context tools [ "summarize_files", { schema: summarizeFilesSchema, handler: summarizeFilesHandler }, ], [ "aggregate_context", { schema: aggregateContextSchema, handler: aggregateContextHandler }, ], // Product tools [ "define_user_stories", { schema: defineUserStoriesSchema, handler: defineUserStoriesHandler }, ], [ "create_personas", { schema: createPersonasSchema, handler: createPersonasHandler }, ], [ "perform_market_analysis", { schema: marketAnalysisSchema, handler: marketAnalysisHandler }, ], // Template tools ["get_template", { schema: getTemplateSchema, handler: getTemplateHandler }], // API tools (Admin) [ "get_usage_stats", { schema: usageStatsSchema, handler: async (args: { userId?: number }) => { const stats = await getUsageStats(args.userId); return { content: [ { type: "text", text: `# Usage Statistics\n\n${stats.map((s) => `- **${s.tool_name}**: ${s.count} calls`).join("\n")}`, }, ], }; }, adminOnly: true, }, ], // Self-Improvement tools [ "generate_documentation", { schema: generateDocumentationSchema, handler: generateDocumentationHandler, }, ], [ "generate_dashboard", { schema: dashboardGeneratorSchema, handler: dashboardGeneratorHandler, }, ], ]); // Health check app.get("/", (req, res) => { res.send(` <html> <head><title>Code-MCP Running</title></head> <body style="font-family: sans-serif; padding: 2rem;"> <h1>🚀 Code-MCP is Running</h1> <p>Status: <strong>Healthy</strong></p> <p>Version: 1.2.0</p> <p><a href="/health">Check Health JSON</a></p> </body> </html> `); }); // Health check JSON app.get("/health", (req, res) => { res.json({ status: "healthy", version: "1.2.0", tools: toolRegistry.size, resources: (languagesRegistry as any).languages.length + (databasesRegistry as any).databases.length + (frameworksRegistry as any).frameworks.length, prompts: Object.keys(prompts).length, }); }); // List tools (auth + rate limit) app.get("/tools", authMiddleware, limiter, (req, res) => { // Show all tools to everyone (or filter? let's show, but fail on call) // Actually, good security practice: don't even show admin tools to non-admins if possible. // For now, listing them is fine, better for discovery. const tools = Array.from(toolRegistry.values()).map(({ schema }) => ({ name: schema.name, description: schema.description, inputSchema: zodToJsonSchema(schema.inputSchema), })); res.json({ tools }); }); // Call tool app.post( "/tools/:name", authMiddleware, async (req: AuthenticatedRequest, res: Response) => { const { name } = req.params; const args = req.body; const tool = toolRegistry.get(name); if (!tool) { return res.status(404).json({ error: `Tool not found: ${name}` }); } // Role Guard if (tool.adminOnly && req.user?.role !== "admin") { console.warn( `User ${req.user?.id} attempted to access admin tool ${name}`, ); return res .status(403) .json({ error: "Forbidden: Admin access required" }); } const startTime = Date.now(); try { const result = await tool.handler(args); // Log usage (async, don't block response) if (req.user?.id) { logUsage(req.user.id, name, Date.now() - startTime).catch(() => {}); } res.json(result); } catch (error) { res.status(500).json({ error: (error as Error).message }); } }, ); // List resources app.get("/resources", authMiddleware, (req, res) => { const langs = (languagesRegistry as any).languages.map((l: any) => ({ uri: `code-rules://language/${l.id}`, name: `${l.name} Coding Rules`, })); const dbs = (databasesRegistry as any).databases.map((d: any) => ({ uri: `code-rules://database/${d.id}`, name: `${d.name} Best Practices`, })); const fws = (frameworksRegistry as any).frameworks.map((f: any) => ({ uri: `code-rules://framework/${f.id}`, name: `${f.name} Best Practices`, })); res.json({ resources: [...langs, ...dbs, ...fws] }); }); // List prompts app.get("/prompts", authMiddleware, (req, res) => { res.json({ prompts: Object.values(prompts).map((p) => ({ name: p.name, description: p.description, })), }); }); // MCP-compatible endpoint (JSON-RPC) app.post( "/mcp", authMiddleware, async (req: AuthenticatedRequest, res: Response) => { const { jsonrpc, id, method, params } = req.body; try { let result; switch (method) { case "tools/list": result = { tools: Array.from(toolRegistry.values()).map(({ schema }) => ({ name: schema.name, description: schema.description, inputSchema: zodToJsonSchema(schema.inputSchema), })), }; break; case "tools/call": const tool = toolRegistry.get(params.name); if (!tool) throw new Error(`Tool not found: ${params.name}`); // Role Guard if (tool.adminOnly && req.user?.role !== "admin") { throw new Error("Forbidden: Admin access required"); } result = await tool.handler(params.arguments); break; // Add other MCP methods as needed (resources/list, prompts/list, etc) default: // For now, minimal implementation. // ideally implement specific handlers or reuse existing logic if (method === "resources/list") { /* ... */ } // throw new Error(`Unknown method: ${method}`); // Return empty/null or handle gracefully result = {}; } res.json({ jsonrpc: "2.0", id, result }); } catch (error) { res.json({ jsonrpc: "2.0", id, error: { message: (error as Error).message }, }); } }, ); const PORT = process.env.PORT || 3000; // Track database initialization state let dbInitialized = false; let dbError: Error | null = null; // Start HTTP server immediately for health checks app.listen(PORT, () => { console.log(`Code-MCP HTTP Server running on port ${PORT}`); console.log(`Join our Discord: https://discord.gg/UzP2fRefKh`); console.log( `Tools: ${toolRegistry.size} | Resources: 130+ | Prompts: ${Object.keys(prompts).length}`, ); // Initialize database in background (only if DATABASE_URL is set) if (process.env.DATABASE_URL) { console.log("DATABASE_URL found, initializing database in background..."); initDatabase() .then(() => { dbInitialized = true; console.log("Database initialized successfully"); console.log("Auth: PostgreSQL"); }) .catch((error) => { dbError = error as Error; console.error("Database initialization failed:", error); console.log( "Server will continue running but auth features may not work", ); }); } else { console.log("No DATABASE_URL - running in local/no-auth mode"); console.log("Auth: Disabled"); } });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/millsydotdev/Code-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server