ci: publish server.json to the Official MCP Registry from GitHub Actions - #7
Merged
Merged
Conversation
The registry grants an organisation's io.github.<org>/* namespace only to org Owners on a personal login; ordinary members are refused, which is what blocked the manual publish. Workflows in this organisation's repositories get the namespace through GitHub Actions OIDC, so the publish moves into CI. - .github/workflows/publish-mcp-registry.yml: runs when server.json or the workflow lands on main, and on demand (main only). Validates with the registry's own validator, skips versions that are already published, publishes with login github-oidc, then confirms the exact version entry and links the Glama page in the job summary. Publisher pinned to 1.8.1 with the release checksum verified; no npm code runs next to the OIDC token. - scripts/check-plugin-manifests.sh + validate-plugin.yml: server.json joins the consistency check (version equals plugin.json, remote URL equals the MCP files) and runs on pull requests. actions/checkout bumped to v5 ahead of the Node 20 removal from runners on 2026-09-23. - glama.json: maintainers who can claim the Glama pages. Refs Linear GTM-86. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 4 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/workflows/publish-mcp-registry.yml">
<violation number="1" location=".github/workflows/publish-mcp-registry.yml:70">
P2: When the registry lookup gets a transient 5xx, rate limit, or network error, this conditional treats the version as unpublished and runs the publish path. Distinguish HTTP 404 from lookup errors and retry or fail before publishing.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| name=$(jq -r .name server.json) | ||
| version=$(jq -r .version server.json) | ||
| encoded=$(jq -rn --arg n "$name" '$n | @uri') | ||
| if curl -fsS -o /dev/null "$REGISTRY_URL/v0/servers/$encoded/versions/$version"; then |
There was a problem hiding this comment.
P2: When the registry lookup gets a transient 5xx, rate limit, or network error, this conditional treats the version as unpublished and runs the publish path. Distinguish HTTP 404 from lookup errors and retry or fail before publishing.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/publish-mcp-registry.yml, line 70:
<comment>When the registry lookup gets a transient 5xx, rate limit, or network error, this conditional treats the version as unpublished and runs the publish path. Distinguish HTTP 404 from lookup errors and retry or fail before publishing.</comment>
<file context>
@@ -0,0 +1,99 @@
+ name=$(jq -r .name server.json)
+ version=$(jq -r .version server.json)
+ encoded=$(jq -rn --arg n "$name" '$n | @uri')
+ if curl -fsS -o /dev/null "$REGISTRY_URL/v0/servers/$encoded/versions/$version"; then
+ echo "::notice::$name@$version is already in the registry; bump version in server.json to publish again"
+ echo "skip=true" >> "$GITHUB_OUTPUT"
</file context>
okwasniewski
approved these changes
Sep 21, 2026
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.
Why
Publishing
io.github.tester-army/testerarmyto the Official MCP Registry from a laptop only works for an org Owner: the registry grants an organisation'sio.github.<org>/*namespace to GitHub users whose org role is Owner (itsgithub_at.goand authentication docs), and refuses ordinary members with "only io.github.lil-bsz/* allowed". Public membership makes no difference.The route that needs nobody's personal login is GitHub Actions OIDC: the registry grants
io.github.<repository owner>/*to any workflow running in this organisation's repositories. So the publish moves into CI. Tracked in Linear GTM-86 (Listings project).What changes
.github/workflows/publish-mcp-registry.ymlruns whenserver.json(or the workflow file) lands onmain, and on demand from the Actions tab (main only). Steps:mcp-publisher1.8.1, verifying the download against the release checksumsmcp-publisher validate server.json(the registry's own validator, schema plus semantic rules)login github-oidc,publishPermissions are
contents: readplusid-token: writeon the publish job only. Nopull_requesttrigger, no secrets, no npm code runs in the job, so fork PRs cannot reach anything. The job declares themcp-registry-publishenvironment so an Owner can add a deployment branch rule and a required reviewer later without a code change; until then theif: github.ref == 'refs/heads/main'guard is the gate, because the registry authorises on the repository owner alone and never checks the branch.Merging this PR triggers the first publish of version 1.0.0 (the workflow file is in its own path filter and
server.jsonis already on main).scripts/check-plugin-manifests.shandvalidate-plugin.ymlnow coverserver.json: valid JSON,versionequal toplugin.json,remotes[0].urlequal to the MCP files. It runs on pull requests that touchserver.json, so a version bump that forgets the registry manifest fails before merge.actions/checkoutgoes to v5 in both workflows ahead of GitHub removing Node 20 from runners on September 23.glama.jsonnames the maintainers (Oskar, Szymon, Bartek) who may claim the Glama pages that the registry entry will generate. Glama, PulseMCP and the other aggregators ingest the official registry.Verification
actionlintclean on both workflows; YAML parsesmcp-publisher validate server.jsonagainst the live registry: validserver.jsonis bumped alone (tested)After merge
glama.json.mcp-registry-publish, deployment branches limited tomain, add a required reviewer.🤖 Generated with Claude Code