@modelcontextprotocol/node
Advanced tools
+4
-4
| { | ||
| "name": "@modelcontextprotocol/node", | ||
| "version": "2.0.0-beta.2", | ||
| "version": "2.0.0-beta.3", | ||
| "description": "Model Context Protocol implementation for TypeScript - Node.js middleware", | ||
@@ -45,3 +45,3 @@ "license": "MIT", | ||
| "hono": "^4.11.4", | ||
| "@modelcontextprotocol/server": "^2.0.0-beta.2" | ||
| "@modelcontextprotocol/server": "^2.0.0-beta.3" | ||
| }, | ||
@@ -64,4 +64,4 @@ "peerDependenciesMeta": { | ||
| "vitest": "^4.0.15", | ||
| "@modelcontextprotocol/server": "^2.0.0-beta.2", | ||
| "@modelcontextprotocol/core-internal": "^2.0.0-beta.1", | ||
| "@modelcontextprotocol/server": "^2.0.0-beta.3", | ||
| "@modelcontextprotocol/core-internal": "^2.0.0-beta.2", | ||
| "@modelcontextprotocol/eslint-config": "^2.0.0", | ||
@@ -68,0 +68,0 @@ "@modelcontextprotocol/test-helpers": "^2.0.0-beta.0", |
+15
-2
@@ -20,2 +20,4 @@ # `@modelcontextprotocol/node` | ||
| - `toNodeHandler(handler, opts?)` — adapt a web-standard `{ fetch }` MCP handler to a Node `(req, res, parsedBody?)` handler | ||
| - `hostHeaderValidation(allowedHostnames)` / `localhostHostValidation()` — `Host` header guards for hand-wired `node:http` servers | ||
| - `originValidation(allowedOriginHostnames)` / `localhostOriginValidation()` — `Origin` header guards for hand-wired `node:http` servers | ||
| - `ToNodeHandlerOptions`, `FetchLikeMcpHandler`, `NodeMcpRequestHandler` (types for `toNodeHandler`) | ||
@@ -49,5 +51,12 @@ - `toWebRequest(req, parsedBody?, opts?)` — the Node `IncomingMessage` → web-standard `Request` conversion `toNodeHandler` performs internally, exported on its own (for example to feed `isLegacyRequest()` from a hand-wired `(req, res)` handler) | ||
| Plain `node:http` has no middleware chain, so bind loopback explicitly and | ||
| compose the `Host`/`Origin` guards in front of the transport — matching the | ||
| defaults the framework app factories (`createMcpExpressApp`, | ||
| `createMcpHonoApp`, `createMcpFastifyApp`) apply for you. The guards answer | ||
| rejected requests with `403` themselves and return `false`, so the handler | ||
| must not touch the request further. | ||
| ```ts | ||
| import { createServer } from 'node:http'; | ||
| import { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node'; | ||
| import { localhostHostValidation, localhostOriginValidation, NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node'; | ||
| import { McpServer } from '@modelcontextprotocol/server'; | ||
@@ -57,7 +66,11 @@ | ||
| const validateHost = localhostHostValidation(); | ||
| const validateOrigin = localhostOriginValidation(); | ||
| createServer(async (req, res) => { | ||
| if (!validateHost(req, res) || !validateOrigin(req, res)) return; | ||
| const transport = new NodeStreamableHTTPServerTransport({ sessionIdGenerator: undefined }); | ||
| await server.connect(transport); | ||
| await transport.handleRequest(req, res); | ||
| }).listen(3000); | ||
| }).listen(3000, '127.0.0.1'); | ||
| ``` |
137185
0.67%74
21.31%