Skip to content

Conversation

@chazcb
Copy link

@chazcb chazcb commented Jan 21, 2026

Summary

This RFD proposes a capability-gated log notification (agent → client) so agents can share diagnostic messages without polluting conversation history.

Key features

  • Capability-gated: Clients opt in via clientCapabilities.logging; agents only send logs to clients that declare the capability
  • Level filtering: Clients can specify minimum log level (default: info)
  • Optional sessionId: Connection-wide if absent, session-specific if present
  • RFC 5424 severity levels: debug, info, notice, warning, error, critical, alert, emergency
  • Optional fields: logger name, timestamp, structured data

Problem

Today, agents have limited ways to inform clients about status that might impact their experience:

  • JSON-RPC errors: Terminate the request immediately (can't use for non-fatal conditions)
  • session/update: Puts diagnostics in chat history (not appropriate for transient status)

Neither works when:

  • There's no active JSON RPC request to attach an error response to
  • We don't want to fail the request (e.g., retries, rate limiting, fallback selection)
  • There's no session yet (diagnostics after initialize but before session/new)
  • We don't want to put diagnostics in chat history

Example

{
  "jsonrpc": "2.0",
  "method": "log",
  "params": {
    "level": "warning",
    "message": "Backing model rate limited, retrying in 5 seconds...",
    "sessionId": "abc-123",
    "logger": "model",
    "timestamp": "2025-01-21T10:30:00Z",
    "data": { "model": "claude-3", "retryIn": 5 }
  }
}

Capability negotiation

{
  "method": "initialize",
  "params": {
    "clientCapabilities": {
      "logging": {
        "level": "warning"
      }
    }
  }
}

🤖 Generated with Claude Code

Proposes a `log` notification method that allows agents to send
diagnostic messages (errors, warnings, info, etc.) to clients.

Key features:
- Optional sessionId for session-scoped vs connection-wide messages
- 8 severity levels (RFC 5424/MCP-compatible)
- Optional structured data, error codes, and timestamps
- Follows ACP naming conventions (no namespace, like initialize/authenticate)

Co-Authored-By: Claude <noreply@anthropic.com>
@chazcb chazcb requested a review from a team as a code owner January 21, 2026 16:06
@chazcb chazcb marked this pull request as draft January 21, 2026 16:07
chazcb and others added 14 commits January 21, 2026 11:18
- Fix transport-agnostic language (stderr is stdio-specific)
- Add comparison table with MCP, LSP, A2A, AG-UI
- Clarify key design choices vs other protocols

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Explains that `log` notifications (in-band, user-facing) and OTEL
telemetry export (out-of-band, observability) are complementary.

Co-Authored-By: Claude <noreply@anthropic.com>
- Connection-level messages are essential (pre-session errors)
- Separation of concerns (logs != conversation state)
- Can't require capability negotiation (pre-initialize errors)
- Clarify: JSON-RPC errors for request failures, log for out-of-band

Co-Authored-By: Claude <noreply@anthropic.com>
JSON-RPC 2.0 notifications are fire-and-forget - clients safely
ignore unknown methods. No version negotiation required.

Co-Authored-By: Claude <noreply@anthropic.com>
Key insight: JSON-RPC errors terminate the run, log notifications don't.

Changes:
- Add `logging` capability requirement (non-breaking, clean opt-in)
- Clarify the core question: "should the run stop?"
- Non-fatal issues, warnings, degraded functionality shouldn't abort
- Connection-wide issues, out-of-band timing, alternative patterns

Co-Authored-By: Claude <noreply@anthropic.com>
Major revision:
- Require capability negotiation (non-breaking, opt-in)
- Lead with key insight: JSON-RPC errors terminate, log doesn't
- Consolidate FAQ from 12 to 8 focused questions
- Add "why not separate channel" FAQ (transport-agnostic, etc.)
- Fix connection-wide example (before session/new, not multi-session)
- Remove redundant/contradictory text
- 176 lines (down from 323)

Co-Authored-By: Claude <noreply@anthropic.com>
MCP server disconnection is a session-level concern, not a good example
for run-time log notifications. Better examples are backing model rate
limiting and backing service disconnection.

Co-Authored-By: Claude <noreply@anthropic.com>
Use generic examples (server shutting down, configuration problems)
instead of MCP-specific examples for connection-wide error scenarios.

Co-Authored-By: Claude <noreply@anthropic.com>
Addresses the alternative of sending diagnostic info as fake
agent_message_chunk content.

Co-Authored-By: Claude <noreply@anthropic.com>
- Add "purely informational" to elevator pitch
- Add explicit statement that clients MAY display but MUST NOT take automated action
- Remove top-level code field (error codes don't make sense for info/debug messages)
- Clarify data field is opaque, for display/debugging only

Co-Authored-By: Claude <noreply@anthropic.com>
The "why" is already covered in Status quo (gaps/problems) and FAQ
(why not alternatives). Elevator pitch should be punchy.

Co-Authored-By: Claude <noreply@anthropic.com>
@chazcb chazcb marked this pull request as ready for review January 21, 2026 20:04
@chazcb chazcb changed the title RFD: Server-to-Client Logging Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant