-
Notifications
You must be signed in to change notification settings - Fork 144
RFD: Agent-to-Client Logging #392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
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>
- 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>
benbrandt
left a comment
There was a problem hiding this 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" |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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:
- New "setLogLevel" method that can be called prior to initialization
- 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")
- 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`. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect thanks!
Summary
This RFD proposes a capability-gated
lognotification (agent → client) so agents can share diagnostic messages without polluting conversation history.Key features
clientCapabilities.logging; agents only send logs to clients that declare the capabilityinfo)sessionId: Connection-wide if absent, session-specific if presentProblem
Today, agents have limited ways to inform clients about status that might impact their experience:
session/update: Puts diagnostics in chat history (not appropriate for transient status)Neither works when:
initializebut beforesession/new)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