Skip to content

context

BaseContext - the user-facing per-request context.

Composition over a DispatchContext: forwards the transport metadata, the back-channel (send_raw_request/notify), progress reporting, and the cancel event. Adds meta (the inbound request's _meta field).

Satisfies Outbound, so ClientPeer can wrap it. Shared between client and server: the server's Context extends this with lifespan/connection; ClientContext is just an alias.

BaseContext

Bases: Generic[TransportT]

Per-request context wrapping a DispatchContext.

ServerRunner constructs one per inbound request and passes it to the user's handler.

Source code in src/mcp/shared/context.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
class BaseContext(Generic[TransportT]):
    """Per-request context wrapping a `DispatchContext`.

    `ServerRunner` constructs one per inbound request and passes it to the
    user's handler.
    """

    def __init__(self, dctx: DispatchContext[TransportT], meta: RequestParamsMeta | None = None) -> None:
        self._dctx = dctx
        self._meta = meta

    @property
    def transport(self) -> TransportT:
        """Transport-specific metadata for this inbound request."""
        return self._dctx.transport

    @property
    def cancel_requested(self) -> anyio.Event:
        """Set when the peer sends `notifications/cancelled` for this request."""
        return self._dctx.cancel_requested

    @property
    def can_send_request(self) -> bool:
        """Whether the back-channel can currently deliver server-initiated requests.

        `False` when the transport has no back-channel, or when the underlying
        dispatch context has been closed because the inbound request finished.
        """
        return self._dctx.can_send_request

    @property
    def meta(self) -> RequestParamsMeta | None:
        """The inbound request's `_meta` field, if present."""
        return self._meta

    async def send_raw_request(
        self,
        method: str,
        params: Mapping[str, Any] | None,
        opts: CallOptions | None = None,
    ) -> dict[str, Any]:
        """Send a request to the peer on the back-channel.

        Raises:
            MCPError: The peer responded with an error.
            NoBackChannelError: `can_send_request` is `False`.
        """
        return await self._dctx.send_raw_request(method, params, opts)

    async def notify(self, method: str, params: Mapping[str, Any] | None) -> None:
        """Send a notification to the peer on the back-channel."""
        await self._dctx.notify(method, params)

    async def report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None:
        """Report progress for this request, if the peer supplied a progress token.

        A no-op when no token was supplied.
        """
        await self._dctx.progress(progress, total, message)

transport property

transport: TransportT

Transport-specific metadata for this inbound request.

cancel_requested property

cancel_requested: Event

Set when the peer sends notifications/cancelled for this request.

can_send_request property

can_send_request: bool

Whether the back-channel can currently deliver server-initiated requests.

False when the transport has no back-channel, or when the underlying dispatch context has been closed because the inbound request finished.

meta property

meta: RequestParamsMeta | None

The inbound request's _meta field, if present.

send_raw_request async

send_raw_request(
    method: str,
    params: Mapping[str, Any] | None,
    opts: CallOptions | None = None,
) -> dict[str, Any]

Send a request to the peer on the back-channel.

Raises:

Type Description
MCPError

The peer responded with an error.

NoBackChannelError

can_send_request is False.

Source code in src/mcp/shared/context.py
62
63
64
65
66
67
68
69
70
71
72
73
74
async def send_raw_request(
    self,
    method: str,
    params: Mapping[str, Any] | None,
    opts: CallOptions | None = None,
) -> dict[str, Any]:
    """Send a request to the peer on the back-channel.

    Raises:
        MCPError: The peer responded with an error.
        NoBackChannelError: `can_send_request` is `False`.
    """
    return await self._dctx.send_raw_request(method, params, opts)

notify async

notify(
    method: str, params: Mapping[str, Any] | None
) -> None

Send a notification to the peer on the back-channel.

Source code in src/mcp/shared/context.py
76
77
78
async def notify(self, method: str, params: Mapping[str, Any] | None) -> None:
    """Send a notification to the peer on the back-channel."""
    await self._dctx.notify(method, params)

report_progress async

report_progress(
    progress: float,
    total: float | None = None,
    message: str | None = None,
) -> None

Report progress for this request, if the peer supplied a progress token.

A no-op when no token was supplied.

Source code in src/mcp/shared/context.py
80
81
82
83
84
85
async def report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None:
    """Report progress for this request, if the peer supplied a progress token.

    A no-op when no token was supplied.
    """
    await self._dctx.progress(progress, total, message)