fix(admin): use PATCH status endpoints in takedown script and runbook - #1518
Merged
Conversation
`tools/admin/takedown.sh` could not work. It sent `PUT` with a `?status=deleted`
query parameter to two routes:
- `PUT /v0/servers/{name}/versions/{version}?status=deleted` — this route exists
but requires a full `ServerJSON` body and has no `status` query parameter
- `PUT /v0/servers/{name}?status=deleted` — this route is not registered at all,
so the whole-server takedown path returned 404
The real endpoints are `PATCH /v0/servers/{name}/versions/{version}/status` and
`PATCH /v0/servers/{name}/status`, both taking `{"status": ..., "statusMessage": ...}`.
Script changes:
- Send `PATCH` with a JSON body built by `jq`
- Require either `VERSION` or `ALL_VERSIONS=true` explicitly. Previously a missing
`VERSION` silently meant "entire server"; since `PATCH .../status` updates every
version, an operator who forgot `VERSION` would have taken down the whole server
- Support `STATUS` (default `deleted`) and `STATUS_MESSAGE` for recording a reason
- Add `set -euo pipefail`, propagate a non-zero exit on HTTP errors, and print the
response body so huma's error detail is visible
Runbook changes in `docs/administration/admin-operations.md`:
- `GET /v0/servers/{name}` is not a route; use `GET .../versions/latest`
- Replace the per-version `?status=deleted` loop with the single all-versions
`PATCH .../status` call, which reports `updatedCount`
- Keep the per-version `PUT` loop for content edits, which genuinely has no bulk
endpoint, and show that it needs the full body
- Correct the note claiming server-wide changes must be applied per version; that
is true for content but not for status
- Fix the broken `moderation-guidelines.md` link, which has been
`../modelcontextprotocol-io/moderation-policy.mdx` since the docs restructuring
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rdimitrov
added a commit
that referenced
this pull request
Aug 10, 2026
) Deletes `complete.md` and cleans up the last references to the pre-restructuring docs layout. ## Why `complete.md` goes It is 2,944 lines (31% of all documentation lines in the repo) self-described as *"all documentation from the docs/ directory compiled into a single markdown file"*. But: - **No generator exists.** No make target, no workflow, no script. `grep -rn "complete\.md"` finds **zero** references anywhere in the repo. - **It mirrors a docs tree that no longer exists** — `docs/guides/`, `docs/explanations/`, `docs/concepts/`. - **All 72 of its relative links are broken**, and six of the basenames it references exist nowhere in the repo. - **~14 current docs are missing from it entirely** (`about.mdx`, `authentication.mdx`, `package-types.mdx`, both CHANGELOGs, ...). - **Its `server.json` examples pin the superseded `2025-07-09` schema** (current is `2025-12-11`). The strongest argument is its own last commit. [PR #1278](#1278) closed [issue #767](#767) — a real user-reported CLI flag bug — by editing **only `complete.md`**. A genuine fix landed in a file nobody reads, while the docs a reader would actually find stayed wrong. A generated file with no generator degrades into a trap: authoritative enough that people edit it, with nothing validating it. If the LLM-consumption use case is worth keeping, the right shape is a `make docs-bundle` target plus a `check-docs-bundle` CI job mirroring the existing `check-schema` pattern — happy to do that instead if you would rather keep it. ## Remaining stale references | File | Was | Now | |---|---|---| | `contributing/add-package-registry.md` | Add `docs/guides/publishing/publish-[yourregistry].md`, update `docs/guides/publishing/README.md` | Add a section to `package-types.mdx`. These were the **last live references** to the obsolete `docs/guides/` layout outside `complete.md` | | `administration/maintainer-onboarding.md` | Add them to "Current key maintainers" in README | "Registry Working Group" — the section that actually exists | | `reference/README.md` | Omitted 6 reference docs | Adds `api/extensions.md`, `api/openapi.yaml`, `api/CHANGELOG.md`, `server-json/CHANGELOG.md`, `server-json/CONTRIBUTING.md`, `server-json/draft/` | | `docs/README.md` | Index omitted `community-projects.md` | Listed | | `reference/api/generic-registry-api.md` | `PUT .../versions/{version}` "not implemented by official registry" | It **is** implemented ([edit.go:36](https://github.com/modelcontextprotocol/registry/blob/main/internal/api/handlers/v0/edit.go#L36)), and `official-registry-api.md` already lists it as an admin endpoint | | `reference/api/official-registry-api.md` | Omitted 3 registered routes | Adds `POST /v0.1/validate` (which `mcp-publisher validate` calls), `GET /v0.1/ping`, `GET /v0.1/version`, and notes these plus `/health` are absent from `openapi.yaml` | | `server-json/official-registry-requirements.md` | Per-registry verification → `quickstart.mdx` | → `package-types.mdx`, which has an Ownership Verification section per registry | | `design/design-principles.md` | Sections 1,2,3,4,**6**,7 | Renumbered 1–6 | | `contributing/releasing.md` | Steps 1,2,3,**5**,6 | Renumbered 1–5 | I left the sibling `DELETE` claim in `generic-registry-api.md` alone — it is accurate, no DELETE route is registered (the `http.MethodDelete` hit in `server.go` is CORS config, not a route). ## Staleness banners rather than rewrites **`design/tech-architecture.md`** is substantially fictional. Rather than a vague "may be outdated", the banner lists what I verified is wrong: - Describes Helm-chart deployment; the registry is a plain `Deployment` ([registry.go:65](https://github.com/modelcontextprotocol/registry/blob/main/deploy/pkg/k8s/registry.go#L65)). Helm is used only for third-party components. - Diagram shows a `StatefulSet` on port **27017** — MongoDB's port. The DB is PostgreSQL on 5432 via the CloudNativePG operator. - Documents a `verify-domain` challenge flow (`POST /verify-domain`, `/verify-domain/check`, server-issued tokens) that **was never built**. - Documents `/admin/*` routes that are not registered. - Says the DB stores user auth state and DNS verification records; only `servers` and `server_extensions` tables exist. **`design/roadmap.md`** still says "Phase 1: MVP/Go-Live (Current Focus)" ~11 months after launch. I added a dated note rather than inventing a current phase — that is a working-group call. ## Verification All **101** remaining relative links across every `.md`/`.mdx` in the repo resolve. The only two non-resolving matches are the intentional `[project-name](link)` template placeholder and the moderation link fixed in #1518. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The admin takedown script cannot work as written, and the runbook that documents it has the same problem.
The bug
tools/admin/takedown.shsentPUTwith a?status=deletedquery parameter to two routes:PUT /v0/servers/{name}/versions/{version}?status=deletedServerJSONbody and has nostatusquery parameterPUT /v0/servers/{name}?status=deletedThe real endpoints are
PATCH /v0/servers/{name}/versions/{version}/statusandPATCH /v0/servers/{name}/status(status.go:83, :198), both taking{"status": ..., "statusMessage": ...}.edit.goeven says so in its own description: use the status endpoint for status changes.Script changes
PATCHwith a JSON body built viajqVERSIONorALL_VERSIONS=trueexplicitly. Previously a missingVERSIONmeant "entire server". SincePATCH .../statusupdates every version, an operator who simply forgotVERSIONwould have taken down the whole server. Now that needs saying out loud.STATUS(defaultdeleted) andSTATUS_MESSAGE, so a takedown can record its reasonset -euo pipefail, non-zero exit on HTTP errors, and print the response body so huma error detail is visible instead of being swallowedRunbook changes
GET /v0/servers/{name}is not a route — useGET .../versions/latest(which is supported, see servers.go:155-178)?status=deletedloop with the single all-versionsPATCH .../statuscall, which reportsupdatedCountPUTloop for content edits, which genuinely has no bulk endpoint, and show that it needs the full bodymoderation-guidelines.mdlink (dead since the docs restructuring; the file is nowmodelcontextprotocol-io/moderation-policy.mdx)Verification
shellcheckclean,bash -nclean, and all three guard paths exercised (no args / neither VERSION nor ALL_VERSIONS / both set). BothPATCHpaths confirmed present indocs/reference/api/openapi.yaml. I did not run a live takedown against production.Kept on
/v0rather than/v0.1to match the existing admin/deploy convention — happy to switch if you would rather admin tooling target the frozen version.🤖 Generated with Claude Code