Skip to content

orb(mcp): ORB management tool family — instance doctor/status/logs, queue+kill-switch ops, fleet + hosted-tenant administration #9522

Description

@JSONbored

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:

  • 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.
  • Operator HTTP routes with no MCP equivalent: operator dashboard (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).
  • Fleet/internal routes with no MCP equivalent: fleet analytics (: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).
  • Hosted control plane (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).
  • 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).

Requirements

  1. Every tool above: contract entry with real input/output schemas, registered per contract(remote): migrate the remote MCP server's tools to @loopover/contract — typed handlers, real output schemas #9518's mechanics; smoke-called in 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).
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. .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.
  7. 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

Deliverables

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.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.orbGittensory Orb related - maintainer self-hosting analytics.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions