[mcp] Support server-driven elicitations (#17043)

- [x] Enables MCP elicitation for custom servers, not just Codex Apps
- [x] Adds an RMCP service wrapper to preserve elicitation _meta
- [x] Round-trips response _meta for persist/approval choices
- [x] Updates TUI empty-schema elicitations into message-only approval
prompts
This commit is contained in:
Matthew Zeng authored and GitHub committed 2026-04-08 10:18:58 -07:00
1 parent 06d88b7e81
commit 7b6486a145
8 files changed
+372 -83

No files matched your search

@@ -1319,19 +1319,15 @@ impl From<anyhow::Error> for StartupOutcomeError {
}
}
fn elicitation_capability_for_server(server_name: &str) -> Option<ElicitationCapability> {
if server_name == CODEX_APPS_MCP_SERVER_NAME {
// https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation#capabilities
// indicates this should be an empty object.
Some(ElicitationCapability {
form: Some(FormElicitationCapability {
schema_validation: None,
}),
url: None,
})
} else {
None
}
fn elicitation_capability_for_server(_server_name: &str) -> Option<ElicitationCapability> {
// https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation#capabilities
// indicates this should be an empty object.
Some(ElicitationCapability {
form: Some(FormElicitationCapability {
schema_validation: None,
}),
url: None,
})
}
async fn start_server_task(
@@ -508,19 +508,19 @@ async fn list_all_tools_uses_startup_snapshot_when_client_startup_fails() {
}
#[test]
fn elicitation_capability_enabled_only_for_codex_apps() {
let codex_apps_capability = elicitation_capability_for_server(CODEX_APPS_MCP_SERVER_NAME);
assert!(matches!(
codex_apps_capability,
Some(ElicitationCapability {
form: Some(FormElicitationCapability {
schema_validation: None
}),
url: None,
})
));
assert!(elicitation_capability_for_server("custom_mcp").is_none());
fn elicitation_capability_enabled_for_custom_servers() {
for server_name in [CODEX_APPS_MCP_SERVER_NAME, "custom_mcp"] {
let capability = elicitation_capability_for_server(server_name);
assert!(matches!(
capability,
Some(ElicitationCapability {
form: Some(FormElicitationCapability {
schema_validation: None
}),
url: None,
})
));
}
}
#[test]