Skip to main content
Glama
portel-dev

NCP - Natural Context Provider

by portel-dev
dummy-mcp-server.ts9.23 kB
#!/usr/bin/env node /** * Configurable Dummy MCP Server * * This server loads tool definitions from a JSON file and provides realistic MCP interfaces * for testing the semantic enhancement system. All tool calls return dummy results. * * Usage: * node dummy-mcp-server.js --mcp-name shell * node dummy-mcp-server.js --mcp-name postgres * node dummy-mcp-server.js --definitions-file custom.json --mcp-name myMcp */ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, ErrorCode, McpError, } from '@modelcontextprotocol/sdk/types.js'; import * as fs from 'fs'; import * as path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); interface ToolDefinition { name: string; description: string; inputSchema: any; } interface McpDefinition { name: string; version: string; description: string; category: string; tools: Record<string, ToolDefinition>; } interface McpDefinitionsFile { mcps: Record<string, McpDefinition>; } class DummyMcpServer { private mcpDefinition: McpDefinition; private server: Server; constructor(definitionsFile: string, mcpName: string) { // Load MCP definition from JSON this.mcpDefinition = this.loadMcpDefinition(definitionsFile, mcpName); // Create MCP server this.server = new Server( { name: this.mcpDefinition.name, version: this.mcpDefinition.version, }, { capabilities: { tools: {}, }, } ); this.setupHandlers(); } private loadMcpDefinition(definitionsFile: string, mcpName: string): McpDefinition { try { const fullPath = path.resolve(definitionsFile); const fileContent = fs.readFileSync(fullPath, 'utf-8'); const definitions: McpDefinitionsFile = JSON.parse(fileContent); if (!definitions.mcps[mcpName]) { throw new Error(`MCP '${mcpName}' not found in definitions file. Available: ${Object.keys(definitions.mcps).join(', ')}`); } const mcpDef = definitions.mcps[mcpName]; console.error(`[${mcpName}] Loaded MCP with ${Object.keys(mcpDef.tools).length} tools: ${Object.keys(mcpDef.tools).join(', ')}`); return mcpDef; } catch (error: any) { console.error(`Failed to load MCP definition: ${error.message}`); process.exit(1); } } private setupHandlers(): void { // List tools handler this.server.setRequestHandler(ListToolsRequestSchema, async () => { const tools = Object.values(this.mcpDefinition.tools).map(tool => ({ name: tool.name, description: tool.description, inputSchema: tool.inputSchema, })); return { tools }; }); // Call tool handler this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; const tool = this.mcpDefinition.tools[name]; if (!tool) { throw new McpError(ErrorCode.MethodNotFound, `Tool '${name}' not found`); } // Generate dummy result based on tool type and MCP category const result = this.generateDummyResult(name, args, this.mcpDefinition); return { content: [ { type: 'text', text: result, }, ], }; }); } private generateDummyResult(toolName: string, args: any, mcpDef: McpDefinition): string { const mcpName = mcpDef.name; const category = mcpDef.category; // Generate contextually appropriate dummy responses switch (category) { case 'system-operations': if (toolName === 'run_command') { return `[DUMMY] Command executed: ${args.command}\nOutput: Command completed successfully\nExit code: 0`; } if (toolName === 'build') { return `[DUMMY] Docker build completed for tag: ${args.tag}\nImage ID: sha256:abc123def456\nSize: 45.2MB`; } if (toolName === 'run') { return `[DUMMY] Container started from image: ${args.image}\nContainer ID: abc123def456\nStatus: running`; } break; case 'developer-tools': if (toolName === 'commit') { return `[DUMMY] Git commit created\nCommit hash: abc123def456\nMessage: ${args.message}\nFiles changed: ${args.files?.length || 'all'} files`; } if (toolName === 'push') { return `[DUMMY] Pushed to ${args.remote || 'origin'}/${args.branch || 'main'}\nObjects pushed: 3 commits, 12 files\nStatus: up-to-date`; } if (toolName === 'create_repository') { return `[DUMMY] Repository created: ${args.name}\nURL: https://github.com/user/${args.name}\nPrivate: ${args.private || false}`; } if (toolName === 'create_issue') { return `[DUMMY] Issue created in ${args.repository}\nIssue #42: ${args.title}\nLabels: ${args.labels?.join(', ') || 'none'}`; } break; case 'database': if (toolName === 'query') { return `[DUMMY] Query executed: ${args.sql}\nRows returned: 15\nExecution time: 2.3ms`; } if (toolName === 'insert') { return `[DUMMY] Data inserted into ${args.table}\nRows affected: 1\nReturning: ${JSON.stringify(args.returning || ['id'])}`; } break; case 'financial': if (toolName === 'charge') { return `[DUMMY] Payment processed\nAmount: $${(args.amount / 100).toFixed(2)}\nCharge ID: ch_dummy123456\nStatus: succeeded`; } if (toolName === 'refund') { return `[DUMMY] Refund processed\nCharge ID: ${args.charge_id}\nRefund ID: re_dummy123456\nAmount: $${args.amount ? (args.amount / 100).toFixed(2) : 'full'}\nStatus: succeeded`; } break; case 'cloud-infrastructure': if (toolName === 'deploy') { return `[DUMMY] Deployment to AWS ${args.service} in ${args.region}\nDeployment ID: deploy-dummy123\nStatus: successful\nEndpoint: https://api.example.com`; } if (toolName === 's3_upload') { return `[DUMMY] File uploaded to S3\nBucket: ${args.bucket}\nKey: ${args.key}\nSize: 2.4MB\nETag: "abc123def456"`; } break; case 'ai-ml': if (toolName === 'completion' || toolName === 'generate') { const prompt = args.prompt || args.messages?.[0]?.content || 'user prompt'; return `[DUMMY] AI Response Generated\nModel: ${args.model || 'gpt-4'}\nPrompt: "${prompt.substring(0, 50)}..."\nResponse: "This is a dummy AI-generated response for testing purposes. The actual response would be contextually relevant to your prompt."\nTokens: 45`; } break; default: return `[DUMMY] Tool '${toolName}' executed successfully\nMCP: ${mcpName}\nArguments: ${JSON.stringify(args, null, 2)}\nResult: Operation completed`; } // Fallback generic response return `[DUMMY] Tool '${toolName}' from ${mcpName} MCP executed successfully\nArguments: ${JSON.stringify(args, null, 2)}\nResult: Operation completed`; } async start(): Promise<void> { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error(`[${this.mcpDefinition.name}] Dummy MCP Server started - providing ${Object.keys(this.mcpDefinition.tools).length} tools`); } } // Command line interface function parseArgs(): { definitionsFile: string; mcpName: string } { const args = process.argv.slice(2); let definitionsFile = path.join(__dirname, 'mcp-definitions.json'); let mcpName = ''; for (let i = 0; i < args.length; i++) { switch (args[i]) { case '--definitions-file': definitionsFile = args[++i]; break; case '--mcp-name': mcpName = args[++i]; break; case '--help': console.log(` Usage: node dummy-mcp-server.js --mcp-name <name> [--definitions-file <path>] Options: --mcp-name <name> Name of MCP to simulate (required) --definitions-file <path> Path to JSON definitions file (default: mcp-definitions.json) --help Show this help message Examples: node dummy-mcp-server.js --mcp-name shell node dummy-mcp-server.js --mcp-name postgres node dummy-mcp-server.js --mcp-name github --definitions-file custom.json `); process.exit(0); break; } } if (!mcpName) { console.error('Error: --mcp-name is required'); console.error('Use --help for usage information'); process.exit(1); } return { definitionsFile, mcpName }; } // Main execution async function main(): Promise<void> { try { const { definitionsFile, mcpName } = parseArgs(); const server = new DummyMcpServer(definitionsFile, mcpName); await server.start(); } catch (error) { console.error('Failed to start dummy MCP server:', error); process.exit(1); } } if (import.meta.url === `file://${process.argv[1]}`) { main().catch((error) => { console.error('Unhandled error:', error); process.exit(1); }); } export { DummyMcpServer };

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/portel-dev/ncp'

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