V1 Retirement Checklist
When to read this
Read this before touching anything related to MCP V1 decommissioning, or before assuming V1 is safe to remove because the code looks unused.
V1 is not retired, deliberately. Nothing on this page has been signed off. Every item is a condition that must become true before V1 can be switched off — not a description of work already done.
Do not remove the 11 retained MCP V1 aliases. That is a standing decision, recorded in the audit, and it is the item most likely to be "cleaned up" by someone reading only the code.
The standing decision, support contract, and provenance now live in the MCP platform contract. This runbook is the executable retirement checklist for that master specification.
Where things actually stand
Verified in the 2026-08-17 audit:
| Fact | Value |
|---|---|
| V2 canonical MCP tools | 104 |
| Retained V1 aliases | 94 |
| Total discoverable identifiers | 198 (plus 5 prompts, 2 resources) |
| Current V1 registered tools | 83 — all 83 present in V2 |
| Aliases present in the authoritative baseline but absent from the current V1 checkout | 11 — retained in V2 on purpose |
| Alias contract match | 90 exact; 4 Google segment aliases are additive V2-only supersets |
| Read-only classification match | 89/94; 5 V2 aliases apply an intentionally stricter write gate |
| Live two-runtime output comparison | Never completed — blocked on authorization |
The authoritative V1 baseline is commit b395cfb0d80a73655f975b711414dfbfaa006570. Note the trap it exposes: get-scale-winning-ads-rows-tool.limit defaults to 100 (max 200) in the authoritative baseline and V2 matches it. The 50 default exists only in a later current staging checkout — that is later V1 drift, not the retirement contract. Do not "fix" V2 to match staging.
Exit criteria
1. The authorized live output comparison must pass
This is the primary blocker and it has never been run to completion.
No successful live V1/V2 MCP sample exists; there is no saved docs/mcp-parity-live-2026-08-16.json. An approved mcp:read OAuth attempt found that V2 requires a Google SSO session while V1 rejected the available email/password test account. No authorization code or token was ever issued.
What must be recorded:
- Both approvals completed from valid, provider-compatible sessions.
-
npx tsx scripts/authorize-mcp-parity-audit.tsrun to completion — or pre-approved read-only tokens plus a private fixture supplied toaudit-mcp-v1-v2.ts --execute-readonly. - All source identifiers present in the live discovery response.
- Schemas equal, or every difference explicitly approved in writing.
- Fixture value results matched.
scripts/audit-mcp-output-parity-local.ts is V2 regression coverage only — it is not a V1 runtime comparison. The repository script invokes V2 against fixed V1 fixture expectations; it does not launch PHP/MySQL/V1. An earlier "two-runtime output audit" description was inaccurate and has been corrected. Even a full pass here does not clear the live parity gate.
It also needs an isolated ClickHouse endpoint (127.0.0.1:18123 by default) and must only ever be pointed at a disposable database.
2. Every retained alias needs per-alias evidence before it is dropped
- For each of the 11 aliases absent from the current V1 checkout: evidence that no live caller uses it. The authoritative baseline contains all 94 identifiers, which is the standing argument for keeping all of them — a later V1 checkout dropping 11 is not evidence that callers stopped calling them.
- For the remaining aliases: caller migration confirmed before discovery stops advertising the identifier.
- The 4 additive Google segment aliases: confirm no consumer depends on the V1-narrower shape.
- The 5 stricter-gated aliases (Google media mix, Pup Labs workbook, Scale ad preview, creative strategist brief, and the fourth mutation-classified pair): recorded as a deliberate safety hardening, not an alias-removal reason.
3. Parity gates must be green
Run all five and record the output:
npm run audit:v1-v2 # scripts/audit-v1-v2-metrics.ts
npm run audit:v1-v2-site # scripts/audit-v1-v2-site-data.ts
npm run audit:v1-v2-client-metrics # scripts/audit-v1-v2-client-metrics.ts
npm run audit:crm-parity # scripts/audit-v1-v2-crm-parity.ts
npm run audit:parity-all # scripts/audit-parity-all.ts
They are not currently green. /admin/parity-check reported Pass 11 / Fail 14 / Error 0 at last capture, with failures concentrated in crm-attribution revenue differences (for example credit-secrets-cs at 0.68%). These are known and tracked, not new breakage — and they are the reason V1 cannot be switched off.
-
audit:parity-allre-run and all rows passing, or every remaining failure explicitly waived with a recorded threshold. -
/admin/parity-checkshowing zero fails.
Re-run npm run audit:parity-all before making any claim about parity. A parity number in a document is a point-in-time observation, not a current fact.
4. Data-completeness thresholds for the V1 MySQL → V2 ClickHouse migration
- A written per-domain row-count and value-sum tolerance (spend, revenue, orders), agreed with the account owner — not inferred from whatever the audit happened to report.
- Date-range coverage confirmed: the earliest V1 date present in V2, per client.
- Every client with a V1 history verified individually. Fleet-level aggregates hide a single-tenant gap.
- The disposition of the V1 Cloud SQL archive decided (retain read-only / export / destroy) and dated.
No dated completeness thresholds exist in the repo today. The audit records the V1 infrastructure decommission as having "no dated plan yet". This section is the shape of what must be written, not a summary of an existing agreement.
5. Write-tool acceptance
Provider/action behavior has not been executed against V1 or V2 in any audit: exports, refreshes, notes, ClickUp writes, GCS saves, CRM syncs, and generated assets were all intentionally excluded from parity testing.
- A staging/sandbox acceptance record for every externally-effectful tool family, with idempotency notes and a rollback procedure.
- Keep V1 available to write users until each family has that record.
No production command is recommended for this. Run only an approved staging/sandbox test plan with mcp:write, test credentials, and post-action assertions.
6. Infrastructure decommission — in this order
Shut down in dependency order; each step is reversible only until the next one runs.
- Stop new traffic: point remaining V1 callers at V2 and confirm zero V1 request volume for a full business week.
- Revoke V1 tokens and MCP OAuth clients.
- V1 MCP server — decommission after (1) and (2), with monitoring confirming no callers.
- V1 application hosting (Cloud Run) — decommission next.
- Cloud SQL proxy — remove the proxy path once nothing reaches the database.
- V1 Cloud SQL instance — final. Take and verify a restorable export before deletion, per the disposition decided in criterion 4.
- DNS and endpoint retirement, with the rollback window still open.
- Monitoring and alerting for V1 removed last, so a failed cutover is still visible.
A separate, approved operational decommission plan covering endpoint/DNS, token revocation, monitoring, rollback window, and alias retention is itself one of the audit's three named exit criteria.
No such plan exists in the repo at HEAD.
7. Rollback plan while V1 still runs
Until step 6 completes, V1 remains the fallback:
- A named rollback window per decommission step, agreed before that step runs.
- V1 credentials and access retained (not rotated away) for the duration of the window.
- A documented procedure for re-pointing callers back to V1, tested at least once.
- A single named owner with authority to call the rollback.
Once step 6.6 (Cloud SQL deletion) runs, rollback is no longer possible. Treat that as the point of no return and gate it separately.
Re-evaluation trigger
The retirement audit is a decision record, not a permanent state. Re-evaluate this page — and archive the audit — once the authorized live output comparison in criterion 1 completes. Until then the standing decision holds: do not retire V1, and do not remove the 11 retained aliases.