notifications/message is a server → client notification. The server uses it to send structured log messages to the client (warnings, debug traces, audit lines) — typically rendered in a side panel in clients like Claude Desktop and Cursor.
GetMCP exposes a callable emitter API. The level filter the client requested via logging/setLevel is honoured before queuing.
Wire-level Shape
One of
debug, info, notice, warning, error, critical, alert, emergency (RFC 5424 syslog levels).Optional logger name — useful for routing in the client. Convention: dot-notation per subsystem (
getmcp.tool.<name>, getmcp.auth, etc.).The log payload. Most clients render
data.message as the headline and the rest of the object as structured detail.Emitting From PHP
logging/setLevel) and drops the message if it’s below the threshold. If no level was set, the default is info — debug messages are suppressed.
Delivery Model
Like other server-initiated traffic on Streamable HTTP, log messages are queued in the per-session outbound queue and delivered as part of the next JSON-RPC response batch. Clients that already handle batched responses (the official SDKs do) will surface them in real time as they arrive.When to Emit
Good fits:- Auditable side effects — “Created Stripe invoice
inv_abc123” - Soft warnings the user should see — “Upstream API returned a 429; retried after 1.2s”
- Debug traces gated behind log level — keep them at
debugso production clients don’t see them
- Tool errors — return them as
isError: truein thetools/callresponse so the model knows it failed - Per-request telemetry — write to your own log destination;
notifications/messageis for the user, not for ops dashboards
Log notifications are advisory and lossy — clients may render them, drop them, or rate-limit them. Don’t rely on them for state that has to reach the user; surface that as part of the tool response instead.

