From 9947f35d4959e27b01a275ce15a5779aa3495e2d Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Thu, 5 Mar 2026 21:51:51 +0200 Subject: [PATCH 1/4] docs: add RFD for `getAuthState` method --- docs/rfds/get-auth-state.mdx | 295 +++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 docs/rfds/get-auth-state.mdx diff --git a/docs/rfds/get-auth-state.mdx b/docs/rfds/get-auth-state.mdx new file mode 100644 index 00000000..fd046d6e --- /dev/null +++ b/docs/rfds/get-auth-state.mdx @@ -0,0 +1,295 @@ +--- +title: "Agent Authentication State Query" +--- + +- Author(s): [@xtmq](https://github.com/xtmq) + +> **Note:** This RFD is very preliminary and intended to start a dialog about this feature. The proposed design may change significantly based on feedback and further discussion. + +## Elevator pitch + +> What are you proposing to change? + +Add a `getAuthState` method 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 of `session/new`. + +## Status quo + +> How do things work today and what problems does this cause? Why would we change things? + +Currently, there is no dedicated way for a client to determine whether an agent has valid authentication configured. The typical workaround is: + +1. Call `initialize` +2. Call `session/new` +3. If the agent has no credentials, it _may_ return an authorization error +4. The client handles the error and initiates an authorization flow + +This approach has significant problems: + +- **Unreliable detection**: The `session/new` method 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 on `session/new` to consistently surface auth issues. +- **Wasted resources**: Creating a session only to discard it on auth failure is wasteful, especially if session creation has side effects (resource allocation, logging, history file creation, etc.). +- **Poor user experience**: The client cannot proactively guide the user through authorization before session creation. Instead, users encounter errors mid-flow. + +## Shiny future + +> How will things play out once this feature exists? + +Clients will be able to: +1. Discover whether an agent supports auth state queries via capabilities during initialization +2. Query the agent's current authentication state immediately after initialization +3. Make an informed decision about whether to proceed with session creation, initiate an authorization flow, or configure endpoints (e.g., via `setLlmEndpoints`) +4. Provide clear, proactive UX — e.g., showing a "Sign in" prompt before any session is created +5. Completely skip authentication process if the agent is already authenticated + +## Implementation details and plan + +> Tell me more about your implementation. What is your detailed implementation plan? + +### Intended flow + +The client calls `initialize`, inspects capabilities to confirm `getAuthState` support, then queries auth state before deciding how to proceed. + +```mermaid +sequenceDiagram + participant Client + participant Agent + + Client->>Agent: initialize + Note right of Agent: Agent reports capabilities,
including getAuthState support + Agent-->>Client: initialize response
(agentCapabilities.getAuthState) + + Client->>Agent: getAuthState + Agent-->>Client: getAuthState response
(authenticated, providers) + + alt Authenticated + Client->>Agent: session/new + else Not authenticated + Note over Client: Client initiates
authorization flow
(e.g., call authenticate, setLlmEndpoints) + Client->>Agent: authenticate + Client->>Agent: session/new + end +``` + +1. **Initialization**: The client calls `initialize`. The agent responds with capabilities, including `getAuthState` if supported. +2. **Auth state query**: The client calls `getAuthState`. The agent inspects its local configuration, stored credentials, or environment to determine the current auth state. +3. **Client-side decision**: Based on the response, the client either proceeds to session creation or initiates an authorization flow first. + +### Capability advertisement + +The agent advertises support for the `getAuthState` method via a new capability in `agentCapabilities`: + +```typescript +interface AgentCapabilities { + // ... existing fields ... + + /** + * Auth state query support. + * If true, the agent supports the getAuthState method. + */ + getAuthState?: boolean; +} +``` + +**Initialize Response example:** +```json +{ + "jsonrpc": "2.0", + "id": 0, + "result": { + "protocolVersion": 1, + "agentInfo": { + "name": "MyAgent", + "version": "2.0.0" + }, + "agentCapabilities": { + "getAuthState": true, + "sessionCapabilities": {} + } + } +} +``` + +### `getAuthState` method + +A method that can be called after initialization to query the agent's current authentication state. + +```typescript +interface AuthProviderState { + /** + * Whether the agent has credentials configured for this provider. + * true means credentials are present (validity is not guaranteed). + */ + authenticated: boolean; + + /** Human-readable description of the auth state (e.g., "API key configured via environment") */ + message?: string; + + /** Extension metadata */ + _meta?: Record; +} + +interface GetAuthStateRequest { + /** Extension metadata */ + _meta?: Record; +} + +interface GetAuthStateResponse { + /** + * Whether the agent has credentials configured. + * true means credentials are present (validity is not guaranteed). + * false means no credentials are configured. + */ + authenticated: boolean; + + /** + * Optional per-provider breakdown of auth state. + * Keys are provider identifiers (e.g., "anthropic", "openai"). + */ + providers?: Record; + + /** Human-readable description of the overall auth state */ + message?: string; + + /** Extension metadata */ + _meta?: Record; +} +``` + +#### JSON Schema Additions + +```json +{ + "$defs": { + "AuthProviderState": { + "description": "Authentication state for a specific provider.", + "properties": { + "authenticated": { + "type": "boolean", + "description": "Whether credentials are configured for this provider." + }, + "message": { + "type": ["string", "null"], + "description": "Human-readable description of the auth state." + }, + "_meta": { + "additionalProperties": true, + "type": ["object", "null"] + } + }, + "required": ["authenticated"], + "type": "object" + }, + "GetAuthStateResponse": { + "description": "Response to getAuthState method.", + "properties": { + "authenticated": { + "type": "boolean", + "description": "Whether the agent has credentials configured." + }, + "providers": { + "type": ["object", "null"], + "description": "Per-provider auth state breakdown.", + "additionalProperties": { + "$ref": "#/$defs/AuthProviderState" + } + }, + "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:** +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "getAuthState", + "params": {} +} +``` + +**getAuthState Response (authenticated):** +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "authenticated": true, + "providers": { + "anthropic": { + "authenticated": true, + "message": "API key configured via local config" + } + } + } +} +``` + +**getAuthState Response (unauthenticated):** +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "authenticated": false, + "message": "No credentials configured. Please provide API keys or configure an LLM endpoint." + } +} +``` + +#### Behavior + +1. **Capability advertisement**: The agent MUST include `getAuthState` in `agentCapabilities` if it supports the `getAuthState` method. Clients SHOULD check for this capability before calling the method. + +2. **Timing**: The `getAuthState` method MUST be callable after `initialize`. It MAY be called multiple times (e.g., after `authenticate`, to re-check state). + +3. **Local checks only**: The agent SHOULD determine auth state based on locally available information (config files, environment variables, stored tokens). It SHOULD NOT make external API calls to validate credentials. `authenticated: true` means credentials are present, not that they are guaranteed to be valid. + +4. **No side effects**: Calling `getAuthState` MUST NOT modify any agent state. It is a pure query. + +5. **Per-provider breakdown**: The `providers` field is optional. Agents that use multiple LLM providers MAY include per-provider state to help clients make fine-grained decisions. + +## Open questions + +### Is a per-provider breakdown needed, or is an aggregate state sufficient? + +The current design includes an optional `providers` field with per-provider auth state. However, for many agents a single aggregate `state` may be enough. A per-provider breakdown adds complexity to both the agent implementation and client logic. Should we simplify to just the top-level `state` and `message`? + +### Should `getAuthState` indicate what kind of auth is expected? + +When the state is `"unauthenticated"`, should the response include hints about what the agent needs? For example: +- "Needs an API key for Anthropic **or** OpenAI" + +This could help clients build more targeted authorization flows, but it adds complexity. + +## Frequently asked questions + +> What questions have arisen over the course of authoring this document? + +### Why not rely on `session/new` errors? + +The `session/new` method 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 successful `session/new` does not guarantee the agent is authenticated, and a failed `session/new` may fail for reasons unrelated to authentication. A dedicated method provides a clear, unambiguous signal. + +### Why not include auth state in the `initialize` response directly? + +The `initialize` response contains capabilities — what the agent _supports_. Auth state is runtime information — what the agent _currently has configured_. Mixing these concerns would make `initialize` less predictable. Additionally, auth state may change after initialization (e.g., after a `setLlmEndpoints` call), 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 + +- 2026-03-05: Initial draft — preliminary proposal to start discussion From f52769a34c0504ad1ed40125a10b639b5c5a7804 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Sat, 7 Mar 2026 19:56:40 +0200 Subject: [PATCH 2/4] docs: address review feedback for getAuthState RFD --- docs/rfds/get-auth-state.mdx | 68 +++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/docs/rfds/get-auth-state.mdx b/docs/rfds/get-auth-state.mdx index fd046d6e..e2fbbb77 100644 --- a/docs/rfds/get-auth-state.mdx +++ b/docs/rfds/get-auth-state.mdx @@ -4,8 +4,6 @@ title: "Agent Authentication State Query" - Author(s): [@xtmq](https://github.com/xtmq) -> **Note:** This RFD is very preliminary and intended to start a dialog about this feature. The proposed design may change significantly based on feedback and further discussion. - ## Elevator pitch > What are you proposing to change? @@ -58,7 +56,7 @@ sequenceDiagram Agent-->>Client: initialize response
(agentCapabilities.getAuthState) Client->>Agent: getAuthState - Agent-->>Client: getAuthState response
(authenticated, providers) + Agent-->>Client: getAuthState response
(authenticated, authMethods) alt Authenticated Client->>Agent: session/new @@ -113,9 +111,15 @@ interface AgentCapabilities { A method that can be called after initialization to query the agent's current authentication state. ```typescript -interface AuthProviderState { +interface AuthMethodState { /** - * Whether the agent has credentials configured for this provider. + * The ID of the authentication method. + * Corresponds to an `id` from the `authMethods` array returned during initialization. + */ + authMethodId: string; + + /** + * Whether the agent has credentials configured for this auth method. * true means credentials are present (validity is not guaranteed). */ authenticated: boolean; @@ -141,10 +145,11 @@ interface GetAuthStateResponse { authenticated: boolean; /** - * Optional per-provider breakdown of auth state. - * Keys are provider identifiers (e.g., "anthropic", "openai"). + * Optional per-auth-method breakdown of auth state. + * Each entry corresponds to an auth method from the `authMethods` array + * returned during initialization. */ - providers?: Record; + authMethods?: AuthMethodState[]; /** Human-readable description of the overall auth state */ message?: string; @@ -159,12 +164,16 @@ interface GetAuthStateResponse { ```json { "$defs": { - "AuthProviderState": { - "description": "Authentication state for a specific provider.", + "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 provider." + "description": "Whether credentials are configured for this auth method." }, "message": { "type": ["string", "null"], @@ -175,7 +184,7 @@ interface GetAuthStateResponse { "type": ["object", "null"] } }, - "required": ["authenticated"], + "required": ["authMethodId", "authenticated"], "type": "object" }, "GetAuthStateResponse": { @@ -185,11 +194,11 @@ interface GetAuthStateResponse { "type": "boolean", "description": "Whether the agent has credentials configured." }, - "providers": { - "type": ["object", "null"], - "description": "Per-provider auth state breakdown.", - "additionalProperties": { - "$ref": "#/$defs/AuthProviderState" + "authMethods": { + "type": ["array", "null"], + "description": "Per-auth-method state breakdown.", + "items": { + "$ref": "#/$defs/AuthMethodState" } }, "message": { @@ -227,12 +236,13 @@ interface GetAuthStateResponse { "id": 1, "result": { "authenticated": true, - "providers": { - "anthropic": { + "authMethods": [ + { + "authMethodId": "anthropic-api-key", "authenticated": true, "message": "API key configured via local config" } - } + ] } } ``` @@ -251,28 +261,21 @@ interface GetAuthStateResponse { #### Behavior -1. **Capability advertisement**: The agent MUST include `getAuthState` in `agentCapabilities` if it supports the `getAuthState` method. Clients SHOULD check for this capability before calling the method. +1. **Capability advertisement**: The agent SHOULD include `getAuthState` in `agentCapabilities` if it supports the `getAuthState` method. Clients MUST check for this capability before calling the method. 2. **Timing**: The `getAuthState` method MUST be callable after `initialize`. It MAY be called multiple times (e.g., after `authenticate`, to re-check state). -3. **Local checks only**: The agent SHOULD determine auth state based on locally available information (config files, environment variables, stored tokens). It SHOULD NOT make external API calls to validate credentials. `authenticated: true` means credentials are present, not that they are guaranteed to be valid. +3. **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: true` means credentials are present, NOT that they are guaranteed to be valid. 4. **No side effects**: Calling `getAuthState` MUST NOT modify any agent state. It is a pure query. -5. **Per-provider breakdown**: The `providers` field is optional. Agents that use multiple LLM providers MAY include per-provider state to help clients make fine-grained decisions. +5. **Per-auth-method breakdown**: The `authMethods` field 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-provider breakdown needed, or is an aggregate state sufficient? - -The current design includes an optional `providers` field with per-provider auth state. However, for many agents a single aggregate `state` may be enough. A per-provider breakdown adds complexity to both the agent implementation and client logic. Should we simplify to just the top-level `state` and `message`? - -### Should `getAuthState` indicate what kind of auth is expected? - -When the state is `"unauthenticated"`, should the response include hints about what the agent needs? For example: -- "Needs an API key for Anthropic **or** OpenAI" +### Is a per-auth-method breakdown needed, or is an aggregate state sufficient? -This could help clients build more targeted authorization flows, but it adds complexity. +The current design includes an optional `authMethods` field with per-auth-method state. However, for many agents a single aggregate `state` may be enough. A per-method breakdown adds complexity to both the agent implementation and client logic. Should we simplify to just the top-level `state` and `message`? ## Frequently asked questions @@ -292,4 +295,5 @@ Agents may obtain credentials from many sources: config files, keychains, OAuth ## Revision history +- 2026-03-07: Address review feedback, replace per-provider breakdown with per-auth-method - 2026-03-05: Initial draft — preliminary proposal to start discussion From 1abefd5af8a4eca6680f2893cd893a7dedd70651 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Mon, 9 Mar 2026 10:42:29 +0200 Subject: [PATCH 3/4] docs: formatting for getAuthState RFD --- docs/rfds/get-auth-state.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/rfds/get-auth-state.mdx b/docs/rfds/get-auth-state.mdx index e2fbbb77..a8ece141 100644 --- a/docs/rfds/get-auth-state.mdx +++ b/docs/rfds/get-auth-state.mdx @@ -32,6 +32,7 @@ This approach has significant problems: > How will things play out once this feature exists? Clients will be able to: + 1. Discover whether an agent supports auth state queries via capabilities during initialization 2. Query the agent's current authentication state immediately after initialization 3. Make an informed decision about whether to proceed with session creation, initiate an authorization flow, or configure endpoints (e.g., via `setLlmEndpoints`) @@ -88,6 +89,7 @@ interface AgentCapabilities { ``` **Initialize Response example:** + ```json { "jsonrpc": "2.0", @@ -220,6 +222,7 @@ interface GetAuthStateResponse { #### Example Exchange **getAuthState Request:** + ```json { "jsonrpc": "2.0", @@ -230,6 +233,7 @@ interface GetAuthStateResponse { ``` **getAuthState Response (authenticated):** + ```json { "jsonrpc": "2.0", @@ -248,6 +252,7 @@ interface GetAuthStateResponse { ``` **getAuthState Response (unauthenticated):** + ```json { "jsonrpc": "2.0", From debb4a866fb6320516f751fc995521aa89302d45 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Tue, 10 Mar 2026 21:52:36 +0200 Subject: [PATCH 4/4] docs: naming improvements in `auth/status` RFD --- docs/rfds/get-auth-state.mdx | 57 +++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/docs/rfds/get-auth-state.mdx b/docs/rfds/get-auth-state.mdx index a8ece141..5dd4895b 100644 --- a/docs/rfds/get-auth-state.mdx +++ b/docs/rfds/get-auth-state.mdx @@ -8,7 +8,7 @@ title: "Agent Authentication State Query" > What are you proposing to change? -Add a `getAuthState` method 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 of `session/new`. +Add an `auth/status` method 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 of `session/new`. ## Status quo @@ -45,7 +45,7 @@ Clients will be able to: ### Intended flow -The client calls `initialize`, inspects capabilities to confirm `getAuthState` support, then queries auth state before deciding how to proceed. +The client calls `initialize`, inspects capabilities to confirm `auth/status` support, then queries auth state before deciding how to proceed. ```mermaid sequenceDiagram @@ -53,11 +53,11 @@ sequenceDiagram participant Agent Client->>Agent: initialize - Note right of Agent: Agent reports capabilities,
including getAuthState support - Agent-->>Client: initialize response
(agentCapabilities.getAuthState) + Note right of Agent: Agent reports capabilities,
including auth/status support + Agent-->>Client: initialize response
(agentCapabilities.auth.status) - Client->>Agent: getAuthState - Agent-->>Client: getAuthState response
(authenticated, authMethods) + Client->>Agent: auth/status + Agent-->>Client: auth/status response
(authenticated, authMethods) alt Authenticated Client->>Agent: session/new @@ -68,23 +68,23 @@ sequenceDiagram end ``` -1. **Initialization**: The client calls `initialize`. The agent responds with capabilities, including `getAuthState` if supported. -2. **Auth state query**: The client calls `getAuthState`. The agent inspects its local configuration, stored credentials, or environment to determine the current auth state. +1. **Initialization**: The client calls `initialize`. The agent responds with capabilities, including `auth/status` support via `agentCapabilities.auth`. +2. **Auth state query**: The client calls `auth/status`. The agent inspects its local configuration, stored credentials, or environment to determine the current auth state. 3. **Client-side decision**: Based on the response, the client either proceeds to session creation or initiates an authorization flow first. ### Capability advertisement -The agent advertises support for the `getAuthState` method via a new capability in `agentCapabilities`: +The agent advertises support for the `auth/status` method via the existing `auth` capability in `agentCapabilities`: ```typescript -interface AgentCapabilities { - // ... existing fields ... +interface AuthCapabilities { + // ... existing fields (e.g., terminal) ... /** - * Auth state query support. - * If true, the agent supports the getAuthState method. + * Auth status query support. + * If true, the agent supports the auth/status method. */ - getAuthState?: boolean; + status?: boolean; } ``` @@ -101,14 +101,16 @@ interface AgentCapabilities { "version": "2.0.0" }, "agentCapabilities": { - "getAuthState": true, + "auth": { + "status": true + }, "sessionCapabilities": {} } } } ``` -### `getAuthState` method +### `auth/status` method A method that can be called after initialization to query the agent's current authentication state. @@ -133,12 +135,12 @@ interface AuthMethodState { _meta?: Record; } -interface GetAuthStateRequest { +interface AuthStatusRequest { /** Extension metadata */ _meta?: Record; } -interface GetAuthStateResponse { +interface AuthStatusResponse { /** * Whether the agent has credentials configured. * true means credentials are present (validity is not guaranteed). @@ -189,8 +191,8 @@ interface GetAuthStateResponse { "required": ["authMethodId", "authenticated"], "type": "object" }, - "GetAuthStateResponse": { - "description": "Response to getAuthState method.", + "AuthStatusResponse": { + "description": "Response to auth/status method.", "properties": { "authenticated": { "type": "boolean", @@ -221,18 +223,18 @@ interface GetAuthStateResponse { #### Example Exchange -**getAuthState Request:** +**auth/status Request:** ```json { "jsonrpc": "2.0", "id": 1, - "method": "getAuthState", + "method": "auth/status", "params": {} } ``` -**getAuthState Response (authenticated):** +**auth/status Response (authenticated):** ```json { @@ -251,7 +253,7 @@ interface GetAuthStateResponse { } ``` -**getAuthState Response (unauthenticated):** +**auth/status Response (unauthenticated):** ```json { @@ -266,13 +268,13 @@ interface GetAuthStateResponse { #### Behavior -1. **Capability advertisement**: The agent SHOULD include `getAuthState` in `agentCapabilities` if it supports the `getAuthState` method. Clients MUST check for this capability before calling the method. +1. **Capability advertisement**: The agent SHOULD include `auth.status` in `agentCapabilities` if it supports the `auth/status` method. Clients MUST check for this capability before calling the method. -2. **Timing**: The `getAuthState` method MUST be callable after `initialize`. It MAY be called multiple times (e.g., after `authenticate`, to re-check state). +2. **Timing**: The `auth/status` method MUST be callable after `initialize`. It MAY be called multiple times (e.g., after `authenticate`, to re-check state). 3. **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: true` means credentials are present, NOT that they are guaranteed to be valid. -4. **No side effects**: Calling `getAuthState` MUST NOT modify any agent state. It is a pure query. +4. **No side effects**: Calling `auth/status` MUST NOT modify any agent state. It is a pure query. 5. **Per-auth-method breakdown**: The `authMethods` field is optional. Agents that support multiple authentication methods MAY include per-method state to help clients make fine-grained decisions. @@ -300,5 +302,6 @@ Agents may obtain credentials from many sources: config files, keychains, OAuth ## Revision history +- 2026-03-10: Rename `getAuthState` to `auth/status`, nest capability under `agentCapabilities.auth` - 2026-03-07: Address review feedback, replace per-provider breakdown with per-auth-method - 2026-03-05: Initial draft — preliminary proposal to start discussion