Skip to content

Streamable Http transport handle ping message #1146

Closed

Description

@Gujiawei-Edinburgh

Initial Checks

Description

code in src/mcp/client/streamable_http.py:162 validates the payload from incoming SSE messages.
However, on the server side, EventSourceResponse is used, which periodically sends ping message. These ping messages will cause client side parsing message error.
When SSE is used to stream logs, these ping messages trigger unwanted behavior, such as flushing logs unnecessarily. Currently, there doesn’t appear to be a configuration option to disable the ping messages or adjust their interval.
As a potential improvement, the client could check if the incoming message has an empty data field before validation. If the data is empty, the client can treat it as a ping message and safely ignore it.

Example Code

async def _handle_sse_event(
        self,
        sse: ServerSentEvent,
        read_stream_writer: StreamWriter,
        original_request_id: RequestId | None = None,
        resumption_callback: Callable[[str], Awaitable[None]] | None = None,
        is_initialization: bool = False,
    ) -> bool:
        """Handle an SSE event, returning True if the response is complete."""
        if sse.event == "message":
            try:
               # potential changes here
                if not sse.data:
                   logger.debug("Receiving a ping message")
                   # double check if directly return True is compatible or enough
                   return True
                message = JSONRPCMessage.model_validate_json(sse.data)
                logger.debug(f"SSE message: {message}")

Python & MCP Python SDK

python version: 3.13
MCP SDK version: 1.11.0

Activity

  1. raptium commented on Aug 22, 2025

    @raptium
  2. added
    bugSomething isn't working
    needs reproneeds additional information to be able to reproduce bug
    on Oct 3, 2025
  3. felixweinberger commented on Oct 3, 2025

    @felixweinberger
    Contributor

    Hi @Gujiawei-Edinburgh thanks for submitting this issue, could you provide a snippet or minimal example that demonstrates the pings causing an issue? By default there shouldn't be anything broken by sending pings.

  4. meffmadd commented on Nov 26, 2025

    @meffmadd

    I am getting the exact same error! I have mcp version 1.22.0. Here is an example:

    1. Start the everything MCP server: npx @modelcontextprotocol/server-everything@2025.11.25 streamableHttp
    2. Run the following file:
    import asyncio
    
    from mcp import ClientSession
    from mcp.client.streamable_http import streamablehttp_client
    
    
    async def example():
        async with streamablehttp_client("http://localhost:3001/mcp", headers={"Content-Type": "application/json"}) as (
                read_stream,
                write_stream,
                _,
        ):
            async with ClientSession(read_stream, write_stream) as session:
                await session.initialize()
    
    if __name__ == "__main__":
        asyncio.run(example())
    1. See output:
    Error parsing SSE message
    Traceback (most recent call last):
      File "/path/to/.venv/lib/python3.12/site-packages/mcp/client/streamable_http.py", line 164, in _handle_sse_event
        message = JSONRPCMessage.model_validate_json(sse.data)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/path/to/.venv/lib/python3.12/site-packages/pydantic/main.py", line 744, in model_validate_json
        return cls.__pydantic_validator__.validate_json(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    pydantic_core._pydantic_core.ValidationError: 1 validation error for JSONRPCMessage
      Invalid JSON: EOF while parsing a value at line 1 column 0 [type=json_invalid, input_value='', input_type=str]
        For further information visit https://errors.pydantic.dev/2.11/v/json_invalid
    
    Process finished with exit code 0
    

    This fails because sse.data is an empty string. Since the everything MCP Server is a reference implementation I would expect that this should not fail and that this is a standard and expected case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds reproneeds additional information to be able to reproduce bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions