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
This commit is contained in:
Jerome 2025-06-30 15:21:57 +01:00
commit bda811a950
No known key found for this signature in database
4 changed files with 41 additions and 0 deletions

View file

@ -584,6 +584,26 @@ app.listen(3000);
> );
> ```
#### CORS Configuration for Browser-Based Clients
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:
```typescript
import cors from 'cors';
// Add CORS middleware before your MCP routes
app.use(cors({
origin: '*', // Configure appropriately for production
exposedHeaders: ['Mcp-Session-Id']
}));
```
This configuration is necessary because:
- The MCP streamable HTTP transport uses the `Mcp-Session-Id` header for session management
- Browsers restrict access to response headers unless explicitly exposed via CORS
- Without this configuration, browser-based clients won't be able to read the session ID from initialization responses
#### Without Session Management (Stateless)
For simpler use cases where session management isn't needed:

View file

@ -4,6 +4,7 @@ import { McpServer } from '../../server/mcp.js';
import { StreamableHTTPServerTransport } from '../../server/streamableHttp.js';
import { z } from 'zod';
import { CallToolResult, isInitializeRequest } from '../../types.js';
import cors from 'cors';
// Create an MCP server with implementation details
@ -81,6 +82,12 @@ const getServer = () => {
const app = express();
app.use(express.json());
// Configure CORS to expose Mcp-Session-Id header for browser-based clients
app.use(cors({
origin: '*', // Allow all origins - adjust as needed for production
exposedHeaders: ['Mcp-Session-Id']
}));
// Map to store transports by session ID
const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};

View file

@ -3,6 +3,7 @@ import { McpServer } from '../../server/mcp.js';
import { StreamableHTTPServerTransport } from '../../server/streamableHttp.js';
import { z } from 'zod';
import { CallToolResult, GetPromptResult, ReadResourceResult } from '../../types.js';
import cors from 'cors';
const getServer = () => {
// Create an MCP server with implementation details
@ -96,6 +97,12 @@ const getServer = () => {
const app = express();
app.use(express.json());
// Configure CORS to expose Mcp-Session-Id header for browser-based clients
app.use(cors({
origin: '*', // Allow all origins - adjust as needed for production
exposedHeaders: ['Mcp-Session-Id']
}));
app.post('/mcp', async (req: Request, res: Response) => {
const server = getServer();
try {

View file

@ -6,6 +6,7 @@ import { SSEServerTransport } from '../../server/sse.js';
import { z } from 'zod';
import { CallToolResult, isInitializeRequest } from '../../types.js';
import { InMemoryEventStore } from '../shared/inMemoryEventStore.js';
import cors from 'cors';
/**
* This example server demonstrates backwards compatibility with both:
@ -71,6 +72,12 @@ const getServer = () => {
const app = express();
app.use(express.json());
// Configure CORS to expose Mcp-Session-Id header for browser-based clients
app.use(cors({
origin: '*', // Allow all origins - adjust as needed for production
exposedHeaders: ['Mcp-Session-Id']
}));
// Store transports by session ID
const transports: Record<string, StreamableHTTPServerTransport | SSEServerTransport> = {};