Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
080d871
Refine MCP explicit environment candidate
starr-openai May 19, 2026
e2b7fc9
Fix duplicate MCP environment field
starr-openai May 19, 2026
ab444d9
Pass MCP runtime context env manager by arc
starr-openai May 19, 2026
60a4f5f
Pass plugin connector env manager by arc
starr-openai May 19, 2026
9d58222
Clarify MCP status env reporting
starr-openai May 19, 2026
3b8b6b1
test app-server MCP environment matrix
starr-openai May 20, 2026
8831901
Clarify threadless MCP comments
starr-openai May 20, 2026
ee19ab9
Clarify MCP default environment
starr-openai May 20, 2026
5a5a758
Normalize MCP environment ids
starr-openai May 20, 2026
ca44cdf
Preserve legacy MCP environment alias
starr-openai May 20, 2026
dda4556
Populate MCP status test environments
starr-openai May 20, 2026
c08a905
Avoid MCP runtime result equality
starr-openai May 20, 2026
984b700
Fix MCP environment CI test setup
starr-openai May 20, 2026
bc85985
codex: fix CI failure on PR #23583
starr-openai May 20, 2026
7def3d4
codex: fix CI failure on PR #23583
starr-openai May 20, 2026
7e2c41d
codex: fix CI failure on PR #23583
starr-openai May 20, 2026
50376bd
codex: simplify MCP stdio environment launch
starr-openai May 20, 2026
406ceba
codex: centralize MCP local environment default
starr-openai May 20, 2026
8ed88b5
codex: restore local MCP stdio launcher
starr-openai May 20, 2026
726ff39
codex: remove dead MCP env residue
starr-openai May 20, 2026
89b33cc
Model MCP runtime placement explicitly
starr-openai May 20, 2026
8bc1eee
codex: remove MCP expect calls
starr-openai May 21, 2026
a6bd6d3
codex: fix MCP config round-trip test
starr-openai May 21, 2026
78130db
codex: simplify MCP runtime environment routing
starr-openai May 21, 2026
a3aaddc
codex: narrow MCP stdio cwd fallback
starr-openai May 21, 2026
32798e8
codex: reuse MCP local environment constant
starr-openai May 21, 2026
563988c
codex: fix PR 23583 CI compile errors
starr-openai May 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions codex-rs/app-server/src/request_processors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,12 +340,11 @@ use codex_login::complete_device_code_login;
use codex_login::login_with_api_key;
use codex_login::request_device_code;
use codex_login::run_login_server;
use codex_mcp::McpRuntimeEnvironment;
use codex_mcp::McpRuntimeContext;
use codex_mcp::McpServerStatusSnapshot;
use codex_mcp::McpSnapshotDetail;
use codex_mcp::collect_mcp_server_status_snapshot_with_detail;
use codex_mcp::discover_supported_scopes;
use codex_mcp::effective_mcp_servers;
use codex_mcp::read_mcp_resource as read_mcp_resource_without_thread;
use codex_mcp::resolve_oauth_scopes;
use codex_memories_write::clear_memory_roots_contents;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl AppsRequestProcessor {
connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager(
&accessible_config,
force_refetch,
&environment_manager,
Arc::clone(&environment_manager),
)
.await
.map_err(|err| format!("failed to load accessible apps: {err}"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ impl ConfigRequestProcessor {
connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager(
&config,
/*force_refetch*/ true,
&environment_manager,
Arc::clone(&environment_manager),
),
);
let all_connectors = match all_connectors_result {
Expand Down
64 changes: 24 additions & 40 deletions codex-rs/app-server/src/request_processors/mcp_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,24 +205,20 @@ impl McpRequestProcessor {
.await;
let auth = self.auth_manager.auth().await;
let environment_manager = self.thread_manager.environment_manager();
// Status listing has no turn cwd. Prefer the configured default env,
// then configured local if present; do not manufacture a hidden local
// env in no-local modes.
let runtime_environment = McpRuntimeEnvironment::new(
environment_manager.default_or_local_environment(),
environment_manager.try_local_environment(),
config.cwd.to_path_buf(),
);
// This threadless status path has no turn cwd or turn-selected
// environment. Use config cwd only as the local stdio fallback; named
// environment stdio MCPs must declare their own absolute cwd.
let runtime_context =
McpRuntimeContext::new(Arc::clone(&environment_manager), config.cwd.to_path_buf());

tokio::spawn(async move {
Self::list_mcp_server_status_task(
outgoing,
request,
params,
config,
mcp_config,
auth,
runtime_environment,
runtime_context,
)
.await;
});
Expand All @@ -233,18 +229,16 @@ impl McpRequestProcessor {
outgoing: Arc<OutgoingMessageSender>,
request_id: ConnectionRequestId,
params: ListMcpServerStatusParams,
config: Config,
mcp_config: codex_mcp::McpConfig,
auth: Option<CodexAuth>,
runtime_environment: McpRuntimeEnvironment,
runtime_context: McpRuntimeContext,
) {
let result = Self::list_mcp_server_status_response(
request_id.request_id.to_string(),
params,
config,
mcp_config,
auth,
runtime_environment,
runtime_context,
)
.await;
outgoing.send_result(request_id, result).await;
Expand All @@ -253,10 +247,9 @@ impl McpRequestProcessor {
async fn list_mcp_server_status_response(
request_id: String,
params: ListMcpServerStatusParams,
config: Config,
mcp_config: codex_mcp::McpConfig,
auth: Option<CodexAuth>,
runtime_environment: McpRuntimeEnvironment,
runtime_context: McpRuntimeContext,
) -> Result<ListMcpServerStatusResponse, JSONRPCErrorError> {
let detail = match params.detail.unwrap_or(McpServerStatusDetail::Full) {
McpServerStatusDetail::Full => McpSnapshotDetail::Full,
Expand All @@ -267,31 +260,25 @@ impl McpRequestProcessor {
&mcp_config,
auth.as_ref(),
request_id,
runtime_environment,
runtime_context,
detail,
)
.await;

let effective_servers = effective_mcp_servers(&mcp_config, auth.as_ref());
let McpServerStatusSnapshot {
tools_by_server,
resources,
resource_templates,
auth_statuses,
mut server_names,
} = snapshot;

let mut server_names: Vec<String> = config
.mcp_servers
.keys()
.cloned()
// 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())
.chain(auth_statuses.keys().cloned())
.chain(resources.keys().cloned())
.chain(resource_templates.keys().cloned())
.collect();
server_names.extend(
auth_statuses
.keys()
.cloned()
.chain(resources.keys().cloned())
.chain(resource_templates.keys().cloned()),
);
server_names.sort();
server_names.dedup();

Expand Down Expand Up @@ -367,21 +354,18 @@ impl McpRequestProcessor {
.await;
let auth = self.auth_manager.auth().await;
let environment_manager = self.thread_manager.environment_manager();
// Resource reads without a thread have no turn cwd. Prefer the
// configured default env, then configured local if present; do not
// manufacture a hidden local env in no-local modes.
let runtime_environment = McpRuntimeEnvironment::new(
environment_manager.default_or_local_environment(),
environment_manager.try_local_environment(),
config.cwd.to_path_buf(),
);
// This threadless resource-read path has no turn cwd or turn-selected
// environment. Use config cwd only as the local stdio fallback; named
// environment stdio MCPs must declare their own absolute cwd.
let runtime_context =
McpRuntimeContext::new(Arc::clone(&environment_manager), config.cwd.to_path_buf());
let request_id = request_id.clone();

tokio::spawn(async move {
let result = read_mcp_resource_without_thread(
&mcp_config,
auth.as_ref(),
runtime_environment,
runtime_context,
&server,
&uri,
)
Expand Down
21 changes: 14 additions & 7 deletions codex-rs/app-server/src/request_processors/plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,9 +959,12 @@ impl PluginRequestProcessor {
None => None,
};
let environment_manager = self.thread_manager.environment_manager();
let app_summaries =
load_plugin_app_summaries(&config, &outcome.plugin.apps, &environment_manager)
.await;
let app_summaries = load_plugin_app_summaries(
&config,
&outcome.plugin.apps,
Arc::clone(&environment_manager),
)
.await;
let visible_skills = outcome
.plugin
.skills
Expand Down Expand Up @@ -1037,8 +1040,12 @@ impl PluginRequestProcessor {
.map(codex_plugin::AppConnectorId)
.collect::<Vec<_>>();
let environment_manager = self.thread_manager.environment_manager();
let app_summaries =
load_plugin_app_summaries(&config, &plugin_apps, &environment_manager).await;
let app_summaries = load_plugin_app_summaries(
&config,
&plugin_apps,
Arc::clone(&environment_manager),
)
.await;
remote_plugin_detail_to_info(remote_detail, app_summaries)
}
};
Expand Down Expand Up @@ -1506,7 +1513,7 @@ impl PluginRequestProcessor {
connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager(
config,
/*force_refetch*/ true,
&environment_manager
Arc::clone(&environment_manager)
),
);

Expand Down Expand Up @@ -1772,7 +1779,7 @@ impl PluginRequestProcessor {
async fn load_plugin_app_summaries(
config: &Config,
plugin_apps: &[codex_plugin::AppConnectorId],
environment_manager: &EnvironmentManager,
environment_manager: Arc<EnvironmentManager>,
) -> Vec<AppSummary> {
if plugin_apps.is_empty() {
return Vec::new();
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/cli/src/mcp_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ async fn run_add(config_overrides: &CliConfigOverrides, add_args: AddArgs) -> Re

let new_entry = McpServerConfig {
transport: transport.clone(),
experimental_environment: None,
environment_id: codex_config::DEFAULT_MCP_SERVER_ENVIRONMENT_ID.to_string(),
enabled: true,
required: false,
supports_parallel_tool_calls: false,
Expand Down
6 changes: 3 additions & 3 deletions codex-rs/codex-mcp/src/connection_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::rmcp_client::MCP_TOOLS_LIST_DURATION_METRIC;
use crate::rmcp_client::ManagedClient;
use crate::rmcp_client::StartupOutcomeError;
use crate::rmcp_client::list_tools_for_client_uncached;
use crate::runtime::McpRuntimeEnvironment;
use crate::runtime::McpRuntimeContext;
use crate::runtime::emit_duration;
use crate::server::EffectiveMcpServer;
use crate::server::McpServerMetadata;
Expand Down Expand Up @@ -176,7 +176,7 @@ impl McpConnectionManager {
submit_id: String,
tx_event: Sender<Event>,
initial_permission_profile: PermissionProfile,
runtime_environment: McpRuntimeEnvironment,
runtime_context: McpRuntimeContext,
codex_home: PathBuf,
codex_apps_tools_cache_key: CodexAppsToolsCacheKey,
host_owned_codex_apps_enabled: bool,
Expand Down Expand Up @@ -248,7 +248,7 @@ impl McpConnectionManager {
elicitation_requests.clone(),
codex_apps_tools_cache_context,
Arc::clone(&tool_plugin_provenance),
runtime_environment.clone(),
runtime_context.clone(),
runtime_auth_provider,
client_elicitation_capability.clone(),
);
Expand Down
14 changes: 7 additions & 7 deletions codex-rs/codex-mcp/src/connection_manager_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::tools::normalize_tools_for_model;
use crate::tools::tool_with_model_visible_input_schema;
use codex_config::Constrained;
use codex_config::McpServerConfig;
use codex_exec_server::EnvironmentManager;
use codex_protocol::ToolName;
use codex_protocol::models::PermissionProfile;
use codex_protocol::protocol::GranularApprovalConfig;
Expand Down Expand Up @@ -864,7 +865,7 @@ async fn no_local_runtime_fails_local_stdio_but_keeps_local_http_server() {
env_vars: Vec::new(),
cwd: None,
},
experimental_environment: None,
environment_id: codex_config::DEFAULT_MCP_SERVER_ENVIRONMENT_ID.to_string(),
enabled: true,
required: false,
supports_parallel_tool_calls: false,
Expand All @@ -889,7 +890,7 @@ async fn no_local_runtime_fails_local_stdio_but_keeps_local_http_server() {
http_headers: None,
env_http_headers: None,
},
experimental_environment: None,
environment_id: codex_config::DEFAULT_MCP_SERVER_ENVIRONMENT_ID.to_string(),
enabled: true,
required: false,
supports_parallel_tool_calls: false,
Expand All @@ -915,9 +916,8 @@ async fn no_local_runtime_fails_local_stdio_but_keeps_local_http_server() {
String::new(),
tx_event,
PermissionProfile::default(),
McpRuntimeEnvironment::new(
/*environment*/ None,
/*local_environment*/ None,
McpRuntimeContext::new(
Arc::new(EnvironmentManager::without_environments()),
PathBuf::from("/tmp"),
),
codex_home.path().to_path_buf(),
Expand Down Expand Up @@ -988,7 +988,7 @@ fn mcp_init_error_display_prompts_for_github_pat() {
http_headers: None,
env_http_headers: None,
},
experimental_environment: None,
environment_id: codex_config::DEFAULT_MCP_SERVER_ENVIRONMENT_ID.to_string(),
enabled: true,
required: false,
supports_parallel_tool_calls: false,
Expand Down Expand Up @@ -1041,7 +1041,7 @@ fn mcp_init_error_display_reports_generic_errors() {
http_headers: None,
env_http_headers: None,
},
experimental_environment: None,
environment_id: codex_config::DEFAULT_MCP_SERVER_ENVIRONMENT_ID.to_string(),
enabled: true,
required: false,
supports_parallel_tool_calls: false,
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/codex-mcp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub use elicitation::ElicitationReviewRequest;
pub use elicitation::ElicitationReviewer;
pub use elicitation::ElicitationReviewerHandle;
pub use rmcp_client::MCP_SANDBOX_STATE_META_CAPABILITY;
pub use runtime::McpRuntimeEnvironment;
pub use runtime::McpRuntimeContext;
pub use runtime::SandboxState;
pub use tools::ToolInfo;

Expand Down
Loading
Loading