> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getmcp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# notifications/message

> Server-emitted log messages routed to the connected MCP client.

`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

```json theme={null}
{
  "jsonrpc": "2.0",
  "method":  "notifications/message",
  "params": {
    "level":  "warning",
    "logger": "getmcp.tool.create_invoice",
    "data": {
      "message":   "Stripe rate limit at 80% of cap",
      "remaining": 12,
      "limit":     60
    }
  }
}
```

<ParamField body="params.level" type="string" required>
  One of `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency` (RFC 5424 syslog levels).
</ParamField>

<ParamField body="params.logger" type="string">
  Optional logger name — useful for routing in the client. Convention: dot-notation per subsystem (`getmcp.tool.<name>`, `getmcp.auth`, etc.).
</ParamField>

<ParamField body="params.data" type="object | string" required>
  The log payload. Most clients render `data.message` as the headline and the rest of the object as structured detail.
</ParamField>

***

## Emitting From PHP

```php theme={null}
use GetMCP\Protocol\MessageEmitter;

MessageEmitter::emit(
    $session_id,
    'warning',                            // level
    'getmcp.tool.create_invoice',         // logger
    array(
        'message'   => 'Stripe rate limit at 80% of cap',
        'remaining' => 12,
        'limit'     => 60,
    )
);
```

The emitter checks the session's current log level (set by the client via `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 `debug` so production clients don't see them

Bad fits:

* **Tool errors** — return them as `isError: true` in the `tools/call` response so the model knows it failed
* **Per-request telemetry** — write to your own log destination; `notifications/message` is for the user, not for ops dashboards

***

<Note>
  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.
</Note>
