Skip to content

Commit 716b282

Browse files
committed
Keep _on_request private, expose it via an on_request property
Mirror the on_notify/_on_notify split rather than making the worker method public.
1 parent c42f11d commit 716b282

3 files changed

Lines changed: 9 additions & 5 deletions

File tree

src/mcp/server/context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ async def log(self, level: LoggingLevel, data: Any, logger: str | None = None, *
125125
class ServerMiddleware(Protocol[_MwLifespanT]):
126126
"""Context-tier middleware: `(ctx, call_next) -> result`.
127127
128-
Runs at the top of `ServerRunner.on_request` / `_on_notify` after `ctx`
128+
Runs at the top of `ServerRunner._on_request` / `_on_notify` after `ctx`
129129
is built but before any validation, lookup, or handshake. Wraps every
130130
inbound request and notification: `initialize`, the pre-init gate,
131131
`METHOD_NOT_FOUND`, params validation, the handler call, and

src/mcp/server/lowlevel/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ def __init__(
231231
self._session_manager: StreamableHTTPSessionManager | None = None
232232
# Context-tier middleware: wraps every inbound request (including
233233
# `initialize`, lookup, validation, handler) with
234-
# `(ctx, call_next)`. Applied in `ServerRunner.on_request`.
234+
# `(ctx, call_next)`. Applied in `ServerRunner._on_request`.
235235
# `OpenTelemetryMiddleware` ships on by default so every server emits a
236236
# SERVER span per message; it is a no-op until an OTel exporter is
237237
# installed. Drop it from this list to opt out.

src/mcp/server/runner.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,15 @@ class ServerRunner(Generic[LifespanT]):
142142
init_options: InitializationOptions | None = None
143143
"""`InitializeResult` payload. Defaults to `server.create_initialization_options()`."""
144144

145+
@cached_property
146+
def on_request(self) -> OnRequest:
147+
return self._on_request
148+
145149
@cached_property
146150
def on_notify(self) -> OnNotify:
147151
return self._on_notify
148152

149-
async def on_request(
153+
async def _on_request(
150154
self,
151155
dctx: DispatchContext[TransportContext],
152156
method: str,
@@ -263,7 +267,7 @@ async def _inner(ctx: ServerRequestContext[LifespanT, Any]) -> None:
263267
def _compose_server_middleware(self, inner: CallNext) -> CallNext:
264268
"""Wrap `inner` in `Server.middleware`, outermost-first.
265269
266-
Shared by `on_request` and `_on_notify` so the same middleware chain
270+
Shared by `_on_request` and `_on_notify` so the same middleware chain
267271
observes every inbound message. The composed callable takes the `ctx`
268272
at call time, so a middleware can rewrite it for the rest of the chain.
269273
"""
@@ -338,7 +342,7 @@ def _negotiate_initialize(params: Mapping[str, Any] | None) -> tuple[InitializeR
338342
return init, negotiated
339343

340344
def _handle_initialize(self, params: Mapping[str, Any] | None) -> InitializeResult:
341-
"""Build the `initialize` result; state commits later in `on_request`."""
345+
"""Build the `initialize` result; state commits later in `_on_request`."""
342346
_, negotiated = self._negotiate_initialize(params)
343347
opts = self.init_options if self.init_options is not None else self.server.create_initialization_options()
344348
return InitializeResult(

0 commit comments

Comments
 (0)