MCPcopy Index your code
hub / github.com/modelcontextprotocol/python-sdk / serve_loop

Function serve_loop

src/mcp/server/runner.py:440–470  ·  view source on GitHub ↗

Drive ``server`` in loop mode over a stream pair until the channel closes. Builds the loop-mode `JSONRPCDispatcher` + `Connection` and hands them to `serve_connection`, so loop-mode callers share one dispatcher-construction recipe (notably the `inline_methods={"initialize"}` rule). Call

(
    server: Server[LifespanT],
    read_stream: ReadStream[SessionMessage | Exception],
    write_stream: WriteStream[SessionMessage],
    *,
    lifespan_state: LifespanT,
    session_id: str | None = None,
    init_options: InitializationOptions | None = None,
    raise_exceptions: bool = False,
)

Source from the content-addressed store, hash-verified

438
439
440async def serve_loop(
441 server: Server[LifespanT],
442 read_stream: ReadStream[SessionMessage | Exception],
443 write_stream: WriteStream[SessionMessage],
444 *,
445 lifespan_state: LifespanT,
446 session_id: str | None = None,
447 init_options: InitializationOptions | None = None,
448 raise_exceptions: bool = False,
449) -> None:
450 """Drive ``server`` in loop mode over a stream pair until the channel closes.
451
452 Builds the loop-mode `JSONRPCDispatcher` + `Connection` and hands them to
453 `serve_connection`, so loop-mode callers share one dispatcher-construction
454 recipe (notably the `inline_methods={"initialize"}` rule). Callers that own
455 a lifespan (the streamable-HTTP manager) pass it in; callers that don't
456 (`Server.run` for stdio/memory) enter the lifespan and then call this.
457 """
458 dispatcher: JSONRPCDispatcher[TransportContext] = JSONRPCDispatcher(
459 read_stream,
460 write_stream,
461 raise_handler_exceptions=raise_exceptions,
462 # Handle `initialize` inline so a client that pipelines it with the
463 # next request (spec: SHOULD NOT, not MUST NOT) sees the initialized
464 # state instead of failing the init-gate.
465 inline_methods=frozenset({"initialize"}),
466 )
467 connection = Connection.for_loop(dispatcher, session_id=session_id)
468 await serve_connection(
469 server, dispatcher, connection=connection, lifespan_state=lifespan_state, init_options=init_options
470 )
471
472
473async def serve_one(

Callers 2

run_serverMethod · 0.90
runMethod · 0.90

Calls 3

JSONRPCDispatcherClass · 0.90
serve_connectionFunction · 0.85
for_loopMethod · 0.80

Tested by

no test coverage detected