Use MCP_PROXY_FULL_ADDRESS for SSE transport backed endpoints

The STDIO and SSE transports use SSE between the client and the proxy
server.  SSE requires the client to initiate the MCP conversation
(event-stream) at the endpoint provided by the server.  The endpoint
provided by the server must obey where the client sees the server,
rather than being assumed to be server-root `/message`.

The Streamable HTTP endpoint does not need the full proxy address
because the response is an event-stream directly, and does not use SSE.
This commit is contained in:
Richard Michael 2025-08-10 13:06:19 -07:00
commit 3628abca9e
2 changed files with 32 additions and 4 deletions

View file

@ -409,11 +409,20 @@ export function useConnection({
let mcpProxyServerUrl; let mcpProxyServerUrl;
switch (transportType) { switch (transportType) {
case "stdio": case "stdio": {
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/stdio`); mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/stdio`);
mcpProxyServerUrl.searchParams.append("command", command); mcpProxyServerUrl.searchParams.append("command", command);
mcpProxyServerUrl.searchParams.append("args", args); mcpProxyServerUrl.searchParams.append("args", args);
mcpProxyServerUrl.searchParams.append("env", JSON.stringify(env)); mcpProxyServerUrl.searchParams.append("env", JSON.stringify(env));
const proxyFullAddress = config.MCP_PROXY_FULL_ADDRESS
.value as string;
if (proxyFullAddress) {
mcpProxyServerUrl.searchParams.append(
"proxyFullAddress",
proxyFullAddress,
);
}
transportOptions = { transportOptions = {
authProvider: serverAuthProvider, authProvider: serverAuthProvider,
eventSourceInit: { eventSourceInit: {
@ -431,10 +440,20 @@ export function useConnection({
}, },
}; };
break; break;
}
case "sse": case "sse": {
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/sse`); mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/sse`);
mcpProxyServerUrl.searchParams.append("url", sseUrl); mcpProxyServerUrl.searchParams.append("url", sseUrl);
const proxyFullAddressSSE = config.MCP_PROXY_FULL_ADDRESS
.value as string;
if (proxyFullAddressSSE) {
mcpProxyServerUrl.searchParams.append(
"proxyFullAddress",
proxyFullAddressSSE,
);
}
transportOptions = { transportOptions = {
eventSourceInit: { eventSourceInit: {
fetch: ( fetch: (
@ -451,6 +470,7 @@ export function useConnection({
}, },
}; };
break; break;
}
case "streamable-http": case "streamable-http":
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/mcp`); mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/mcp`);

View file

@ -391,7 +391,11 @@ app.get(
throw error; throw error;
} }
const webAppTransport = new SSEServerTransport("/message", res); const proxyFullAddress = (req.query.proxyFullAddress as string) || "";
const prefix = proxyFullAddress || "";
const endpoint = `${prefix}/message`;
const webAppTransport = new SSEServerTransport(endpoint, res);
console.log("Created client transport"); console.log("Created client transport");
webAppTransports.set(webAppTransport.sessionId, webAppTransport); webAppTransports.set(webAppTransport.sessionId, webAppTransport);
@ -511,7 +515,11 @@ app.get(
} }
if (serverTransport) { if (serverTransport) {
const webAppTransport = new SSEServerTransport("/message", res); const proxyFullAddress = (req.query.proxyFullAddress as string) || "";
const prefix = proxyFullAddress || "";
const endpoint = `${prefix}/message`;
const webAppTransport = new SSEServerTransport(endpoint, res);
webAppTransports.set(webAppTransport.sessionId, webAppTransport); webAppTransports.set(webAppTransport.sessionId, webAppTransport);
console.log("Created client transport"); console.log("Created client transport");
serverTransports.set(webAppTransport.sessionId, serverTransport!); serverTransports.set(webAppTransport.sessionId, serverTransport!);