Skip to content

Commit 6c23ed6

Browse files
feat: Add CORS configuration for browser-based MCP clients
- Add cors middleware to example servers with Mcp-Session-Id exposed - Add CORS documentation section to README - Configure minimal CORS settings (only expose required headers) This enables browser-based clients to connect to MCP servers by properly exposing the Mcp-Session-Id header required for session management. Reported-by: Jerome
1 parent 64a60c4 commit 6c23ed6

File tree

4 files changed

+41
-0
lines changed

4 files changed

+41
-0
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,26 @@ app.listen(3000);
519519
> );
520520
> ```
521521
522+
523+
#### CORS Configuration for Browser-Based Clients
524+
525+
If you'd like your server to be accessible by browser-based MCP clients, you'll need to configure CORS headers. The `Mcp-Session-Id` header must be exposed for browser clients to access it:
526+
527+
```typescript
528+
import cors from 'cors';
529+
530+
// Add CORS middleware before your MCP routes
531+
app.use(cors({
532+
origin: '*', // Configure appropriately for production
533+
exposedHeaders: ['Mcp-Session-Id']
534+
}));
535+
```
536+
537+
This configuration is necessary because:
538+
- The MCP streamable HTTP transport uses the `Mcp-Session-Id` header for session management
539+
- Browsers restrict access to response headers unless explicitly exposed via CORS
540+
- Without this configuration, browser-based clients won't be able to read the session ID from initialization responses
541+
522542
#### Without Session Management (Stateless)
523543

524544
For simpler use cases where session management isn't needed:

src/examples/server/jsonResponseStreamableHttp.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { McpServer } from '../../server/mcp.js';
44
import { StreamableHTTPServerTransport } from '../../server/streamableHttp.js';
55
import { z } from 'zod';
66
import { CallToolResult, isInitializeRequest } from '../../types.js';
7+
import cors from 'cors';
78

89

910
// Create an MCP server with implementation details
@@ -81,6 +82,12 @@ const getServer = () => {
8182
const app = express();
8283
app.use(express.json());
8384

85+
// Configure CORS to expose Mcp-Session-Id header for browser-based clients
86+
app.use(cors({
87+
origin: '*', // Allow all origins - adjust as needed for production
88+
exposedHeaders: ['Mcp-Session-Id']
89+
}));
90+
8491
// Map to store transports by session ID
8592
const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};
8693

src/examples/server/simpleStatelessStreamableHttp.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { McpServer } from '../../server/mcp.js';
33
import { StreamableHTTPServerTransport } from '../../server/streamableHttp.js';
44
import { z } from 'zod';
55
import { CallToolResult, GetPromptResult, ReadResourceResult } from '../../types.js';
6+
import cors from 'cors';
67

78
const getServer = () => {
89
// Create an MCP server with implementation details
@@ -96,6 +97,12 @@ const getServer = () => {
9697
const app = express();
9798
app.use(express.json());
9899

100+
// Configure CORS to expose Mcp-Session-Id header for browser-based clients
101+
app.use(cors({
102+
origin: '*', // Allow all origins - adjust as needed for production
103+
exposedHeaders: ['Mcp-Session-Id']
104+
}));
105+
99106
app.post('/mcp', async (req: Request, res: Response) => {
100107
const server = getServer();
101108
try {

src/examples/server/sseAndStreamableHttpCompatibleServer.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { SSEServerTransport } from '../../server/sse.js';
66
import { z } from 'zod';
77
import { CallToolResult, isInitializeRequest } from '../../types.js';
88
import { InMemoryEventStore } from '../shared/inMemoryEventStore.js';
9+
import cors from 'cors';
910

1011
/**
1112
* This example server demonstrates backwards compatibility with both:
@@ -71,6 +72,12 @@ const getServer = () => {
7172
const app = express();
7273
app.use(express.json());
7374

75+
// Configure CORS to expose Mcp-Session-Id header for browser-based clients
76+
app.use(cors({
77+
origin: '*', // Allow all origins - adjust as needed for production
78+
exposedHeaders: ['Mcp-Session-Id']
79+
}));
80+
7481
// Store transports by session ID
7582
const transports: Record<string, StreamableHTTPServerTransport | SSEServerTransport> = {};
7683

0 commit comments

Comments
 (0)