fix(mcp): make workspace config the canonical store for the disable toggle#114
Conversation
…oggle The context-bar MCP disable toggle lived only in React state: it was never sent to the backend, so runs still connected 'disabled' servers and the toggle silently reset on app restart. - WorkspaceConfig gains workspace-level disabled_mcp_servers (McpRef, serde default so old configs parse unchanged). The manager row's selected_mcp_servers keeps meaning the effective enabled set, so scheduled runs and Workspace Settings are untouched. - SessionContext is NOT extended: sessions only ever receive the derived enabled list. - workspace_update_session_mcp sanitizes the request (enabled and disabled kept disjoint), writes the enabled list to the session and both lists to the workspace config; the disabled list persists even when no manager row exists. - desired_workspace_context derives the enabled set from the config for general workspaces: manager-less workspaces keep the session's list minus config-disabled ids; the legacy session fallback applies only when a manager exists and the config records nothing. - WorkspaceSnapshot exposes disabled_mcp_server_ids with enabled-wins disjointness enforced at the read boundary; the bar rebuilds attached = enabled + disabled from the snapshot, prefers the config-derived list over a stale session list, and rolls back the optimistic update if the backend rejects it. - MCP rename/delete sweeps now refresh the workspace-level disabled refs; refresh_mcp_refs_after_rename also fixes a pre-existing bug where renaming a server dropped agent selections (old-name refs were resolved against the post-rename config and discarded). - workspace_update_agent re-enables servers re-selected for the manager by dropping them from the disabled list.
1a8dae5 to
4be48eb
Compare
Renames no longer require sweeping every workspace config; display names resolve from AppConfig at read time. Legacy name-only refs are dropped on load (users re-attach the server).
|
Follow-up commits per review discussion: c321a0d — refactor(mcp): store workspace MCP refs by server id
Scope note (verified): the context-bar disable toggle only affects the manager/session — Verification: cargo test 797/797, fmt clean, tsc clean, WorkspaceContextBar vitest 7/7. Two independent reviews: production_quality (minor doc-comment finding fixed in d2a62de). |
Replaces the workspace-level disabled_mcp_servers list (introduced earlier
on this branch, never shipped) with a disabled flag on McpRef: the manager
agent's selectedMcpServers now records every attached server, and
{"id": ..., "disabled": true} marks a context-bar toggle-off. Absent key
means enabled, so member agents and existing configs are untouched.
- descriptor/sessions/scheduled runs consume enabled refs only (new
enabled_mcp_ids helper); Settings surfaces keep showing all attached refs
- Settings saves preserve the toggle via merge_mcp_selection (attachment
and enablement are orthogonal)
- drops the disjointness invariant maintained in three places
- drops WorkspaceSnapshot.selectedMcpServerNames: the FE never read it and
already resolves names from ids
|
New commit 78117ef — refactor(mcp): record the disable toggle per-ref on the manager row (user-directed design):
Open design question (pre-dates this commit, present since 4be48eb): the legacy fallback in |
With the workspace config as the canonical store, a manager row with zero MCP refs now means zero MCP servers. The legacy fallback that kept a session's pre-mirror list alive is removed: a Settings remove-all clears live sessions immediately, and session-only selections from before the config mirror are dropped once (re-attach to migrate), matching the migration policy used when name-based refs were dropped.
The context bar duplicated the removed backend fallback: with both config partitions empty it displayed the session's MCP list and would re-persist it on the next edit, resurrecting servers a Settings remove-all had just cleared. It now falls back to the session list only for manager-less workspaces (defaultWorkspaceAgentId null), matching the backend rule. WorkspaceSettingsModal also dispatches workspace-settings-changed after a successful save (and agent delete) so the self-loading bar refetches its snapshot instead of holding stale local state.
|
Two new commits per the option-(a) decision (config strictly canonical): 58976fe — refactor(mcp): make an empty manager MCP selection authoritative 530400e — fix(mcp): mirror the authoritative empty selection in the context bar Verification: cargo 800/800, vitest 9/9 (3 new/updated context-bar tests), tsc + eslint clean. Independent review round 4: production_quality (round 3 needs_work findings both fixed and re-verified). |
Problem
The MCP disable toggle in the workspace context bar lived only in React state: it was never sent to the backend, so runs still connected 'disabled' servers, and the toggle silently reset on app restart.
Design (reworked after review discussion)
The per-workspace
.clai/config.jsonis the canonical store for a general workspace's MCP selection —SessionContextis not extended and only ever receives the derived enabled list.WorkspaceConfiggains workspace-leveldisabledMcpServers(by-nameMcpRef, serde default → old configs parse unchanged). The manager row'sselectedMcpServerskeeps meaning the effective enabled set, so scheduled runs and Workspace Settings are untouched.workspace_update_session_mcpsanitizes the request (enabled/disabled kept disjoint), writes the enabled list to the session and both lists to the config; the disabled list persists even with no manager row.desired_workspace_contextderives the enabled set from config for general workspaces; manager-less workspaces keep the session's list minus config-disabled ids; the legacy session fallback applies only when a manager exists and the config records nothing (pre-2026-05-19 sessions predate the config mirror).WorkspaceSnapshotexposesdisabledMcpServerIdswith enabled-wins disjointness enforced at the read boundary; the bar rebuilds attached = enabled ∪ disabled, prefers the config-derived list over a stale session list, and rolls back the optimistic update on backend rejection.refresh_mcp_refs_after_renamealso fixes a pre-existing bug where renaming a server dropped agent selections (old-name refs resolved against the post-rename config and discarded).workspace_update_agentre-enables servers re-selected for the manager by dropping them from the disabled list.Testing