UNPKG

node-red-contrib-mcp-server

Version:

A comprehensive Node-RED wrapper for Model Context Protocol (MCP) servers providing standardized AI agent tool interfaces, server lifecycle management, real-time communication capabilities, and visual MCP server creation

298 lines (297 loc) 11.6 kB
[ { "id": "mcp-flow-example", "type": "tab", "label": "Flow-Based MCP Server Example", "disabled": false, "info": "This flow demonstrates creating a complete MCP server within Node-RED.\n\n**Setup:**\n1. Deploy this flow\n2. The MCP Flow Server will start on port 8001\n3. Test with: curl -X POST http://localhost:8001/mcp -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\",\"params\":{}}'\n\n**Features:**\n- Complete MCP server running in Node-RED\n- Custom tools defined visually\n- Calculator and greeting tools\n- Auto-start server\n- Tool execution handled by flows" }, { "id": "mcp-flow-server-1", "type": "mcp-flow-server", "z": "mcp-flow-example", "name": "Demo MCP Server", "serverName": "demo-flow-server", "serverPort": 8001, "autoStart": true, "enableCors": true, "x": 180, "y": 100, "wires": [["tool-execution-router"]] }, { "id": "tool-registry-calc", "type": "mcp-tool-registry", "z": "mcp-flow-example", "name": "Calculator Tool", "toolName": "calculate_tool", "toolDescription": "Perform basic mathematical calculations", "toolSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"operation\": {\n \"type\": \"string\",\n \"enum\": [\"add\", \"subtract\", \"multiply\", \"divide\"],\n \"description\": \"Mathematical operation to perform\"\n },\n \"a\": {\n \"type\": \"number\",\n \"description\": \"First number\"\n },\n \"b\": {\n \"type\": \"number\",\n \"description\": \"Second number\"\n }\n },\n \"required\": [\"operation\", \"a\", \"b\"]\n}", "autoRegister": true, "x": 180, "y": 200, "wires": [["debug-registry"]] }, { "id": "tool-registry-greeting", "type": "mcp-tool-registry", "z": "mcp-flow-example", "name": "Greeting Tool", "toolName": "greet_user_tool", "toolDescription": "Generate a personalized greeting message", "toolSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"description\": \"Name of the person to greet\"\n },\n \"language\": {\n \"type\": \"string\",\n \"enum\": [\"english\", \"spanish\", \"french\"],\n \"description\": \"Language for the greeting\"\n },\n \"formal\": {\n \"type\": \"boolean\",\n \"description\": \"Whether to use formal greeting\"\n }\n },\n \"required\": [\"name\"]\n}", "autoRegister": true, "x": 180, "y": 260, "wires": [["debug-registry"]] }, { "id": "debug-registry", "type": "debug", "z": "mcp-flow-example", "name": "Registry Events", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 430, "y": 230, "wires": [] }, { "id": "tool-execution-router", "type": "switch", "z": "mcp-flow-example", "name": "Route Tool Execution", "property": "payload.toolName", "propertyType": "msg", "rules": [ { "t": "eq", "v": "calculate_tool", "vt": "str" }, { "t": "eq", "v": "greet_user_tool", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 450, "y": 100, "wires": [["calculator-handler"], ["greeting-handler"]] }, { "id": "calculator-handler", "type": "function", "z": "mcp-flow-example", "name": "Calculate", "func": "const args = msg.payload.arguments;\nconst { operation, a, b } = args;\n\nlet result;\nswitch (operation) {\n case 'add':\n result = a + b;\n break;\n case 'subtract':\n result = a - b;\n break;\n case 'multiply':\n result = a * b;\n break;\n case 'divide':\n if (b === 0) {\n return {\n topic: 'mcp-tool-response',\n payload: {\n executionId: msg.payload.executionId,\n error: 'Division by zero is not allowed'\n }\n };\n }\n result = a / b;\n break;\n default:\n return {\n topic: 'mcp-tool-response',\n payload: {\n executionId: msg.payload.executionId,\n error: 'Unknown operation: ' + operation\n }\n };\n}\n\nreturn {\n topic: 'mcp-tool-response',\n payload: {\n executionId: msg.payload.executionId,\n result: {\n operation: operation,\n operands: [a, b],\n result: result,\n message: `${a} ${operation} ${b} = ${result}`\n }\n }\n};", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 650, "y": 60, "wires": [["mcp-flow-server-1", "debug-calc"]] }, { "id": "greeting-handler", "type": "function", "z": "mcp-flow-example", "name": "Generate Greeting", "func": "const args = msg.payload.arguments;\nconst { name, language = 'english', formal = false } = args;\n\nconst greetings = {\n english: {\n formal: `Good day, ${name}. It is a pleasure to meet you.`,\n informal: `Hello ${name}! Nice to meet you!`\n },\n spanish: {\n formal: `Buenos días, ${name}. Es un placer conocerle.`,\n informal: `¡Hola ${name}! ¡Encantado de conocerte!`\n },\n french: {\n formal: `Bonjour ${name}. C'est un plaisir de vous rencontrer.`,\n informal: `Salut ${name} ! Ravi de te rencontrer !`\n }\n};\n\nconst greeting = greetings[language] \n ? greetings[language][formal ? 'formal' : 'informal']\n : greetings.english[formal ? 'formal' : 'informal'];\n\nreturn {\n topic: 'mcp-tool-response',\n payload: {\n executionId: msg.payload.executionId,\n result: {\n greeting: greeting,\n name: name,\n language: language,\n formal: formal,\n timestamp: new Date().toISOString()\n }\n }\n};", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 670, "y": 140, "wires": [["mcp-flow-server-1", "debug-greet"]] }, { "id": "debug-calc", "type": "debug", "z": "mcp-flow-example", "name": "Calculator Results", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 890, "y": 60, "wires": [] }, { "id": "debug-greet", "type": "debug", "z": "mcp-flow-example", "name": "Greeting Results", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 890, "y": 140, "wires": [] }, { "id": "test-client", "type": "mcp-client", "z": "mcp-flow-example", "name": "Test Client", "serverUrl": "http://localhost:8001", "connectionType": "sse", "autoConnect": false, "reconnect": true, "reconnectInterval": 5000, "timeout": 30000, "x": 170, "y": 380, "wires": [["debug-test-client"]] }, { "id": "debug-test-client", "type": "debug", "z": "mcp-flow-example", "name": "Test Responses", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 390, "y": 380, "wires": [] }, { "id": "inject-connect", "type": "inject", "z": "mcp-flow-example", "name": "Connect to Server", "props": [ { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "connect", "x": 120, "y": 440, "wires": [["test-client"]] }, { "id": "inject-test-calc", "type": "inject", "z": "mcp-flow-example", "name": "Test Calculator", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "request", "payload": "{\"method\":\"calculate_tool\",\"params\":{\"operation\":\"multiply\",\"a\":7,\"b\":6}}", "payloadType": "json", "x": 120, "y": 500, "wires": [["test-client"]] }, { "id": "inject-test-greet", "type": "inject", "z": "mcp-flow-example", "name": "Test Greeting", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "request", "payload": "{\"method\":\"greet_user_tool\",\"params\":{\"name\":\"Node-RED User\",\"language\":\"spanish\",\"formal\":false}}", "payloadType": "json", "x": 110, "y": 560, "wires": [["test-client"]] }, { "id": "comment-flow-1", "type": "comment", "z": "mcp-flow-example", "name": "MCP Flow Server", "info": "The MCP Flow Server creates a complete MCP server within Node-RED.\nIt automatically handles MCP protocol, serves tools, and manages execution.", "x": 150, "y": 40, "wires": [] }, { "id": "comment-flow-2", "type": "comment", "z": "mcp-flow-example", "name": "Tool Definitions", "info": "Tool Registry nodes define the available tools with their schemas.\nThese are automatically registered with the Flow Server.", "x": 150, "y": 160, "wires": [] }, { "id": "comment-flow-3", "type": "comment", "z": "mcp-flow-example", "name": "Tool Implementation", "info": "Function nodes implement the actual tool logic.\nThey receive tool execution requests and return results to the Flow Server.", "x": 500, "y": 200, "wires": [] }, { "id": "comment-flow-4", "type": "comment", "z": "mcp-flow-example", "name": "Testing the Server", "info": "These nodes demonstrate testing the MCP server we just created.\nThe client connects to our Flow Server and calls the tools we defined.", "x": 150, "y": 340, "wires": [] } ]