notifications/progress is a server → client notification. The client opts in by sending _meta.progressToken on the tools/call params; the server can then emit progress events as the work proceeds.
GetMCP exposes an emitter API that custom tools and integrations can call. The built-in ToolExecutor is synchronous and doesn’t auto-emit progress — it’s straightforward request-response — so this is wired for tools you author yourself.
Opt-in From the Client
The client signals it wants progress updates by attaching aprogressToken to its tools/call request:
Wire-level Shape (emitted by server)
Echoes the token the client supplied on the originating request.
Monotonically increasing counter. Same units as
total when set.Optional ceiling — clients render a percentage when both are present.
Optional human-readable status line (“Processed 42 of 100 orders”).
Emitting From PHP
Delivery Model
Because Streamable HTTP doesn’t keep an SSE channel open by default, progress notifications are queued server-side and delivered piggy-backed onto the next response. For long-running tool calls this means:- If the tool runs in a single HTTP request that takes 30 seconds, progress is queued but not delivered until the request completes — at which point all progress events arrive as a batch alongside the final result.
- If the tool returns quickly and the client polls again, progress emitted between calls arrives on the next response.
Progress notifications are informational. Clients are not required to render them. Always make sure your tool returns a final result regardless of whether progress was delivered — the protocol guarantees the result, not the progress events.

