docs(rfd): Agent Authentication State Query#658
docs(rfd): Agent Authentication State Query#658xtmq wants to merge 3 commits intoagentclientprotocol:mainfrom
Conversation
| * The ID of the authentication method. | ||
| * Corresponds to an `id` from the `authMethods` array returned during initialization. | ||
| */ | ||
| authMethodId: string; |
There was a problem hiding this comment.
Hmm I am not always sure this will map 1:1
For example, a terminal auth may ultimately support more than one login method (they often have a way to choose how you want to authenticate)
There was a problem hiding this comment.
Also, does it matter which one was chosen specifically in terms of ids?
Maybe we can just have the boolean and a message/label to show the user?
There was a problem hiding this comment.
I think it can be useful to be able to distinguish saved api key case from oauth. Don't you think so? But we can put it in _meta later on and now stick to the simpliest solution.
There was a problem hiding this comment.
I think it is useful... but I just don't think it will map 1:1 to the auth method id is my concern... because several of these agents you can get multiple types of auth from the same auth method
Maybe we need some kind of category of auth? curious to hear your thoughts too @anna239
| "version": "2.0.0" | ||
| }, | ||
| "agentCapabilities": { | ||
| "getAuthState": true, |
There was a problem hiding this comment.
Maybe we can nest this under the current auth capabilities structure?
There was a problem hiding this comment.
Yes, we can! Will do a change a bit later
|
|
||
| ### Capability advertisement | ||
|
|
||
| The agent advertises support for the `getAuthState` method via a new capability in `agentCapabilities`: |
There was a problem hiding this comment.
we don't encode get or other such methods in the method names usually.
Maybe this could be auth/info or auth/status?
There was a problem hiding this comment.
sorry, it is my .net/java background :) I will adjust naming for sure!
| * Each entry corresponds to an auth method from the `authMethods` array | ||
| * returned during initialization. | ||
| */ | ||
| authMethods?: AuthMethodState[]; |
There was a problem hiding this comment.
Yeah do we need this list is I guess what I am asking?
title: "Agent Authentication State Query"
Elevator pitch
Add a
getAuthStatemethod and corresponding capability that allows clients to query the agent's current authentication state. This lets clients determine whether the agent is already configured with valid credentials or requires authorization before creating a session, without relying on the ambiguous error behavior ofsession/new.Status quo
Currently, there is no dedicated way for a client to determine whether an agent has valid authentication configured. The typical workaround is:
initializesession/newThis approach has significant problems:
session/newmethod is not required by the specification to check authorization. Some agents validate credentials eagerly, others do so lazily (e.g., on the first LLM call). The client cannot rely onsession/newto consistently surface auth issues.Shiny future
Clients will be able to:
setLlmEndpoints)Implementation details and plan
Intended flow
The client calls
initialize, inspects capabilities to confirmgetAuthStatesupport, then queries auth state before deciding how to proceed.sequenceDiagram participant Client participant Agent Client->>Agent: initialize Note right of Agent: Agent reports capabilities,<br/>including getAuthState support Agent-->>Client: initialize response<br/>(agentCapabilities.getAuthState) Client->>Agent: getAuthState Agent-->>Client: getAuthState response<br/>(authenticated, authMethods) alt Authenticated Client->>Agent: session/new else Not authenticated Note over Client: Client initiates<br/>authorization flow<br/>(e.g., call authenticate, setLlmEndpoints) Client->>Agent: authenticate Client->>Agent: session/new endinitialize. The agent responds with capabilities, includinggetAuthStateif supported.getAuthState. The agent inspects its local configuration, stored credentials, or environment to determine the current auth state.Capability advertisement
The agent advertises support for the
getAuthStatemethod via a new capability inagentCapabilities:Initialize Response example:
{ "jsonrpc": "2.0", "id": 0, "result": { "protocolVersion": 1, "agentInfo": { "name": "MyAgent", "version": "2.0.0" }, "agentCapabilities": { "getAuthState": true, "sessionCapabilities": {} } } }getAuthStatemethodA method that can be called after initialization to query the agent's current authentication state.
JSON Schema Additions
{ "$defs": { "AuthMethodState": { "description": "Authentication state for a specific auth method.", "properties": { "authMethodId": { "type": "string", "description": "The ID of the authentication method, matching an entry from the authMethods array returned during initialization." }, "authenticated": { "type": "boolean", "description": "Whether credentials are configured for this auth method." }, "message": { "type": ["string", "null"], "description": "Human-readable description of the auth state." }, "_meta": { "additionalProperties": true, "type": ["object", "null"] } }, "required": ["authMethodId", "authenticated"], "type": "object" }, "GetAuthStateResponse": { "description": "Response to getAuthState method.", "properties": { "authenticated": { "type": "boolean", "description": "Whether the agent has credentials configured." }, "authMethods": { "type": ["array", "null"], "description": "Per-auth-method state breakdown.", "items": { "$ref": "#/$defs/AuthMethodState" } }, "message": { "type": ["string", "null"], "description": "Human-readable description of the overall auth state." }, "_meta": { "additionalProperties": true, "type": ["object", "null"] } }, "required": ["authenticated"], "type": "object" } } }Example Exchange
getAuthState Request:
{ "jsonrpc": "2.0", "id": 1, "method": "getAuthState", "params": {} }getAuthState Response (authenticated):
{ "jsonrpc": "2.0", "id": 1, "result": { "authenticated": true, "authMethods": [ { "authMethodId": "anthropic-api-key", "authenticated": true, "message": "API key configured via local config" } ] } }getAuthState Response (unauthenticated):
{ "jsonrpc": "2.0", "id": 1, "result": { "authenticated": false, "message": "No credentials configured. Please provide API keys or configure an LLM endpoint." } }Behavior
Capability advertisement: The agent SHOULD include
getAuthStateinagentCapabilitiesif it supports thegetAuthStatemethod. Clients MUST check for this capability before calling the method.Timing: The
getAuthStatemethod MUST be callable afterinitialize. It MAY be called multiple times (e.g., afterauthenticate, to re-check state).Local checks only: The agent MAY determine auth state based on locally available information (config files, environment variables, stored tokens) or by making external API calls.
authenticated: truemeans credentials are present, NOT that they are guaranteed to be valid.No side effects: Calling
getAuthStateMUST NOT modify any agent state. It is a pure query.Per-auth-method breakdown: The
authMethodsfield is optional. Agents that support multiple authentication methods MAY include per-method state to help clients make fine-grained decisions.Open questions
Is a per-auth-method breakdown needed, or is an aggregate state sufficient?
The current design includes an optional
authMethodsfield with per-auth-method state. However, for many agents a single aggregatestatemay be enough. A per-method breakdown adds complexity to both the agent implementation and client logic. Should we simplify to just the top-levelstateandmessage?Frequently asked questions
Why not rely on
session/newerrors?The
session/newmethod is designed for session creation, not for auth validation. Per the specification, agents are not required to validate credentials during session creation — some agents defer validation to the first actual LLM call. This means a successfulsession/newdoes not guarantee the agent is authenticated, and a failedsession/newmay fail for reasons unrelated to authentication. A dedicated method provides a clear, unambiguous signal.Why not include auth state in the
initializeresponse directly?The
initializeresponse contains capabilities — what the agent supports. Auth state is runtime information — what the agent currently has configured. Mixing these concerns would makeinitializeless predictable. Additionally, auth state may change after initialization (e.g., after asetLlmEndpointscall), and a separate method allows re-querying.Why not just check for the presence of environment variables on the client side?
Agents may obtain credentials from many sources: config files, keychains, OAuth tokens, environment variables, or even embedded keys. The client has no visibility into these mechanisms. Only the agent knows whether it has usable credentials configured.
Revision history