You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Force On MCP servers reach Owners outside the server's ACL #30652
#27944 says "Force On respects the ACL: the forced set is loaded as the chat owner, so a force_on server whose ACL denies the owner never attaches". The forced set is filtered through the owner's RBAC, though, and a site Owner (or an org admin) can read every MCP server config. So a Force On server shared with a single user is forced onto every Owner's chats as well.
The web UI has the same gap for Default On: getDefaultMCPSelection and getSavedMCPSelection select every Force On and Default On server the user can list, and an Owner lists them all.
Steps to reproduce (v2.38.0)
As an Owner, create an MCP server config with availability: force_on.
PATCH /api/v2/organizations/{org}/mcp-servers/{id}/acl with {"user_roles": {"<user A>": "read"}, "group_roles": {"<org ID>": ""}}: shared with user A only, Everyone removed.
As a different Owner, start a chat from the web UI or with POST /api/v2/chats and no mcp_server_ids.
Expected: the chat does not get the server, since its ACL does not name that Owner.
Actual: the chat's mcp_server_ids holds the server and its tools are offered to the model. With default_on instead of force_on, the web UI pre-selects the server for the Owner.
Where
coderd/x/chatd/chatd.go, forcedMCPServerConfigsForOwner: GetForcedMCPServerConfigsByOrganization runs as the owner's RBAC subject. Owner roles grant read on every config, so the ACL is never consulted.
site/src/pages/AgentsPage/utils/mcpSelection.ts: selection is by availability alone.
Suggested fix
Evaluate Force On (and the UI's Default On pre-selection) against the ACL's own principals: the owner's user ID, their groups, and the organization's Everyone group. RBAC read would no longer count. Owners keep managing and reading every config; they only stop getting servers forced or pre-selected that are not shared with them. For the UI, a per-caller field on MCPServerConfig, such as acl_granted, would let the chat input skip those servers.
We run this in a fork and can open a PR if the approach suits you.
Activity
linear-code commentedon Oct 12, 2026
ENG-3463