mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Activate selected executor plugin MCPs in app-server (#27893)
## Why #27870 teaches the MCP extension how to discover stdio MCP servers declared by a selected executor plugin, but app-server does not yet install that contributor or initialize its per-thread state. As a result, `thread/start.selectedCapabilityRoots` can select the plugin while its MCP servers remain inactive. This PR closes that app-server wiring gap: ```text thread/start(selectedCapabilityRoots) -> initialize the thread's selected-plugin MCP snapshot -> read the selected plugin's .mcp.json through its environment -> start declared stdio servers in that environment -> expose their tools only on the selected thread ``` ## What changed - Install the selected-executor-plugin MCP contributor in app-server using the existing shared `EnvironmentManager`. - Initialize its frozen thread snapshot when `thread/start` includes selected capability roots. - Document that selected plugin stdio MCPs are activated in their owning environment. - Add an app-server E2E covering the complete selection-to-tool-call path. The E2E verifies that: - the selected MCP process receives an executor-only environment value, proving the tool runs through the selected environment; - the MCP tool is advertised to the model and can be called; - a normal MCP config reload does not discard the thread's frozen selected-plugin registration; - another thread without the selected root does not see the MCP server. ## Scope - Existing sessions without `selectedCapabilityRoots` are unchanged. - Only stdio MCP declarations are activated. HTTP declarations remain inactive. - This does not change selected-root persistence across resume/fork or add hosted-plugin behavior. ## Verification - Focused app-server E2E: `selected_executor_plugin_exposes_its_stdio_mcp_only_to_that_thread` ## Stack Stacked on #27870.
This commit is contained in:
@@ -9,6 +9,7 @@ use codex_core::NewThread;
|
||||
use codex_core::StartThreadOptions;
|
||||
use codex_core::ThreadManager;
|
||||
use codex_core::config::Config;
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_extension_api::AgentSpawnFuture;
|
||||
use codex_extension_api::AgentSpawner;
|
||||
use codex_extension_api::ExtensionEventSink;
|
||||
@@ -27,9 +28,6 @@ use crate::outgoing_message::OutgoingMessageSender;
|
||||
use crate::thread_state::ThreadListenerCommand;
|
||||
use crate::thread_state::ThreadStateManager;
|
||||
|
||||
// TODO(jif): Enable once /ps/mcp serves complete hosted skill packages.
|
||||
const ORCHESTRATOR_SKILLS_ENABLED: bool = false;
|
||||
|
||||
pub(crate) struct ThreadExtensionDependencies {
|
||||
pub(crate) event_sink: Arc<dyn ExtensionEventSink>,
|
||||
pub(crate) auth_manager: Arc<AuthManager>,
|
||||
@@ -37,6 +35,7 @@ pub(crate) struct ThreadExtensionDependencies {
|
||||
pub(crate) analytics_events_client: AnalyticsEventsClient,
|
||||
pub(crate) thread_manager: Weak<ThreadManager>,
|
||||
pub(crate) goal_service: Arc<GoalService>,
|
||||
pub(crate) environment_manager: Arc<EnvironmentManager>,
|
||||
pub(crate) executor_skill_provider: Arc<dyn codex_skills_extension::SkillProvider>,
|
||||
/// Process-scoped persistence backend for extensions that need stored thread history.
|
||||
pub(crate) thread_store: Arc<dyn ThreadStore>,
|
||||
@@ -56,6 +55,7 @@ where
|
||||
analytics_events_client,
|
||||
thread_manager,
|
||||
goal_service,
|
||||
environment_manager,
|
||||
executor_skill_provider,
|
||||
thread_store: _thread_store,
|
||||
} = dependencies;
|
||||
@@ -74,15 +74,14 @@ where
|
||||
codex_guardian::install(&mut builder, guardian_agent_spawner);
|
||||
codex_memories_extension::install(&mut builder, codex_otel::global());
|
||||
codex_mcp_extension::install(&mut builder);
|
||||
codex_mcp_extension::install_executor_plugins(&mut builder, environment_manager);
|
||||
codex_web_search_extension::install(&mut builder, auth_manager.clone());
|
||||
codex_image_generation_extension::install(&mut builder, auth_manager);
|
||||
let mut skill_providers = codex_skills_extension::SkillProviders::new()
|
||||
.with_executor_provider(executor_skill_provider);
|
||||
if ORCHESTRATOR_SKILLS_ENABLED {
|
||||
skill_providers = skill_providers.with_orchestrator_provider(Arc::new(
|
||||
let skill_providers = codex_skills_extension::SkillProviders::new()
|
||||
.with_executor_provider(executor_skill_provider)
|
||||
.with_orchestrator_provider(Arc::new(
|
||||
codex_skills_extension::OrchestratorSkillProvider::new(),
|
||||
));
|
||||
}
|
||||
codex_skills_extension::install_with_providers(
|
||||
&mut builder,
|
||||
skill_providers,
|
||||
|
||||
Reference in New Issue
Block a user