chore: drop built-in MCPs (#22173)

Drop something that was never used
This commit is contained in:
jif-oai
2026-05-11 19:45:08 +02:00
committed by GitHub
Unverified
parent a124ddb854
commit 32b1ae7099
22 changed files with 12 additions and 559 deletions
-12
View File
@@ -2162,17 +2162,6 @@ dependencies = [
"serde_with",
]
[[package]]
name = "codex-builtin-mcps"
version = "0.0.0"
dependencies = [
"anyhow",
"codex-memories-mcp",
"codex-utils-absolute-path",
"pretty_assertions",
"tokio",
]
[[package]]
name = "codex-bwrap"
version = "0.0.0"
@@ -3065,7 +3054,6 @@ dependencies = [
"async-channel",
"codex-api",
"codex-async-utils",
"codex-builtin-mcps",
"codex-config",
"codex-exec-server",
"codex-login",
-3
View File
@@ -5,7 +5,6 @@ members = [
"agent-graph-store",
"agent-identity",
"backend-client",
"builtin-mcps",
"bwrap",
"ansi-escape",
"async-utils",
@@ -144,7 +143,6 @@ codex-apply-patch = { path = "apply-patch" }
codex-arg0 = { path = "arg0" }
codex-async-utils = { path = "async-utils" }
codex-backend-client = { path = "backend-client" }
codex-builtin-mcps = { path = "builtin-mcps" }
codex-chatgpt = { path = "chatgpt" }
codex-cli = { path = "cli" }
codex-client = { path = "codex-client" }
@@ -180,7 +178,6 @@ codex-linux-sandbox = { path = "linux-sandbox" }
codex-lmstudio = { path = "lmstudio" }
codex-login = { path = "login" }
codex-message-history = { path = "message-history" }
codex-memories-mcp = { path = "memories/mcp" }
codex-memories-read = { path = "memories/read" }
codex-memories-write = { path = "memories/write" }
codex-mcp = { path = "codex-mcp" }
@@ -286,7 +286,7 @@ impl McpRequestProcessor {
.mcp_servers
.keys()
.cloned()
// Include built-in/plugin MCP servers that are present in the
// Include runtime-added/plugin MCP servers that are present in the
// effective runtime config even when they are not user-declared in
// `config.mcp_servers`.
.chain(effective_servers.keys().cloned())
-6
View File
@@ -1,6 +0,0 @@
load("//:defs.bzl", "codex_rust_crate")
codex_rust_crate(
name = "builtin-mcps",
crate_name = "codex_builtin_mcps",
)
-22
View File
@@ -1,22 +0,0 @@
[package]
edition.workspace = true
license.workspace = true
name = "codex-builtin-mcps"
version.workspace = true
[lib]
name = "codex_builtin_mcps"
path = "src/lib.rs"
doctest = false
[lints]
workspace = true
[dependencies]
anyhow = { workspace = true }
codex-memories-mcp = { workspace = true }
codex-utils-absolute-path = { workspace = true }
tokio = { workspace = true, features = ["io-util"] }
[dev-dependencies]
pretty_assertions = { workspace = true }
-101
View File
@@ -1,101 +0,0 @@
//! Built-in MCP servers shipped with Codex.
//!
//! This crate owns the catalog of product-owned MCP servers and the small
//! amount of server-specific dispatch needed to run them. Runtime placement is
//! chosen by `codex-mcp`; built-ins should not be flattened into user-facing
//! MCP server config just to make them launchable.
use std::path::Path;
use tokio::io::AsyncRead;
use tokio::io::AsyncWrite;
pub const MEMORIES_MCP_SERVER_NAME: &str = "memories";
/// Product-owned MCP servers that Codex can provide without user config.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BuiltinMcpServer {
Memories,
}
#[derive(Debug, Clone, Copy)]
struct BuiltinMcpServerMetadata {
name: &'static str,
supports_parallel_tool_calls: bool,
pollutes_memory: bool,
}
impl BuiltinMcpServer {
const fn metadata(self) -> BuiltinMcpServerMetadata {
match self {
Self::Memories => BuiltinMcpServerMetadata {
name: MEMORIES_MCP_SERVER_NAME,
supports_parallel_tool_calls: true,
pollutes_memory: false,
},
}
}
pub const fn name(self) -> &'static str {
self.metadata().name
}
pub const fn supports_parallel_tool_calls(self) -> bool {
self.metadata().supports_parallel_tool_calls
}
pub const fn pollutes_memory(self) -> bool {
self.metadata().pollutes_memory
}
pub async fn serve<T>(self, codex_home: &Path, transport: T) -> anyhow::Result<()>
where
T: AsyncRead + AsyncWrite + Send + 'static,
{
match self {
Self::Memories => {
let codex_home = codex_utils_absolute_path::AbsolutePathBuf::try_from(codex_home)?;
codex_memories_mcp::run_server(&codex_home, transport).await
}
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct BuiltinMcpServerOptions {
pub memories_enabled: bool,
}
pub fn enabled_builtin_mcp_servers(options: BuiltinMcpServerOptions) -> Vec<BuiltinMcpServer> {
let mut servers = Vec::new();
if options.memories_enabled {
servers.push(BuiltinMcpServer::Memories);
}
servers
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn enabled_builtin_mcp_servers_adds_memories_when_enabled() {
assert_eq!(
enabled_builtin_mcp_servers(BuiltinMcpServerOptions {
memories_enabled: true,
}),
vec![BuiltinMcpServer::Memories]
);
}
#[test]
fn enabled_builtin_mcp_servers_omits_memories_when_disabled() {
assert_eq!(
enabled_builtin_mcp_servers(BuiltinMcpServerOptions {
memories_enabled: false,
}),
Vec::<BuiltinMcpServer>::new()
);
}
}
-1
View File
@@ -17,7 +17,6 @@ anyhow = { workspace = true }
async-channel = { workspace = true }
codex-async-utils = { workspace = true }
codex-api = { workspace = true }
codex-builtin-mcps = { workspace = true }
codex-config = { workspace = true }
codex-exec-server = { workspace = true }
codex-login = { workspace = true }
-39
View File
@@ -1,39 +0,0 @@
use std::io;
use std::path::PathBuf;
use codex_builtin_mcps::BuiltinMcpServer;
use codex_rmcp_client::InProcessTransportFactory;
use futures::FutureExt;
use futures::future::BoxFuture;
#[derive(Clone)]
pub(crate) struct BuiltinMcpServerFactory {
server: BuiltinMcpServer,
codex_home: PathBuf,
}
impl BuiltinMcpServerFactory {
pub(crate) fn new(server: BuiltinMcpServer, codex_home: PathBuf) -> Self {
Self { server, codex_home }
}
}
impl InProcessTransportFactory for BuiltinMcpServerFactory {
fn open(&self) -> BoxFuture<'static, io::Result<tokio::io::DuplexStream>> {
let server = self.server;
let codex_home = self.codex_home.clone();
async move {
let (client_transport, server_transport) = tokio::io::duplex(64 * 1024);
tokio::spawn(async move {
if let Err(err) = server.serve(&codex_home, server_transport).await {
tracing::warn!(
server = server.name(),
"built-in MCP server exited: {err:#}"
);
}
});
Ok(client_transport)
}
.boxed()
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
//! Codex Apps support for the built-in apps MCP server.
//! Codex Apps support for the host-owned apps MCP server.
//!
//! This module owns the pieces that are unique to ChatGPT-hosted app
//! connectors: cache scoping by authenticated user, disk cache reads/writes,
@@ -246,7 +246,6 @@ impl McpConnectionManager {
codex_apps_tools_cache_context,
Arc::clone(&tool_plugin_provenance),
runtime_environment.clone(),
codex_home.clone(),
runtime_auth_provider,
);
clients.insert(server_name.clone(), async_managed_client.clone());
-6
View File
@@ -23,11 +23,6 @@ pub use auth_elicitation::build_auth_elicitation_plan;
pub use auth_elicitation::connector_auth_failure_from_tool_result;
pub use codex_apps::CodexAppsToolsCacheKey;
pub use codex_apps::codex_apps_tools_cache_key;
pub use codex_builtin_mcps::BuiltinMcpServer;
pub use codex_builtin_mcps::BuiltinMcpServerOptions;
pub use codex_builtin_mcps::MEMORIES_MCP_SERVER_NAME;
pub use codex_builtin_mcps::enabled_builtin_mcp_servers;
pub use mcp::configured_mcp_servers;
pub use mcp::effective_mcp_servers;
pub use mcp::effective_mcp_servers_from_configured;
@@ -57,7 +52,6 @@ pub use mcp::qualified_mcp_tool_name_prefix;
pub use tools::declared_openai_file_input_param_names;
pub(crate) mod auth_elicitation;
pub(crate) mod builtin;
pub(crate) mod codex_apps;
pub(crate) mod connection_manager;
pub(crate) mod elicitation;
+4 -13
View File
@@ -106,7 +106,7 @@ pub struct McpPermissionPromptAutoApproveContext {
pub struct McpConfig {
/// Base URL for ChatGPT-hosted app MCP servers, copied from the root config.
pub chatgpt_base_url: String,
/// Optional path override for the built-in apps MCP server.
/// Optional path override for the host-owned apps MCP server.
pub apps_mcp_path_override: Option<String>,
/// Codex home directory used for MCP OAuth state and app-tool cache files.
pub codex_home: PathBuf,
@@ -126,16 +126,13 @@ pub struct McpConfig {
pub use_legacy_landlock: bool,
/// Whether the app MCP integration is enabled by config.
///
/// ChatGPT auth is checked separately at runtime before the built-in apps
/// ChatGPT auth is checked separately at runtime before the host-owned apps
/// MCP server is added.
pub apps_enabled: bool,
/// Config-backed MCP servers keyed by server name.
///
/// Product-owned built-ins and runtime-only additions are merged later by
/// [`effective_mcp_servers`].
/// Runtime-only additions are merged later by [`effective_mcp_servers`].
pub configured_mcp_servers: HashMap<String, McpServerConfig>,
/// Product-owned built-ins enabled for this runtime config.
pub builtin_mcp_servers: Vec<codex_builtin_mcps::BuiltinMcpServer>,
/// Plugin metadata used to attribute MCP tools/connectors to plugin display names.
pub plugin_capability_summaries: Vec<PluginCapabilitySummary>,
}
@@ -234,16 +231,10 @@ pub fn effective_mcp_servers_from_configured(
config: &McpConfig,
auth: Option<&CodexAuth>,
) -> HashMap<String, EffectiveMcpServer> {
let mut servers = configured_servers
let servers = configured_servers
.into_iter()
.map(|(name, server)| (name, EffectiveMcpServer::configured(server)))
.collect::<HashMap<_, _>>();
for builtin_server in &config.builtin_mcp_servers {
servers.insert(
builtin_server.name().to_string(),
EffectiveMcpServer::builtin(*builtin_server),
);
}
with_codex_apps_mcp(servers, auth, config)
}
-52
View File
@@ -13,7 +13,6 @@ use codex_protocol::protocol::GranularApprovalConfig;
use pretty_assertions::assert_eq;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
fn test_mcp_config(codex_home: PathBuf) -> McpConfig {
McpConfig {
@@ -29,7 +28,6 @@ fn test_mcp_config(codex_home: PathBuf) -> McpConfig {
use_legacy_landlock: false,
apps_enabled: false,
configured_mcp_servers: HashMap::new(),
builtin_mcp_servers: Vec::new(),
plugin_capability_summaries: Vec::new(),
}
}
@@ -347,53 +345,3 @@ async fn effective_mcp_servers_preserve_user_servers_and_add_codex_apps() {
other => panic!("expected streamable http transport, got {other:?}"),
}
}
#[test]
fn effective_mcp_servers_preserve_builtin_runtime_shape() {
let mut config = test_mcp_config(PathBuf::from("/tmp"));
config.builtin_mcp_servers = vec![codex_builtin_mcps::BuiltinMcpServer::Memories];
let effective = effective_mcp_servers(&config, /*auth*/ None);
let memories = effective
.get(codex_builtin_mcps::MEMORIES_MCP_SERVER_NAME)
.expect("memories server should exist");
assert!(!crate::server::McpServerMetadata::from(memories).pollutes_memory);
assert!(matches!(
memories.launch(),
crate::server::McpServerLaunch::Builtin(codex_builtin_mcps::BuiltinMcpServer::Memories)
));
}
#[tokio::test]
async fn builtin_memories_server_runs_in_process() {
let codex_home = tempfile::tempdir().expect("tempdir");
let mut config = test_mcp_config(codex_home.path().to_path_buf());
config.builtin_mcp_servers = vec![codex_builtin_mcps::BuiltinMcpServer::Memories];
let snapshot = collect_mcp_server_status_snapshot_with_detail(
&config,
/*auth*/ None,
"builtin-memories-test".to_string(),
McpRuntimeEnvironment::new(
Arc::new(codex_exec_server::Environment::default_for_tests()),
codex_home.path().to_path_buf(),
),
McpSnapshotDetail::ToolsAndAuthOnly,
)
.await;
let tools = snapshot
.tools_by_server
.get(codex_builtin_mcps::MEMORIES_MCP_SERVER_NAME)
.expect("memories tools should be listed");
assert_eq!(
tools
.keys()
.cloned()
.collect::<std::collections::BTreeSet<_>>(),
["list".to_string(), "read".to_string(), "search".to_string()]
.into_iter()
.collect()
);
}
-13
View File
@@ -10,14 +10,12 @@ use std::borrow::Cow;
use std::collections::HashMap;
use std::env;
use std::ffi::OsString;
use std::path::PathBuf;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::time::Duration;
use std::time::Instant;
use crate::builtin::BuiltinMcpServerFactory;
use crate::codex_apps::CachedCodexAppsToolsLoad;
use crate::codex_apps::CodexAppsToolsCacheContext;
use crate::codex_apps::filter_disallowed_codex_apps_tools;
@@ -51,7 +49,6 @@ use codex_exec_server::HttpClient;
use codex_exec_server::ReqwestHttpClient;
use codex_protocol::protocol::Event;
use codex_rmcp_client::ExecutorStdioServerLauncher;
use codex_rmcp_client::InProcessTransportFactory;
use codex_rmcp_client::LocalStdioServerLauncher;
use codex_rmcp_client::RmcpClient;
use codex_rmcp_client::StdioServerLauncher;
@@ -146,7 +143,6 @@ impl AsyncManagedClient {
codex_apps_tools_cache_context: Option<CodexAppsToolsCacheContext>,
tool_plugin_provenance: Arc<ToolPluginProvenance>,
runtime_environment: McpRuntimeEnvironment,
codex_home: PathBuf,
runtime_auth_provider: Option<SharedAuthProvider>,
) -> Self {
let tool_filter = server
@@ -174,7 +170,6 @@ impl AsyncManagedClient {
server.clone(),
store_mode,
runtime_environment,
codex_home,
runtime_auth_provider,
)
.await?,
@@ -569,18 +564,10 @@ async fn make_rmcp_client(
server: EffectiveMcpServer,
store_mode: OAuthCredentialsStoreMode,
runtime_environment: McpRuntimeEnvironment,
codex_home: PathBuf,
runtime_auth_provider: Option<SharedAuthProvider>,
) -> Result<RmcpClient, StartupOutcomeError> {
let config = match server.launch() {
McpServerLaunch::Configured(config) => config.as_ref().clone(),
McpServerLaunch::Builtin(builtin_server) => {
let factory: Arc<dyn InProcessTransportFactory> =
Arc::new(BuiltinMcpServerFactory::new(*builtin_server, codex_home));
return RmcpClient::new_in_process_client(factory)
.await
.map_err(|err| StartupOutcomeError::from(anyhow!(err)));
}
};
let McpServerConfig {
transport,
+1 -19
View File
@@ -1,4 +1,3 @@
use codex_builtin_mcps::BuiltinMcpServer;
use codex_config::McpServerConfig;
use codex_config::McpServerTransportConfig;
@@ -6,10 +5,9 @@ use codex_config::McpServerTransportConfig;
#[derive(Debug, Clone)]
pub(crate) enum McpServerLaunch {
Configured(Box<McpServerConfig>),
Builtin(BuiltinMcpServer),
}
/// MCP server after product-owned runtime additions have been applied.
/// MCP server after runtime additions have been applied.
#[derive(Debug, Clone)]
pub struct EffectiveMcpServer {
launch: McpServerLaunch,
@@ -22,12 +20,6 @@ impl EffectiveMcpServer {
}
}
pub fn builtin(server: BuiltinMcpServer) -> Self {
Self {
launch: McpServerLaunch::Builtin(server),
}
}
pub(crate) fn launch(&self) -> &McpServerLaunch {
&self.launch
}
@@ -35,21 +27,18 @@ impl EffectiveMcpServer {
pub fn configured_config(&self) -> Option<&McpServerConfig> {
match &self.launch {
McpServerLaunch::Configured(config) => Some(config.as_ref()),
McpServerLaunch::Builtin(_) => None,
}
}
pub fn enabled(&self) -> bool {
match &self.launch {
McpServerLaunch::Configured(config) => config.enabled,
McpServerLaunch::Builtin(_) => true,
}
}
pub fn required(&self) -> bool {
match &self.launch {
McpServerLaunch::Configured(config) => config.required,
McpServerLaunch::Builtin(_) => false,
}
}
}
@@ -57,7 +46,6 @@ impl EffectiveMcpServer {
/// Transport origin retained for metrics and diagnostics after server launch.
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) enum McpServerOrigin {
InProcess,
Stdio,
StreamableHttp(String),
}
@@ -65,7 +53,6 @@ pub(crate) enum McpServerOrigin {
impl McpServerOrigin {
pub fn as_str(&self) -> &str {
match self {
Self::InProcess => "in_process",
Self::Stdio => "stdio",
Self::StreamableHttp(origin) => origin,
}
@@ -98,11 +85,6 @@ impl From<&EffectiveMcpServer> for McpServerMetadata {
origin: McpServerOrigin::from_transport(&config.transport),
supports_parallel_tool_calls: config.supports_parallel_tool_calls,
},
McpServerLaunch::Builtin(server) => Self {
pollutes_memory: server.pollutes_memory(),
origin: Some(McpServerOrigin::InProcess),
supports_parallel_tool_calls: server.supports_parallel_tool_calls(),
},
}
}
}
-6
View File
@@ -379,9 +379,6 @@
"browser_use_external": {
"type": "boolean"
},
"builtin_mcp": {
"type": "boolean"
},
"child_agents_md": {
"type": "boolean"
},
@@ -3935,9 +3932,6 @@
"browser_use_external": {
"type": "boolean"
},
"builtin_mcp": {
"type": "boolean"
},
"child_agents_md": {
"type": "boolean"
},
-144
View File
@@ -3370,69 +3370,6 @@ async fn add_dir_override_extends_workspace_writable_roots() -> std::io::Result<
Ok(())
}
#[tokio::test]
async fn to_mcp_config_empty_mcp_requirements_preserve_builtin_mcps() -> anyhow::Result<()> {
let codex_home = TempDir::new()?;
let requirements = codex_config::ConfigRequirementsToml {
mcp_servers: Some(BTreeMap::new()),
..Default::default()
};
let mut config = ConfigBuilder::default()
.codex_home(codex_home.path().to_path_buf())
.cloud_requirements(CloudRequirementsLoader::new(async move {
Ok(Some(requirements))
}))
.build()
.await?;
let _ = config.features.enable(Feature::BuiltInMcp);
let _ = config.features.enable(Feature::MemoryTool);
let plugins_manager = PluginsManager::new(codex_home.path().to_path_buf());
let mcp_config = config.to_mcp_config(&plugins_manager).await;
assert_eq!(
mcp_config.builtin_mcp_servers,
vec![codex_mcp::BuiltinMcpServer::Memories]
);
Ok(())
}
#[tokio::test]
async fn to_mcp_config_nonempty_mcp_requirements_preserve_builtin_mcps() -> anyhow::Result<()> {
let codex_home = TempDir::new()?;
let requirements = codex_config::ConfigRequirementsToml {
mcp_servers: Some(BTreeMap::from([(
"docs".to_string(),
McpServerRequirement {
identity: McpServerIdentity::Command {
command: "docs-mcp".to_string(),
},
},
)])),
..Default::default()
};
let mut config = ConfigBuilder::default()
.codex_home(codex_home.path().to_path_buf())
.cloud_requirements(CloudRequirementsLoader::new(async move {
Ok(Some(requirements))
}))
.build()
.await?;
let _ = config.features.enable(Feature::BuiltInMcp);
let _ = config.features.enable(Feature::MemoryTool);
let plugins_manager = PluginsManager::new(codex_home.path().to_path_buf());
let mcp_config = config.to_mcp_config(&plugins_manager).await;
assert_eq!(
mcp_config.builtin_mcp_servers,
vec![codex_mcp::BuiltinMcpServer::Memories]
);
Ok(())
}
#[tokio::test]
async fn sqlite_home_defaults_to_codex_home_for_workspace_write() -> std::io::Result<()> {
let codex_home = TempDir::new()?;
@@ -4255,87 +4192,6 @@ async fn to_mcp_config_preserves_apps_feature_from_config() -> std::io::Result<(
Ok(())
}
#[tokio::test]
async fn to_mcp_config_includes_enabled_builtin_mcps() -> std::io::Result<()> {
let codex_home = TempDir::new()?;
let mut config = Config::load_from_base_config_with_overrides(
ConfigToml::default(),
ConfigOverrides::default(),
codex_home.abs(),
)
.await?;
let _ = config.features.enable(Feature::BuiltInMcp);
let _ = config.features.enable(Feature::MemoryTool);
let plugins_manager = PluginsManager::new(codex_home.path().to_path_buf());
let mcp_config = config.to_mcp_config(&plugins_manager).await;
assert_eq!(
mcp_config.builtin_mcp_servers,
vec![codex_mcp::BuiltinMcpServer::Memories]
);
assert!(
!mcp_config
.configured_mcp_servers
.contains_key(codex_mcp::MEMORIES_MCP_SERVER_NAME)
);
Ok(())
}
#[tokio::test]
async fn to_mcp_config_omits_builtin_mcps_when_feature_is_disabled() -> std::io::Result<()> {
let codex_home = TempDir::new()?;
let mut config = Config::load_from_base_config_with_overrides(
ConfigToml::default(),
ConfigOverrides::default(),
codex_home.abs(),
)
.await?;
let _ = config.features.enable(Feature::MemoryTool);
let plugins_manager = PluginsManager::new(codex_home.path().to_path_buf());
let mcp_config = config.to_mcp_config(&plugins_manager).await;
assert!(mcp_config.builtin_mcp_servers.is_empty());
Ok(())
}
#[tokio::test]
async fn to_mcp_config_reserves_enabled_builtin_mcp_names() -> std::io::Result<()> {
let codex_home = TempDir::new()?;
let mut config = Config::load_from_base_config_with_overrides(
ConfigToml {
mcp_servers: HashMap::from([(
codex_mcp::MEMORIES_MCP_SERVER_NAME.to_string(),
http_mcp("https://user.example/memories"),
)]),
..ConfigToml::default()
},
ConfigOverrides::default(),
codex_home.abs(),
)
.await?;
let _ = config.features.enable(Feature::BuiltInMcp);
let _ = config.features.enable(Feature::MemoryTool);
let plugins_manager = PluginsManager::new(codex_home.path().to_path_buf());
let mcp_config = config.to_mcp_config(&plugins_manager).await;
assert_eq!(
mcp_config.builtin_mcp_servers,
vec![codex_mcp::BuiltinMcpServer::Memories]
);
assert!(
!mcp_config
.configured_mcp_servers
.contains_key(codex_mcp::MEMORIES_MCP_SERVER_NAME)
);
Ok(())
}
#[tokio::test]
async fn load_global_mcp_servers_rejects_inline_bearer_token() -> anyhow::Result<()> {
let codex_home = TempDir::new()?;
+2 -14
View File
@@ -66,9 +66,7 @@ use codex_features::FeaturesToml;
use codex_features::MultiAgentV2ConfigToml;
use codex_git_utils::resolve_root_git_project_for_trust;
use codex_login::AuthManagerConfig;
use codex_mcp::BuiltinMcpServerOptions;
use codex_mcp::McpConfig;
use codex_mcp::enabled_builtin_mcp_servers;
use codex_memories_read::memory_root;
use codex_model_provider_info::LEGACY_OLLAMA_CHAT_PROVIDER_ID;
use codex_model_provider_info::ModelProviderInfo;
@@ -707,7 +705,7 @@ pub struct Config {
/// Base URL for requests to ChatGPT (as opposed to the OpenAI API).
pub chatgpt_base_url: String,
/// Optional path override for the built-in apps MCP server.
/// Optional path override for the host-owned apps MCP server.
pub apps_mcp_path_override: Option<String>,
/// Machine-local realtime audio device preferences used by realtime voice.
@@ -1086,11 +1084,6 @@ impl Config {
) -> McpConfig {
let plugins_input = self.plugins_config_input();
let loaded_plugins = plugins_manager.plugins_for_config(&plugins_input).await;
let builtin_mcp_servers = enabled_builtin_mcp_servers(BuiltinMcpServerOptions {
memories_enabled: self.features.enabled(Feature::BuiltInMcp)
&& self.features.enabled(Feature::MemoryTool)
&& self.memories.use_memories,
});
let mut configured_mcp_servers = self.mcp_servers.get().clone();
for plugin in loaded_plugins
.plugins()
@@ -1111,13 +1104,9 @@ impl Config {
&& mcp_requirements.value.is_empty()
{
// A present empty allowlist bans configurable MCPs, including plugin MCPs merged
// above. Built-ins are product-owned and stay available regardless of admin
// allowlists.
// above.
filter_mcp_servers_by_requirements(&mut configured_mcp_servers, Some(mcp_requirements));
}
for builtin_server in &builtin_mcp_servers {
configured_mcp_servers.remove(builtin_server.name());
}
McpConfig {
chatgpt_base_url: self.chatgpt_base_url.clone(),
@@ -1134,7 +1123,6 @@ impl Config {
use_legacy_landlock: self.features.use_legacy_landlock(),
apps_enabled: self.features.enabled(Feature::Apps),
configured_mcp_servers,
builtin_mcp_servers,
plugin_capability_summaries: loaded_plugins.capability_summaries().to_vec(),
}
}
-87
View File
@@ -2,7 +2,6 @@ use anyhow::Result;
use codex_config::types::McpServerConfig;
use codex_config::types::McpServerTransportConfig;
use codex_features::Feature;
use codex_mcp::MEMORIES_MCP_SERVER_NAME;
use codex_protocol::ThreadId;
use codex_protocol::dynamic_tools::DynamicToolSpec;
use codex_protocol::models::PermissionProfile;
@@ -448,92 +447,6 @@ async fn mcp_call_marks_thread_memory_mode_polluted_when_configured() -> Result<
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn builtin_memories_mcp_call_does_not_mark_thread_memory_mode_polluted_when_configured()
-> Result<()> {
let server = start_mock_server().await;
let call_id = "call-123";
let namespace = format!("mcp__{MEMORIES_MCP_SERVER_NAME}__");
mount_sse_once(
&server,
responses::sse(vec![
ev_response_created("resp-1"),
responses::ev_function_call_with_namespace(call_id, &namespace, "list", "{}"),
ev_completed("resp-1"),
]),
)
.await;
mount_sse_once(
&server,
responses::sse(vec![
responses::ev_assistant_message("msg-1", "memories list tool completed."),
ev_completed("resp-2"),
]),
)
.await;
let mut builder = test_codex().with_config(|config| {
config
.features
.enable(Feature::Sqlite)
.expect("test config should allow feature update");
config
.features
.enable(Feature::BuiltInMcp)
.expect("test config should allow feature update");
config
.features
.enable(Feature::MemoryTool)
.expect("test config should allow feature update");
config.memories.use_memories = true;
config.memories.disable_on_external_context = true;
});
let test = builder.build(&server).await?;
let db = test.codex.state_db().expect("state db enabled");
let thread_id = test.session_configured.thread_id;
let cwd = test.cwd_path().to_path_buf();
let (sandbox_policy, permission_profile) =
turn_permission_fields(PermissionProfile::read_only(), cwd.as_path());
test.codex
.submit(Op::UserTurn {
environments: None,
items: vec![UserInput::Text {
text: "call the memories list tool".to_string(),
text_elements: Vec::new(),
}],
final_output_json_schema: None,
cwd,
approval_policy: AskForApproval::Never,
approvals_reviewer: None,
sandbox_policy,
permission_profile,
model: test.session_configured.model.clone(),
effort: None,
summary: None,
service_tier: None,
collaboration_mode: None,
personality: None,
})
.await?;
wait_for_event(&test.codex, |event| {
matches!(event, EventMsg::McpToolCallEnd(_))
})
.await;
wait_for_event_match(&test.codex, |event| match event {
EventMsg::Error(err) => Some(Err(anyhow::anyhow!(err.message.clone()))),
EventMsg::TurnComplete(_) => Some(Ok(())),
_ => None,
})
.await?;
assert_ne!(
db.get_thread_memory_mode(thread_id).await?.as_deref(),
Some("polluted")
);
Ok(())
}
#[tokio::test(flavor = "current_thread")]
async fn tool_call_logs_include_thread_id() -> Result<()> {
let server = start_mock_server().await;
+1 -9
View File
@@ -134,8 +134,6 @@ pub enum Feature {
Sqlite,
/// Enable startup memory extraction and file-backed memory consolidation.
MemoryTool,
/// Enable product-owned built-in MCP servers.
BuiltInMcp,
/// Enable the Chronicle sidecar for passive screen-context memories.
Chronicle,
/// Append additional AGENTS.md guidance to user instructions.
@@ -152,7 +150,7 @@ pub enum Feature {
Apps,
/// Enable MCP apps.
EnableMcpApps,
/// Use the new path for the built-in apps MCP server.
/// Use the new path for the host-owned apps MCP server.
AppsMcpPathOverride,
/// Enable the tool_search tool for apps.
ToolSearch,
@@ -797,12 +795,6 @@ pub const FEATURES: &[FeatureSpec] = &[
},
default_enabled: false,
},
FeatureSpec {
id: Feature::BuiltInMcp,
key: "builtin_mcp",
stage: Stage::UnderDevelopment,
default_enabled: false,
},
FeatureSpec {
id: Feature::Chronicle,
key: "chronicle",
-7
View File
@@ -145,13 +145,6 @@ fn responses_websocket_response_processed_is_under_development() {
);
}
#[test]
fn builtin_mcp_is_under_development() {
assert_eq!(Feature::BuiltInMcp.stage(), Stage::UnderDevelopment);
assert_eq!(Feature::BuiltInMcp.default_enabled(), false);
assert_eq!(feature_for_key("builtin_mcp"), Some(Feature::BuiltInMcp));
}
#[test]
fn terminal_resize_reflow_is_experimental_and_enabled_by_default() {
assert_eq!(
+2 -2
View File
@@ -10,8 +10,8 @@ Runtime orchestration for Phase 1 and Phase 2 still lives in `codex-core` under
- `codex-rs/memories/read` (`codex-memories-read`) owns the read path:
memory developer-instruction injection, memory citation parsing, and
read-usage telemetry classification.
- `codex-rs/memories/mcp` (`codex-memories-mcp`) exposes the read-only memory
filesystem through the built-in MCP surface.
- `codex-rs/memories/mcp` (`codex-memories-mcp`) owns the read-only memory
filesystem MCP server implementation.
- `codex-rs/memories/write` (`codex-memories-write`) owns the write path:
Phase 1 and Phase 2 prompt rendering, filesystem artifact helpers,
workspace diff helpers, and extension resource pruning.