Skip to content

Conversation

@chazcb
Copy link
Contributor

@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 RFD: Agent-to-Client Logging Jan 22, 2026
Copy link
Member

@benbrandt benbrandt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my notes on status vs logging.

I think I am trying to better understand the motivating use case. In my mind, I think we would want a more semantically meaningful status update if these will be user-facing within the main UI.

However, given that we are moving more things to remote scenarios, what this seems to show me is a way for a client to subscribe to the equivalent of stderr with a filter? Which could be helpful in debug scenarios where you need to look at the logs from the client side and don't have the luxury of having access to stderr as you would from a local process.

If we are targeting the latter, then I think this could definitely provide some value. I just think (speaking from Zed) we would likely relegate this to our ACP log/debug views that the user pulls up on-demand rather than utilize them within the main UI to avoid overly noisy logs (even with WARN/ERROR it is unclear that these should always be surfaced based on the semantics, as with many logs, they serve a different purpose potentially than a UI facing status update).

Curious to get your thoughts on all of this, and if I am completely missing the purpose of what you are proposing here.

"params": {
"clientCapabilities": {
"logging": {
"level": "warning"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to say as a notification we could just add this, but having some sort of filter totally makes sense here.

Another option would be the default filter level is "error" and the client can opt-in to allowing more?

This also gives me some pause as it feels like we are mixing configuration with capabilities, so I wonder if this needs to live somewhere else, but just a gut reaction

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, agree on mixing config and capabilities. At the same time, I don't like needing to add new methods for setting logging levels, especially when you want to init a session with a specific logging level.

For our debug logging, it's important that we can get logs immediately after initialization. Other ways to accomplish that:

  1. New "setLogLevel" method that can be called prior to initialization
  2. New field on "params" for initialize that opts the client into logging with a specific configuration (the theory being that this is not a client "capability")
  3. Or finally, if the client specifies "logging" in client capabilities, then we default to sending all log levels (for now).

Thoughts on those options?


Instead of general-purpose logging, define a more structured `status` notification explicitly for lightweight status info—similar to Claude Code's interim status messages ("Thinking...", "Searching files..."). This would be scoped to either the current session or the agent/connection level.

**Tradeoffs**: More constrained semantics could be clearer for clients, but less flexible. Logging with severity levels is a well-understood pattern; inventing a new "status" abstraction may not add value over `log` with `level: info`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. I do feel like this more structured status would be super helpful, but understand that you are trying to get at a different use case here.

I think the clients would benefit a lot from these more interactive status messages, but you are proposing something else here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this proposal is really about debug and / or error logging, specifically for developers trying to get a better sense of why something went wrong or what is happening under the hood. I would imagine some UIs might provide the "show logs" pane so end users can also debug, but this is really about getting the info to the client and not about structuring dynamic UIs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool yeah then we are aligned here. Basically allows a client to offer some sort of log UI

It does now beg the question for me though 😄 :
Do we want a way for a client to be able to change the requested log-level while the connection is active? I could see it being helpful to adjust this after you have already connected, but we can also say the user needs to specify/configure this beforehand

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this can totally be a "we do this later" thing, just a thought I had)


> How will things play out once this feature exists?

- **Clear connection feedback**: Clients can surface warnings (rate limits, retries, fallbacks) so users understand what's happening.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding this: I think for clients to give a meaningful, user-facing status update, we may want to go with the more structured status approach? With the current proposal, speaking from the client perspective, I don't know that we would surface these as they would potentially be too noisy/unpredictable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree this should get removed from proposal language and proposal should focus more around logging for client visibility into internals, rather than for UIs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants