Repository navigation
Conversation
The MCP Registry workflow only ever validated server.json; nothing published it. Release now calls it with the released version: it checks out the release tag, waits for npm to serve @pascal-app/mcp with its mcpName, publishes, and fails unless the registry lists the version.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Aymericr
left a comment
There was a problem hiding this comment.
Reviewed, and this looks right to me.
releasealready exposesversionandchannel, and every package is tagged in lockstep, sorefs/tags/@pascal-app/mcp@<version>will exist when themcp-registryjob runs (@pascal-app/mcp@1.0.6is there today).- The registry check before publishing makes reruns safe, and the final listing check means a green run actually proves the version is in the registry.
hosted-matches-manifestkeying offinputs.check-hostedkeeps it out of push, PR, andworkflow_callruns, which is what we want.
One small nit, not blocking: a manual dispatch with publish=true and no version publishes whatever server.json is on the dispatched ref without the tag check. Making version required whenever publish is set would close that gap.
Before this is useful, MCP_REGISTRY_PRIVATE_KEY has to be added (repo or npm environment). Until then the next stable release will finish with a red mcp-registry job after npm has already published. After merge, 1.0.6 still needs a one-time dispatch. I'll merge once quality, cli-smoke, and Bugbot are green.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e38db492f2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # A beta leaves server.json on the last stable version, which is already listed. | ||
| mcp-registry: | ||
| needs: release | ||
| if: inputs.dry-run == false && needs.release.outputs.channel == 'latest' |
There was a problem hiding this comment.
Exclude prerelease recovery runs from registry publishing
When a partial beta release is recovered with the documented bump=none, the release keeps its *-beta.* version but NPM_TAG/the channel output is set to latest because only the literal beta input selects the beta channel. This condition therefore invokes the registry workflow with the prerelease version, while sync-agent-versions.ts intentionally leaves server.json on the previous stable version; the called workflow then fails its VERSION != EXPECTED_VERSION check. A recovery that otherwise successfully publishes or tags the beta is consequently reported failed. Gate this job on the released version containing no prerelease suffix, or expose an explicit stable-release output instead of inferring stability from channel.
Useful? React with 👍 / 👎.
What does this PR do?
Root cause: no workflow in this repo has ever published
server.jsonto the MCP Registry.mcp-registry.ymlonly validates the manifest. The green run at 00:51 UTC (run 39880562788) was thepushtrigger fired by the 1.0.6 release commit changingserver.json. Only itsvalidatejob ran, andhosted-matches-manifestwas skipped. Publishing was a manual owner step (wiki/npm-release.md), and that step was done for 1.0.5 (00:42 UTC) but not for 1.0.6. The hunch about ordering was close, but the real issue is simpler: the workflow never publishes at all, so a green result says nothing about the registry.Changes:
mcp-registry.ymlnow also runs as a reusable workflow (workflow_call) and by manual dispatch, withversionandpublishinputs. A newpublishjob (needsvalidate, environmentnpm):@pascal-app/mcp@<version>tag and fails ifserver.jsonisn't at that version;npm view @pascal-app/mcp@<version> mcpNamereturnsapp.pascal/editor;mcp-publisher login dns --domain pascal.appand runsmcp-publisher publish;/v0/servers/app.pascal%2Feditor/versionsthen lists the version.validatechecks out the same tag, so a called run validates the released manifest instead of the pre-bump commit.hosted-matches-manifestnow runs only when thecheck-hosteddispatch input is set, and it doesn't gate the publish.release.yml: a newmcp-registryjob runs afterrelease, which has already published to npm and pushed tags. It runs only when the run is not a dry run and the channel islatest. Betas leaveserver.jsonon the last stable version, so they're skipped.Docs: the MCP Registry section of
wiki/npm-release.mdand the README describe the automated flow and how to recover a missed version.Version sourcing (criterion 2): this was already in place.
scripts/sync-agent-versions.tsrewritesserver.json'sversionandpackages[0].versionfrompackages/mcp/package.jsonduring the release, andskills:validatefails on drift. This PR doesn't change it.Server card (criterion 3): the server card isn't in this repo. The hosted deployment serves it, and this PR doesn't change it.
"version": "1.0"is the server-card document format version (themcp-server-card/v1schema), not the package version. It is meant to differ from the package version.serverInfo.versionand the API catalog's"1.0.4"should track the package.@pascal-app/mcpalready exportsversion, read from itspackage.json, andcreatePascalMcpServeruses it for the handshake. So the hosted side just needs to report that export and run the current package. Right now it's running/reporting@pascal-app/mcp@1.0.4. That's a hosted-deployment fix and can't be made from this repo. Thehosted-matches-manifestjob still flags the mismatch when it's dispatched.Maintainer action needed: the
app.pascalnamespace is verified through DNS, so CI needs the Ed25519 private key that matches thepascal.appTXT record. Add it asMCP_REGISTRY_PRIVATE_KEY, either as a repository secret or in thenpmenvironment. This PR doesn't add the secret. Until it exists, the new job fails with an error naming the missing secret. After merge, 1.0.6 has to be published once by hand:gh workflow run mcp-registry.yml -f version=1.0.6 -f publish=true -f check-hosted=false, ormcp-publisher publishfrom the@pascal-app/mcp@1.0.6tag.How to test
actionlint .github/workflows/mcp-registry.yml .github/workflows/release.ymlreports no errors (ran with actionlint 1.7.7).MCP Registryworkflow runs thevalidatejob only.publishandhosted-matches-manifestare skipped because their inputs are unset.version=1.0.6 publish=true check-hosted=false. The run should go green andcurl https://registry.modelcontextprotocol.io/v0/servers/app.pascal%2Feditor/versionsshould list 1.0.6. Dispatching again should skip the publish step and stay green.Checked locally: I ran the npm-wait and registry-listing shell logic read-only against the live services. It finds 1.0.5 listed, 1.0.6 missing, and the 1.0.6 npm
mcpName=app.pascal/editor.bun run check(pre-existing warnings only),bun run skills:validateandbun test scripts/sync-agent-versions.test.tspass. I did not run a registry publish.Screenshots / screen recording
N/A — non-visual change
Checklist
bun devbun checkto verify)mainbranchNote
Medium Risk
Adds automated external registry publishing that depends on a new CI secret and correct npm/registry timing; misconfiguration could fail releases or leave discovery out of sync until a manual dispatch.
Reviewed by Cursor Bugbot for commit e38db49. Bugbot is set up for automated code reviews on this repo. Configure here.