fix: installing or connecting one MCP server no longer strips other servers' tools from the profile

connect_plugin_mcp and the connector flow call register_mcp_servers with only the
server they connect. The scope reconcile treated that dict as the profile's whole
config, so every other server in the profile looked removed and lost its overlay
while its connection stayed up: after onboarding installed nvidia-app then
nvidia-broadcast, the Plugins tab said nvidia-app was connected but no chat could
see its 12 tools. A name the caller omits is now judged against the profile's own
MCP config.
This commit is contained in:
alt-glitch
2026-09-23 11:10:30 +05:30
committed by Siddharth Balyan
parent c0d7294769
commit dbe2f6964d

View File

@@ -10,6 +10,7 @@ from dataclasses import dataclass
from types import SimpleNamespace
from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional
from tools.mcp_tool_common import _parse_boolish, _core, _resolve_tool_timeout, mcp_field, mcp_server_enabled
from tools import mcp_tool_config as _config
from tools import mcp_tool_handlers as _handlers
from tools import mcp_tool_schema as _schema
from tools.mcp_tool_handlers import (
@@ -461,13 +462,24 @@ def _register_connected_into_current_scope(servers: dict) -> int:
if scope is None:
return 0
# Callers that connect a subset (plugin go-live, a connector, orphan re-registration) pass only
# those names. A name they omit is judged against this profile's own config, or connecting one
# server would strip every other server's tools from the profile while their connections live on.
with _core._lock:
omitted = {_key_name(key) for key, scopes in _core._server_tool_scopes.items()
if scope in scopes and _key_name(key) not in servers}
profile_servers = _config._load_mcp_config() if omitted else {}
with _core._lock:
stale = []
for key, scopes in _core._server_tool_scopes.items():
if scope not in scopes:
continue
name = _key_name(key)
if name not in servers and name not in omitted:
continue # attached after the config read; the next pass judges it
server = _core._servers.get(key)
config = servers.get(_key_name(key))
config = servers[name] if name in servers else profile_servers.get(name)
cross_profile = _key_scope(key) != scope
if (config is None or not mcp_server_enabled(config) or server is None
or getattr(server, "session", None) is None