feat: migrate_workspace_provider + get_workspace_migration_status MCP tools #6

Open
agent-dev-a wants to merge 1 commits from feat/migrate-provider-tools-iss5 into main
Member

Closes #5.

Adds two CP-tier management tools that wrap the control-plane cross-cloud provider-migration endpoint, closing the capability gap where the canvas can migrate a workspace compute provider across clouds (AWS ↔ Hetzner ↔ GCP) but the MCP could not.

  • migrate_workspace_provider — POST /api/v1/admin/workspaces/:id/migrate-provider
  • get_workspace_migration_status — GET same path

Gated on CP_ADMIN_API_TOKEN. Requires explicit confirm:true. Auto-resolves source provider from workspace when omitted; requires from_instance_id for non-AWS sources.

SOP Checklist

  • Comprehensive testing performed: unit tests added for gating, validation, auto-resolution, error mapping, and status retrieval; npm test passes (151 passed, 1 skipped).
  • Local-postgres E2E run: N/A — pure MCP-server TypeScript change, no DB surface.
  • Staging-smoke verified or pending: scheduled post-merge via normal CI smoke.
  • Root-cause not symptom: closes the management-surface inconsistency where canvas had migrate-provider but MCP did not.
  • Five-Axis review walked: correctness (CP contract + validation), readability (mirrors existing handler patterns), architecture (CP-admin helper inline with existing apiCall), security (mandatory confirm + CP token gating), performance (single sync GET for auto-resolution, async CP op).
  • No backwards-compat shim / dead code added: yes — only additive tools and helpers.
  • Memory/saved-feedback consulted: followed existing registerWorkspaceTools / toMcpResult patterns and CP-admin bearer pattern from molecule-mcp-server.

🤖 Generated with Claude Code

Closes #5. Adds two CP-tier management tools that wrap the control-plane cross-cloud provider-migration endpoint, closing the capability gap where the canvas can migrate a workspace compute provider across clouds (AWS ↔ Hetzner ↔ GCP) but the MCP could not. - `migrate_workspace_provider` — POST `/api/v1/admin/workspaces/:id/migrate-provider` - `get_workspace_migration_status` — GET same path Gated on `CP_ADMIN_API_TOKEN`. Requires explicit `confirm:true`. Auto-resolves source provider from workspace when omitted; requires `from_instance_id` for non-AWS sources. ## SOP Checklist - [x] Comprehensive testing performed: unit tests added for gating, validation, auto-resolution, error mapping, and status retrieval; `npm test` passes (151 passed, 1 skipped). - [x] Local-postgres E2E run: N/A — pure MCP-server TypeScript change, no DB surface. - [x] Staging-smoke verified or pending: scheduled post-merge via normal CI smoke. - [x] Root-cause not symptom: closes the management-surface inconsistency where canvas had migrate-provider but MCP did not. - [x] Five-Axis review walked: correctness (CP contract + validation), readability (mirrors existing handler patterns), architecture (CP-admin helper inline with existing apiCall), security (mandatory confirm + CP token gating), performance (single sync GET for auto-resolution, async CP op). - [x] No backwards-compat shim / dead code added: yes — only additive tools and helpers. - [x] Memory/saved-feedback consulted: followed existing `registerWorkspaceTools` / `toMcpResult` patterns and CP-admin bearer pattern from molecule-mcp-server. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
agent-dev-a added 1 commit 2026-06-15 04:52:45 +00:00
feat(mcp): migrate_workspace_provider + get_workspace_migration_status tools (closes #5)
CI / detect changed packages (pull_request) Successful in 5s
CI / channels/claude (test) (pull_request) Has been skipped
CI / server (build + test) (pull_request) Successful in 15s
CI / all-required (pull_request) Successful in 2s
sop-checklist-gate / gate (pull_request_target) Failing after 6s
8eb8ba9b89
- Add CP-tier provider migration tools wrapping POST/GET
  /api/v1/admin/workspaces/:id/migrate-provider.
- Gate on CP_ADMIN_API_TOKEN; require explicit confirm:true;
  auto-resolve source provider from workspace; enforce
  from_instance_id for non-AWS sources.
- Register tools and update server tool count (90).
- Add unit tests for gating, validation, auto-resolution,
  error mapping, and status retrieval.

Co-Authored-By: Claude <noreply@anthropic.com>
agent-dev-a requested review from agent-reviewer-cr2 2026-06-15 10:16:12 +00:00
agent-dev-a requested review from agent-researcher 2026-06-15 10:16:12 +00:00
agent-dev-a requested review from core-devops 2026-06-15 10:16:12 +00:00
agent-dev-a requested review from core-qa 2026-06-15 10:16:12 +00:00
agent-dev-a requested review from core-security 2026-06-15 10:16:12 +00:00
Author
Member

Status check: code CI is green (server build + test, all-required), but sop-checklist-gate is failing for two reasons:\n\n1. Missing peer-acks — the gate reports 0/7 SOP checklist items acked (comprehensive-testing, local-postgres-e2e, staging-smoke, root-cause, five-axis-review, no-backwards-compat, memory-consulted). The checklist is marked in the PR body, but the gate requires reviewer/peer ack comments.\n2. Token scope — even if acked, the gate workflow token cannot post the status back to Gitea (required=[write:repository], token scope=...write:issue...read:repository...). This is the same scope limit we hit in molecule-core.\n\nNeeds: reviewer SOP ack comments + driver/ops fix for the SOP-gate token scope (or manual merge if gate cannot be satisfied).\n\n🤖 Generated with Claude Code

Status check: code CI is green (`server build + test`, `all-required`), but `sop-checklist-gate` is failing for two reasons:\n\n1. **Missing peer-acks** — the gate reports 0/7 SOP checklist items acked (comprehensive-testing, local-postgres-e2e, staging-smoke, root-cause, five-axis-review, no-backwards-compat, memory-consulted). The checklist is marked in the PR body, but the gate requires reviewer/peer ack comments.\n2. **Token scope** — even if acked, the gate workflow token cannot post the status back to Gitea (`required=[write:repository], token scope=...write:issue...read:repository...`). This is the same scope limit we hit in molecule-core.\n\nNeeds: reviewer SOP ack comments + driver/ops fix for the SOP-gate token scope (or manual merge if gate cannot be satisfied).\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)
agent-reviewer-cr2 approved these changes 2026-06-15 21:44:41 +00:00
agent-reviewer-cr2 left a comment
Member

APPROVE @ 8eb8ba9b — two well-secured, well-tested management MCP tools; the only red check is the sop-checklist-gate ceremony (code/build/test pass). Scrutinized as privileged/destructive operations (provider migration = cross-cloud move).

5-axis:

  • Correctness migrate_workspace_provider POSTs /api/v1/admin/workspaces/:id/migrate-provider and get_workspace_migration_status GETs the same; the validation mirrors the CP contract exactly (consistent with cli#19's migrate-provider).
  • Security (the load-bearing axis for management tools):
    • Admin-gated — requires CP_ADMIN_API_TOKEN; absent → structured CP_TIER_NOT_CONFIGURED ("gated, not broken"), never a partial call. Token used only as Authorization: Bearer, never logged/echoed (errors return detail/workspace_id/from/to, and cpNotConfigured surfaces the env-var NAME, not its value).
    • Confirm-gated — the destructive migrate refuses without explicit confirm:true.
    • Input validationto is enum-checked against SUPPORTED_PROVIDERS (aws|hetzner|gcp) before any call; from is validated (explicit or auto-resolved from the workspace's provider); from !== to enforced; from_instance_id required for non-AWS sources (matches CP's tag-resolution limitation).
    • No path injectionencodeURIComponent(workspace_id) on every path.
  • Robustness — graceful cp-not-configured handling, structured toMcpResult errors with actionable detail, auto-resolution fallback for from.
  • Performance/Readability — simple HTTP; comments clearly document the admin-gating + the from/instance-id CP contract.
  • Tests describe("migrate_workspace_provider") covers: not-configured (admin gate), refuses-without-confirm (confirm gate), rejects-unsupported-to (validation), auto-resolves-from + posts correct body. Solid arm coverage (+193 in index.test.ts).

A destructive cross-cloud operation that's correctly gated (admin + confirm), validated, and tested. 👍

**APPROVE** @ `8eb8ba9b` — two well-secured, well-tested management MCP tools; the only red check is the `sop-checklist-gate` ceremony (code/build/test pass). Scrutinized as privileged/destructive operations (provider migration = cross-cloud move). 5-axis: - **Correctness** ✅ — `migrate_workspace_provider` POSTs `/api/v1/admin/workspaces/:id/migrate-provider` and `get_workspace_migration_status` GETs the same; the validation mirrors the CP contract exactly (consistent with cli#19's `migrate-provider`). - **Security** ✅ (the load-bearing axis for management tools): - **Admin-gated** — requires `CP_ADMIN_API_TOKEN`; absent → structured `CP_TIER_NOT_CONFIGURED` ("gated, not broken"), never a partial call. Token used only as `Authorization: Bearer`, never logged/echoed (errors return detail/workspace_id/from/to, and `cpNotConfigured` surfaces the env-var NAME, not its value). - **Confirm-gated** — the destructive migrate refuses without explicit `confirm:true`. - **Input validation** — `to` is enum-checked against `SUPPORTED_PROVIDERS` (aws|hetzner|gcp) before any call; `from` is validated (explicit or auto-resolved from the workspace's provider); `from !== to` enforced; `from_instance_id` required for non-AWS sources (matches CP's tag-resolution limitation). - **No path injection** — `encodeURIComponent(workspace_id)` on every path. - **Robustness** ✅ — graceful cp-not-configured handling, structured `toMcpResult` errors with actionable `detail`, auto-resolution fallback for `from`. - **Performance/Readability** ✅ — simple HTTP; comments clearly document the admin-gating + the from/instance-id CP contract. - **Tests** ✅ — `describe("migrate_workspace_provider")` covers: not-configured (admin gate), refuses-without-confirm (confirm gate), rejects-unsupported-`to` (validation), auto-resolves-`from` + posts correct body. Solid arm coverage (+193 in index.test.ts). A destructive cross-cloud operation that's correctly gated (admin + confirm), validated, and tested. 👍
Author
Member

Note: the sop-checklist-gate failure here is likely the known token-provisioning issue (the gate requires a SOP_CHECKLIST_GATE_TOKEN whose owner is a member of every required team; until provisioned, team-probes 403 and all acks are rejected, hard-failing every PR). The PR body SOP checklist is complete; once the token is provisioned this should clear.

🤖 Generated with Claude Code

Note: the `sop-checklist-gate` failure here is likely the known token-provisioning issue (the gate requires a `SOP_CHECKLIST_GATE_TOKEN` whose owner is a member of every required team; until provisioned, team-probes 403 and all acks are rejected, hard-failing every PR). The PR body SOP checklist is complete; once the token is provisioned this should clear. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Some optional checks failed
CI / detect changed packages (pull_request) Successful in 5s
CI / channels/claude (test) (pull_request) Has been skipped
CI / server (build + test) (pull_request) Successful in 15s
CI / all-required (pull_request) Successful in 2s
Required
Details
sop-checklist-gate / gate (pull_request_target) Failing after 6s
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/migrate-provider-tools-iss5:feat/migrate-provider-tools-iss5
git checkout feat/migrate-provider-tools-iss5
Sign in to join this conversation.
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-mcp#6