You will find FastMCP
far easier (it uses The official Typescript SDK for Model Context Protocol under the hood)
Here is a demo to get you going
[{"id":"fd8aaf75d0b12524","type":"function","z":"f2a7cc4cf78e0527","name":"\"my-mcp-server\"","func":"/// nothing to see here - checkout the On Start and On Stop tabs","outputs":0,"timeout":0,"noerr":0,"initialize":"const { FastMCP, Tool, Content } = fastmcp\nconst { z } = zod\nnode.warn({z,FastMCP});\n\nconst PORT = 8080\nconst SERVER_NAME = \"my-mcp-server\"\n\nconst GreetingSchema = z.object({\n // name with min len of 1 and max len of 100\n name: z.string().min(1).max(100)\n});\n\n/**\n * MCP tool for greeting the user\n * @param name The name of the user\n */\nconst greeterTool = {\n name: 'greet_person',\n description: 'Greet person by name',\n parameters: GreetingSchema,\n annotations: {\n title: 'Greet Person',\n readOnlyHint: true\n },\n execute: async ({ name }) => {\n try {\n console.log('Fetching greeting for person:', name);\n const greetingMessage = `Hi there ${name}! Welcome to MCP Server running in Node-RED!`;\n return { text: greetingMessage, type: 'text' };\n } catch (error) {\n throw error;\n }\n },\n};\n\ntry {\n\n const transportType = 'sse'\n const server = new FastMCP({\n name: SERVER_NAME,\n version: '1.0.0'\n });\n\n server.addTool(greeterTool);\n context.set('server', server)\n\n server.start({\n transportType,\n sse: {\n endpoint: '/sse',\n port: PORT,\n },\n });\n const info = `http://<ip>:${PORT}/sse`\n node.status({ fill: \"green\", shape: \"dot\", text: `${SERVER_NAME} is running at ${info}` });\n\n} catch (error) {\n node.status({fill:\"red\",shape:\"ring\",text:\"Failed to start server\"});\n node.error(`Failed to start server ${SERVER_NAME}: ${error.message}`)\n}\n","finalize":"let server = context.get('server')\nif (server?.stop) {\n node.warn(\"Shutting down MCP Server\");\n server.stop()\n server = null\n}\n","libs":[{"var":"fastmcp","module":"fastmcp"},{"var":"zod","module":"zod"}],"x":1620,"y":320,"wires":[]}]