diff --git a/examples/server/src/elicitationUrlExample.ts b/examples/server/src/elicitationUrlExample.ts index c38dd75e8..f1bbf31ac 100644 --- a/examples/server/src/elicitationUrlExample.ts +++ b/examples/server/src/elicitationUrlExample.ts @@ -220,12 +220,14 @@ const AUTH_PORT = process.env.MCP_AUTH_PORT ? Number.parseInt(process.env.MCP_AU const app = createMcpExpressApp(); -// Allow CORS all domains, expose the Mcp-Session-Id header +// CORS: allow only localhost origins (typical for local dev / Inspector direct connect). +// If you intentionally expose this demo remotely, replace this allowlist with your own. +// Also expose the Mcp-Session-Id header. app.use( cors({ - origin: '*', // Allow all origins + origin: [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/], exposedHeaders: ['Mcp-Session-Id'], - credentials: true // Allow cookies to be sent cross-origin + credentials: true }) ); diff --git a/examples/server/src/honoWebStandardStreamableHttp.ts b/examples/server/src/honoWebStandardStreamableHttp.ts index b15f9885f..e1600b1aa 100644 --- a/examples/server/src/honoWebStandardStreamableHttp.ts +++ b/examples/server/src/honoWebStandardStreamableHttp.ts @@ -14,6 +14,8 @@ import { Hono } from 'hono'; import { cors } from 'hono/cors'; import * as z from 'zod/v4'; +const LOCALHOST_ORIGINS = [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/]; + // Create the MCP server const server = new McpServer({ name: 'hono-webstandard-mcp-server', @@ -41,11 +43,11 @@ const transport = new WebStandardStreamableHTTPServerTransport(); // Create the Hono app const app = new Hono(); -// Enable CORS for all origins +// CORS: allow only localhost origins (typical for local dev / Inspector direct connect). app.use( '*', cors({ - origin: '*', + origin: (origin, _c) => (LOCALHOST_ORIGINS.some(re => re.test(origin)) ? origin : null), allowMethods: ['GET', 'POST', 'DELETE', 'OPTIONS'], allowHeaders: ['Content-Type', 'mcp-session-id', 'Last-Event-ID', 'mcp-protocol-version'], exposeHeaders: ['mcp-session-id', 'mcp-protocol-version'] diff --git a/examples/server/src/simpleStreamableHttp.ts b/examples/server/src/simpleStreamableHttp.ts index dc86b17bd..cb5af762e 100644 --- a/examples/server/src/simpleStreamableHttp.ts +++ b/examples/server/src/simpleStreamableHttp.ts @@ -508,7 +508,7 @@ const app = createMcpExpressApp(); app.use( cors({ exposedHeaders: ['WWW-Authenticate', 'Mcp-Session-Id', 'Last-Event-Id', 'Mcp-Protocol-Version'], - origin: '*' // WARNING: This allows all origins to access the MCP server. In production, you should restrict this to specific origins. + origin: [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/] // Default to localhost for demo safety. In production, configure this explicitly. }) ); diff --git a/examples/server/src/ssePollingExample.ts b/examples/server/src/ssePollingExample.ts index 3897b392e..337d4ef31 100644 --- a/examples/server/src/ssePollingExample.ts +++ b/examples/server/src/ssePollingExample.ts @@ -84,7 +84,11 @@ server.registerTool( // Set up Express app const app = createMcpExpressApp(); -app.use(cors()); +app.use( + cors({ + origin: [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/] + }) +); // Create event store for resumability const eventStore = new InMemoryEventStore(); diff --git a/examples/shared/src/authServer.ts b/examples/shared/src/authServer.ts index e967b23d9..6388efab0 100644 --- a/examples/shared/src/authServer.ts +++ b/examples/shared/src/authServer.ts @@ -106,7 +106,7 @@ export function setupAuthServer(options: SetupAuthServerOptions): void { // WARNING: This configuration is for demo purposes only. In production, you should restrict this to specific origins and configure CORS yourself. authApp.use( cors({ - origin: '*' // WARNING: This allows all origins to access the auth server. In production, you should restrict this to specific origins. + origin: [/^http:\/\/localhost(?::\d+)?$/, /^http:\/\/127\.0\.0\.1(?::\d+)?$/, /^http:\/\/\[::1\](?::\d+)?$/] // Default to localhost for demo safety. In production, configure this explicitly. }) );