Refresh MCP runtimes across thread startup (#35204)

## Why

MCP configuration can change while a thread is still starting, before it appears in the thread manager's loaded-thread list. In that window, invalidation could miss the new thread and leave it with a stale MCP runtime.

## What changed

- Centralize MCP runtime invalidation in `ThreadManager` so it refreshes loaded threads and marks in-progress thread startups for refresh after publication.
- Use the centralized invalidation path for account and plugin changes.
- Invalidate MCP runtimes after successful server and plugin OAuth logins.

## Testing

- Add a regression test that pauses thread startup, invalidates MCP runtimes, and verifies that the newly published thread refreshes its MCP projection.

GitOrigin-RevId: 8944f5a21816a1405e038a0d4c08b66362ea9368
This commit is contained in:
jif authored and copyberry committed 2026-07-24 15:06:02 +00:00
1 parent fe8500c0a0
commit 3645a4397c
8 files changed
+154 -39

No files matched your search

@@ -201,12 +201,16 @@ impl McpRequestProcessor {
let notification_name = name.clone();
let notification_thread_id = thread_id;
let outgoing = Arc::clone(&self.outgoing);
let thread_manager = Arc::clone(&self.thread_manager);
tokio::spawn(async move {
let (success, error) = match handle.wait().await {
Ok(()) => (true, None),
Err(err) => (false, Some(err.to_string())),
};
if success {
thread_manager.invalidate_mcp_runtimes().await;
}
let notification = ServerNotification::McpServerOauthLoginCompleted(
McpServerOauthLoginCompletedNotification {