Skip to content

MCP Server incompatible with MCP SDK ≥1.28 clients: stateless_http=True causes immediate session termination #227

Description

@marten-lucas

Summary

The context_agent MCP server (/ex_app/lib/main.py) is configured with stateless_http=True:

http_mcp_app = mcp.http_app("/", transport="http", stateless_http=True)

In stateless mode, the MCP server terminates the session immediately after each individual HTTP request. This is incompatible with MCP clients using MCP SDK ≥1.28 (e.g. Hermes Agent v0.20, Claude Code, etc.) which expect a persistent session after initialize.

Steps to Reproduce

  1. Install context_agent 2.8.0 on Nextcloud AIO 33.x
  2. Connect any MCP client using MCP SDK ≥1.28 (Streamable HTTP transport)
  3. Client sends initialize → succeeds
  4. Server immediately calls transport.terminate() (stateless mode: terminate after every request)
  5. Client's subsequent tools/list or keepalive hits a terminated session → receives McpError: Session terminated
  6. Client disconnects / parks the server

Root Cause

In mcp.server.streamable_http_manager.StreamableHTTPSessionManager._handle_stateless_request():

await http_transport.handle_request(scope, receive, send)
await http_transport.terminate()  # ← terminates after EVERY request

This means each POST is a completely independent transaction. MCP clients that open a persistent ClientSession after initialize will fail on every subsequent request.

Observed Behavior

McpError: Session terminated
MCP server 'Nextcloud' failed initial connection after 3 attempts, parking

The session connects briefly (tools are discovered), but parks immediately due to the rapid-drop budget in the client.

Expected Behavior

The MCP server should use stateless_http=False (persistent sessions) OR the documentation should clarify which MCP client versions/transports are supported.

Workaround

Change line 41 of /ex_app/lib/main.py in the container:

# Before (broken with MCP SDK ≥1.28 clients):
http_mcp_app = mcp.http_app("/", transport="http", stateless_http=True)

# After (working):
http_mcp_app = mcp.http_app("/", transport="http", stateless_http=False)

This requires recreating the Docker container with a bind-mount for the patched file, as the container image hardcodes the original value.

Environment

  • Nextcloud: 33.0.7 (AIO deployment)
  • context_agent: 2.8.0
  • fastmcp: 2.14.7
  • mcp SDK (server): 1.29.0
  • MCP client: Hermes Agent v0.20.0 (mcp SDK 1.28.1, Streamable HTTP transport)
  • AppAPI: 33.0.0 with HaRP deploy daemon

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