ci: derive the npm dist-tag from the version instead of defaulting to latest - #1834
Merged
Conversation
… latest `npm publish` defaults to `--tag latest` regardless of semver prerelease status, and the publish step passed no `--tag`. So cutting the `2.0.0-rc.1` release that #1818 calls for would have published the release candidate to `latest` — pointing every `npx @modelcontextprotocol/inspector` at an RC. That is the same class of failure #1816 fixed for v1, except triggered deliberately by following the runbook. Derives the tag from the version: a hyphen after the patch component means a prerelease (`2.0.0-rc.1` → `next`), anything else is a release (`2.0.0` → `latest`). Build metadata (`2.0.0+build.5`) is correctly not a prerelease. Implemented as a shell `case` rather than with `semver`, which is only a transitive dependency here and should not be relied on in CI. Also makes the RC step of #1818 possible at all — there was previously no way to pass a dist-tag through a release-triggered publish. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD
5 tasks
Merged
cliffhall
added a commit
that referenced
this pull request
Jul 28, 2026
Release candidate for the 2.0.0 go-live (#1818, §6). Publishes under the `next` dist-tag via the derivation added in #1834 — verified: `2.0.0-rc.1` contains a hyphen after the patch component, so it resolves to `next`, leaving `latest` on 1.0.1 untouched. The RC exists to exercise what only exists against the live registry: the `next`-tag publish path itself (newly written in #1834), provenance/OIDC minting, the `files` allowlist as npm actually packs it, and the postinstall cascade's early-exit under a real dependency install on a clean machine. Claude-Session: https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
cliffhall
added a commit
that referenced
this pull request
Jul 28, 2026
…TOKEN (#1836) * fix(ci): publish via OIDC trusted publishing, not a non-existent NPM_TOKEN The 2.0.0-rc.1 publish failed with `npm error code ENEEDAUTH`. Two causes, both in the v2 publish job, which had never actually executed before — every prior release was cut from the v1 workflow. 1. `NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}` pointed at a secret that does not exist (the repo has no secrets at repo or environment level — publishing moved to OIDC trusted publishing). `setup-node` therefore wrote an *empty* `_authToken` into its generated `.npmrc`, and npm failed ENEEDAUTH before OIDC was ever attempted. Removed, with a comment saying why it must not be "restored". 2. The job never upgraded the npm CLI. Trusted publishing requires npm >= 11.5.1 and Node 22 bundles 10.x, so this would have failed even with the token line gone. The v1 workflow has this step; v2 was missing it. The RC did its job: it caught both against the real registry, and consumed nothing — the run failed before `npm publish` wrote anything, so no version was burned and the dist-tags are untouched. Also confirms #1834 works: the log shows `Publishing 2.0.0-rc.1 under dist-tag 'next'` before the auth failure. README corrected — it documented `NPM_TOKEN` as part of the publish setup. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD * docs: restructure the test-servers section into navigable subsections The section had grown into eight undifferentiated paragraphs, the longest 1,965 characters, each describing one or two showcase configs. The content is good reference material — the problem was purely that you could not find anything in it or tell where one config's description ended and the next began. Restructured, not rewritten. No facts removed: - A summary table of all nine showcase configs, with what each demonstrates and its tracking issue, so the set is visible at a glance. - One `####` subsection per config family, so each is linkable and skimmable. - Enumerations that were buried in prose are now tables: the six MRTR presets, the four `trigger_*` spec-error tools and their status/code pairs. - Step sequences (advertised extensions) and era contrasts (logging, subscriptions, tasks) are now bullets rather than run-on sentences. - Two caveats that were parenthetical asides — browser `Mcp-Param-*` skipping, and `collect_elicitation` erroring on the modern leg — are now blockquotes, since both are things you hit and then have to go hunting for. Longest line drops 1,965 → 620 characters. Verified every previously-documented config and all technical identifiers survive. Noted while auditing: `demo.json`, `oauth-step-up-demo.json`, `url-elicitation-form.json` and `xaa-ema-http.json` exist in `test-servers/configs/` but have never been documented here. Left alone — that is a pre-existing gap, not a regression from this change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Merged
cliffhall
added a commit
that referenced
this pull request
Jul 28, 2026
The v2 go-live release (#1818, phase 5 of #1804). This is byte-identical to 2.0.0-rc.3 apart from dropping the prerelease suffix, which is what makes rc.3's validation meaningful: the tree that ships is the tree that was validated against the live registry. `2.0.0` has no hyphen, so the derivation added in #1834 resolves it to `latest` — this is the release that takes the tag from 1.0.1. Validated across three release candidates: - rc.1 caught two publish-path defects invisible to every local check — `NODE_AUTH_TOKEN` pointing at a non-existent secret (shadowing OIDC trusted publishing) and a missing npm CLI upgrade (trusted publishing needs >= 11.5.1; Node 22 bundles 10.x). Both fixed in #1836. - rc.2 validated the dependency sweep (#1837) that cleared every prod-scope advisory using lockfile-only changes. - rc.3 validated the vite 8.1.5 bump (#1841) closing three high-severity dev-server file-read advisories. Each RC was verified with a cold `node:22` container install driving the published tarball end to end — install, `--help`, and a real `--cli tools/list` against a live stdio server. `latest` remained on 1.0.1 throughout, proving the `--tag` derivation. Zero open Dependabot alerts at time of release. Claude-Session: https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Jul 28, 2026
Closed
cliffhall
added a commit
that referenced
this pull request
Aug 2, 2026
…#1904) main's copy of .github/workflows/main.yml carried three release fixes v2/main never took -- #1831 (least-privilege default GITHUB_TOKEN scope), #1834 (derive the npm dist-tag from the version) and #1836 (publish via npm OIDC trusted publishing). Diffing the file both directions shows v2/main has NOTHING main lacks: its only unique content is the superseded publish step, run: npm publish --access public --provenance env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} which is exactly what #1836 replaced. Every other line already matched. So this is a verbatim copy of main's file rather than a hunk-by-hunk forward-port -- fewer ways to get it wrong, and it leaves the two branches byte-identical (`git diff origin/main -- .github/workflows` is now empty). Not a back-merge: only this one file is taken, so none of main's pre-swap v1 lineage enters v2/main's ancestry (see #1868). Claude-Session: https://claude.ai/code/session_01YAt8rqxysNbhYWLhoRm3fU Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2 tasks
pull Bot
pushed a commit
to Bang2985/inspector
that referenced
this pull request
Aug 5, 2026
Resolves the eight conflicts from the first v2/main -> main milestone merge on a branch cut from main, so v2/main's ancestry stays clean -- resolving them on the PR head would have back-merged main into v2/main, which is exactly what modelcontextprotocol#1868 was closed to avoid. All eight took v2/main's side, each verifiably the newer content: - README.md stale Mcp-Param-* callout; v2/main's is corrected by modelcontextprotocol#1847 (the Inspector builds the headers itself) - SECURITY.md add/add (modelcontextprotocol#1843 on main, modelcontextprotocol#1867 on v2/main); differ by one line, the CONTRIBUTORS.md -> CONTRIBUTING.md rename from modelcontextprotocol#1884 - clients/web/package.json vitest ^4.1.0 -> ^4.1.10, the modelcontextprotocol#1899 fix - the five package-lock.json files, then regenerated from a clean install rather than hand-merged main's release-workflow commits (modelcontextprotocol#1831 least-privilege token, modelcontextprotocol#1834 dist-tag derivation, modelcontextprotocol#1836 OIDC trusted publishing) auto-merged and are preserved -- .github/workflows/main.yml is the only file where the merged tree differs from v2/main. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YAt8rqxysNbhYWLhoRm3fU
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.
Blocking prerequisite for #1818. Found while preparing the RC step, which could not have worked as written.
The bug
npm publishdefaults to--tag latestregardless of semver prerelease status, and the publish step passed no--tag:So cutting the
2.0.0-rc.1release that #1818 calls for would have published the release candidate tolatest— everynpx @modelcontextprotocol/inspectorin the world would resolve to an RC.That is the same class of failure #1816 fixed for v1 (a missing
--tagsilently claiminglatest), except here it would have been triggered deliberately, by following the runbook.There was also simply no mechanism to pass a dist-tag through a release-triggered publish, so the RC step was not achievable at all before this.
The fix
A hyphen after the patch component is a prerelease per semver; build metadata uses
+and correctly is not. Verified against real inputs:2.0.0latest2.0.1latest10.20.30latest2.0.0-rc.1next2.0.0-beta.3next2.0.0+build.5latestWhy shell and not
semversemverresolves in this repo only as a transitive dependency. Relying on it in CI means a publish step that breaks whenever some unrelated package drops it from its tree — not a dependency worth taking for a one-line predicate.Notes
The step also logs the chosen tag before publishing, so the release run shows which dist-tag was claimed rather than leaving it to be inferred afterwards.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD