This directory contains runnable MCP server examples built with @modelcontextprotocol/server plus framework adapters:
@modelcontextprotocol/express@modelcontextprotocol/honoFor client examples, see ../client/README.md. For guided docs, see ../../docs/server.md.
From anywhere in the SDK:
pnpm install
pnpm --filter @modelcontextprotocol/examples-server exec tsx src/simpleStreamableHttp.ts
Or, from within this package:
cd examples/server
pnpm tsx src/simpleStreamableHttp.ts
| Scenario | Description | File |
|---|---|---|
| Streamable HTTP server (stateful) | Feature-rich server with tools/resources/prompts, logging, tasks, sampling, and optional OAuth. | src/simpleStreamableHttp.ts |
| Streamable HTTP server (stateless) | No session tracking; good for simple API-style servers. | src/simpleStatelessStreamableHttp.ts |
| JSON response mode (no SSE) | Streamable HTTP with JSON-only responses and limited notifications. | src/jsonResponseStreamableHttp.ts |
| Server notifications over Streamable HTTP | Demonstrates server-initiated notifications via GET+SSE. | src/standaloneSseWithGetStreamableHttp.ts |
| Output schema server | Demonstrates tool output validation with structured output schemas. | src/mcpServerOutputSchema.ts |
| Form elicitation server | Collects non-sensitive user input via schema-driven forms. | src/elicitationFormExample.ts |
| URL elicitation server | Secure browser-based flows for sensitive input (API keys, OAuth, payments). | src/elicitationUrlExample.ts |
| Sampling + tasks server | Demonstrates sampling and experimental task-based execution. | src/toolWithSampleServer.ts |
| Task interactive server | Task-based execution with interactive server→client requests. | src/simpleTaskInteractive.ts |
| Hono Streamable HTTP server | Streamable HTTP server built with Hono instead of Express. | src/honoWebStandardStreamableHttp.ts |
| SSE polling demo server | Legacy SSE server intended for polling demos. | src/ssePollingExample.ts |
pnpm --filter @modelcontextprotocol/examples-server exec tsx src/simpleStreamableHttp.ts --oauth
pnpm --filter @modelcontextprotocol/examples-server exec tsx src/simpleStreamableHttp.ts --oauth --oauth-strict
Run the server:
pnpm --filter @modelcontextprotocol/examples-server exec tsx src/elicitationUrlExample.ts
Run the client in another terminal:
pnpm --filter @modelcontextprotocol/examples-client exec tsx src/elicitationUrlExample.ts
When deploying MCP servers in a horizontally scaled environment (multiple server instances), there are a few different options that can be useful for different use cases:
To enable stateless mode, configure the NodeStreamableHTTPServerTransport with:
sessionIdGenerator: undefined;
┌─────────────────────────────────────────────┐
│ Client │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Load Balancer │
└─────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────────┐
│ MCP Server #1 │ │ MCP Server #2 │
│ (Node.js) │ │ (Node.js) │
└─────────────────┘ └─────────────────────┘
Configure the transport with session management, but use an external event store:
sessionIdGenerator: () => randomUUID(),
eventStore: databaseEventStore
┌─────────────────────────────────────────────┐
│ Client │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Load Balancer │
└─────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────────┐
│ MCP Server #1 │ │ MCP Server #2 │
│ (Node.js) │ │ (Node.js) │
└─────────────────┘ └─────────────────────┘
│ │
│ │
▼ ▼
┌─────────────────────────────────────────────┐
│ Database (PostgreSQL) │
│ │
│ • Session state │
│ • Event storage for resumability │
└─────────────────────────────────────────────┘
For scenarios where local in-memory state must be maintained on specific nodes, combine Streamable HTTP with pub/sub routing so one node can terminate the client connection while another node owns the session state.
┌─────────────────────────────────────────────┐
│ Client │
└─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Load Balancer │
└─────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────────┐
│ MCP Server #1 │◄───►│ MCP Server #2 │
│ (Has Session A) │ │ (Has Session B) │
└─────────────────┘ └─────────────────────┘
▲│ ▲│
│▼ │▼
┌─────────────────────────────────────────────┐
│ Message Queue / Pub-Sub │
│ │
│ • Session ownership registry │
│ • Bidirectional message routing │
│ • Request/response forwarding │
└─────────────────────────────────────────────┘
Start the server:
pnpm --filter @modelcontextprotocol/examples-server exec tsx src/simpleStreamableHttp.ts
Then run the backwards-compatible client:
pnpm --filter @modelcontextprotocol/examples-client exec tsx src/streamableHttpWithSseFallbackClient.ts