Use MCP bindings as the step tool catalog (#36360)

## What changed

- Read the frozen MCP tool catalog directly from the step-scoped `McpBinding`
  when building tool routers, plugin injections, and connector state.
- Remove the redundant `Vec<ToolInfo>` from `StepContext` and stop returning a
  duplicate catalog from `built_tools`.

GitOrigin-RevId: d12d694e1224da3f6ccb1960868491f0d80c6e19
This commit is contained in:
jif
2026-07-31 16:35:14 +00:00
committed by copyberry
parent d97cb0dcad
commit 385fe95ce1
5 changed files with 11 additions and 19 deletions
+1 -2
View File
@@ -3105,7 +3105,7 @@ impl Session {
}
.or_cancel(cancellation_token)
.await?;
let (mcp_tools, tool_router) = turn::built_tools(
let tool_router = turn::built_tools(
self.as_ref(),
turn_context.as_ref(),
&environments,
@@ -3121,7 +3121,6 @@ impl Session {
selected_capability_roots,
executor_capability_discovery,
mcp,
mcp_tools,
tool_router,
loaded_agents_md,
}))
@@ -7,7 +7,6 @@ use crate::tools::router::ToolRouter;
use codex_exec_server::ExecutorCapabilityDiscoverySnapshot;
use codex_exec_server::ResolvedSelectedCapabilityRoot;
use codex_mcp::McpBinding;
use codex_mcp::ToolInfo;
/// Request-scoped state that may change between model sampling requests.
pub(crate) struct StepContext {
@@ -19,8 +18,6 @@ pub(crate) struct StepContext {
pub(crate) executor_capability_discovery: Option<Arc<ExecutorCapabilityDiscoverySnapshot>>,
/// The exact MCP connections, configuration, and catalog captured for this step.
pub(crate) mcp: Arc<McpBinding>,
/// The fixed MCP tool list used for this exact sampling request.
pub(crate) mcp_tools: Vec<ToolInfo>,
/// The finalized tool plan advertised and executed for this exact sampling request.
pub(crate) tool_router: Arc<ToolRouter>,
/// The canonical AGENTS.md value observed with this environment snapshot.
-1
View File
@@ -217,7 +217,6 @@ impl StepContext {
mcp: Arc::new(codex_mcp::McpBinding::empty(mcp_config_for_test(
&turn.config,
))),
mcp_tools: Vec::new(),
tool_router: Arc::new(ToolRouter::from_parts(
ToolRegistry::empty_for_test(),
Vec::new(),
+9 -12
View File
@@ -80,7 +80,6 @@ use codex_features::Feature;
use codex_file_system::FindUpErrorPolicy;
use codex_file_system::find_nearest_ancestor_with_markers;
use codex_login::CodexAuth;
use codex_mcp::ToolInfo;
use codex_protocol::ResponseItemId;
use codex_protocol::config_types::AutoCompactTokenLimitScope;
use codex_protocol::config_types::ModeKind;
@@ -742,9 +741,9 @@ async fn build_skills_and_plugins(
// Plugin mentions need raw MCP/app inventory even when app tools
// are normally hidden so we can describe the plugin's currently
// usable capabilities for this turn.
step_context.mcp.tools().to_vec()
step_context.mcp.tools()
} else {
Vec::new()
&[]
};
let available_connectors = if turn_context.apps_enabled() {
let connectors = codex_connectors::merge::merge_plugin_connectors_with_accessible(
@@ -752,7 +751,7 @@ async fn build_skills_and_plugins(
.connector_ids()
.iter()
.map(|connector_id| connector_id.0.clone()),
connectors::accessible_connectors_from_mcp_tools(&mcp_tools),
connectors::accessible_connectors_from_mcp_tools(mcp_tools),
);
connectors::with_app_enabled_state(connectors, &turn_context.config)
} else {
@@ -809,8 +808,7 @@ async fn build_skills_and_plugins(
&available_connectors,
&skill_name_counts_lower,
);
let plugin_items =
build_plugin_injections(mentioned_plugins, &mcp_tools, &available_connectors);
let plugin_items = build_plugin_injections(mentioned_plugins, mcp_tools, &available_connectors);
let mut explicitly_enabled_connectors = collect_explicit_app_ids(user_input);
explicitly_enabled_connectors.extend(skill_connector_ids);
let connector_names_by_id = available_connectors
@@ -1469,13 +1467,13 @@ pub(crate) async fn built_tools(
mcp: &codex_mcp::McpBinding,
step_store: &ExtensionData,
prepared_recommendations: PreparedToolRecommendations,
) -> (Vec<ToolInfo>, Arc<ToolRouter>) {
let all_mcp_tools = mcp.tools().to_vec();
) -> Arc<ToolRouter> {
let all_mcp_tools = mcp.tools();
let connector_snapshot = mcp.config().connector_snapshot.clone();
let apps_enabled = turn_context.apps_enabled();
let accessible_connectors =
apps_enabled.then(|| connectors::accessible_connectors_from_mcp_tools(&all_mcp_tools));
apps_enabled.then(|| connectors::accessible_connectors_from_mcp_tools(all_mcp_tools));
let accessible_connectors_with_enabled_state =
accessible_connectors.as_ref().map(|connectors| {
connectors::with_app_enabled_state(connectors.clone(), &turn_context.config)
@@ -1551,7 +1549,7 @@ pub(crate) async fn built_tools(
.instrument(trace_span!("built_tools.load_discoverable_tools"))
.await
};
let tool_router = Arc::new(build_tool_router(
Arc::new(build_tool_router(
sess,
turn_context,
environments,
@@ -1559,8 +1557,7 @@ pub(crate) async fn built_tools(
connectors.as_deref(),
step_store,
tool_suggest_candidates.as_ref(),
));
(all_mcp_tools, tool_router)
))
}
#[derive(Debug)]
+1 -1
View File
@@ -168,7 +168,7 @@ impl Session {
let apps_available =
if turn_context.config.include_apps_instructions && turn_context.apps_enabled() {
connectors::with_app_enabled_state(
connectors::accessible_connectors_from_mcp_tools(&step_context.mcp_tools),
connectors::accessible_connectors_from_mcp_tools(step_context.mcp.tools()),
&turn_context.config,
)
.into_iter()