Reuse stable MCP bindings across sampling steps (#37101)

## What changed

- Cache an `McpBinding` on each published MCP runtime once server startup has
  settled and the tool catalog revision is stable.
- Reuse the cached binding while the catalog revision remains unchanged, and
  rebuild it after a runtime publish or catalog change.
- Treat terminal failures from optional servers as stable, while continuing to
  wait for required servers and reconnecting Codex Apps servers.

## Testing

- Cover binding reuse within one published runtime and invalidation after a
  republish.
- Cover stability checks for pending, failed optional, required, and
  reconnected servers.

GitOrigin-RevId: 783a6b04897f6c484a6d56fd9cee542814041759
This commit is contained in:
jif authored and copyberry committed 2026-08-05 14:04:39 +00:00
1 parent 5c44f11064
commit 952e87d3f2
6 files changed
+174 -14

No files matched your search

+18
View File
@@ -492,6 +492,24 @@ impl AsyncManagedClient {
self.client.clone().await
}
pub(crate) fn ready_transport(&self) -> Option<Arc<RmcpClient>> {
let recovered = self.startup_reconnect.as_ref().and_then(|reconnect| {
reconnect
.state
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.current_client
.as_ref()
.map(|client| Arc::clone(&client.client))
});
recovered.or_else(|| {
self.client
.peek()
.and_then(|result| result.as_ref().ok())
.map(|client| Arc::clone(&client.client))
})
}
pub(crate) async fn reconnect_failed_startup(&self) {
let Some(startup_reconnect) = self.startup_reconnect.as_ref() else {
return;