Expose cached MCP tools before server startup (#35590)

## Why

Cached MCP definitions can be supplied to inference without waiting for the
server to finish initializing.

## What changed

- Publish cached tools while startup is still in progress, clearing their
  potentially stale read-only hint.
- Wait for the selected server to start before executing a tool call, then
  prepare the call against the refreshed live binding.
- Keep cached tools visible in a binding even when no live client is available,
  while rejecting attempts to prepare those calls.

## Testing

- Cover cached-tool visibility before startup and replacement with live tool
  metadata afterward.
- Verify cached definitions reach inference before MCP initialization and that
  calls unavailable in the live catalog return the expected model-visible
  error.

GitOrigin-RevId: 3aae8f474c344ccdc5e08fe321bbad21d85bffd1
This commit is contained in:
jif
2026-07-27 10:25:32 +00:00
committed by copyberry
parent 95637f7056
commit 3bbf1fe757
6 changed files with 89 additions and 20 deletions
@@ -143,6 +143,19 @@ impl McpConnectionSet {
.startup_complete
.load(Ordering::Acquire)
{
if view.connection.client.has_cached_tools() {
if let Some(server_tools) =
view.listed_tools(&self.tool_plugin_provenance).await
{
listed_tools.extend(server_tools.into_iter().map(|mut tool| {
if let Some(annotations) = tool.tool.annotations.as_mut() {
annotations.read_only_hint = None;
}
Self::with_server_metadata(tool, &view.metadata)
}));
}
continue;
}
let _ = view.connection.client.client().await;
}
view.connection.client.reconnect_failed_startup().await;
@@ -186,6 +199,7 @@ impl McpConnectionSet {
continue;
}
let Some(client) = clients.client(&tool_info.server_name) else {
tools.push(tool_info);
continue;
};
let Some(call) = self.prepare_call(&tool_info, client, Arc::clone(&config), *revision)