vercel/ai · error · MCPClientError

MCP SSE Transport Error: Endpoint origin does not match conn

Error message

MCP SSE Transport Error: Endpoint origin does not match connection origin: ${endpoint.origin}

What it means

The MCP spec forbids the server's advertised message-posting endpoint from pointing at a different origin than the SSE connection, because that would leak messages/API keys cross-origin. processEvents validates the endpoint event's URL origin against this.url.origin and throws MCPClientError if they differ.

Source

Thrown at packages/mcp/src/tool/mcp-sse-transport.ts:183

                  }
                  return;
                }

                const { event, data } = value;

                if (event === 'endpoint') {
                  if (this.endpoint) {
                    continue;
                  }

                  const endpoint = new URL(data, this.url);

                  if (endpoint.origin !== this.url.origin) {
                    this.connected = false;
                    this.endpoint = undefined;
                    this.sseConnection?.close();
                    this.abortController?.abort();
                    throw new MCPClientError({
                      message: `MCP SSE Transport Error: Endpoint origin does not match connection origin: ${endpoint.origin}`,
                    });
                  }

                  this.endpoint = endpoint;
                  this.connected = true;
                  resolve();
                } else if (isMessageEvent(event)) {
                  try {
                    const message = await parseJSONRPCMessage(data);
                    this.onmessage?.(message);
                  } catch (error) {
                    const e = new MCPClientError({
                      message:
                        'MCP SSE Transport Error: Failed to parse message',
                      cause: error,
                    });
                    this.onerror?.(e);

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Fix the MCP server/proxy to advertise an endpoint on the same origin as the SSE URL (same scheme+host+port), or use a relative endpoint URL
  2. Connect to the same public origin the server advertises (adjust your client URL or DNS/proxy so origins match)
  3. If a proxy rewrites the endpoint, configure it to preserve or rewrite consistently to the public origin

Example fix

// before
// server sends: event: endpoint data: http://internal-host:8080/messages
// after
// server sends: event: endpoint data: /messages  (same origin as SSE connection)
Defensive patterns

Strategy: validation

Validate before calling

// validate the server endpoint before connecting
const serverUrl = new URL(process.env.MCP_SSE_URL);
if (serverUrl.origin !== expectedOrigin) throw new Error('MCP server URL origin mismatch with expected origin');

Type guard

function originsMatch(endpointUrl: string | URL, connectionUrl: URL): boolean {
  return new URL(endpointUrl).origin === connectionUrl.origin;
}

Try / catch

try {
  await client.connect();
} catch (error) {
  if (MCPClientError.isInstance(error) && error.message.includes('origin does not match')) {
    // fix proxy/server endpoint advertisement, then reconnect
  } else throw error;
}

Prevention

When it happens

Trigger: The server's SSE 'endpoint' event returns an absolute URL on another origin (misconfigured base URL behind a proxy, or a malicious/compromised server); client connects via https://api.example.com but server advertises http://localhost:8080/message.

Common situations: Reverse proxies that rewrite the endpoint to an internal address; servers configured with an external URL different from the one the client dialed; man-in-the-middle or misconfigured multi-domain setups.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/0234347b6a3ec39e. Report an issue: GitHub.