From fba7393f60d9883e8690b1e6f66039e305b1c6f2 Mon Sep 17 00:00:00 2001 From: Charles Covey-Brandt Date: Thu, 22 Jan 2026 15:17:52 -0500 Subject: [PATCH 1/6] Add RFD: Session Input Options Discovery Proposal for allowing Agents to declare what input options they accept for session/new and session/load requests in InitializeResponse. This complements the existing Session Config Options RFD: - Input Options: Discovery of options for session creation/loading - Config Options: Runtime configuration during a session Key features: - JSON Schema subset for rich type definitions - Separate schemas for newSession vs loadSession - Enables dynamic client UIs for session configuration - All options are optional - Agents must provide defaults Co-Authored-By: Claude --- docs/rfds/session-input-options.mdx | 289 ++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 docs/rfds/session-input-options.mdx diff --git a/docs/rfds/session-input-options.mdx b/docs/rfds/session-input-options.mdx new file mode 100644 index 00000000..78c65a2c --- /dev/null +++ b/docs/rfds/session-input-options.mdx @@ -0,0 +1,289 @@ +--- +title: "Session Input Options Discovery" +--- + +Author(s): [@chazcb](https://github.com/chazcb) + +## Elevator pitch + +> What are you proposing to change? + +Allow Agents to declare what input options they accept for `session/new` and `session/load` requests in the `InitializeResponse`. This enables Clients to build dynamic configuration UIs *before* creating a session, showing users exactly what options are available and their types. + +This proposal complements the existing [Session Config Options RFD](./session-config-options) which handles *runtime* configuration (mode/model selectors during a session). This RFD addresses *input* discovery - what options can be passed when creating or loading sessions. + +## Status quo + +> How do things work today and what problems does this cause? Why would we change things? + +Currently, the ACP schema defines some standard fields on `NewSessionRequest` and `LoadSessionRequest`: + +- `cwd` - Working directory for the session +- `mcpServers` - List of MCP servers to connect + +However: + +1. **Not all Agents support all options** - Some agents don't use `cwd` or have their own working directory handling. Some agents don't support client-provided MCP servers. Clients have no way to know which standard options an agent actually accepts. + +2. **Agent-specific options are invisible** - Agents may want to accept additional options (like initial model, system prompt, subagents, etc.), but there's no standard way to expose these to clients. + +3. **New vs Load may differ** - Creating a new session might accept different options than loading an existing one (e.g., you might set certain options only at creation time). + +4. **Client UIs are static** - Without discovery, clients must either hardcode known options or provide generic key-value inputs, neither of which provides a good user experience. + +## What we propose to do about it + +> What are you proposing to improve the situation? + +Add an `inputOptions` field to `InitializeResponse` that declares what options an Agent accepts for session creation and loading. Use a JSON Schema subset for type definitions to enable rich client UIs. + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "protocolVersion": 1, + "agentCapabilities": { ... }, + "agentInfo": { ... }, + "inputOptions": { + "newSession": { + "model": { + "enum": ["claude-sonnet-4-20250514", "claude-opus-4-20250514", "claude-haiku"], + "description": "Model to use for this session" + }, + "systemPrompt": { + "type": "string", + "description": "Custom system prompt to guide the agent's behavior" + }, + "enabledSubagents": { + "type": "array", + "items": { "type": "string" }, + "description": "List of subagent IDs to enable for this session" + }, + "maxTokens": { + "type": "integer", + "description": "Maximum tokens per response" + } + }, + "loadSession": { + "model": { + "enum": ["claude-sonnet-4-20250514", "claude-opus-4-20250514", "claude-haiku"], + "description": "Model to use when resuming (can differ from original)" + } + } + } + } +} +``` + +Clients pass input options via `inputOptions` on `NewSessionRequest` and `LoadSessionRequest`: + +```json +{ + "jsonrpc": "2.0", + "id": 2, + "method": "session/new", + "params": { + "cwd": "/path/to/project", + "mcpServers": [], + "inputOptions": { + "model": "claude-sonnet-4-20250514", + "systemPrompt": "You are a helpful coding assistant.", + "enabledSubagents": ["web-search", "code-execution"], + "maxTokens": 4096 + } + } +} +``` + +## Shiny future + +> How will things will play out once this feature exists? + +**For Clients:** +- Query `inputOptions` from `InitializeResponse` to know what the Agent accepts +- Build dynamic forms showing available options with proper input types (text fields, dropdowns for enums, checkboxes for booleans) +- Show different options for "New Session" vs "Load Session" flows +- Gracefully handle Agents that don't declare any `inputOptions` + +**For Agents:** +- Declare supported options with types and descriptions +- MUST handle all options as optional - clients may not provide all (or any) options +- MUST provide sensible defaults for undeclared options +- Can declare standard ACP options (`cwd`, `mcpServers`) in `inputOptions` to indicate explicit support + +**Key behaviors:** +- Input options are for session *creation/loading*, not runtime configuration +- Runtime configuration (mode switching, model selection during a session) is handled by the [Session Config Options RFD](./session-config-options) +- Agents can support both: `inputOptions` for initial setup, `configOptions` for runtime changes + +## Implementation details and plan + +> Tell me more about your implementation. What is your detailed implementation plan? + +### Schema + +The `inputOptions` schema uses a simplified JSON Schema subset to balance expressiveness with cross-language compatibility: + +```typescript +type InputOptionSchema = + | { type: "string"; description?: string } + | { type: "number"; description?: string } + | { type: "integer"; description?: string } + | { type: "boolean"; description?: string } + | { enum: (string | number | boolean | null)[]; description?: string } + | { type: "array"; items: InputOptionSchema; description?: string } + | { type: "object"; properties: Record; required?: string[]; description?: string }; + +interface InitializeResponse { + protocolVersion: number; + agentCapabilities: AgentCapabilities; + agentInfo: AgentInfo; + inputOptions?: { + newSession?: Record; + loadSession?: Record; + }; +} + +interface NewSessionRequest { + cwd: string; + mcpServers: McpServer[]; + inputOptions?: Record; +} + +interface LoadSessionRequest { + sessionId: string; + cwd: string; + mcpServers: McpServer[]; + inputOptions?: Record; +} +``` + +### Why JSON Schema subset instead of `select`/`text` types? + +The existing [Session Config Options RFD](./session-config-options) uses `select` and `text` types because runtime selectors are primarily UI widgets - dropdowns and text fields. + +Input options need richer types because they're data inputs: +- **Booleans** - checkboxes, toggle switches +- **Numbers/Integers** - numeric inputs with validation +- **Enums** - constrained choice from known values +- **Arrays** - multi-select or list inputs +- **Objects** - nested configuration groups + +### Passing input options + +Clients send input options in `inputOptions` on session requests: + +```json +{ + "method": "session/new", + "params": { + "cwd": "/path/to/project", + "mcpServers": [], + "inputOptions": { + "mode": "code", + "maxResults": 50, + "enableFeature": true + } + } +} +``` + +Values should match the declared types (strings, numbers, booleans - not string-encoded). + +### Relationship to well-known protocol fields + +The ACP protocol already defines some fields on `NewSessionRequest` and `LoadSessionRequest`: + +- `cwd` - Working directory (required, top-level) +- `mcpServers` - MCP server configurations (required, top-level) + +These **remain top-level fields** on the request - they are not moved into `inputOptions`. The `inputOptions` field is for **additional agent-specific options** beyond what the protocol defines. + +```json +{ + "method": "session/new", + "params": { + "cwd": "/path/to/project", + "mcpServers": [...], + "inputOptions": { + "model": "claude-sonnet-4-20250514", + "systemPrompt": "You are a helpful assistant." + } + } +} +``` + +This keeps a clean separation: +- **Protocol fields** - Always present, well-defined schemas, top-level +- **Agent-specific options** - Discovered via `inputOptions` schema, passed in `inputOptions` object + +### Implementation phases + +**Phase 1: Schema definition** +- Add `InputOptionSchema` type definitions to ACP schema +- Add `inputOptions` to `InitializeResponse` +- Add `inputOptions` to `NewSessionRequest` and `LoadSessionRequest` + +**Phase 2: Client support** +- Update TypeScript SDK to expose `inputOptions` +- Implement example UI rendering in reference client + +**Phase 3: Agent adoption** +- Document pattern for agents to declare their options +- Add examples to protocol documentation + +## Frequently asked questions + +> What questions have arisen over the course of authoring this document or during subsequent discussions? + +### What alternative approaches did you consider, and why did you settle on this one? + +1. **Extend Session Config Options with richer types** - The existing [Session Config Options RFD](./session-config-options) uses `select`/`text` types. We could update that RFD to support richer types (boolean, number, array, nested objects) and use the same schema for both input options and runtime config options. This would provide consistency across the protocol. The main tradeoff is that runtime selectors (mode/model dropdowns) have different UX needs than input options (forms with various field types), but a unified schema could still work well for both. + +2. **Separate discovery endpoint** - Could add a `session/describe` method. Rejected because `InitializeResponse` already exists for capability discovery and adding another round-trip adds latency. + +3. **Use full JSON Schema** - Could support the complete JSON Schema spec. Rejected for cross-language compatibility - a simplified subset is easier to implement consistently across TypeScript, Python, Kotlin, etc. + +### How does this relate to Session Config Options? + +| Aspect | Input Options (this RFD) | Config Options (existing RFD) | +|--------|-------------------------|-------------------------------| +| When | Before session creation | During session runtime | +| Purpose | Set initial configuration | Change configuration mid-session | +| Examples | Initial model, system prompt, subagents | Switch modes, change model mid-session | +| Schema | JSON Schema subset | `select`/`text` types | +| Location | `InitializeResponse.inputOptions` | `NewSessionResponse.configOptions` | + +Agents can support both - use `inputOptions` for things that can only be set at creation time, and `configOptions` for things that can be changed during the session. + +### Should we unify the schema with Session Config Options? + +This is an open question worth discussing. The Session Config Options RFD currently uses `select`/`text` types, while this proposal uses a JSON Schema subset. We could: + +**Option A: Keep them separate** (current proposal) +- Input options use JSON Schema subset (richer types for form inputs) +- Config options use `select`/`text` (simpler for runtime selectors) +- Pro: Each is optimized for its use case +- Con: Two different schema systems to learn and implement + +**Option B: Unify on JSON Schema subset** +- Update Session Config Options RFD to use the same JSON Schema subset +- Both input options and config options use identical schema definitions +- Pro: Consistency, single schema system +- Con: May be overkill for simple runtime selectors + +**Option C: Unify on extended select/text** +- Extend the `select`/`text` types to support boolean, number, array, etc. +- Pro: Builds on existing work +- Con: Inventing a new schema language vs using JSON Schema conventions + +Feedback welcome on which approach the community prefers. + +### Are input options required? + +No. Agents MUST handle missing options gracefully. Clients MAY not support input options UI. This is purely for discoverability and better UX. + +## Revision history + +- 2025-01-22: Initial draft From 1faeaa7fef3b52046c5aac893eb065394b8bf033 Mon Sep 17 00:00:00 2001 From: Charles Covey-Brandt Date: Mon, 26 Jan 2026 11:47:16 -0500 Subject: [PATCH 2/6] Add hint and default optional fields to input options schema - Add `hint` for UI guidance (placeholder text, input hints) - Add `default` for declaring default values agents will use - Update examples to demonstrate usage - Add open question about whether both description and hint are needed Co-Authored-By: Claude --- docs/rfds/session-input-options.mdx | 72 ++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/docs/rfds/session-input-options.mdx b/docs/rfds/session-input-options.mdx index 78c65a2c..ba2ad8ac 100644 --- a/docs/rfds/session-input-options.mdx +++ b/docs/rfds/session-input-options.mdx @@ -49,20 +49,25 @@ Add an `inputOptions` field to `InitializeResponse` that declares what options a "newSession": { "model": { "enum": ["claude-sonnet-4-20250514", "claude-opus-4-20250514", "claude-haiku"], + "default": "claude-sonnet-4-20250514", "description": "Model to use for this session" }, "systemPrompt": { "type": "string", - "description": "Custom system prompt to guide the agent's behavior" + "description": "Custom system prompt to guide the agent's behavior", + "hint": "You are a helpful coding assistant..." }, "enabledSubagents": { "type": "array", "items": { "type": "string" }, - "description": "List of subagent IDs to enable for this session" + "description": "List of subagent IDs to enable for this session", + "default": [] }, "maxTokens": { "type": "integer", - "description": "Maximum tokens per response" + "description": "Maximum tokens per response", + "default": 4096, + "hint": "Enter a value between 1 and 8192" } }, "loadSession": { @@ -103,13 +108,18 @@ Clients pass input options via `inputOptions` on `NewSessionRequest` and `LoadSe **For Clients:** - Query `inputOptions` from `InitializeResponse` to know what the Agent accepts - Build dynamic forms showing available options with proper input types (text fields, dropdowns for enums, checkboxes for booleans) +- Use `description` to show help text explaining each option +- Use `hint` for placeholder text or input guidance (e.g., example values) +- Pre-populate form fields with `default` values when provided - Show different options for "New Session" vs "Load Session" flows - Gracefully handle Agents that don't declare any `inputOptions` **For Agents:** -- Declare supported options with types and descriptions +- Declare supported options with types, descriptions, hints, and defaults +- Use `default` to communicate the value that will be used if the client omits the option +- Use `hint` to provide example values or input guidance for clients to display - MUST handle all options as optional - clients may not provide all (or any) options -- MUST provide sensible defaults for undeclared options +- MUST use declared `default` values when options are not provided by the client - Can declare standard ACP options (`cwd`, `mcpServers`) in `inputOptions` to indicate explicit support **Key behaviors:** @@ -126,14 +136,19 @@ Clients pass input options via `inputOptions` on `NewSessionRequest` and `LoadSe The `inputOptions` schema uses a simplified JSON Schema subset to balance expressiveness with cross-language compatibility: ```typescript +interface InputOptionBase { + description?: string; // Human-readable description of the option + hint?: string; // UI hint (e.g., placeholder text for input fields) +} + type InputOptionSchema = - | { type: "string"; description?: string } - | { type: "number"; description?: string } - | { type: "integer"; description?: string } - | { type: "boolean"; description?: string } - | { enum: (string | number | boolean | null)[]; description?: string } - | { type: "array"; items: InputOptionSchema; description?: string } - | { type: "object"; properties: Record; required?: string[]; description?: string }; + | InputOptionBase & { type: "string"; default?: string } + | InputOptionBase & { type: "number"; default?: number } + | InputOptionBase & { type: "integer"; default?: number } + | InputOptionBase & { type: "boolean"; default?: boolean } + | InputOptionBase & { enum: (string | number | boolean | null)[]; default?: string | number | boolean | null } + | InputOptionBase & { type: "array"; items: InputOptionSchema; default?: unknown[] } + | InputOptionBase & { type: "object"; properties: Record; required?: string[]; default?: Record }; interface InitializeResponse { protocolVersion: number; @@ -159,6 +174,18 @@ interface LoadSessionRequest { } ``` +### Optional metadata fields + +All option types support three optional metadata fields: + +- **`description`** - Human-readable explanation of what the option does. Clients typically display this as help text or tooltips. + +- **`hint`** - UI guidance for input fields. For text inputs, this is typically shown as placeholder text. For numeric inputs, it might describe valid ranges. For enums, it could explain how to choose between options. + +- **`default`** - The value the agent will use if the client doesn't provide this option. Clients SHOULD pre-populate form fields with default values. Agents MUST use the declared default when an option is omitted. + +All three fields are optional. Agents can declare options with just a type, or provide any combination of these metadata fields. + ### Why JSON Schema subset instead of `select`/`text` types? The existing [Session Config Options RFD](./session-config-options) uses `select` and `text` types because runtime selectors are primarily UI widgets - dropdowns and text fields. @@ -284,6 +311,27 @@ Feedback welcome on which approach the community prefers. No. Agents MUST handle missing options gracefully. Clients MAY not support input options UI. This is purely for discoverability and better UX. +### Should we have both `description` and `hint`, or just `description`? + +This is an open question. The current proposal includes both: + +- **`description`** - Explains what the option does (shown as help text/tooltip) +- **`hint`** - Provides input guidance (shown as placeholder text) + +**Arguments for having both:** +- They serve different UI purposes: `description` is explanatory, `hint` is exemplary +- Matches common form patterns where labels/help text differ from placeholder text +- Allows "System prompt" (description) vs "You are a helpful assistant..." (hint) + +**Arguments for just `description`:** +- Simpler schema with fewer fields to implement +- Clients can derive placeholder text from description if needed +- Less ambiguity about which field to use for what purpose +- Many options don't need both (e.g., boolean toggles, enum dropdowns) + +Feedback welcome on whether the added complexity of `hint` is worth it. + ## Revision history +- 2025-01-26: Added `hint` and `default` optional fields to schema - 2025-01-22: Initial draft From a6fb0ef761ba693c06b52f5b11e7969fde9937f0 Mon Sep 17 00:00:00 2001 From: Charles Covey-Brandt Date: Tue, 27 Jan 2026 09:41:33 -0500 Subject: [PATCH 3/6] Update session-input-options.mdx --- docs/rfds/session-input-options.mdx | 504 +++++++++++++++++----------- 1 file changed, 314 insertions(+), 190 deletions(-) diff --git a/docs/rfds/session-input-options.mdx b/docs/rfds/session-input-options.mdx index ba2ad8ac..c9742548 100644 --- a/docs/rfds/session-input-options.mdx +++ b/docs/rfds/session-input-options.mdx @@ -8,34 +8,30 @@ Author(s): [@chazcb](https://github.com/chazcb) > What are you proposing to change? -Allow Agents to declare what input options they accept for `session/new` and `session/load` requests in the `InitializeResponse`. This enables Clients to build dynamic configuration UIs *before* creating a session, showing users exactly what options are available and their types. +Allow Agents to declare what input options they accept for `session/new` and `session/load` requests in the `InitializeResponse`. This enables Clients to build dynamic configuration UIs _before_ creating a session, showing users exactly what options are available and their types. -This proposal complements the existing [Session Config Options RFD](./session-config-options) which handles *runtime* configuration (mode/model selectors during a session). This RFD addresses *input* discovery - what options can be passed when creating or loading sessions. +This proposal has two parts: -## Status quo - -> How do things work today and what problems does this cause? Why would we change things? - -Currently, the ACP schema defines some standard fields on `NewSessionRequest` and `LoadSessionRequest`: +1. **Input options discovery** - A mechanism for agents to declare what options they accept when creating or loading sessions +2. **Session config schema** - A shared type system for defining options, designed to be used by both this RFD and [Session Config Options](./session-config-options.mdx) -- `cwd` - Working directory for the session -- `mcpServers` - List of MCP servers to connect +This complements the existing [Session Config Options RFD](./session-config-options.mdx) which handles _runtime_ configuration (mode/model selectors during a session). This RFD addresses _input_ discovery - what options can be passed when creating or loading sessions. -However: +## Status quo -1. **Not all Agents support all options** - Some agents don't use `cwd` or have their own working directory handling. Some agents don't support client-provided MCP servers. Clients have no way to know which standard options an agent actually accepts. +> How do things work today and what problems does this cause? Why would we change things? -2. **Agent-specific options are invisible** - Agents may want to accept additional options (like initial model, system prompt, subagents, etc.), but there's no standard way to expose these to clients. +1. **Agent-specific options are invisible** - Agents may want to accept additional options (like initial model, system prompt, subagents, etc.), but there's no standard way to expose these to clients. -3. **New vs Load may differ** - Creating a new session might accept different options than loading an existing one (e.g., you might set certain options only at creation time). +2. **New vs Load may differ** - Creating a new session might accept different options than loading an existing one (e.g., you might set certain options only at creation time). -4. **Client UIs are static** - Without discovery, clients must either hardcode known options or provide generic key-value inputs, neither of which provides a good user experience. +3. **Client UIs are static** - Without discovery, clients must either hardcode known options or provide generic key-value inputs, neither of which provides a good user experience. ## What we propose to do about it > What are you proposing to improve the situation? -Add an `inputOptions` field to `InitializeResponse` that declares what options an Agent accepts for session creation and loading. Use a JSON Schema subset for type definitions to enable rich client UIs. +Add a `configOptions` field to `InitializeResponse` that declares what options an Agent accepts for session creation and loading. The options are keyed by the JSON-RPC method name they apply to (`session/new`, `session/load`). ```json { @@ -45,43 +41,60 @@ Add an `inputOptions` field to `InitializeResponse` that declares what options a "protocolVersion": 1, "agentCapabilities": { ... }, "agentInfo": { ... }, - "inputOptions": { - "newSession": { - "model": { - "enum": ["claude-sonnet-4-20250514", "claude-opus-4-20250514", "claude-haiku"], - "default": "claude-sonnet-4-20250514", - "description": "Model to use for this session" + "configOptions": { + "session/new": [ + { + "id": "model", + "name": "Model", + "description": "Model to use for this session", + "type": "select", + "defaultValue": "claude-sonnet-4-20250514", + "options": [ + { "value": "claude-sonnet-4-20250514", "name": "Sonnet 4" }, + { "value": "claude-opus-4-20250514", "name": "Opus 4" }, + { "value": "claude-haiku", "name": "Haiku" } + ] }, - "systemPrompt": { - "type": "string", + { + "id": "systemPrompt", + "name": "System Prompt", "description": "Custom system prompt to guide the agent's behavior", - "hint": "You are a helpful coding assistant..." - }, - "enabledSubagents": { - "type": "array", - "items": { "type": "string" }, - "description": "List of subagent IDs to enable for this session", - "default": [] + "type": "text" }, - "maxTokens": { - "type": "integer", + { + "id": "maxTokens", + "name": "Max Tokens", "description": "Maximum tokens per response", - "default": 4096, - "hint": "Enter a value between 1 and 8192" + "type": "number", + "defaultValue": 4096 + }, + { + "id": "enableTools", + "name": "Enable Tools", + "description": "Allow the agent to use tools", + "type": "boolean", + "defaultValue": true } - }, - "loadSession": { - "model": { - "enum": ["claude-sonnet-4-20250514", "claude-opus-4-20250514", "claude-haiku"], - "description": "Model to use when resuming (can differ from original)" + ], + "session/load": [ + { + "id": "model", + "name": "Model", + "description": "Model to use when resuming (can differ from original)", + "type": "select", + "options": [ + { "value": "claude-sonnet-4-20250514", "name": "Sonnet 4" }, + { "value": "claude-opus-4-20250514", "name": "Opus 4" }, + { "value": "claude-haiku", "name": "Haiku" } + ] } - } + ] } } } ``` -Clients pass input options via `inputOptions` on `NewSessionRequest` and `LoadSessionRequest`: +Clients pass config options via `configOptions` on `NewSessionRequest` and `LoadSessionRequest`: ```json { @@ -89,13 +102,12 @@ Clients pass input options via `inputOptions` on `NewSessionRequest` and `LoadSe "id": 2, "method": "session/new", "params": { - "cwd": "/path/to/project", - "mcpServers": [], - "inputOptions": { + ... + "configOptions": { "model": "claude-sonnet-4-20250514", "systemPrompt": "You are a helpful coding assistant.", - "enabledSubagents": ["web-search", "code-execution"], - "maxTokens": 4096 + "maxTokens": 4096, + "enableTools": true } } } @@ -106,159 +118,271 @@ Clients pass input options via `inputOptions` on `NewSessionRequest` and `LoadSe > How will things will play out once this feature exists? **For Clients:** -- Query `inputOptions` from `InitializeResponse` to know what the Agent accepts -- Build dynamic forms showing available options with proper input types (text fields, dropdowns for enums, checkboxes for booleans) -- Use `description` to show help text explaining each option -- Use `hint` for placeholder text or input guidance (e.g., example values) -- Pre-populate form fields with `default` values when provided + +- Query `configOptions` from `InitializeResponse` to know what the Agent accepts +- Build dynamic forms showing available options with proper input types (text fields, dropdowns for selects, checkboxes for booleans, number inputs) +- Use `name` for field labels and `description` for help text/tooltips +- For select options, display `name` to users while sending `value` to the agent +- Pre-populate form fields with `defaultValue` values when provided - Show different options for "New Session" vs "Load Session" flows -- Gracefully handle Agents that don't declare any `inputOptions` +- Gracefully handle Agents that don't declare any `configOptions` **For Agents:** -- Declare supported options with types, descriptions, hints, and defaults -- Use `default` to communicate the value that will be used if the client omits the option -- Use `hint` to provide example values or input guidance for clients to display + +- Declare supported options with types, names, descriptions, and default values +- Use `defaultValue` to communicate the value that will be used if the client omits the option - MUST handle all options as optional - clients may not provide all (or any) options -- MUST use declared `default` values when options are not provided by the client -- Can declare standard ACP options (`cwd`, `mcpServers`) in `inputOptions` to indicate explicit support +- MUST use declared `defaultValue` values when options are not provided by the client **Key behaviors:** -- Input options are for session *creation/loading*, not runtime configuration -- Runtime configuration (mode switching, model selection during a session) is handled by the [Session Config Options RFD](./session-config-options) -- Agents can support both: `inputOptions` for initial setup, `configOptions` for runtime changes + +- Options under `session/new` and `session/load` are for session _creation/loading_ +- Runtime configuration (mode switching, model selection during a session) is handled by the [Session Config Options RFD](./session-config-options.mdx) +- See open question: [Should this RFD also cover runtime config options?](#should-this-rfd-also-cover-runtime-config-options-sessionset_config_option) ## Implementation details and plan > Tell me more about your implementation. What is your detailed implementation plan? -### Schema +### Passing config options -The `inputOptions` schema uses a simplified JSON Schema subset to balance expressiveness with cross-language compatibility: +Clients send config options in `configOptions` on session requests: -```typescript -interface InputOptionBase { - description?: string; // Human-readable description of the option - hint?: string; // UI hint (e.g., placeholder text for input fields) +```json +{ + "method": "session/new", + "params": { + ... + "configOptions": { + "model": "claude-sonnet-4-20250514", + "maxTokens": 4096, + "enableTools": true + } + } } +``` -type InputOptionSchema = - | InputOptionBase & { type: "string"; default?: string } - | InputOptionBase & { type: "number"; default?: number } - | InputOptionBase & { type: "integer"; default?: number } - | InputOptionBase & { type: "boolean"; default?: boolean } - | InputOptionBase & { enum: (string | number | boolean | null)[]; default?: string | number | boolean | null } - | InputOptionBase & { type: "array"; items: InputOptionSchema; default?: unknown[] } - | InputOptionBase & { type: "object"; properties: Record; required?: string[]; default?: Record }; +Values should match the declared types (strings, numbers, booleans - not string-encoded). -interface InitializeResponse { - protocolVersion: number; - agentCapabilities: AgentCapabilities; - agentInfo: AgentInfo; - inputOptions?: { - newSession?: Record; - loadSession?: Record; - }; -} +## Session Config Schema -interface NewSessionRequest { - cwd: string; - mcpServers: McpServer[]; - inputOptions?: Record; -} +This section defines the shared schema for declaring configuration options. This schema is designed to be used by both this RFD (for input options) and [Session Config Options](./session-config-options.mdx) (for runtime options). -interface LoadSessionRequest { - sessionId: string; - cwd: string; - mcpServers: McpServer[]; - inputOptions?: Record; +### Design principles + +1. **Value/name separation** - All selectable options distinguish between machine-readable `value` and human-readable `name` +2. **Consistent metadata** - All option types support `id`, `name`, `description`, and `defaultValue` +3. **Alignment with Config Options** - Use similar patterns to Session Config Options for consistency across the protocol +4. **Cross-language compatibility** - Use simple types that work well in TypeScript, Python, Kotlin, etc. + +### Base option structure + +All input options share a common base structure: + +```typescript +interface ConfigOptionBase { + id: string; // Unique identifier for this option (used as key in configOptions object) + name: string; // Human-readable label for the option + description?: string; // Longer explanation of what the option does } ``` -### Optional metadata fields +### Option types -All option types support three optional metadata fields: +#### Select (single choice from a list) -- **`description`** - Human-readable explanation of what the option does. Clients typically display this as help text or tooltips. +```typescript +interface SelectOption extends ConfigOptionBase { + type: "select"; + defaultValue?: string | number | boolean | null; + options: Array<{ + value: string | number | boolean | null; // Machine-readable value + name: string; // Human-readable display text + description?: string; // Optional description for this choice + }>; +} +``` -- **`hint`** - UI guidance for input fields. For text inputs, this is typically shown as placeholder text. For numeric inputs, it might describe valid ranges. For enums, it could explain how to choose between options. +Example: -- **`default`** - The value the agent will use if the client doesn't provide this option. Clients SHOULD pre-populate form fields with default values. Agents MUST use the declared default when an option is omitted. +```json +{ + "id": "model", + "name": "Model", + "description": "Model to use for this session", + "type": "select", + "defaultValue": "claude-sonnet-4-20250514", + "options": [ + { + "value": "claude-sonnet-4-20250514", + "name": "Sonnet 4", + "description": "Fast and capable" + }, + { + "value": "claude-opus-4-20250514", + "name": "Opus 4", + "description": "Most powerful" + }, + { + "value": "claude-haiku", + "name": "Haiku", + "description": "Fastest responses" + } + ] +} +``` -All three fields are optional. Agents can declare options with just a type, or provide any combination of these metadata fields. +#### Text (free-form string input) -### Why JSON Schema subset instead of `select`/`text` types? +```typescript +interface TextOption extends ConfigOptionBase { + type: "text"; + defaultValue?: string; +} +``` -The existing [Session Config Options RFD](./session-config-options) uses `select` and `text` types because runtime selectors are primarily UI widgets - dropdowns and text fields. +Example: -Input options need richer types because they're data inputs: -- **Booleans** - checkboxes, toggle switches -- **Numbers/Integers** - numeric inputs with validation -- **Enums** - constrained choice from known values -- **Arrays** - multi-select or list inputs -- **Objects** - nested configuration groups +```json +{ + "id": "systemPrompt", + "name": "System Prompt", + "description": "Custom system prompt to guide the agent's behavior", + "type": "text" +} +``` -### Passing input options +#### Number (numeric input) -Clients send input options in `inputOptions` on session requests: +```typescript +interface NumberOption extends ConfigOptionBase { + type: "number"; + defaultValue?: number; +} +``` + +Example: ```json { - "method": "session/new", - "params": { - "cwd": "/path/to/project", - "mcpServers": [], - "inputOptions": { - "mode": "code", - "maxResults": 50, - "enableFeature": true - } - } + "id": "maxTokens", + "name": "Max Tokens", + "description": "Maximum tokens per response", + "type": "number", + "defaultValue": 4096 } ``` -Values should match the declared types (strings, numbers, booleans - not string-encoded). +#### Boolean (true/false toggle) -### Relationship to well-known protocol fields +```typescript +interface BooleanOption extends ConfigOptionBase { + type: "boolean"; + defaultValue?: boolean; +} +``` -The ACP protocol already defines some fields on `NewSessionRequest` and `LoadSessionRequest`: +Example: -- `cwd` - Working directory (required, top-level) -- `mcpServers` - MCP server configurations (required, top-level) +```json +{ + "id": "enableTools", + "name": "Enable Tools", + "description": "Allow the agent to use tools", + "type": "boolean", + "defaultValue": true +} +``` + +#### Multi-select (multiple choices from a list) + +```typescript +interface MultiSelectOption extends ConfigOptionBase { + type: "multiselect"; + defaultValue?: Array; + options: Array<{ + value: string | number | boolean | null; + name: string; + description?: string; + }>; +} +``` -These **remain top-level fields** on the request - they are not moved into `inputOptions`. The `inputOptions` field is for **additional agent-specific options** beyond what the protocol defines. +Example: ```json { - "method": "session/new", - "params": { - "cwd": "/path/to/project", - "mcpServers": [...], - "inputOptions": { - "model": "claude-sonnet-4-20250514", - "systemPrompt": "You are a helpful assistant." + "id": "enabledSubagents", + "name": "Enabled Subagents", + "description": "Which subagents to enable for this session", + "type": "multiselect", + "defaultValue": [], + "options": [ + { + "value": "web-search", + "name": "Web Search", + "description": "Search the web" + }, + { + "value": "code-execution", + "name": "Code Execution", + "description": "Run code in a sandbox" + }, + { + "value": "file-browser", + "name": "File Browser", + "description": "Browse local files" } - } + ] } ``` -This keeps a clean separation: -- **Protocol fields** - Always present, well-defined schemas, top-level -- **Agent-specific options** - Discovered via `inputOptions` schema, passed in `inputOptions` object +### Combined type definition + +```typescript +type ConfigOptionSchema = + | SelectOption + | TextOption + | NumberOption + | BooleanOption + | MultiSelectOption; -### Implementation phases +interface InitializeResponse { + protocolVersion: number; + agentCapabilities: AgentCapabilities; + agentInfo: AgentInfo; + configOptions?: { + "session/new"?: ConfigOptionSchema[]; + "session/load"?: ConfigOptionSchema[]; + // "session/set_config_option"?: ConfigOptionSchema[]; // see open question about runtime options + }; +} -**Phase 1: Schema definition** -- Add `InputOptionSchema` type definitions to ACP schema -- Add `inputOptions` to `InitializeResponse` -- Add `inputOptions` to `NewSessionRequest` and `LoadSessionRequest` +// This RFD adds configOptions to the existing request types +interface NewSessionRequest { + // ... existing fields ... + configOptions?: Record; +} + +interface LoadSessionRequest { + // ... existing fields ... + configOptions?: Record; +} +``` -**Phase 2: Client support** -- Update TypeScript SDK to expose `inputOptions` -- Implement example UI rendering in reference client +### Relationship to Session Config Options -**Phase 3: Agent adoption** -- Document pattern for agents to declare their options -- Add examples to protocol documentation +This schema is designed to be shared with [Session Config Options](./session-config-options.mdx): + +| Aspect | Input Options (this RFD) | Config Options (existing RFD) | +| --------------- | ------------------------------------------ | -------------------------------- | +| When | Before session creation | During session runtime | +| Purpose | Set initial configuration | Change configuration mid-session | +| Schema style | Array of typed options | Array of typed options | +| Value/name | `value`/`name` on options | `value`/`name` on options | +| Types supported | select, text, number, boolean, multiselect | select (expandable) | + +Both RFDs use the same `value`/`name` pattern for option choices, enabling schema reuse across the protocol. ## Frequently asked questions @@ -266,72 +390,72 @@ This keeps a clean separation: ### What alternative approaches did you consider, and why did you settle on this one? -1. **Extend Session Config Options with richer types** - The existing [Session Config Options RFD](./session-config-options) uses `select`/`text` types. We could update that RFD to support richer types (boolean, number, array, nested objects) and use the same schema for both input options and runtime config options. This would provide consistency across the protocol. The main tradeoff is that runtime selectors (mode/model dropdowns) have different UX needs than input options (forms with various field types), but a unified schema could still work well for both. +1. **Use JSON Schema directly** - Could use standard JSON Schema for type definitions. Rejected because full JSON Schema is complex to implement consistently across languages, and we only need a subset of its expressiveness. 2. **Separate discovery endpoint** - Could add a `session/describe` method. Rejected because `InitializeResponse` already exists for capability discovery and adding another round-trip adds latency. -3. **Use full JSON Schema** - Could support the complete JSON Schema spec. Rejected for cross-language compatibility - a simplified subset is easier to implement consistently across TypeScript, Python, Kotlin, etc. +3. **Extend NewSessionRequest/LoadSessionRequest directly** - Could add optional typed fields to the request schemas. Rejected because it would require protocol changes for each new option type, and doesn't allow agent-specific options. ### How does this relate to Session Config Options? -| Aspect | Input Options (this RFD) | Config Options (existing RFD) | -|--------|-------------------------|-------------------------------| -| When | Before session creation | During session runtime | -| Purpose | Set initial configuration | Change configuration mid-session | -| Examples | Initial model, system prompt, subagents | Switch modes, change model mid-session | -| Schema | JSON Schema subset | `select`/`text` types | -| Location | `InitializeResponse.inputOptions` | `NewSessionResponse.configOptions` | +| Aspect | Creation Options (this RFD) | Runtime Options (existing RFD) | +| ------------------ | ----------------------------- | -------------------------------------- | +| When discovered | At initialization | At session creation | +| Purpose | Set initial configuration | Change configuration mid-session | +| Examples | Initial model, system prompt | Switch modes, change model mid-session | +| Has `currentValue` | No (options declared upfront) | Yes (reflects current state) | +| Update method | N/A (set once at creation) | `session/set_config_option` | + +The [Session Config Options RFD](./session-config-options.mdx) returns options with their current values when a session is created, allowing clients to show the current state and update it. This RFD declares available options _before_ any session exists. -Agents can support both - use `inputOptions` for things that can only be set at creation time, and `configOptions` for things that can be changed during the session. +See open question: [Should this RFD also cover runtime config options?](#should-this-rfd-also-cover-runtime-config-options-sessionset_config_option) ### Should we unify the schema with Session Config Options? -This is an open question worth discussing. The Session Config Options RFD currently uses `select`/`text` types, while this proposal uses a JSON Schema subset. We could: +Yes. This proposal intentionally uses the same schema patterns as Session Config Options, including the `value`/`name` convention for option choices. The key addition is support for more types (text, number, boolean, multiselect) beyond just `select`. -**Option A: Keep them separate** (current proposal) -- Input options use JSON Schema subset (richer types for form inputs) -- Config options use `select`/`text` (simpler for runtime selectors) -- Pro: Each is optimized for its use case -- Con: Two different schema systems to learn and implement +If Session Config Options expands to support these types, the schemas will be fully compatible. -**Option B: Unify on JSON Schema subset** -- Update Session Config Options RFD to use the same JSON Schema subset -- Both input options and config options use identical schema definitions -- Pro: Consistency, single schema system -- Con: May be overkill for simple runtime selectors +### Are input options required? -**Option C: Unify on extended select/text** -- Extend the `select`/`text` types to support boolean, number, array, etc. -- Pro: Builds on existing work -- Con: Inventing a new schema language vs using JSON Schema conventions +No. Agents MUST handle missing options gracefully. Clients MAY not support input options UI. This is purely for discoverability and better UX. -Feedback welcome on which approach the community prefers. +### Why use arrays instead of objects for option definitions? -### Are input options required? +Arrays ensure consistent ordering across languages. Some languages don't preserve object key order, which would make UI rendering inconsistent. This matches the approach used in Session Config Options. -No. Agents MUST handle missing options gracefully. Clients MAY not support input options UI. This is purely for discoverability and better UX. +### Should this RFD also cover runtime config options (`session/set_config_option`)? + +This proposal focuses on options for `session/new` and `session/load`. However, we _could_ also include `session/set_config_option` in the same `configOptions` discovery mechanism, which would unify all config option discovery in one place. + +**Arguments for including runtime options:** + +- Single discovery mechanism for all config options +- Consistent schema across creation and runtime options +- Simplifies client implementation + +**Arguments against:** + +- Runtime options are already addressed by the [Session Config Options RFD](./session-config-options.mdx) +- Keeps this RFD focused on a smaller scope +- Runtime options have different semantics (can change mid-session, have `currentValue`) -### Should we have both `description` and `hint`, or just `description`? +Feedback welcome on whether to expand scope or keep this focused on creation/load options only. -This is an open question. The current proposal includes both: +### What about protocol-defined fields like `cwd` and `mcpServers`? -- **`description`** - Explains what the option does (shown as help text/tooltip) -- **`hint`** - Provides input guidance (shown as placeholder text) +The ACP protocol already defines some fields on `NewSessionRequest` and `LoadSessionRequest` (such as `cwd` and `mcpServers`). This RFD does not aim to address whether these existing protocol fields should be migrated to `configOptions` or remain as top-level fields. -**Arguments for having both:** -- They serve different UI purposes: `description` is explanatory, `hint` is exemplary -- Matches common form patterns where labels/help text differ from placeholder text -- Allows "System prompt" (description) vs "You are a helpful assistant..." (hint) +Future work may consider: -**Arguments for just `description`:** -- Simpler schema with fewer fields to implement -- Clients can derive placeholder text from description if needed -- Less ambiguity about which field to use for what purpose -- Many options don't need both (e.g., boolean toggles, enum dropdowns) +- Whether agents should be able to declare support/non-support for protocol fields +- Whether some protocol fields should become discoverable via `configOptions` +- How to handle fields that some agents support and others don't -Feedback welcome on whether the added complexity of `hint` is worth it. +For now, this proposal focuses solely on enabling agents to declare _additional_ agent-specific options beyond what the protocol already defines. ## Revision history -- 2025-01-26: Added `hint` and `default` optional fields to schema +- 2026-01-27: Restructured document; renamed schema section to "Session Config Schema"; aligned with Session Config Options using `value`/`name` pattern; removed `hint` field; renamed `inputOptions` to `configOptions` with method-name keys (`session/new`, `session/load`) +- 2025-01-26: Added `hint` and `defaultValue` optional fields to schema - 2025-01-22: Initial draft From 147bb5a8409a39e67ef894d8a36b5793e7fb588f Mon Sep 17 00:00:00 2001 From: Charles Covey-Brandt Date: Tue, 3 Feb 2026 13:00:29 -0500 Subject: [PATCH 4/6] Adopt MCP elicitation JSON Schema format for session input options - Change schema format from custom types to JSON Schema 2020-12 subset - Rename configOptions (schema) to configSchema in InitializeResponse - Add alternatives considered section documenting post-session elicitation - Reference MCP elicitation spec instead of duplicating schema details Co-Authored-By: Claude Opus 4.5 --- docs/rfds/session-input-options.mdx | 482 ++++++++++------------------ 1 file changed, 172 insertions(+), 310 deletions(-) diff --git a/docs/rfds/session-input-options.mdx b/docs/rfds/session-input-options.mdx index c9742548..fcdcaf1d 100644 --- a/docs/rfds/session-input-options.mdx +++ b/docs/rfds/session-input-options.mdx @@ -8,14 +8,9 @@ Author(s): [@chazcb](https://github.com/chazcb) > What are you proposing to change? -Allow Agents to declare what input options they accept for `session/new` and `session/load` requests in the `InitializeResponse`. This enables Clients to build dynamic configuration UIs _before_ creating a session, showing users exactly what options are available and their types. +Allow Agents to declare what input options they accept for `session/new` and `session/load` requests. This enables Clients to build dynamic configuration UIs, showing users exactly what options are available and their types. -This proposal has two parts: - -1. **Input options discovery** - A mechanism for agents to declare what options they accept when creating or loading sessions -2. **Session config schema** - A shared type system for defining options, designed to be used by both this RFD and [Session Config Options](./session-config-options.mdx) - -This complements the existing [Session Config Options RFD](./session-config-options.mdx) which handles _runtime_ configuration (mode/model selectors during a session). This RFD addresses _input_ discovery - what options can be passed when creating or loading sessions. +This RFD presents three approaches to solving this problem, all using the same **restricted JSON Schema 2020-12 subset** aligned with [MCP elicitation](https://spec.modelcontextprotocol.io/specification/draft/server/elicitation/). ## Status quo @@ -27,11 +22,93 @@ This complements the existing [Session Config Options RFD](./session-config-opti 3. **Client UIs are static** - Without discovery, clients must either hardcode known options or provide generic key-value inputs, neither of which provides a good user experience. +## Proposed Options + +There are three potential approaches to solving session input options. All use the same JSON Schema format from the [Elicitation RFD](https://github.com/agentclientprotocol/agent-client-protocol/pull/376). + +### Option 1: Use In-Session Elicitation + +Use the elicitation mechanism from [PR #376](https://github.com/agentclientprotocol/agent-client-protocol/pull/376) as-is. Agent sends `elicitation/create` after session creation but before meaningful work begins. + +**Flow:** +1. Client calls `session/new` +2. Agent returns session ID +3. Agent sends `elicitation/create` with config schema +4. Client shows form, user fills it +5. Agent receives config, session is ready for prompts + +**Pros:** +- No new protocol additions - reuses elicitation +- Consistent with MCP patterns +- Dynamic - agent can ask different questions per session + +**Cons:** +- **Client cannot show config UI until session exists** - This creates awkward UX flows where clients must create a session just to discover if there are config options to show. Users may see a "New Session" button, click it, and only then be prompted for configuration. +- Session exists in "pending config" state - semantically awkward +- **Agent initialization complexity** - Agent cannot directly use config for session initialization (model selection, system prompt setup, etc.) since the session is already created. Implementations can work around this (e.g., minting IDs that are passed to underlying engines later), but this adds complexity that will deter many agent developers. + +**Verdict:** This approach works for mid-session information gathering but doesn't solve the initialization use case. + +--- + +### Option 2: Extend Elicitation for Pre-Session Use + +Extend the [Elicitation RFD](https://github.com/agentclientprotocol/agent-client-protocol/pull/376) to support elicitation _during_ the `session/new` or `session/load` flow, before the session ID is returned. + +**Flow:** +1. Client calls `session/new` +2. Agent sends `elicitation/create` (while `session/new` is pending) +3. Client shows form, user fills it +4. Client responds to elicitation +5. Agent uses config values, creates session, returns session ID + +**Pros:** +- Reuses elicitation infrastructure +- Agent receives config before session creation - can use for initialization decisions +- Single mechanism for all elicitation needs + +**Cons:** +- **Client still cannot show config UI before user clicks "New Session"** - Same UX limitation as Option 1. Client must initiate session creation before discovering what config is needed. +- **Correlation problem** - Without a session ID, client doesn't know which pending `session/new` request the elicitation belongs to. Requires protocol additions (e.g., `relatedRequestId` on elicitation) to link them. +- **Unclear lifecycle semantics** - `session/new` "hangs" waiting for user input. What are the timeout/cancellation semantics? What if user never responds? + +**Verdict:** Solves the agent initialization problem from Option 1, but still has the core UX limitation. Adds protocol complexity to solve the correlation problem. + +--- + +### Option 3: Init-Time Config Schema Declaration (Recommended) + +Agent declares config schemas at initialization. Client knows what options exist before any session is created. + +**Flow:** +1. Client calls `initialize` +2. Agent returns capabilities including `configSchema` for `session/new` and `session/load` +3. Client can show config UI immediately (before user clicks "New Session") +4. User configures options, clicks "New Session" +5. Client calls `session/new` with `configOptions` +6. Agent uses config, returns session ID - session immediately usable + +**Pros:** +- **Client can show config UI before "New Session"** - Best UX, no waiting +- Agent receives config with the session request - can use for initialization +- Clean session lifecycle - no intermediate states +- Simple protocol addition - just schema in init response +- No correlation problems + +**Cons:** +- **Separate mechanism from elicitation** - Clients must implement another way to show config UIs, distinct from elicitation (though using the same JSON Schema format). This adds implementation surface area. +- New field in `InitializeResponse` (though minimal) +- Static declaration - same options for all sessions (agent can't dynamically vary) + +**Verdict:** Recommended approach. Solves the core use case with minimal protocol complexity. + ## What we propose to do about it > What are you proposing to improve the situation? -Add a `configOptions` field to `InitializeResponse` that declares what options an Agent accepts for session creation and loading. The options are keyed by the JSON-RPC method name they apply to (`session/new`, `session/load`). +We recommend **Option 3: Init-Time Config Schema Declaration**. + +Add a `configSchema` field to `InitializeResponse` that declares what options an Agent accepts for session creation and loading. Each schema is a JSON Schema object describing the expected `configOptions` for that method. ```json { @@ -41,54 +118,55 @@ Add a `configOptions` field to `InitializeResponse` that declares what options a "protocolVersion": 1, "agentCapabilities": { ... }, "agentInfo": { ... }, - "configOptions": { - "session/new": [ - { - "id": "model", - "name": "Model", - "description": "Model to use for this session", - "type": "select", - "defaultValue": "claude-sonnet-4-20250514", - "options": [ - { "value": "claude-sonnet-4-20250514", "name": "Sonnet 4" }, - { "value": "claude-opus-4-20250514", "name": "Opus 4" }, - { "value": "claude-haiku", "name": "Haiku" } - ] - }, - { - "id": "systemPrompt", - "name": "System Prompt", - "description": "Custom system prompt to guide the agent's behavior", - "type": "text" - }, - { - "id": "maxTokens", - "name": "Max Tokens", - "description": "Maximum tokens per response", - "type": "number", - "defaultValue": 4096 - }, - { - "id": "enableTools", - "name": "Enable Tools", - "description": "Allow the agent to use tools", - "type": "boolean", - "defaultValue": true + "configSchema": { + "session/new": { + "type": "object", + "properties": { + "model": { + "type": "string", + "title": "Model", + "description": "Model to use for this session", + "oneOf": [ + { "const": "claude-sonnet-4-20250514", "title": "Sonnet 4" }, + { "const": "claude-opus-4-20250514", "title": "Opus 4" }, + { "const": "claude-haiku", "title": "Haiku" } + ], + "default": "claude-sonnet-4-20250514" + }, + "systemPrompt": { + "type": "string", + "title": "System Prompt", + "description": "Custom system prompt to guide the agent's behavior" + }, + "maxTokens": { + "type": "number", + "title": "Max Tokens", + "description": "Maximum tokens per response", + "default": 4096 + }, + "enableTools": { + "type": "boolean", + "title": "Enable Tools", + "description": "Allow the agent to use tools", + "default": true + } } - ], - "session/load": [ - { - "id": "model", - "name": "Model", - "description": "Model to use when resuming (can differ from original)", - "type": "select", - "options": [ - { "value": "claude-sonnet-4-20250514", "name": "Sonnet 4" }, - { "value": "claude-opus-4-20250514", "name": "Opus 4" }, - { "value": "claude-haiku", "name": "Haiku" } - ] + }, + "session/load": { + "type": "object", + "properties": { + "model": { + "type": "string", + "title": "Model", + "description": "Model to use when resuming (can differ from original)", + "oneOf": [ + { "const": "claude-sonnet-4-20250514", "title": "Sonnet 4" }, + { "const": "claude-opus-4-20250514", "title": "Opus 4" }, + { "const": "claude-haiku", "title": "Haiku" } + ] + } } - ] + } } } } @@ -119,26 +197,22 @@ Clients pass config options via `configOptions` on `NewSessionRequest` and `Load **For Clients:** -- Query `configOptions` from `InitializeResponse` to know what the Agent accepts -- Build dynamic forms showing available options with proper input types (text fields, dropdowns for selects, checkboxes for booleans, number inputs) -- Use `name` for field labels and `description` for help text/tooltips -- For select options, display `name` to users while sending `value` to the agent -- Pre-populate form fields with `defaultValue` values when provided +- Query `configSchema` from `InitializeResponse` to get JSON Schema for each method +- Build dynamic forms using standard JSON Schema form rendering (same as MCP elicitation) +- **Show config UI before user starts a new session** - no waiting for round-trips +- Use `title` for field labels and `description` for help text/tooltips +- For select options (using `oneOf`), display `title` to users while sending `const` value to the agent +- Pre-populate form fields with `default` values when provided - Show different options for "New Session" vs "Load Session" flows -- Gracefully handle Agents that don't declare any `configOptions` +- Gracefully handle Agents that don't declare any `configSchema` **For Agents:** -- Declare supported options with types, names, descriptions, and default values -- Use `defaultValue` to communicate the value that will be used if the client omits the option +- Declare supported options using JSON Schema with `title`, `description`, and `default` +- Use `default` to communicate the value that will be used if the client omits the option - MUST handle all options as optional - clients may not provide all (or any) options -- MUST use declared `defaultValue` values when options are not provided by the client - -**Key behaviors:** - -- Options under `session/new` and `session/load` are for session _creation/loading_ -- Runtime configuration (mode switching, model selection during a session) is handled by the [Session Config Options RFD](./session-config-options.mdx) -- See open question: [Should this RFD also cover runtime config options?](#should-this-rfd-also-cover-runtime-config-options-sessionset_config_option) +- MUST use declared `default` values when options are not provided by the client +- Receive config values as part of `session/new` - can use for initialization decisions ## Implementation details and plan @@ -164,197 +238,22 @@ Clients send config options in `configOptions` on session requests: Values should match the declared types (strings, numbers, booleans - not string-encoded). -## Session Config Schema - -This section defines the shared schema for declaring configuration options. This schema is designed to be used by both this RFD (for input options) and [Session Config Options](./session-config-options.mdx) (for runtime options). - -### Design principles - -1. **Value/name separation** - All selectable options distinguish between machine-readable `value` and human-readable `name` -2. **Consistent metadata** - All option types support `id`, `name`, `description`, and `defaultValue` -3. **Alignment with Config Options** - Use similar patterns to Session Config Options for consistency across the protocol -4. **Cross-language compatibility** - Use simple types that work well in TypeScript, Python, Kotlin, etc. - -### Base option structure - -All input options share a common base structure: - -```typescript -interface ConfigOptionBase { - id: string; // Unique identifier for this option (used as key in configOptions object) - name: string; // Human-readable label for the option - description?: string; // Longer explanation of what the option does -} -``` - -### Option types - -#### Select (single choice from a list) - -```typescript -interface SelectOption extends ConfigOptionBase { - type: "select"; - defaultValue?: string | number | boolean | null; - options: Array<{ - value: string | number | boolean | null; // Machine-readable value - name: string; // Human-readable display text - description?: string; // Optional description for this choice - }>; -} -``` - -Example: - -```json -{ - "id": "model", - "name": "Model", - "description": "Model to use for this session", - "type": "select", - "defaultValue": "claude-sonnet-4-20250514", - "options": [ - { - "value": "claude-sonnet-4-20250514", - "name": "Sonnet 4", - "description": "Fast and capable" - }, - { - "value": "claude-opus-4-20250514", - "name": "Opus 4", - "description": "Most powerful" - }, - { - "value": "claude-haiku", - "name": "Haiku", - "description": "Fastest responses" - } - ] -} -``` - -#### Text (free-form string input) - -```typescript -interface TextOption extends ConfigOptionBase { - type: "text"; - defaultValue?: string; -} -``` - -Example: - -```json -{ - "id": "systemPrompt", - "name": "System Prompt", - "description": "Custom system prompt to guide the agent's behavior", - "type": "text" -} -``` - -#### Number (numeric input) - -```typescript -interface NumberOption extends ConfigOptionBase { - type: "number"; - defaultValue?: number; -} -``` - -Example: - -```json -{ - "id": "maxTokens", - "name": "Max Tokens", - "description": "Maximum tokens per response", - "type": "number", - "defaultValue": 4096 -} -``` - -#### Boolean (true/false toggle) - -```typescript -interface BooleanOption extends ConfigOptionBase { - type: "boolean"; - defaultValue?: boolean; -} -``` - -Example: - -```json -{ - "id": "enableTools", - "name": "Enable Tools", - "description": "Allow the agent to use tools", - "type": "boolean", - "defaultValue": true -} -``` - -#### Multi-select (multiple choices from a list) +## Schema Format -```typescript -interface MultiSelectOption extends ConfigOptionBase { - type: "multiselect"; - defaultValue?: Array; - options: Array<{ - value: string | number | boolean | null; - name: string; - description?: string; - }>; -} -``` - -Example: +Config schemas use the **restricted JSON Schema subset** defined by [MCP elicitation](https://spec.modelcontextprotocol.io/specification/draft/server/elicitation/). This allows clients to reuse their MCP form-rendering infrastructure for ACP session options. -```json -{ - "id": "enabledSubagents", - "name": "Enabled Subagents", - "description": "Which subagents to enable for this session", - "type": "multiselect", - "defaultValue": [], - "options": [ - { - "value": "web-search", - "name": "Web Search", - "description": "Search the web" - }, - { - "value": "code-execution", - "name": "Code Execution", - "description": "Run code in a sandbox" - }, - { - "value": "file-browser", - "name": "File Browser", - "description": "Browse local files" - } - ] -} -``` +See the MCP elicitation specification for supported types, formats, and constraints. -### Combined type definition +### TypeScript definition ```typescript -type ConfigOptionSchema = - | SelectOption - | TextOption - | NumberOption - | BooleanOption - | MultiSelectOption; - interface InitializeResponse { protocolVersion: number; agentCapabilities: AgentCapabilities; agentInfo: AgentInfo; - configOptions?: { - "session/new"?: ConfigOptionSchema[]; - "session/load"?: ConfigOptionSchema[]; - // "session/set_config_option"?: ConfigOptionSchema[]; // see open question about runtime options + configSchema?: { + "session/new"?: JSONSchema; + "session/load"?: JSONSchema; }; } @@ -370,92 +269,55 @@ interface LoadSessionRequest { } ``` -### Relationship to Session Config Options - -This schema is designed to be shared with [Session Config Options](./session-config-options.mdx): - -| Aspect | Input Options (this RFD) | Config Options (existing RFD) | -| --------------- | ------------------------------------------ | -------------------------------- | -| When | Before session creation | During session runtime | -| Purpose | Set initial configuration | Change configuration mid-session | -| Schema style | Array of typed options | Array of typed options | -| Value/name | `value`/`name` on options | `value`/`name` on options | -| Types supported | select, text, number, boolean, multiselect | select (expandable) | - -Both RFDs use the same `value`/`name` pattern for option choices, enabling schema reuse across the protocol. - ## Frequently asked questions > What questions have arisen over the course of authoring this document or during subsequent discussions? -### What alternative approaches did you consider, and why did you settle on this one? +### Why not just use elicitation (Option 1)? -1. **Use JSON Schema directly** - Could use standard JSON Schema for type definitions. Rejected because full JSON Schema is complex to implement consistently across languages, and we only need a subset of its expressiveness. +Elicitation happens _after_ session creation. For session config, the agent needs values _before_ creating the session to make initialization decisions (model selection, system prompt setup, etc.). -2. **Separate discovery endpoint** - Could add a `session/describe` method. Rejected because `InitializeResponse` already exists for capability discovery and adding another round-trip adds latency. +Additionally, Option 3 allows clients to show config UI before the user even clicks "New Session" - better UX with no waiting. -3. **Extend NewSessionRequest/LoadSessionRequest directly** - Could add optional typed fields to the request schemas. Rejected because it would require protocol changes for each new option type, and doesn't allow agent-specific options. +### Why not extend elicitation for pre-session use (Option 2)? -### How does this relate to Session Config Options? +Option 2 requires solving the correlation problem: when an elicitation request arrives during a pending `session/new`, the client needs to know which request it belongs to. This requires protocol additions (e.g., `relatedRequestId`) and adds complexity. -| Aspect | Creation Options (this RFD) | Runtime Options (existing RFD) | -| ------------------ | ----------------------------- | -------------------------------------- | -| When discovered | At initialization | At session creation | -| Purpose | Set initial configuration | Change configuration mid-session | -| Examples | Initial model, system prompt | Switch modes, change model mid-session | -| Has `currentValue` | No (options declared upfront) | Yes (reflects current state) | -| Update method | N/A (set once at creation) | `session/set_config_option` | +Option 3 avoids this entirely - config schema is declared upfront, no correlation needed. -The [Session Config Options RFD](./session-config-options.mdx) returns options with their current values when a session is created, allowing clients to show the current state and update it. This RFD declares available options _before_ any session exists. +### How does this relate to MCP elicitation? -See open question: [Should this RFD also cover runtime config options?](#should-this-rfd-also-cover-runtime-config-options-sessionset_config_option) +This proposal uses the same JSON Schema subset as [MCP elicitation](https://spec.modelcontextprotocol.io/specification/draft/server/elicitation/). Clients implementing MCP elicitation can reuse their form-rendering infrastructure for ACP session options. -### Should we unify the schema with Session Config Options? +The key difference is **timing**: MCP elicitation is on-demand (server requests info when needed), while this proposal provides upfront discovery at initialization. -Yes. This proposal intentionally uses the same schema patterns as Session Config Options, including the `value`/`name` convention for option choices. The key addition is support for more types (text, number, boolean, multiselect) beyond just `select`. +### How does this relate to Session Config Options? -If Session Config Options expands to support these types, the schemas will be fully compatible. +| Aspect | Input Options (this RFD) | Runtime Options (existing RFD) | +| ------------------ | ------------------------------- | -------------------------------------- | +| When discovered | At initialization | At session creation | +| Schema format | JSON Schema subset | Custom (could adopt JSON Schema later) | +| Purpose | Set initial configuration | Change configuration mid-session | +| Examples | Initial model, system prompt | Switch modes, change model mid-session | +| Has `currentValue` | No (options declared upfront) | Yes (reflects current state) | +| Update method | N/A (set once at creation) | `session/set_config_option` | ### Are input options required? -No. Agents MUST handle missing options gracefully. Clients MAY not support input options UI. This is purely for discoverability and better UX. - -### Why use arrays instead of objects for option definitions? - -Arrays ensure consistent ordering across languages. Some languages don't preserve object key order, which would make UI rendering inconsistent. This matches the approach used in Session Config Options. - -### Should this RFD also cover runtime config options (`session/set_config_option`)? +No. Agents MUST handle missing options gracefully. Clients MAY not support config options UI. This is purely for discoverability and better UX. -This proposal focuses on options for `session/new` and `session/load`. However, we _could_ also include `session/set_config_option` in the same `configOptions` discovery mechanism, which would unify all config option discovery in one place. - -**Arguments for including runtime options:** - -- Single discovery mechanism for all config options -- Consistent schema across creation and runtime options -- Simplifies client implementation - -**Arguments against:** - -- Runtime options are already addressed by the [Session Config Options RFD](./session-config-options.mdx) -- Keeps this RFD focused on a smaller scope -- Runtime options have different semantics (can change mid-session, have `currentValue`) - -Feedback welcome on whether to expand scope or keep this focused on creation/load options only. +In a future protocol version, agents could use the `required` array to indicate mandatory fields, but for v1 all fields must be optional to maintain backward compatibility. ### What about protocol-defined fields like `cwd` and `mcpServers`? The ACP protocol already defines some fields on `NewSessionRequest` and `LoadSessionRequest` (such as `cwd` and `mcpServers`). This RFD does not aim to address whether these existing protocol fields should be migrated to `configOptions` or remain as top-level fields. -Future work may consider: - -- Whether agents should be able to declare support/non-support for protocol fields -- Whether some protocol fields should become discoverable via `configOptions` -- How to handle fields that some agents support and others don't - For now, this proposal focuses solely on enabling agents to declare _additional_ agent-specific options beyond what the protocol already defines. ## Revision history +- 2026-02-04: Restructured to present three options; clarified relationship to Elicitation RFD; recommended Option 3 (init-time declaration) +- 2026-02-03: Adopted JSON Schema 2020-12 subset aligned with MCP elicitation; renamed `configOptions` schema to `configSchema`; added alternatives considered section - 2026-01-27: Restructured document; renamed schema section to "Session Config Schema"; aligned with Session Config Options using `value`/`name` pattern; removed `hint` field; renamed `inputOptions` to `configOptions` with method-name keys (`session/new`, `session/load`) - 2025-01-26: Added `hint` and `defaultValue` optional fields to schema - 2025-01-22: Initial draft From 55c08ef541e36dcf577577e6a71cd0677e0eb227 Mon Sep 17 00:00:00 2001 From: Charles Covey-Brandt Date: Wed, 4 Feb 2026 12:14:57 -0500 Subject: [PATCH 5/6] Simplify RFD: adopt MCP elicitation schema, move alternatives to end - Use MCP elicitation JSON Schema format (no need to redefine) - Clarify status quo: _meta workarounds, no discovery or standard config field - Move elicitation alternatives to "Alternatives Considered" section - Streamline document to focus on init-time discovery proposal Co-Authored-By: Claude Opus 4.5 --- docs/rfds/session-input-options.mdx | 248 ++++++++++------------------ 1 file changed, 83 insertions(+), 165 deletions(-) diff --git a/docs/rfds/session-input-options.mdx b/docs/rfds/session-input-options.mdx index fcdcaf1d..f8b1b6e6 100644 --- a/docs/rfds/session-input-options.mdx +++ b/docs/rfds/session-input-options.mdx @@ -1,5 +1,5 @@ --- -title: "Session Input Options Discovery" +title: "Session Input Options" --- Author(s): [@chazcb](https://github.com/chazcb) @@ -10,106 +10,28 @@ Author(s): [@chazcb](https://github.com/chazcb) Allow Agents to declare what input options they accept for `session/new` and `session/load` requests. This enables Clients to build dynamic configuration UIs, showing users exactly what options are available and their types. -This RFD presents three approaches to solving this problem, all using the same **restricted JSON Schema 2020-12 subset** aligned with [MCP elicitation](https://spec.modelcontextprotocol.io/specification/draft/server/elicitation/). +Input schemas are advertised in `InitializeResult` capabilities, using the **restricted JSON Schema 2020-12 subset** aligned with [MCP elicitation](https://spec.modelcontextprotocol.io/specification/draft/server/elicitation/). ## Status quo > How do things work today and what problems does this cause? Why would we change things? -1. **Agent-specific options are invisible** - Agents may want to accept additional options (like initial model, system prompt, subagents, etc.), but there's no standard way to expose these to clients. +1. **No way to discover session creation options** - Agents may want to accept additional options on `session/new` or `session/load` (like initial model, system prompt, subagents, etc.), but there's no standard way to expose these to clients. Teams currently work around this by passing config in `_meta`, which is not portable, requires hardcoded client knowledge, and isn't discoverable. -2. **New vs Load may differ** - Creating a new session might accept different options than loading an existing one (e.g., you might set certain options only at creation time). - -3. **Client UIs are static** - Without discovery, clients must either hardcode known options or provide generic key-value inputs, neither of which provides a good user experience. - -## Proposed Options - -There are three potential approaches to solving session input options. All use the same JSON Schema format from the [Elicitation RFD](https://github.com/agentclientprotocol/agent-client-protocol/pull/376). - -### Option 1: Use In-Session Elicitation - -Use the elicitation mechanism from [PR #376](https://github.com/agentclientprotocol/agent-client-protocol/pull/376) as-is. Agent sends `elicitation/create` after session creation but before meaningful work begins. - -**Flow:** -1. Client calls `session/new` -2. Agent returns session ID -3. Agent sends `elicitation/create` with config schema -4. Client shows form, user fills it -5. Agent receives config, session is ready for prompts - -**Pros:** -- No new protocol additions - reuses elicitation -- Consistent with MCP patterns -- Dynamic - agent can ask different questions per session - -**Cons:** -- **Client cannot show config UI until session exists** - This creates awkward UX flows where clients must create a session just to discover if there are config options to show. Users may see a "New Session" button, click it, and only then be prompted for configuration. -- Session exists in "pending config" state - semantically awkward -- **Agent initialization complexity** - Agent cannot directly use config for session initialization (model selection, system prompt setup, etc.) since the session is already created. Implementations can work around this (e.g., minting IDs that are passed to underlying engines later), but this adds complexity that will deter many agent developers. - -**Verdict:** This approach works for mid-session information gathering but doesn't solve the initialization use case. - ---- - -### Option 2: Extend Elicitation for Pre-Session Use - -Extend the [Elicitation RFD](https://github.com/agentclientprotocol/agent-client-protocol/pull/376) to support elicitation _during_ the `session/new` or `session/load` flow, before the session ID is returned. - -**Flow:** -1. Client calls `session/new` -2. Agent sends `elicitation/create` (while `session/new` is pending) -3. Client shows form, user fills it -4. Client responds to elicitation -5. Agent uses config values, creates session, returns session ID - -**Pros:** -- Reuses elicitation infrastructure -- Agent receives config before session creation - can use for initialization decisions -- Single mechanism for all elicitation needs - -**Cons:** -- **Client still cannot show config UI before user clicks "New Session"** - Same UX limitation as Option 1. Client must initiate session creation before discovering what config is needed. -- **Correlation problem** - Without a session ID, client doesn't know which pending `session/new` request the elicitation belongs to. Requires protocol additions (e.g., `relatedRequestId` on elicitation) to link them. -- **Unclear lifecycle semantics** - `session/new` "hangs" waiting for user input. What are the timeout/cancellation semantics? What if user never responds? - -**Verdict:** Solves the agent initialization problem from Option 1, but still has the core UX limitation. Adds protocol complexity to solve the correlation problem. - ---- - -### Option 3: Init-Time Config Schema Declaration (Recommended) - -Agent declares config schemas at initialization. Client knows what options exist before any session is created. - -**Flow:** -1. Client calls `initialize` -2. Agent returns capabilities including `configSchema` for `session/new` and `session/load` -3. Client can show config UI immediately (before user clicks "New Session") -4. User configures options, clicks "New Session" -5. Client calls `session/new` with `configOptions` -6. Agent uses config, returns session ID - session immediately usable - -**Pros:** -- **Client can show config UI before "New Session"** - Best UX, no waiting -- Agent receives config with the session request - can use for initialization -- Clean session lifecycle - no intermediate states -- Simple protocol addition - just schema in init response -- No correlation problems - -**Cons:** -- **Separate mechanism from elicitation** - Clients must implement another way to show config UIs, distinct from elicitation (though using the same JSON Schema format). This adds implementation surface area. -- New field in `InitializeResponse` (though minimal) -- Static declaration - same options for all sessions (agent can't dynamically vary) - -**Verdict:** Recommended approach. Solves the core use case with minimal protocol complexity. +2. **No standard way to pass session config** - Even if clients knew what options an agent accepts, there's no designated field on `session/new` or `session/load` to pass them - only `_meta` workarounds. ## What we propose to do about it > What are you proposing to improve the situation? -We recommend **Option 3: Init-Time Config Schema Declaration**. - Add a `configSchema` field to `InitializeResponse` that declares what options an Agent accepts for session creation and loading. Each schema is a JSON Schema object describing the expected `configOptions` for that method. +This approach: + +- Lets clients show config UI before "New Session" - best UX, no waiting +- Gives agents config with the session request - can use for initialization +- Keeps session lifecycle clean - no intermediate states + ```json { "jsonrpc": "2.0", @@ -191,58 +113,9 @@ Clients pass config options via `configOptions` on `NewSessionRequest` and `Load } ``` -## Shiny future - -> How will things will play out once this feature exists? - -**For Clients:** - -- Query `configSchema` from `InitializeResponse` to get JSON Schema for each method -- Build dynamic forms using standard JSON Schema form rendering (same as MCP elicitation) -- **Show config UI before user starts a new session** - no waiting for round-trips -- Use `title` for field labels and `description` for help text/tooltips -- For select options (using `oneOf`), display `title` to users while sending `const` value to the agent -- Pre-populate form fields with `default` values when provided -- Show different options for "New Session" vs "Load Session" flows -- Gracefully handle Agents that don't declare any `configSchema` +## Implementation details -**For Agents:** - -- Declare supported options using JSON Schema with `title`, `description`, and `default` -- Use `default` to communicate the value that will be used if the client omits the option -- MUST handle all options as optional - clients may not provide all (or any) options -- MUST use declared `default` values when options are not provided by the client -- Receive config values as part of `session/new` - can use for initialization decisions - -## Implementation details and plan - -> Tell me more about your implementation. What is your detailed implementation plan? - -### Passing config options - -Clients send config options in `configOptions` on session requests: - -```json -{ - "method": "session/new", - "params": { - ... - "configOptions": { - "model": "claude-sonnet-4-20250514", - "maxTokens": 4096, - "enableTools": true - } - } -} -``` - -Values should match the declared types (strings, numbers, booleans - not string-encoded). - -## Schema Format - -Config schemas use the **restricted JSON Schema subset** defined by [MCP elicitation](https://spec.modelcontextprotocol.io/specification/draft/server/elicitation/). This allows clients to reuse their MCP form-rendering infrastructure for ACP session options. - -See the MCP elicitation specification for supported types, formats, and constraints. +Config schemas use the **restricted JSON Schema subset** defined by [MCP elicitation](https://spec.modelcontextprotocol.io/specification/draft/server/elicitation/). Clients can reuse their MCP form-rendering infrastructure for ACP session options. ### TypeScript definition @@ -273,40 +146,30 @@ interface LoadSessionRequest { > What questions have arisen over the course of authoring this document or during subsequent discussions? -### Why not just use elicitation (Option 1)? - -Elicitation happens _after_ session creation. For session config, the agent needs values _before_ creating the session to make initialization decisions (model selection, system prompt setup, etc.). +### Why not just use elicitation? -Additionally, Option 3 allows clients to show config UI before the user even clicks "New Session" - better UX with no waiting. - -### Why not extend elicitation for pre-session use (Option 2)? - -Option 2 requires solving the correlation problem: when an elicitation request arrives during a pending `session/new`, the client needs to know which request it belongs to. This requires protocol additions (e.g., `relatedRequestId`) and adds complexity. - -Option 3 avoids this entirely - config schema is declared upfront, no correlation needed. +See [Alternatives Considered](#alternatives-considered) below for a detailed comparison. In short: elicitation happens _after_ session creation, but for session config the agent needs values _before_ creating the session. Init-time discovery also allows clients to show config UI before the user even clicks "New Session". ### How does this relate to MCP elicitation? -This proposal uses the same JSON Schema subset as [MCP elicitation](https://spec.modelcontextprotocol.io/specification/draft/server/elicitation/). Clients implementing MCP elicitation can reuse their form-rendering infrastructure for ACP session options. - -The key difference is **timing**: MCP elicitation is on-demand (server requests info when needed), while this proposal provides upfront discovery at initialization. +Same JSON Schema format, different **timing**: MCP elicitation is on-demand (server requests info when needed), while this proposal provides upfront discovery at initialization. ### How does this relate to Session Config Options? -| Aspect | Input Options (this RFD) | Runtime Options (existing RFD) | -| ------------------ | ------------------------------- | -------------------------------------- | -| When discovered | At initialization | At session creation | -| Schema format | JSON Schema subset | Custom (could adopt JSON Schema later) | -| Purpose | Set initial configuration | Change configuration mid-session | -| Examples | Initial model, system prompt | Switch modes, change model mid-session | -| Has `currentValue` | No (options declared upfront) | Yes (reflects current state) | -| Update method | N/A (set once at creation) | `session/set_config_option` | +| Aspect | Input Options (this RFD) | Runtime Options (existing RFD) | +| ------------------ | ----------------------------- | -------------------------------------- | +| When discovered | At initialization | At session creation | +| Schema format | JSON Schema subset | Custom (could adopt JSON Schema later) | +| Purpose | Set initial configuration | Change configuration mid-session | +| Examples | Initial model, system prompt | Switch modes, change model mid-session | +| Has `currentValue` | No (options declared upfront) | Yes (reflects current state) | +| Update method | N/A (set once at creation) | `session/set_config_option` | ### Are input options required? -No. Agents MUST handle missing options gracefully. Clients MAY not support config options UI. This is purely for discoverability and better UX. +Agents MUST accept requests with no `configOptions` at all - clients may not support config UIs. -In a future protocol version, agents could use the `required` array to indicate mandatory fields, but for v1 all fields must be optional to maintain backward compatibility. +However, if a client _does_ provide `configOptions`, it must conform to the declared schema including any `required` fields. This allows agents to enforce that certain options are provided together (e.g., if you specify a custom model, you must also specify an API key). ### What about protocol-defined fields like `cwd` and `mcpServers`? @@ -314,10 +177,65 @@ The ACP protocol already defines some fields on `NewSessionRequest` and `LoadSes For now, this proposal focuses solely on enabling agents to declare _additional_ agent-specific options beyond what the protocol already defines. +## Alternatives Considered + +### Alternative A: Use In-Session Elicitation + +Use the elicitation mechanism from [MCP Elicitation](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/376) as-is. Agent sends `elicitation/create` after session creation but before meaningful work begins. + +**Flow:** + +1. Client calls `session/new` +2. Agent returns session ID +3. Agent sends `elicitation/create` with config schema +4. Client shows form, user fills it +5. Agent receives config, session is ready for prompts + +**Pros:** + +- No new protocol additions - reuses elicitation +- Consistent with MCP patterns +- Dynamic - agent can ask different questions per session + +**Cons:** + +- **Client cannot show config UI until session exists** - Creates awkward UX flows where clients must create a session just to discover if there are config options to show. +- Session exists in "pending config" state - semantically awkward +- **Agent initialization complexity** - Agent cannot directly use config for session initialization (model selection, system prompt setup, etc.) since the session is already created. + +**Why not chosen:** This approach works for mid-session information gathering but doesn't solve the initialization use case well. + +--- + +### Alternative B: Extend Elicitation for Pre-Session Use + +Extend elicitation to support elicitation _during_ the `session/new` or `session/load` flow, before the session ID is returned. + +**Flow:** + +1. Client calls `session/new` +2. Agent sends `elicitation/create` (while `session/new` is pending) +3. Client shows form, user fills it +4. Client responds to elicitation +5. Agent uses config values, creates session, returns session ID + +**Pros:** + +- Reuses elicitation infrastructure +- Agent receives config before session creation - can use for initialization decisions +- Single mechanism for all elicitation needs + +**Cons:** + +- **Client still cannot show config UI before user clicks "New Session"** - Same UX limitation as Alternative A. +- **Correlation problem** - Without a session ID, client doesn't know which pending `session/new` request the elicitation belongs to. Requires protocol additions (e.g., `relatedRequestId`) to link them. +- **Unclear lifecycle semantics** - `session/new` "hangs" waiting for user input. What are the timeout/cancellation semantics? + +**Why not chosen:** Solves the agent initialization problem but still has the core UX limitation. Adds protocol complexity to solve the correlation problem. + ## Revision history -- 2026-02-04: Restructured to present three options; clarified relationship to Elicitation RFD; recommended Option 3 (init-time declaration) -- 2026-02-03: Adopted JSON Schema 2020-12 subset aligned with MCP elicitation; renamed `configOptions` schema to `configSchema`; added alternatives considered section -- 2026-01-27: Restructured document; renamed schema section to "Session Config Schema"; aligned with Session Config Options using `value`/`name` pattern; removed `hint` field; renamed `inputOptions` to `configOptions` with method-name keys (`session/new`, `session/load`) +- 2025-02-04: Adopted MCP elicitation JSON Schema format; documented elicitation alternatives in "Alternatives Considered" section +- 2025-01-27: Restructured document; renamed schema section to "Session Config Schema"; aligned with Session Config Options using `value`/`name` pattern; removed `hint` field; renamed `inputOptions` to `configOptions` with method-name keys (`session/new`, `session/load`) - 2025-01-26: Added `hint` and `defaultValue` optional fields to schema - 2025-01-22: Initial draft From b179dcadbb17fec9b390b2c9a8a1f6d7bb81a81c Mon Sep 17 00:00:00 2001 From: Charles Covey-Brandt Date: Wed, 4 Feb 2026 12:22:40 -0500 Subject: [PATCH 6/6] Improve Alternative A analysis: clarify dynamic pro, expand init workaround Co-Authored-By: Claude Opus 4.5 --- docs/rfds/session-input-options.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rfds/session-input-options.mdx b/docs/rfds/session-input-options.mdx index f8b1b6e6..c44fdccf 100644 --- a/docs/rfds/session-input-options.mdx +++ b/docs/rfds/session-input-options.mdx @@ -195,13 +195,13 @@ Use the elicitation mechanism from [MCP Elicitation](https://github.com/modelcon - No new protocol additions - reuses elicitation - Consistent with MCP patterns -- Dynamic - agent can ask different questions per session +- Dynamic - config options can vary per `session/new` or `session/load` call, not bound to the connection **Cons:** - **Client cannot show config UI until session exists** - Creates awkward UX flows where clients must create a session just to discover if there are config options to show. - Session exists in "pending config" state - semantically awkward -- **Agent initialization complexity** - Agent cannot directly use config for session initialization (model selection, system prompt setup, etc.) since the session is already created. +- **Agent initialization complexity** - Agent cannot directly use config for session initialization (model selection, system prompt setup, etc.) since the session is already created. A workaround is to create a lightweight session that hands off to a configured backend session, but this adds complexity for agent developers and requires the ability to mint session IDs upfront. **Why not chosen:** This approach works for mid-session information gathering but doesn't solve the initialization use case well.