Skip to content

Conversation

@felixweinberger
Copy link
Contributor

Summary

This PR adds a close_sse_stream callback to the tool context, addressing feedback from findleyr on the TypeScript SDK PR. This is a follow-up to #1654 (SEP-1699 SSE polling).

The key improvements:

  • Reduced coupling: Tools no longer need direct access to session_manager - the callback is injected into the context
  • Event store awareness: Callback is None if no event store is configured (so tools don't need to check this themselves)
  • Per-call retry interval: Each call to close_sse_stream() can specify its own retry interval in milliseconds

API Usage

FastMCP (high-level):

@mcp.tool()
async def long_running_task(ctx: Context) -> str:
    await ctx.info("Starting task...")
    
    # Close SSE stream to trigger polling behavior
    # Callback is None if not on streamable HTTP transport or no event store
    if ctx.close_sse_stream:
        await ctx.close_sse_stream(retry_interval=3000)  # Reconnect after 3s
    
    await asyncio.sleep(1)
    return "Task completed"

Lowlevel Server:

@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[types.ContentBlock]:
    ctx = app.request_context
    
    if ctx.close_sse_stream:
        await ctx.close_sse_stream(retry_interval=5000)
    
    return [types.TextContent(type="text", text="Done")]

Changes

  • src/mcp/shared/context.py: Added CloseSSEStreamCallback type and close_sse_stream field to RequestContext
  • src/mcp/shared/message.py: Added close_sse_stream field to ServerMessageMetadata
  • src/mcp/server/fastmcp/server.py: Added close_sse_stream property to Context class
  • src/mcp/server/streamable_http.py: Added callback factory and retry_interval parameter
  • src/mcp/server/streamable_http_manager.py: Pass through retry_interval parameter
  • src/mcp/server/lowlevel/server.py: Extract callback from metadata into RequestContext
  • Updated examples to use the new callback API

Test plan

  • All existing tests pass (772 tests)
  • Manual testing with everything-server test_reconnection tool

@felixweinberger felixweinberger marked this pull request as draft November 25, 2025 16:36
@felixweinberger felixweinberger force-pushed the fweinberger/sep-1699-callback-api branch 3 times, most recently from 86d7bd0 to ef13f29 Compare November 25, 2025 18:41
@felixweinberger felixweinberger marked this pull request as ready for review November 25, 2025 18:44
- Add client auto-reconnection with configurable backoff options
- Add close_sse_stream API for server-initiated disconnects
- Add priming events and event store support for resumability
- Add sse_retry_interval setting to FastMCP
- Add test coverage for SSE polling reconnection
@felixweinberger felixweinberger force-pushed the fweinberger/sep-1699-callback-api branch from ef13f29 to 9059c04 Compare November 26, 2025 14:18
@felixweinberger felixweinberger deleted the fweinberger/sep-1699-callback-api branch November 26, 2025 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants