# Handles notifications without sending a response

- **Pattern:** `ab-001838` (`mcp-server.transport-protocol.notifications`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001838
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001838)

## Why it matters

JSON-RPC 2.0 defines notifications as messages with no `id` — they require no response, and sending one violates the spec. A server that sends error responses to `notifications/initialized` (because it tries to echo the id that isn't there) causes clients to receive unexpected extra messages, which can desync the message stream. A server that crashes on an unknown notification type (`notifications/cancelled`, `notifications/roots/list_changed`) can be triggered by any client action that emits those events, making stability fragile in real workloads.

## Severity rationale

Low because notification handling errors cause protocol drift and occasional crashes rather than data exposure, and most SDK-based servers get this right automatically.

## Remediation

In custom message handlers, check for the absence of `id` to identify notifications and return without responding.

```ts
// src/transport/handler.ts
function handleMessage(message: unknown) {
  // Notifications: no id field — process but do not respond
  if (!('id' in (message as object))) {
    const notification = message as { method: string }
    if (notification.method === 'notifications/initialized') {
      isInitialized = true
    }
    // Unknown notifications: silently ignore
    return
  }
  // Requests: have an id — must respond
  return handleRequest(message as JsonRpcRequest)
}
```

SDK-based servers handle this automatically — do not override the SDK's default notification handling.

## Detection

- **ID:** `notifications`
- **Severity:** `low`
- **What to look for:** Count all notification handlers and emitters. Enumerate which MCP notification types are supported (tools/list_changed, resources/list_changed, progress). In JSON-RPC 2.0, notifications are requests with no `id` field — the server must not send a response. Check that the server correctly identifies notifications (messages without `id`) and does not respond to them. Common notifications from clients: `notifications/initialized`, `notifications/cancelled`, `notifications/roots/list_changed`. For SDK-based servers, this is handled automatically — check that custom message handling doesn't break this.
- **Pass criteria:** The server processes notifications without sending any response. `notifications/initialized` is handled to complete the handshake. Unknown notifications are silently ignored (no error response). At least 2 notification types must be handled or emitted.
- **Fail criteria:** The server sends responses to notifications (violating JSON-RPC 2.0), or crashes on unknown notification types, or does not handle `notifications/initialized`.
- **Skip (N/A) when:** All checks skip when no MCP server is detected.

- **Cross-reference:** For ping support, see `ping-support`.
- **Detail on fail:** `"Custom message handler sends error response for 'notifications/initialized' because it has no 'id' and the handler requires an id for all messages"` or `"Server crashes when receiving 'notifications/cancelled' — unhandled notification type"`
- **Remediation:** Notifications have no `id` and require no response:

  ```ts
  // src/notifications.ts — emit list change notification
  server.notification({ method: "notifications/tools/list_changed" })
  ```

  ```ts
  function handleMessage(message: JsonRpcMessage) {
    // Notifications have no id
    if (!('id' in message)) {
      // Process notification (e.g., update state) but DO NOT respond
      if (message.method === 'notifications/initialized') {
        isInitialized = true
      }
      // Unknown notifications: silently ignore
      return  // no response
    }
    // ... handle requests (which have an id)
  }
  ```

## External references

- external jsonrpc-2.0-notifications — https://www.jsonrpc.org/specification#notification

Taxons: inference-contract, error-resilience

HTML version: https://auditbuffet.com/patterns/ab-001838
