Problem
`src/selfhost/private-config.ts` (the loader for `LOOPOVER_REPO_CONFIG_DIR`) is 100% read-only -- no write path exists anywhere in the codebase -- and the config bind mount is deliberately `:ro` in `docker-compose.yml`. Every config edit (global default or a per-repo override) requires an operator to SSH into their own box, hand-edit YAML, and restart. Sub-issue of #7720.
Area
`src/mcp/server.ts`, `src/selfhost/private-config.ts`, `docker-compose.yml`, `src/env.d.ts`, self-hosting docs.
Proposal
- New MCP tool category (`"admin"` alongside the existing `discovery`/`branch`/`review`/`agent`/`maintainer`/`utility` set in `MCP_TOOL_CATEGORIES`), registered only when `LOOPOVER_MCP_ADMIN_ENABLED` is truthy (default OFF, matching `LOOPOVER_REVIEW_SCREENSHOTS`/`LOOPOVER_REVIEW_ENRICHMENT`/`LOOPOVER_REVIEW_OPS`'s existing "truly inert when off, tool not even registered" convention) -- not just gated at call time.
- A separate, higher-privilege `LOOPOVER_MCP_ADMIN_TOKEN` (distinct from the general `LOOPOVER_MCP_TOKEN`), so a leaked ordinary MCP credential can never rewrite fleet-wide gate policy.
- New write helpers in `private-config.ts` mirroring the existing read path's candidate-path resolution: validate the incoming YAML against the same parser the read path already uses (reuse, don't reinvent), write a timestamped backup of the existing file first, atomic write (temp file + rename).
- Tools: read effective/global/per-repo config, write global/per-repo config (validated, backed-up, atomic), list backups for a scope.
- `docker-compose.yml`'s config mount stays `:ro` by default; an operator who wants this capability explicitly flips it to `:rw` themselves (documented as a required manual step) -- the mount itself isn't secretly writable just because the app flag exists.
Deliverables
Resources
Existing MCP server auth pattern (`src/auth/security.ts`'s `authenticatePrivateToken`/`timingSafeEqual`), `self-hosting-configuration.mdx:117-143`'s existing `LOOPOVER_MCP_TOKEN` docs as the template for the new token's docs.
Boundaries
Config read/write only -- does not include triggering a redeploy (#7720's other sub-issue) and does not touch the public dashboard/API settings surface.
maintainer-only -- new privileged control surface touching self-hosted config, needs maintainer review.
Problem
`src/selfhost/private-config.ts` (the loader for `LOOPOVER_REPO_CONFIG_DIR`) is 100% read-only -- no write path exists anywhere in the codebase -- and the config bind mount is deliberately `:ro` in `docker-compose.yml`. Every config edit (global default or a per-repo override) requires an operator to SSH into their own box, hand-edit YAML, and restart. Sub-issue of #7720.
Area
`src/mcp/server.ts`, `src/selfhost/private-config.ts`, `docker-compose.yml`, `src/env.d.ts`, self-hosting docs.
Proposal
Deliverables
Resources
Existing MCP server auth pattern (`src/auth/security.ts`'s `authenticatePrivateToken`/`timingSafeEqual`), `self-hosting-configuration.mdx:117-143`'s existing `LOOPOVER_MCP_TOKEN` docs as the template for the new token's docs.
Boundaries
Config read/write only -- does not include triggering a redeploy (#7720's other sub-issue) and does not touch the public dashboard/API settings surface.
maintainer-only -- new privileged control surface touching self-hosted config, needs maintainer review.