What are notifications in MCP, and how do they differ from requests?
Quick Answer
A request has an id and demands exactly one matching response (result or error) — used for things like tools/call or resources/read. A notification has no id and gets no response at all — it's fire-and-forget, used for events like notifications/tools/list_changed, notifications/resources/updated, notifications/message (logging), and notifications/progress. Because notifications aren't acknowledged, they're appropriate for informational or best-effort signals, not anything where the sender needs confirmation of delivery or a result. A server that adds a new tool at runtime, for example, sends notifications/tools/list_changed so the client knows to re-fetch the tool list — it doesn't (and can't) wait for a reply.
Detailed Answer
JSON-RPC gives MCP two distinct message patterns, and MCP leans on both deliberately.
Requests vs. notifications
// Request: has "id", caller expects a response
{"jsonrpc": "2.0", "id": 7, "method": "resources/read", "params": {"uri": "file:///a.txt"}}
// Notification: no "id", no response ever sent
{"jsonrpc": "2.0", "method": "notifications/resources/updated", "params": {"uri": "file:///a.txt"}}
A notification has no id. There's nothing for a response to correlate against, so the protocol makes it structurally impossible to reply to one. Sending a notification is inherently best-effort.
Common MCP notifications
notifications/initialized— client confirms the handshake is done.notifications/tools/list_changed,notifications/resources/list_changed,notifications/prompts/list_changed— the set of available tools/resources/prompts changed. The receiver should re-fetch the corresponding*/list.notifications/resources/updated— a specific subscribed resource's content changed.notifications/progress— a long-running request is progressing, paired with aprogressTokenfrom the original request.notifications/message— a log message from a server, at a given severity level.notifications/cancelled— either side is cancelling an in-flight request.
Why the distinction is the right design
If list-changed events were requests, the sender would need to handle "what if the receiver never responds," retries, and timeouts — for something that's really just "hey, something changed, whenever you get to it." Notifications skip all of that. The server doesn't block waiting for acknowledgment, and the client processes it (or ignores it) at its own pace. Anything where the caller genuinely needs a result — reading a resource, calling a tool, listing prompts — has to be a request, since only requests get a result back.