ADR-0008: Per-User and Enterprise-Governed MCP Server Management
Context
MCP server installations were system-wide — when any user installed a server, it appeared for all users. The MCPServerConfig entity had no user_id field and no ownership concept, and MCP endpoints did not enforce authentication or authorization. There was no mechanism for enterprise administrators to govern which MCP servers their members could use.
ADR-0004 established the enterprise account model with roles (owner/admin/member) and personal vs organizational enterprises, but did not address resource scoping.
Decision
A two-layer scoping model for MCP server management:
-
Per-user scoping: Added
user_id(readOnly) andsource(enum: personal|enterprise, readOnly) toMCPServerConfig. All MCP CRUD operations are scoped to the authenticated user. When auth is disabled (local dev), operations fall back to unscoped behavior. -
Enterprise governance: New
EnterpriseMCPServerentity withenterprise_id,auto_enabledboolean, and standard server config fields. Enterprise admins (owner/admin roles) manage an approved list of servers. Servers markedauto_enabled: trueare mandatory for all enterprise members. -
Merged user view:
GET /v1/mcp-serversreturns the union of the user’s personal installations (source: personal) and enterprise auto-enabled servers (source: enterprise). Enterprise-sourced servers cannot be modified or deleted by members. -
Enterprise endpoints: Six new endpoints under
/v1/enterprise/mcp-serversfor CRUD + credentials. Write operations require owner/admin role. Read operations available to any authenticated enterprise member. -
ID prefix convention: User servers use
mcp_prefix, enterprise servers useemcp_prefix, preventing collision and making store routing unambiguous. -
Marketplace integration: The
installedflag on marketplace listings reflects the user’s complete view (personal + enterprise auto-enabled). -
Personal accounts: Gmail/personal email users are the sole owner of their personal enterprise, so they naturally have full admin rights over their own enterprise approved list.
-
Auth enforcement: All MCP and marketplace endpoints now enforce authentication (401 if not authenticated). When auth is disabled (
s.users == nil), endpoints gracefully fall back to unscoped behavior for local development.
Consequences
- Users have isolated MCP server environments — installing a server no longer affects other users
- Enterprise admins can enforce a standard set of MCP servers across their organization
- The
sourcefield in API responses lets UIs distinguish personal from enterprise-managed servers and adjust controls accordingly (e.g., hide delete buttons for enterprise servers) - Vault paths for enterprise servers use a separate namespace (
mcp-servers/enterprise/{ent_id}/{id}/{env_var}) to prevent credential collision - The in-memory store is ephemeral, so no data migration is needed. A future Postgres implementation will need to handle the
user_idandenterprise_idcolumns - The store SPI (
MCPServerFilter.UserID, newEnterpriseMCPServerStoreinterface) is ready for a Postgres implementation