Skip to main content

Module mcp_progress

Module mcp_progress 

Source
Expand description

MCP notifications/progress plumbing — server-to-client progress updates emitted from a long-running tool handler.

The MCP spec (2025-11-25) lets a client opt into progress updates by attaching _meta.progressToken to a request. While the matching tool is in flight, the server may emit any number of notifications/progress notifications carrying the same token. The server must not emit progress for requests without a token, and progress values must strictly increase per token.

Mechanics mirror the elicitation bus (crate::mcp_elicit::ElicitationBus): a per-connection ProgressBus wraps the transport’s outbound JSON sink (installed thread-locally via install_active_bus), and a per-call ProgressContext is bound for the duration of a tool handler future via scope_context (a tokio task-local) so that helpers — notably the mcp_report_progress stdlib builtin — can find the right token without taking it as an explicit argument. The split between thread-local bus and task-local context matters: adapters spawn concurrent tool calls onto a shared LocalSet, so a thread-local context would race across awaits.

Spec: https://modelcontextprotocol.io/specification/2025-11-25/basic/utilities/progress

Structs§

ActiveBusGuard
RAII guard for install_active_bus. Connection-scoped, so a thread-local guard is correct here.
ProgressBus
Per-connection progress notifier.
ProgressContext
Per-call progress context — the bus plus the token the current request supplied. Bound for the lifetime of a tool handler future via scope_context so that mcp_report_progress(...) can find it without explicit threading.

Functions§

active_bus
Snapshot the active connection-scoped progress bus, if any.
current_context
Snapshot the progress context for the current task, if any.
install_active_bus
Install a connection-scoped ProgressBus for the current thread. Connections are single-threaded (the dispatch loop owns one OS thread or LocalSet), so a thread-local is the right scope here: every per-call task derived from this connection sees the same bus.
is_valid_progress_token
MCP progress tokens are constrained to strings or numbers (no nulls, objects, arrays, or booleans). Validate at the boundary so we never echo a malformed token back to the client.
scope_context
Run future with ctx installed as the active progress context. When ctx is None, the future runs without a context (so current_context returns None from inside it). Use this rather than installing into a thread-local: tool handlers are async and concurrent on the same OS thread, so we need per-task scoping.

Type Aliases§

OutboundFn
Outbound JSON sink for progress notifications.