Skip to content

Commit 4ea33ea

Browse files
committed
fix: enhance MCP server error handling and improve CORS headers for better client compatibility
1 parent 2aede17 commit 4ea33ea

6 files changed

Lines changed: 33 additions & 8 deletions

File tree

packages/mcp/src/index.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,11 @@ export async function handleMcpHttpRequest(
355355
// CORS + expose session id per SDK guidance
356356
try {
357357
res.setHeader('Access-Control-Allow-Origin', '*');
358-
res.setHeader('Access-Control-Allow-Headers', 'content-type, mcp-session-id');
358+
// Allow both canonical and lowercase variants; include Accept & MCP-Protocol-Version for spec-compliant clients
359+
res.setHeader(
360+
'Access-Control-Allow-Headers',
361+
'content-type, accept, mcp-session-id, Mcp-Session-Id, mcp-protocol-version, MCP-Protocol-Version'
362+
);
359363
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, DELETE, OPTIONS');
360364
res.setHeader('Access-Control-Expose-Headers', 'Mcp-Session-Id');
361365
} catch {}
@@ -428,9 +432,13 @@ export async function handleMcpHttpRequest(
428432
res.setHeader('content-type', 'application/json');
429433
} catch {}
430434
}
435+
// Make the guidance explicit: POST initialize → read Mcp-Session-Id → include for GET/DELETE (+ protocol header)
431436
res.end(JSON.stringify({
432437
jsonrpc: '2.0',
433-
error: { code: -32000, message: 'Method not allowed. Initialize with POST to obtain Mcp-Session-Id, then include it for GET/DELETE.' },
438+
error: {
439+
code: -32000,
440+
message: 'Method not allowed. To open a server stream, first POST an InitializeRequest to this MCP endpoint and read the Mcp-Session-Id response header. Include that Mcp-Session-Id (and MCP-Protocol-Version) on all subsequent GET/DELETE/POST requests.'
441+
},
434442
id: null
435443
}));
436444
return;

packages/next/src/mcp-route.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,15 @@ function copyHeaders(src: Headers): Headers {
2828
}
2929

3030
async function proxy(method: string, req: NextRequest): Promise<Response> {
31-
await ensureLocalHttpServer();
31+
try {
32+
await ensureLocalHttpServer();
33+
} catch (err: any) {
34+
const message = `[browser-echo] MCP server failed to start: ${err?.message || String(err)}`;
35+
return new Response(JSON.stringify({ error: message }), {
36+
status: 500,
37+
headers: { 'content-type': 'application/json' }
38+
});
39+
}
3240

3341
// Build upstream URL and preserve query string
3442
const upstreamBase = new URL(getLocalMcpUrl());

packages/next/src/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const runtime = 'nodejs';
1010
export const dynamic = 'force-dynamic';
1111

1212
export async function GET(req: NextRequest) {
13-
try { startMcpServer(); } catch {}
13+
try { startMcpServer(); } catch (e) { console.error('[browser-echo] MCP server failed to start:', e); }
1414
const session = req.nextUrl.searchParams.get('session') || undefined;
1515
const text = getLogsAsText(session || undefined);
1616
return new NextResponse(text, {
@@ -23,7 +23,7 @@ export async function GET(req: NextRequest) {
2323
}
2424

2525
export async function POST(req: NextRequest) {
26-
try { startMcpServer(); } catch {}
26+
try { startMcpServer(); } catch (e) { console.error('[browser-echo] MCP server failed to start:', e); }
2727
const mcpOn = _mcpEnvEnabled();
2828

2929
let payload: Payload | null = null;

packages/nuxt/src/runtime/server/handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ type Entry = { level: Level | string; text: string; time?: number; stack?: strin
66
type Payload = { sessionId?: string; entries: Entry[] };
77

88
export default defineEventHandler(async (event) => {
9-
try { startMcpServer(); } catch {}
9+
try { startMcpServer(); } catch (e) { console.error('[browser-echo] MCP server failed to start:', e); }
1010
const mcpOn = _mcpEnvEnabled();
1111

1212
const method = String(event.node?.req?.method || 'POST').toUpperCase();

packages/nuxt/src/runtime/server/mcp.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { handleMcpHttpRequest, startMcpServer } from '@browser-echo/mcp';
33

44
export default defineEventHandler(async (event) => {
55
// Ensure MCP server is ready
6-
try { startMcpServer(); } catch {}
6+
try { startMcpServer(); } catch (e) { console.error('[browser-echo] MCP server failed to start:', e); }
77

88
const req = event.node.req;
99
const res = event.node.res;

packages/vite/src/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,16 @@ export default function browserEcho(opts: BrowserLogsToTerminalOptions = {}): im
7474
},
7575
configureServer(server) {
7676
if (!options.enabled) return;
77-
try { startMcpServer(); } catch {}
77+
try {
78+
startMcpServer();
79+
try {
80+
server.config.logger.info(`${options.tag} MCP endpoint mounted at ${options.mcpRoute}`);
81+
} catch {}
82+
} catch (e: any) {
83+
try {
84+
server.config.logger.error(`${options.tag} MCP server failed to start: ${e?.message || e}`);
85+
} catch {}
86+
}
7887
server.middlewares.use(options.mcpRoute, (req: IncomingMessage, res: ServerResponse, _next: () => void) => {
7988
const m = (req.method || 'GET').toUpperCase();
8089
(async () => {

0 commit comments

Comments
 (0)