mirror of
https://github.com/openai/codex.git
synced 2026-10-22 17:58:46 +00:00
Reuse apps MCP path override for rollout
This commit is contained in:
@@ -109,8 +109,6 @@ pub struct McpConfig {
|
||||
pub chatgpt_base_url: String,
|
||||
/// Optional path override for the host-owned apps MCP server.
|
||||
pub apps_mcp_path_override: Option<String>,
|
||||
/// Whether the host-owned apps MCP server should use the new plugin-service route.
|
||||
pub new_apps_mcp_enabled: bool,
|
||||
/// Codex home directory used for MCP OAuth state and app-tool cache files.
|
||||
pub codex_home: PathBuf,
|
||||
/// Preferred credential store for MCP OAuth tokens.
|
||||
@@ -366,12 +364,10 @@ pub async fn collect_mcp_server_status_snapshot_with_detail(
|
||||
}
|
||||
|
||||
pub(crate) fn codex_apps_mcp_url(config: &McpConfig) -> String {
|
||||
let apps_mcp_path_override = config
|
||||
.apps_mcp_path_override
|
||||
.as_deref()
|
||||
.or(config.new_apps_mcp_enabled.then_some("/ps/mcp"));
|
||||
|
||||
codex_apps_mcp_url_for_base_url(&config.chatgpt_base_url, apps_mcp_path_override)
|
||||
codex_apps_mcp_url_for_base_url(
|
||||
&config.chatgpt_base_url,
|
||||
config.apps_mcp_path_override.as_deref(),
|
||||
)
|
||||
}
|
||||
|
||||
/// The Responses API requires tool names to match `^[a-zA-Z0-9_-]+$`.
|
||||
|
||||
@@ -18,7 +18,6 @@ fn test_mcp_config(codex_home: PathBuf) -> McpConfig {
|
||||
McpConfig {
|
||||
chatgpt_base_url: "https://chatgpt.com".to_string(),
|
||||
apps_mcp_path_override: None,
|
||||
new_apps_mcp_enabled: false,
|
||||
codex_home,
|
||||
mcp_oauth_credentials_store_mode: OAuthCredentialsStoreMode::default(),
|
||||
mcp_oauth_callback_port: None,
|
||||
@@ -205,29 +204,6 @@ fn codex_apps_mcp_url_uses_legacy_codex_apps_path() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_apps_mcp_url_uses_plugin_service_path_when_new_apps_mcp_is_enabled() {
|
||||
let mut config = test_mcp_config(PathBuf::from("/tmp"));
|
||||
config.new_apps_mcp_enabled = true;
|
||||
|
||||
assert_eq!(
|
||||
codex_apps_mcp_url(&config),
|
||||
"https://chatgpt.com/backend-api/ps/mcp"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_apps_mcp_url_prefers_path_override_over_new_apps_mcp() {
|
||||
let mut config = test_mcp_config(PathBuf::from("/tmp"));
|
||||
config.apps_mcp_path_override = Some("/custom/mcp".to_string());
|
||||
config.new_apps_mcp_enabled = true;
|
||||
|
||||
assert_eq!(
|
||||
codex_apps_mcp_url(&config),
|
||||
"https://chatgpt.com/backend-api/custom/mcp"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn codex_apps_server_config_uses_legacy_codex_apps_path() {
|
||||
let mut config = test_mcp_config(PathBuf::from("/tmp"));
|
||||
|
||||
@@ -490,9 +490,6 @@
|
||||
"network_proxy": {
|
||||
"$ref": "#/definitions/FeatureToml_for_NetworkProxyConfigToml"
|
||||
},
|
||||
"new_apps_mcp": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"personality": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -4173,9 +4170,6 @@
|
||||
"network_proxy": {
|
||||
"$ref": "#/definitions/FeatureToml_for_NetworkProxyConfigToml"
|
||||
},
|
||||
"new_apps_mcp": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"personality": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
||||
@@ -4601,17 +4601,14 @@ async fn to_mcp_config_preserves_apps_feature_from_config() -> std::io::Result<(
|
||||
mcp_config.apps_mcp_path_override.as_deref(),
|
||||
Some("/custom/mcp")
|
||||
);
|
||||
assert!(!mcp_config.new_apps_mcp_enabled);
|
||||
|
||||
let _ = config.features.disable(Feature::Apps);
|
||||
let mcp_config = config.to_mcp_config(&plugins_manager).await;
|
||||
assert!(!mcp_config.apps_enabled);
|
||||
|
||||
let _ = config.features.enable(Feature::Apps);
|
||||
let _ = config.features.enable(Feature::NewAppsMcp);
|
||||
let mcp_config = config.to_mcp_config(&plugins_manager).await;
|
||||
assert!(mcp_config.apps_enabled);
|
||||
assert!(mcp_config.new_apps_mcp_enabled);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -8773,13 +8770,13 @@ path = "/custom/mcp"
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn config_loads_new_apps_mcp_feature() -> std::io::Result<()> {
|
||||
async fn config_defaults_enabled_apps_mcp_path_override_to_plugin_service() -> std::io::Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
let toml = r#"
|
||||
model = "gpt-5.4"
|
||||
|
||||
[features]
|
||||
new_apps_mcp = true
|
||||
apps_mcp_path_override = true
|
||||
"#;
|
||||
let cfg: ConfigToml =
|
||||
toml::from_str(toml).expect("TOML deserialization should succeed for apps MCP feature");
|
||||
@@ -8791,22 +8788,19 @@ new_apps_mcp = true
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert!(config.features.enabled(Feature::NewAppsMcp));
|
||||
assert_eq!(config.apps_mcp_path_override, None);
|
||||
assert!(config.features.enabled(Feature::AppsMcpPathOverride));
|
||||
assert_eq!(config.apps_mcp_path_override.as_deref(), Some("/ps/mcp"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn config_preserves_apps_mcp_path_override_with_new_apps_mcp_feature() -> std::io::Result<()>
|
||||
{
|
||||
async fn config_preserves_explicit_apps_mcp_path_override_path() -> std::io::Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
let toml = r#"
|
||||
model = "gpt-5.4"
|
||||
|
||||
[features]
|
||||
new_apps_mcp = true
|
||||
|
||||
[features.apps_mcp_path_override]
|
||||
enabled = true
|
||||
path = "/custom/mcp"
|
||||
"#;
|
||||
let cfg: ConfigToml =
|
||||
@@ -8823,7 +8817,7 @@ path = "/custom/mcp"
|
||||
config.apps_mcp_path_override.as_deref(),
|
||||
Some("/custom/mcp")
|
||||
);
|
||||
assert!(config.features.enabled(Feature::NewAppsMcp));
|
||||
assert!(config.features.enabled(Feature::AppsMcpPathOverride));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -1131,7 +1131,6 @@ impl Config {
|
||||
McpConfig {
|
||||
chatgpt_base_url: self.chatgpt_base_url.clone(),
|
||||
apps_mcp_path_override: self.apps_mcp_path_override.clone(),
|
||||
new_apps_mcp_enabled: self.features.enabled(Feature::NewAppsMcp),
|
||||
codex_home: self.codex_home.to_path_buf(),
|
||||
mcp_oauth_credentials_store_mode: self.mcp_oauth_credentials_store_mode,
|
||||
mcp_oauth_callback_port: self.mcp_oauth_callback_port,
|
||||
@@ -2616,6 +2615,7 @@ impl Config {
|
||||
.and_then(|config| config.path.as_ref())
|
||||
.or_else(|| base.and_then(|config| config.path.as_ref()))
|
||||
.cloned()
|
||||
.or_else(|| Some("/ps/mcp".to_string()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
@@ -158,8 +158,6 @@ pub enum Feature {
|
||||
EnableMcpApps,
|
||||
/// Use the new path for the host-owned apps MCP server.
|
||||
AppsMcpPathOverride,
|
||||
/// Route the host-owned apps MCP server through plugin-service.
|
||||
NewAppsMcp,
|
||||
/// Enable the tool_search tool for apps.
|
||||
ToolSearch,
|
||||
/// Always defer MCP tools behind tool_search instead of exposing small sets directly.
|
||||
@@ -945,12 +943,6 @@ pub const FEATURES: &[FeatureSpec] = &[
|
||||
stage: Stage::UnderDevelopment,
|
||||
default_enabled: false,
|
||||
},
|
||||
FeatureSpec {
|
||||
id: Feature::NewAppsMcp,
|
||||
key: "new_apps_mcp",
|
||||
stage: Stage::UnderDevelopment,
|
||||
default_enabled: false,
|
||||
},
|
||||
FeatureSpec {
|
||||
id: Feature::ToolSearch,
|
||||
key: "tool_search",
|
||||
|
||||
@@ -129,13 +129,6 @@ fn remote_compaction_v2_is_under_development() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_apps_mcp_is_under_development() {
|
||||
assert_eq!(Feature::NewAppsMcp.stage(), Stage::UnderDevelopment);
|
||||
assert_eq!(Feature::NewAppsMcp.default_enabled(), false);
|
||||
assert_eq!(feature_for_key("new_apps_mcp"), Some(Feature::NewAppsMcp));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn responses_websocket_response_processed_is_under_development() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user