Skip to content

Commit 3391bfb

Browse files
authored
docs: make DNS rebinding protection more prominent in server.md (modelcontextprotocol#1586)
1 parent c19dfd9 commit 3391bfb

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

docs/server.md

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,33 @@ Streamable HTTP is the HTTP‑based transport. It supports:
2525
- Optional JSON‑only response mode with no SSE
2626
- Session management and resumability
2727

28-
A minimal stateful setup:
28+
A minimal stateless server using `createMcpExpressApp()`, which includes [DNS rebinding protection](#dns-rebinding-protection) by default:
2929

30-
```ts source="../examples/server/src/serverGuide.examples.ts#streamableHttp_stateful"
31-
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
30+
```ts
31+
const app = createMcpExpressApp();
3232

33-
const transport = new NodeStreamableHTTPServerTransport({
34-
sessionIdGenerator: () => randomUUID()
33+
app.post('/mcp', async (req, res) => {
34+
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
35+
const transport = new NodeStreamableHTTPServerTransport({
36+
sessionIdGenerator: undefined // stateless
37+
});
38+
await server.connect(transport);
39+
await transport.handleRequest(req, res, req.body);
3540
});
3641

37-
await server.connect(transport);
42+
app.listen(3000, '127.0.0.1');
3843
```
3944

45+
For stateful servers with session management, see [`simpleStreamableHttp.ts`](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/examples/server/src/simpleStreamableHttp.ts).
46+
4047
> [!NOTE]
4148
> For full runnable examples, see [`simpleStreamableHttp.ts`](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/examples/server/src/simpleStreamableHttp.ts) (sessions, logging, tasks, elicitation, auth hooks), [`jsonResponseStreamableHttp.ts`](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/examples/server/src/jsonResponseStreamableHttp.ts) (`enableJsonResponse: true`, no SSE), and [`standaloneSseWithGetStreamableHttp.ts`](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/examples/server/src/standaloneSseWithGetStreamableHttp.ts) (notifications with Streamable HTTP GET + SSE).
4249
>
4350
> For protocol details, see [Transports](https://modelcontextprotocol.io/specification/latest/basic/transports) in the MCP specification.
4451
52+
> [!WARNING]
53+
> If your server listens on localhost, use [`createMcpExpressApp()`](#dns-rebinding-protection) or [`createMcpHonoApp()`](#dns-rebinding-protection) instead of using `NodeStreamableHTTPServerTransport` directly — they include [DNS rebinding protection](#dns-rebinding-protection) by default.
54+
4555
#### Stateless vs stateful sessions
4656

4757
Streamable HTTP can run:
@@ -438,7 +448,9 @@ Task-based execution enables "call-now, fetch-later" patterns for long-running o
438448

439449
### DNS rebinding protection
440450

441-
MCP servers running on localhost are vulnerable to DNS rebinding attacks. Use `createMcpExpressApp()` from `@modelcontextprotocol/express` to create an Express app with DNS rebinding protection enabled by default:
451+
Under normal circumstances, cross-origin browser restrictions limit what a malicious website can do to your localhost server. [DNS rebinding attacks](https://en.wikipedia.org/wiki/DNS_rebinding) get around those restrictions entirely by making the requests appear as same-origin, since the attacking domain resolves to localhost. Validating the host header on the server side protects against this scenario. **All localhost MCP servers should use DNS rebinding protection.**
452+
453+
The recommended approach is to use `createMcpExpressApp()` (from `@modelcontextprotocol/express`) or `createMcpHonoApp()` (from `@modelcontextprotocol/hono`), which enable Host header validation by default:
442454

443455
```ts source="../examples/server/src/serverGuide.examples.ts#dnsRebinding_basic"
444456
// Default: DNS rebinding protection auto-enabled (host is 127.0.0.1)
@@ -460,6 +472,10 @@ const app = createMcpExpressApp({
460472
});
461473
```
462474

475+
`createMcpHonoApp()` from `@modelcontextprotocol/hono` provides the same protection for Hono-based servers and Web Standard runtimes (Cloudflare Workers, Deno, Bun).
476+
477+
If you use `NodeStreamableHTTPServerTransport` directly with your own HTTP framework, you must implement Host header validation yourself. See the [`hostHeaderValidation`](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/packages/middleware/express/src/express.ts) middleware source for reference.
478+
463479
## More server features
464480

465481
The sections above cover the essentials. The table below links to additional capabilities demonstrated in the runnable examples.

0 commit comments

Comments
 (0)