X Tutup
Skip to content

Allow explicit message_url override in mcp.client.sse.sse_client #2255

@tonybhaskar

Description

@tonybhaskar

Initial Checks

Description

When using the MCP Python client with SSE transport, the sse_client helper only accepts the SSE endpoint:

async with sse_client(url=mcp_server_sse_url, headers=headers, timeout=timeout) as streams:
    async with ClientSession(*streams) as session:
        await session.initialize()
        return await session.call_tool(name=name, arguments=arguments)

Internally, the MCP client derives the messages endpoint automatically from the SSE URL and sse.data.

However, this assumption breaks in deployments where reverse proxies (e.g., Nginx) inject path prefixes that the backend service is unaware of.

Example deployment

Externally exposed endpoints after reverse proxying:

https://example.com/api/v1/sse
https://example.com/api/v1/messages/{session_id}

Internally, the MCP server only defines:

  • SSE endpoint: /v1/sse
  • Messages POST endpoint: /v1/messages/

The /api prefix is injected by the reverse proxy.

In this situation:

  • The client connects sse endpoint correct (Because we are providing the url): https://example.com/api/v1/sse
  • But the MCP client internally derives the messages endpoint as:
https://example.com/v1/messages/{session_id} -> Based on sse.data

instead of:

https://example.com/api/v1/messages/{session_id}

Because the client assumes a fixed base path.

Current limitation

The sse_client interface does not allow explicitly providing a messages_url, which makes it impossible to support deployments where:

  • the base path is rewritten by a reverse proxy
  • the backend service is unaware of the external prefix

Proposed improvement

Allow explicitly specifying the messages endpoint when creating the SSE client:

async with sse_client(
    url="https://example.com/api/v1/sse",
    messages_url="https://example.com/api/v1/messages",
    headers=headers,
    timeout=timeout
) as streams:

Behavior:

  • If messages_url is provided → use it directly
  • Otherwise → fall back to the current behavior of deriving it from the SSE URL

This change would allow the MCP Python client to work correctly in reverse-proxy deployments, versioned APIs, and gateway setups, while maintaining backward compatibility.

Example Code

Python & MCP Python SDK

Python 3.13.12
mcp>=1.26.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      X Tutup