Skip to content
44 changes: 44 additions & 0 deletions rust/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1860,6 +1860,12 @@ pub struct SessionConfig {
/// applied automatically at session creation/resume time. `None` means no
/// explicit value is set and the runtime default takes effect.
pub mcp_oauth_token_storage: Option<String>,
/// URL identifying this host's OAuth client metadata document.
///
/// Authorization servers that support client ID metadata documents can use
/// this URL as the MCP OAuth client ID. Older runtimes ignore this optional
/// field.
pub auth_client_id_metadata_url: Option<String>,
/// Enables runtime discovery of supported configuration. Explicitly supplied
/// configuration takes precedence over discovered values.
pub enable_config_discovery: Option<bool>,
Expand Down Expand Up @@ -2235,6 +2241,7 @@ impl Default for SessionConfig {
excluded_builtin_agents: None,
mcp_servers: None,
mcp_oauth_token_storage: None,
auth_client_id_metadata_url: None,
enable_config_discovery: None,
skip_embedding_retrieval: None,
organization_custom_instructions: None,
Expand Down Expand Up @@ -2388,6 +2395,7 @@ impl SessionConfig {
tool_filter_precedence: "excluded",
mcp_servers: self.mcp_servers,
mcp_oauth_token_storage: self.mcp_oauth_token_storage,
auth_client_id_metadata_url: self.auth_client_id_metadata_url,
embedding_cache_storage: self.embedding_cache_storage,
env_value_mode: "direct",
enable_config_discovery: self.enable_config_discovery,
Expand Down Expand Up @@ -2715,6 +2723,12 @@ impl SessionConfig {
self
}

/// Set the URL identifying this host's OAuth client metadata document.
pub fn with_auth_client_id_metadata_url(mut self, url: impl Into<String>) -> Self {
self.auth_client_id_metadata_url = Some(url.into());
self
}

/// Set embedding cache storage mode.
pub fn with_embedding_cache_storage(
mut self,
Expand Down Expand Up @@ -3101,6 +3115,9 @@ pub struct ResumeSessionConfig {
/// Controls how MCP OAuth tokens are stored for this session.
/// See [`SessionConfig::mcp_oauth_token_storage`] for details.
pub mcp_oauth_token_storage: Option<String>,
/// Re-supply the host OAuth client metadata document URL on resume.
/// See [`SessionConfig::auth_client_id_metadata_url`] for details.
pub auth_client_id_metadata_url: Option<String>,
/// Enables runtime discovery of supported configuration. Explicitly supplied
/// configuration takes precedence over discovered values.
pub enable_config_discovery: Option<bool>,
Expand Down Expand Up @@ -3457,6 +3474,7 @@ impl ResumeSessionConfig {
tool_filter_precedence: "excluded",
mcp_servers: self.mcp_servers,
mcp_oauth_token_storage: self.mcp_oauth_token_storage,
auth_client_id_metadata_url: self.auth_client_id_metadata_url,
embedding_cache_storage: self.embedding_cache_storage,
env_value_mode: "direct",
enable_config_discovery: self.enable_config_discovery,
Expand Down Expand Up @@ -3556,6 +3574,7 @@ impl ResumeSessionConfig {
excluded_builtin_agents: None,
mcp_servers: None,
mcp_oauth_token_storage: None,
auth_client_id_metadata_url: None,
enable_config_discovery: None,
skip_embedding_retrieval: None,
organization_custom_instructions: None,
Expand Down Expand Up @@ -3855,6 +3874,12 @@ impl ResumeSessionConfig {
self
}

/// Set the host OAuth client metadata document URL on resume.
pub fn with_auth_client_id_metadata_url(mut self, url: impl Into<String>) -> Self {
self.auth_client_id_metadata_url = Some(url.into());
self
}

/// Set embedding cache storage mode on resume.
pub fn with_embedding_cache_storage(
mut self,
Expand Down Expand Up @@ -6375,6 +6400,25 @@ mod tests {
assert!(empty_json.get("largeOutput").is_none());
}

#[test]
fn auth_client_id_metadata_url_reaches_create_and_resume_wire_payloads() {
let url = "https://example.com/oauth/client-metadata.json";

let (create_wire, _) = SessionConfig::default()
.with_auth_client_id_metadata_url(url)
.into_wire(None)
.expect("default create has no duplicate handlers");
let create_json = serde_json::to_value(&create_wire).unwrap();
assert_eq!(create_json["authClientIdMetadataUrl"], url);

let (resume_wire, _) = ResumeSessionConfig::new(SessionId::from("sess-1"))
.with_auth_client_id_metadata_url(url)
.into_wire()
.expect("default resume has no duplicate handlers");
let resume_json = serde_json::to_value(&resume_wire).unwrap();
assert_eq!(resume_json["authClientIdMetadataUrl"], url);
}
Comment thread
SamMorrowDrums marked this conversation as resolved.

#[test]
fn session_config_builder_composes() {
use indexmap::IndexMap;
Expand Down
4 changes: 4 additions & 0 deletions rust/src/wire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ pub(crate) struct SessionCreateWire {
#[serde(skip_serializing_if = "Option::is_none")]
pub mcp_oauth_token_storage: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_client_id_metadata_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub embedding_cache_storage: Option<String>,
pub env_value_mode: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -230,6 +232,8 @@ pub(crate) struct SessionResumeWire {
#[serde(skip_serializing_if = "Option::is_none")]
pub mcp_oauth_token_storage: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_client_id_metadata_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub embedding_cache_storage: Option<String>,
pub env_value_mode: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down
Loading