Bind MCP calls to captured catalog revisions (#34588)

## Why

An MCP connection or tool catalog can change after a model step captures its
available tools. Calls from that step must not be rerouted to a replacement
client or run against a catalog revision the model did not see.

## What changed

- Add `McpBinding` to capture the ready clients, visible tools, resources, and
  server metadata for one sampling request.
- Prepare calls against the captured client and reject them if the tool catalog
  changes before call preparation and execution finish.
- Keep resource access and cache identity tied to the binding's exact connection
  set, and omit servers that do not have a ready client.
- Preserve each client's unfiltered tool catalog so bindings can apply the
  current filter consistently.

## Testing

Add coverage for connection replacement, stale catalog rejection, serialized
call preparation and refresh, ready-client capture, and binding-scoped resource
identity.

GitOrigin-RevId: a25da4d2c7f5ed06c41caa0c6d15c464c1698314
This commit is contained in:
jif authored and copyberry committed 2026-07-21 18:13:41 +00:00
1 parent 51200321eb
commit 65f8bf6853
11 files changed
+1495 -51

No files matched your search

+1 -1
View File
@@ -696,4 +696,4 @@ async fn collect_mcp_server_status_snapshot_from_manager(
#[cfg(test)]
#[path = "mod_tests.rs"]
mod tests;
pub(crate) mod tests;
+1 -1
View File
@@ -17,7 +17,7 @@ use std::collections::HashMap;
use std::collections::HashSet;
use std::path::PathBuf;
fn test_mcp_config(codex_home: PathBuf) -> McpConfig {
pub(crate) fn test_mcp_config(codex_home: PathBuf) -> McpConfig {
McpConfig {
chatgpt_base_url: "https://chatgpt.com".to_string(),
apps_mcp_product_sku: None,