The WebMCP bridge script embeds the MCP endpoint that the browser calls. mcpApiHandler built that endpoint from req.url. Behind a reverse proxy, req.url is the internal URL, for example http://localhost:3000/api/mcp, so the script in the page sends its tool calls to an address the browser cannot reach.
withMcpAuth and protectedResourceHandler already avoid this by reading the public origin from X-Forwarded-Host, X-Forwarded-Proto or Forwarded through getPublicUrl. This change uses the same helper for the bridge script endpoint. The path and query string are unchanged, and requests without proxy headers behave as before.
Tests
embeds the public endpoint URL when behind a proxysends a script request tohttp://localhost:3000/api/mcp?webmcp-script&v=1with forwarded host and protocol headers, and checks that the script embedshttps://example.com/api/mcp?v=1. It fails before the change and passes after.
pnpm vitest run tests/webmcp.test.tsBefore the change: 1 failed, 7 passed. After: 8 passed. The full suite passes (4 files, 47 tests), and tsc --noEmit reports no errors.
A patch changeset is included.
Security review details