Server-side per-request context. Extends `BaseContext` (transport metadata, the raw back-channel, progress reporting) with `lifespan`, `connection`, and request-scoped `log`. Not currently constructed by `ServerRunner`, which hands handlers a `ServerRequestContext` instead.
| 47 | |
| 48 | |
| 49 | class Context(BaseContext[TransportContext], Generic[LifespanT_co]): |
| 50 | """Server-side per-request context. |
| 51 | |
| 52 | Extends `BaseContext` (transport metadata, the raw back-channel, progress |
| 53 | reporting) with `lifespan`, `connection`, and request-scoped `log`. |
| 54 | |
| 55 | Not currently constructed by `ServerRunner`, which hands handlers a |
| 56 | `ServerRequestContext` instead. |
| 57 | """ |
| 58 | |
| 59 | def __init__( |
| 60 | self, |
| 61 | dctx: DispatchContext[TransportContext], |
| 62 | *, |
| 63 | lifespan: LifespanT_co, |
| 64 | connection: Connection, |
| 65 | meta: RequestParamsMeta | None = None, |
| 66 | ) -> None: |
| 67 | super().__init__(dctx, meta=meta) |
| 68 | self._lifespan = lifespan |
| 69 | self._connection = connection |
| 70 | |
| 71 | @property |
| 72 | def lifespan(self) -> LifespanT_co: |
| 73 | """The server-wide lifespan output (what `Server(..., lifespan=...)` yielded).""" |
| 74 | return self._lifespan |
| 75 | |
| 76 | @property |
| 77 | def connection(self) -> Connection: |
| 78 | """The per-client `Connection` for this request's connection.""" |
| 79 | return self._connection |
| 80 | |
| 81 | @property |
| 82 | def session_id(self) -> str | None: |
| 83 | """The transport's session id for this connection, when one exists. |
| 84 | |
| 85 | Convenience for `ctx.connection.session_id`. `None` on stdio and |
| 86 | stateless HTTP. |
| 87 | """ |
| 88 | return self._connection.session_id |
| 89 | |
| 90 | @property |
| 91 | def headers(self) -> Mapping[str, str] | None: |
| 92 | """Request headers carried by this message, when the transport has them. |
| 93 | |
| 94 | Convenience for `ctx.transport.headers`. `None` on stdio. |
| 95 | """ |
| 96 | return self.transport.headers |
| 97 | |
| 98 | @deprecated("The logging capability is deprecated as of 2026-07-28 (SEP-2577).", category=MCPDeprecationWarning) |
| 99 | async def log(self, level: LoggingLevel, data: Any, logger: str | None = None, *, meta: Meta | None = None) -> None: |
| 100 | """Send a request-scoped `notifications/message` log entry. |
| 101 | |
| 102 | Uses this request's back-channel (so the entry rides the request's SSE |
| 103 | stream in streamable HTTP), not the standalone stream - use |
| 104 | `ctx.connection.log(...)` for that. |
| 105 | """ |
| 106 | params: dict[str, Any] = {"level": level, "data": data} |
no outgoing calls