mirror of
https://github.com/coder/coder.git
synced 2026-09-01 14:53:15 +08:00
35cbca080e
## Summary Adds the missing user-facing half of MCP server config ACLs: admins can now share an MCP server with individual users and groups from the UI, backed by a new permission-safe candidate-discovery endpoint. ## Problem The MCP server config ACL backend already existed (share RBAC action, hydrated `GET .../acl`, sparse `PATCH .../acl`), but there was no frontend for it. There was also no way to populate a sharing autocomplete without the generic organization member/group APIs, which require `organization_member:read` and `group:read` and would wrongly couple MCP sharing to the workspace-sharing mode (the same bug fixed for chat models in #28542). ## Changes Backend: - New v2-only `GET /api/v2/organizations/{organization}/mcp-servers/{mcpserverconfig}/acl/available` returning `codersdk.ACLAvailable`; because this API is new, it is not mounted under the experimental compatibility prefix. Gated on `ActionShare` for the specific server config; performs bounded org-scoped member/group lookups via `dbauthz.AsSystemRestricted`; excludes system users; supports `q`, `limit`, `offset`, and `after_id` with template/chat-model autocomplete semantics. - Tests cover authorization (404 without share), search, pagination, system-user exclusion, org scoping, and a share-only custom role under all three workspace-sharing modes (`none`, `service_accounts`, `everyone`). Frontend: - `shareMCPServerConfig` permission plumbing; the MCP servers list, details page, and AI settings sidebar now admit share-only users (share does not require update; share-only users cannot edit the server form). - Share-only access follows the established permission contract: a bare-share role manages sharing through the list and ACL endpoints (the detail route still requires read, update, or delete, matching the existing enterprise permission-matrix tests), and the disabled-config gate now also admits the share permission so a sharer with read access can open a disabled server. Top-level navigation (Admin settings menu and the /ai/settings index redirect) discovers organization-level MCP sharers and surfaces permission lookup failures instead of silently falling back. - "Share server" action on the MCP server edit page opening a sharing dialog: hydrated ACL grants render from the `GET .../acl` response, adds/removals are saved as sparse `PATCH` deltas (`"read"` / `""`). - Principal autocomplete backed exclusively by the new `/acl/available` endpoint; the sharing flow never calls the generic org member/group APIs (Storybook enforces this by rejecting those API spies). A discovery error surfaces under the autocomplete without hiding existing grants. - Storybook interaction coverage for the dialog (hydrated rendering, add/remove, sparse deltas, error/cancel/reopen paths, autocomplete exclusion and failure) and share-only access to the page/form. Dogfood UAT ran remotely against a dev instance and passed, including verifying via the network log that candidate discovery only hits `/acl/available`. The share-only custom role UI flow could not be exercised there (no premium license on the dev instance); it is covered by the backend permission-matrix tests. > 🤖 This PR was authored by Xum (an AI coding agent) acting on Mike's behalf.