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
Part of #9515 — the ORB half of "MCP as the management plane." The management capabilities mostly exist; they're just scattered across interfaces an agent can't reach uniformly:
MCP already (self-host only, 4 tools):loopover_admin_{get_config,write_config,list_config_backups,trigger_redeploy} (src/mcp/server.ts:3295-3336), gated on LOOPOVER_MCP_ADMIN_ENABLED + mcp-admin actor, wired through the Workers-safe capability registries (src/mcp/private-config-admin-registry.ts, redeploy-companion-registry.ts) that only the self-host entry fills.
Confirmed absent everywhere: instance status rollup (image/version/uptime/container health in one answer), bounded log tail, backup status, an ORB doctor (the miner has one; ORB does not — doctor in this repo is miner-only).
All new tools ride the standardized registry (#9518) with auth/locality/availability metadata, and the management routes they wrap are specced by #9519.
Tool catalog (the deliverable — renames/cuts recorded on this issue, not improvised in PRs)
Self-host instance ops (availability selfhost, auth mcp-admin; capability-registry pattern — unset capability ⇒ structured "not configured" result): loopover_admin_get_status (new: app version vs orb-manifest.json target, uptime, container/component health incl. /ready probe detail, queue depth, last redeploy) · loopover_admin_doctor (new: the ORB counterpart of the miner's doctor — secrets presence/shape, GitHub App auth, DB/Redis/Qdrant reachability, config-dir mount + LOOPOVER_REPO_CONFIG_DIR writability, broker enrollment validity, clock skew, disk pressure; read-only, structured pass/warn/fail per check) · loopover_admin_tail_logs (new: bounded tail — capped lines/bytes, redaction-scrubbed via the existing redaction-scrub.ts before return, never a follow mode) · loopover_admin_get_backup_status (new: last backup timestamps/sizes from the backup container's artifacts) · existing 4 admin tools migrate to the registry unchanged in behavior.
Queue + safety ops (availability both, auth operator): loopover_ops_list_dead_letter_jobs · loopover_ops_replay_dead_letter_job · loopover_ops_delete_dead_letter_job (destructive) · loopover_ops_purge_dead_letter_jobs (destructive) · loopover_ops_get_kill_switch · loopover_ops_set_kill_switch · loopover_ops_get_operator_dashboard — thin wrappers over the existing routes' service functions (same handlers, same audit events; no parallel logic).
Fleet (availability cloud primarily, auth internal or operator as the wrapped route dictates): loopover_fleet_get_analytics · loopover_fleet_list_instances · loopover_fleet_register_instance (secret returned once — response schema marks it) · loopover_fleet_list_installations · loopover_fleet_register_installation · loopover_fleet_backfill_installations · loopover_fleet_issue_enrollment / loopover_fleet_rotate_enrollment / loopover_fleet_revoke_enrollment (destructive) · loopover_fleet_config_push · loopover_fleet_run_job (one tool, job enum from the jobs table + mode: enqueue|run, replacing 30 bespoke tools).
Hosted tenants (availability cloud, auth control-plane admin): loopover_tenant_create · loopover_tenant_list · loopover_tenant_set_orb_installation · loopover_tenant_destroy (destructive) · loopover_tenant_rollout — which requires finishing #9143 (implement rollout: staged image-version updates across tenant containers with per-tenant health verification and halt-on-failure; scope the mechanism on #9143, expose it here).
Destructive tools (marked above): destructiveHint: true, required confirm: z.literal(true), and MCP elicitation before execution where the client supports it (the remote server already imports ElicitResultSchema — same pattern as existing mutating tools); declining elicitation returns a structured non-error "declined" result.
New self-host capabilities (status, doctor, tail_logs, backup_status) follow the capability-registry pattern exactly (nullable slots, only src/server.ts fills them, Workers bundle never imports node builtins). Log tail and status must be redaction-scrubbed with the existing helpers before returning.
Wrapped tools call the same service functions as their HTTP routes (extract shared functions where the logic currently lives inline in routes.ts) — one implementation, two transports, asserted by tests that both paths hit the same function.
Auth is enforced per-tool from the registry's auth field (requireMcpAdmin precedent at src/mcp/server.ts:4121-4128), with tests for every deny path. Fleet/internal tools must be unreachable with a plain contributor/maintainer identity.
.github/workflows/self-host-maintenance.yml gains no new duties — but document (in the workflow header + self-hosting docs, generated where applicable) that MCP loopover_fleet_run_job is now the interactive path and the workflow remains the scheduled path.
Full branch-counted coverage; fix-what-you-find applies (expect to find dead or drifted /v1/internal/jobs/* entries — fix or delete them as encountered, recorded in PR bodies).
Non-goals
New privilege levels or write paths — everything routes through existing chokepoints + audit.
An operator (or the #9183 chat surface) can, over MCP alone: diagnose an instance (doctor/status/tail_logs), manage its config with backups and dry-runs, replay or purge its dead letters, flip the kill switch, redeploy it, run any maintenance job, manage fleet enrollments/instances/installations, and administer hosted tenants including staged rollouts — with every mutation audited, schema-validated, and confirmation-gated.
References
Part of #9515. Blocked by #9518 (registry) and #9519 (specced management routes). Advances #4877 Phase B (fleet/ops management) and #9183 (action catalog). Closes the gap with #9143 via the rollout tool.
Context
Part of #9515 — the ORB half of "MCP as the management plane." The management capabilities mostly exist; they're just scattered across interfaces an agent can't reach uniformly:
loopover_admin_{get_config,write_config,list_config_backups,trigger_redeploy}(src/mcp/server.ts:3295-3336), gated onLOOPOVER_MCP_ADMIN_ENABLED+mcp-adminactor, wired through the Workers-safe capability registries (src/mcp/private-config-admin-registry.ts,redeploy-companion-registry.ts) that only the self-host entry fills.src/api/routes.ts:1945), DLQ list/replay/delete/purge (:1955/:1975/:2001/:2027), kill-switch get/set (:2054/:2065), fleet config-push (:2112), bulk agent settings (:2778).:4569), instances list/register (:4621/:4641), installations list/register/backfill (:4670/:4687/:4703), enrollments issue/rotate/revoke (:4721/:4740), ops stats (:4754), ~30/v1/internal/jobs/*(:4886-5187) — today driven only by the GitHub Actions fleet matrix (.github/workflows/self-host-maintenance.yml).control-plane/src/http-app.ts): tenant create/list/patch/delete (:134/:200/:229/:268); rollout is a 501 stub (control-plane: eight pre-deploy defects, headlined by two tenants sharing one Neon database (and one customer's teardown deleting another's) #9143).doctor(the miner has one; ORB does not —doctorin this repo is miner-only).All new tools ride the standardized registry (#9518) with
auth/locality/availabilitymetadata, and the management routes they wrap are specced by #9519.Tool catalog (the deliverable — renames/cuts recorded on this issue, not improvised in PRs)
Self-host instance ops (availability
selfhost, authmcp-admin; capability-registry pattern — unset capability ⇒ structured "not configured" result):loopover_admin_get_status(new: app version vsorb-manifest.jsontarget, uptime, container/component health incl./readyprobe detail, queue depth, last redeploy) ·loopover_admin_doctor(new: the ORB counterpart of the miner's doctor — secrets presence/shape, GitHub App auth, DB/Redis/Qdrant reachability, config-dir mount +LOOPOVER_REPO_CONFIG_DIRwritability, broker enrollment validity, clock skew, disk pressure; read-only, structured pass/warn/fail per check) ·loopover_admin_tail_logs(new: bounded tail — capped lines/bytes, redaction-scrubbed via the existingredaction-scrub.tsbefore return, never a follow mode) ·loopover_admin_get_backup_status(new: last backup timestamps/sizes from the backup container's artifacts) · existing 4 admin tools migrate to the registry unchanged in behavior.Queue + safety ops (availability
both, authoperator):loopover_ops_list_dead_letter_jobs·loopover_ops_replay_dead_letter_job·loopover_ops_delete_dead_letter_job(destructive) ·loopover_ops_purge_dead_letter_jobs(destructive) ·loopover_ops_get_kill_switch·loopover_ops_set_kill_switch·loopover_ops_get_operator_dashboard— thin wrappers over the existing routes' service functions (same handlers, same audit events; no parallel logic).Fleet (availability
cloudprimarily, authinternaloroperatoras the wrapped route dictates):loopover_fleet_get_analytics·loopover_fleet_list_instances·loopover_fleet_register_instance(secret returned once — response schema marks it) ·loopover_fleet_list_installations·loopover_fleet_register_installation·loopover_fleet_backfill_installations·loopover_fleet_issue_enrollment/loopover_fleet_rotate_enrollment/loopover_fleet_revoke_enrollment(destructive) ·loopover_fleet_config_push·loopover_fleet_run_job(one tool,jobenum from the jobs table +mode: enqueue|run, replacing 30 bespoke tools).Hosted tenants (availability
cloud, auth control-plane admin):loopover_tenant_create·loopover_tenant_list·loopover_tenant_set_orb_installation·loopover_tenant_destroy(destructive) ·loopover_tenant_rollout— which requires finishing #9143 (implement rollout: staged image-version updates across tenant containers with per-tenant health verification and halt-on-failure; scope the mechanism on #9143, expose it here).Requirements
validate:mcp(mcp: validate:mcp contract validator — Ajv output enforcement, per-tool smoke gate, version tri-lock across all three servers #9520); audit event on every mutation (existing audit-event machinery, no new write paths).destructiveHint: true, requiredconfirm: z.literal(true), and MCP elicitation before execution where the client supports it (the remote server already importsElicitResultSchema— same pattern as existing mutating tools); declining elicitation returns a structured non-error "declined" result.status,doctor,tail_logs,backup_status) follow the capability-registry pattern exactly (nullable slots, onlysrc/server.tsfills them, Workers bundle never imports node builtins). Log tail and status must be redaction-scrubbed with the existing helpers before returning.routes.ts) — one implementation, two transports, asserted by tests that both paths hit the same function.authfield (requireMcpAdminprecedent atsrc/mcp/server.ts:4121-4128), with tests for every deny path. Fleet/internal tools must be unreachable with a plain contributor/maintainer identity..github/workflows/self-host-maintenance.ymlgains no new duties — but document (in the workflow header + self-hosting docs, generated where applicable) that MCPloopover_fleet_run_jobis now the interactive path and the workflow remains the scheduled path./v1/internal/jobs/*entries — fix or delete them as encountered, recorded in PR bodies).Non-goals
Deliverables
confirmon all destructive tools; audit events on all mutationsstatus/doctor/tail_logs/backup_statuscapabilities on the self-host entryloopover_tenant_rolloutlive (with control-plane: eight pre-deploy defects, headlined by two tenants sharing one Neon database (and one customer's teardown deleting another's) #9143 closed by its own scoped implementation)Expected outcome
An operator (or the #9183 chat surface) can, over MCP alone: diagnose an instance (
doctor/status/tail_logs), manage its config with backups and dry-runs, replay or purge its dead letters, flip the kill switch, redeploy it, run any maintenance job, manage fleet enrollments/instances/installations, and administer hosted tenants including staged rollouts — with every mutation audited, schema-validated, and confirmation-gated.References
Part of #9515. Blocked by #9518 (registry) and #9519 (specced management routes). Advances #4877 Phase B (fleet/ops management) and #9183 (action catalog). Closes the gap with #9143 via the rollout tool.