Releases the pending v1 security and hygiene fixes: the js-yaml
override correction (#2072), the remaining audit advisories (#2074),
and the esbuild/fsevents install-script denials (#2079). Together they
take `npm audit` from 8 advisories to 0.
Version fields only — no functional change.
The lockfile version fields were edited directly rather than via
`npm run update-version`, which finishes with a bare `npm install`
that re-resolves the whole tree; on this branch that churns 164
packages including production deps (@modelcontextprotocol/sdk, hono,
@hono/node-server 1.x -> 2.x major, jose, ws).
Fixes#2080
Claude-Session: https://claude.ai/code/session_01Gq5jMmxRUphrVbfNbYVmQH
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
npm 11.19 gates dependency lifecycle install scripts behind an
allowScripts allowlist and warns about any package not yet reviewed.
Three were pending: esbuild's postinstall and two copies of fsevents.
None of them is needed. esbuild resolves its platform binary through
optionalDependencies (@esbuild/darwin-*), so install.js is only a
validation/fallback-download step, and both fsevents copies ship a
prebuilt fsevents.node — their install script is just a node-gyp
rebuild fallback. Verified: builds and tests pass with the scripts
skipped.
Denying rather than approving keeps the warning quiet without granting
a standing "run this package's arbitrary install script" permission.
Claude-Session: https://claude.ai/code/session_01Gq5jMmxRUphrVbfNbYVmQH
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds overrides for the five advisories present in the production
dependency tree, plus two dev-only stragglers, bringing `npm audit`
to zero.
Only ip-address is meaningfully reachable: server/src/index.ts builds
sandboxRateLimiter from express-rate-limit, which parses IPs via
Address6 for subnet keying. Impact here is a rate-limit key bypass on
/sandbox rather than the SSRF the advisory titles imply, since req.ip
derives from the socket and the proxy binds localhost.
The other four are installed but unexercised: hono middleware is never
wired up, @hono/node-server's serve-static is never imported (only
getRequestListener), fast-uri is reached only for ajv format checks
whose result is never trusted for a host decision, and brace-expansion
expands serve-handler's config-supplied pattern rather than the
attacker-supplied path. nanoid and postcss are dev-only.
Every patched release exists within the current major line.
@hono/node-server is deliberately held at 1.19.17 rather than 2.x — a
major bump has no place on a deprecated branch.
Lock entries are patched in place rather than re-resolved, keeping the
diff to the affected packages.
Fixes#2074
Claude-Session: https://claude.ai/code/session_01Gq5jMmxRUphrVbfNbYVmQH
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The root `overrides` block pinned js-yaml to versions inside the
advisory range (3.15.0 and 4.2.0), so `npm audit fix` reported a fix
as available and then changed nothing — overrides take precedence.
Bumps both pins to the patched `v3-legacy` / `v4-legacy` releases,
addressing GHSA-52cp-r559-cp3m and GHSA-5p4m-2wfm-xmqj.
Exposure is development-only: `npm ls js-yaml --omit=dev` is empty and
both copies are reachable only via eslint and ts-jest/istanbul, neither
of which ships in the published package.
Both patched versions have an identical dependency and bin shape, so
the lock entries were patched in place — 6 lines, no transitive churn.
Fixes#2072
Claude-Session: https://claude.ai/code/session_01Gq5jMmxRUphrVbfNbYVmQH
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Addresses the round-1 Copilot review.
- createPinnedAgent: Node's net.connect runs with autoSelectFamily on
(Node >= 20), so it calls the lookup hook with `{ all: true }` and
requires an ARRAY of `{ address, family }`. The scalar-only callback
failed every hostname request with ERR_INVALID_IP_ADDRESS, so /fetch
could only reach literal-IP targets. Both callback shapes are now
supported. Reproduced against Node 22/26 before and after.
- Tests: cover the `{ all: true }` shape for IPv4 and IPv6, and add an
end-to-end request through the agent over the production path
(node-fetch -> http.Agent -> net.connect) using an unresolvable
hostname, so the request can only succeed via the pinned IP. Verified
these three fail without the fix. Replaced the `Function`-typed casts
with a typed pinnedLookup() helper.
- CI: run the new server suite (.github/workflows/main.yml) and add a
root `test-server` script, so this regression coverage is enforced.
- package-lock.json: sync the server workspace manifest mirror with the
added @types/node and vitest devDependencies.
- index.ts: drop the `agent as any` cast and its eslint-disable — the
node-fetch RequestInit already types `agent`, and tsc is clean without
the suppression.
- Formatting: prettier-check now passes (it failed on the two new files).
Signed-off-by: cliffhall <cliff@futurescale.com>
#1828 pinned v1 publishes to `--tag v1`, following the runbook (#1804 §1). That
tag name is not legal: npm rejects any dist-tag that parses as a SemVer range,
and `v1` parses as `1.x`.
npm error Tag name must not be a valid SemVer range: v1
Found while running the companion `npm dist-tag add` step, which failed the
same way. So the merged flag would not have "published to the wrong tag" — the
next v1 security release would have failed to publish at all, and only at
release time.
`v1-latest` is accepted (verified against semver.validRange, along with
`legacy`, which was the other candidate). The workflow comment now records both
failure modes so neither the flag nor the specific tag name gets "cleaned up"
later.
Claude-Session: https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
`publish-all` had no `--tag`, so npm assigned `latest` to whatever it
published. That was correct for 1.0.1 — the deprecation release had to take
`latest` to reach npx users — but it becomes a trap the moment 2.0.0 ships: a
1.0.2 security fix published from `v1/main` would move `latest` back to v1, and
every `npx @modelcontextprotocol/inspector` in the world would silently get the
deprecated line.
`--tag v1` on both halves covers all four package names — `--workspaces` fans
out to inspector-client/-server/-cli, and the second invocation is the root.
Nothing enforces this flag, and the cost of dropping it surfaces months later
in a way that looks like an npm bug rather than a missing argument, so the
workflow carries a comment at the point of use.
Phase 3 of the v2 go-live runbook (#1804 §1).
Claude-Session: https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: v1 deprecation notices in all four packages, bump to 1.0.1
Phase 2 of the v2 go-live runbook (#1804 §4). v1 publishes four separately
installable names, so each gets its own notice — a root-README-only change is
invisible to anyone who installed a sub-package. `cli/` and `server/` ship no
README at all, so for those two the runtime banner plus the forthcoming
`npm deprecate` (#1816) are the only notice their users ever get.
Notices, all using identical wording so the runtime banner and the npm warning
agree:
- root `README.md` and `client/README.md`
- `cli/src/cli.ts` — stderr banner in `main()`. Also covers the root
`mcp-inspector` bin, which is `cli/build/cli.js`. Deliberately **stderr**:
`--cli` mode emits JSON on stdout and callers pipe it, so a banner there
would corrupt output. Verified against a real server — stdout stays
parseable JSON while the banner goes to stderr.
- `server/src/index.ts` — alongside the existing proxy listening log
- `client/bin/start.js` — alongside the existing startup URL log
- `client/src/components/DeprecationBanner.tsx` — dismissible in-app banner,
dismissal persisted in localStorage with both read and write guarded so a
storage failure degrades to "banner reappears" rather than breaking the app
AGENTS.md is replaced with a hard stop: v1 takes security fixes only, by issue
only, and agents must never open a PR against v1/main.
Version bumped to 1.0.1 across all four package.json files plus the lockfile
(`npm run update-version`); `check-version` passes. The lockfile diff is
restricted to the version fields — the `libc` churn a newer npm wanted to
introduce was reverted as unrelated.
`publish-all` is deliberately NOT changed here: 1.0.1 must take `latest`, which
is the entire point of shipping this notice to npx users. Adding `--tag v1` is
#1816, immediately after this publishes.
Note for review: `client/src/App.tsx` shows ~836 changed lines but `git diff -w`
shows 8 — wrapping the layout in a flex column added one nesting level and
prettier re-indented the subtree. Review it with `-w`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD
* docs: replace the README screenshot with one showing the deprecation banner
Captured from this branch's build: v1.0.1 in the sidebar heading, the
dismissible deprecation banner across the top, connected to the everything
server with tools listed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Txmv2qqv3yeKgRzoqXytzD
* docs: pin the README screenshot to v1/main instead of main
The image URL must stay absolute — a relative path breaks on the npm package
page, which renders the README outside any repo context. But it was pinned to
`main`, so the v1 README rendered whatever `main` happened to hold: today the
pre-deprecation screenshot, and after the v2 tree swap (#1817) either the v2
screenshot or a 404 if that path doesn't exist there.
Pinning to `v1/main` keeps it absolute for npm, shows the deprecation banner
once this merges, and survives the swap. Verified all candidate refs resolve
200 — GitHub disambiguates the slash in `v1/main` as the ref without needing a
`refs/heads/` prefix.
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>
npm does not reliably apply these transitive overrides to an existing
lockfile (bare and targeted overrides via install/update leave residual
vulnerable copies). This regenerates the lockfile from scratch with
version-targeted overrides so every copy of the affected packages
resolves to a patched version.
Resolves Dependabot alerts:
- esbuild #121 (-> 0.28.1)
- minimatch #69, #66, #61 (3.x -> 3.1.5)
- @babel/core #132 (-> 7.29.7; completes the partial fix from #1712)
Also pins js-yaml overrides (3.15.0 / 4.2.0) to prevent regression.
Supersedes #1713, #1714, #1715. Part of #1706.
Verified: 0 vulnerable copies across all advisories; build + client (535)
+ cli tests pass; lockfile internally consistent.
Claude-Session: https://claude.ai/code/session_01HiccCEh9mwCfVzE8qYcop1
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolves Dependabot alert #132. Uses a version-targeted override
(@babel/core@<=7.29.0) so all copies of the vulnerable range are bumped.
Part of #1706.
Claude-Session: https://claude.ai/code/session_01HiccCEh9mwCfVzE8qYcop1
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bumps shell-quote from ^1.8.3 to ^1.8.4 in the root and server
packages to resolve a critical security advisory. Adds an npm
override so concurrency's pinned shell-quote@1.8.3 also resolves to
a patched version, leaving no vulnerable copy in the tree.
Claude-Session: https://claude.ai/code/session_01HiccCEh9mwCfVzE8qYcop1
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The "Check formatting" step in main.yml ran `npx prettier --check .`
before `npm install`, so npx fetched the LATEST prettier rather than the
version pinned in package-lock.json. This made the format check
non-deterministic and red on open PRs whenever the latest published
prettier differed from the pinned one.
- Pin prettier to exact 3.9.5 in devDependencies and update the lockfile
- Reformat the repo with the pinned prettier (expected source churn)
- Move the format check after `npm install --no-package-lock` and run it
via `npm run prettier-check` so CI uses the locally-installed pinned
prettier
Claude-Session: https://claude.ai/code/session_01HiccCEh9mwCfVzE8qYcop1
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Previous fix only added repository.url to the root package.json, but npm
publish --workspaces publishes each workspace using its own package.json.
The provenance check runs per-package, so each published workspace package
also needs repository.url to match the GitHub repo URL. Also adds type: "git"
to the root and directory fields to the workspaces for correct monorepo
linking on npm/GitHub.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add server-side proxy endpoints for OAuth discovery, client registration,
and token exchange to avoid CORS issues when using proxy connection mode.
Server proxy endpoints:
- GET /oauth/resource-metadata - proxies OAuth protected resource metadata
- GET /oauth/metadata - proxies OAuth authorization server metadata
- POST /oauth/register - proxies dynamic client registration
- POST /oauth/token - proxies token exchange
Client changes:
- Construct correct RFC 9728/8414 path-aware well-known URLs client-side
- Route all OAuth discovery through proxy when in proxy connection mode
- Eliminate direct browser fetches that fail with CORS in proxy mode
The sandbox_proxy.html file was not shipped in the npm package because
the files arrays in both package.json and server/package.json only
included the build directory. The server code resolves the file via
join(__dirname, '..', 'static', 'sandbox_proxy.html') which expects
static/ as a sibling of build/, but it was missing from the package.
- Updated all package.json files to version 0.20.0
- Updated workspace dependencies in root package.json
- Updated package-lock.json
- Verified version consistency with check-version-consistency script
Co-authored-by: Ola Hungerford <olaservo@users.noreply.github.com>
- Updated version in root package.json
- Updated version in cli/package.json
- Updated version in client/package.json
- Updated version in server/package.json
- Updated workspace dependencies in root package.json
- Updated package-lock.json via npm install
Co-authored-by: Ola Hungerford <olaservo@users.noreply.github.com>
Ensures fresh installs without lock file get the patched version.
🦉 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Version 0.17.3 had TypeScript build errors that prevented successful builds. This patch release fixes those errors and bumps the version to 0.17.4.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* In package.json under cli/, client/, server/ and /
- bump @modelcontextprotocol/sdk to ^1.20.1
* In client/package.json
- bump @vitejs/plugin-react to ^5.0.4
- bump vite to ^7.1.11
* In package-lock.json
- bump playwright to 1.56.1
- cascading changes to rollup and other dependencies
Add npm override to lock get-intrinsic to version 1.3.0, preventing
upgrades to 1.3.1 which requires the generator-function package.
The generator-function package is not available in Anthropic's internal
Artifactory, causing installation failures when users run
`npx @modelcontextprotocol/inspector` and npm resolves to get-intrinsic@1.3.1.
This override ensures all installations use get-intrinsic@1.3.0 which does
not have the generator-function dependency.
- New feature: Connection Type
- Reverts "fix: filter out client_secret when storing OAuth client information"
- Fixes STDIO "Headers is undefined" message when connecting to an SSE server.
- in createCustomFetch function
- convert finalHeaders to headers object for node-fetch compatibility
- for SSE streams, convert node stream to response body to web ReadableStream since EventSource polyfill expects web-compatible stream
* In package-lock.json and package.json
- add node-fetch as a dependency
This fixes#600
- set TS SDK to 1.17.5, which has the automatic log level handling
* In useConnection.ts
- push the logging/setLevel message onto the message history stack so it is clear in the Inspector that it has been sent.