Skip to content

fix(packaging): bundle fast-uri 3.1.8 in dist to clear nine advisories - #2973

Open
Andiii208 wants to merge 1 commit into
modelcontextprotocol:mainfrom
Andiii208:fix/inlined-fast-uri-advisories
Open

Andiii208 wants to merge 1 commit into
modelcontextprotocol:mainfrom
Andiii208:fix/inlined-fast-uri-advisories

Conversation

@Andiii208

@Andiii208 Andiii208 commented Oct 9, 2026 •

Copy link
Copy Markdown

Closes #2966.

What

Pin fast-uri to 3.1.8 through the root resolutions (the mechanism already used for strip-ansi), so the ajv copy inlined into the client and server dist/ bundles the patched fast-uri instead of 3.1.0. The published dependency manifests are unchanged, so this is a patch, not a major.

Why

packages/client/tsdown.config.ts and packages/server/tsdown.config.ts list ajv/ajv-formats in noExternal, so the transitive fast-uri is inlined into dist/ while neither package declares it in dependencies. Consumers therefore cannot raise it with overrides/resolutions, and lockfile-based scanners cannot see it. fast-uri 3.1.0 carries nine published advisories, all fixed in 3.1.8:

GHSA-4c8g-83qw-93j6, GHSA-7p8r-x3mc-p8w7, GHSA-f65p-4m7j-42xc, GHSA-hrr3-gc8f-f4qj, GHSA-jqff-g426-hqxp, GHSA-q3j6-qgpj-74h6, GHSA-qw65-cvwx-89v3, GHSA-v2hh-gcrm-f6hx, GHSA-v39h-62p7-jpjc.

This is the security-vulnerability update trigger in DEPENDENCY_POLICY.md, and the minimal shape that trigger allows under CLAUDE.md's "small changes" principle.

Reachability on the default path (analysis from #2036 by a downstream consumer): on Node, Client defaults jsonSchemaValidator to the bundled-ajv-backed validator, and Client.callTool() compiles the outputSchema returned by the remote server's tools/list, so URI strings the server controls reach the bundled fast-uri parser.

Verification (all on this branch)

  • pnpm audit: fast-uri advisories 9 → 0. (The remaining findings are pre-existing dev-tree advisories in other packages, untouched by this change.)
  • pnpm run build:all, then the region markers in the built output:
    #region ../../node_modules/.pnpm/fast-uri@3.1.8/ in client/server dist/validators/ajv*.{mjs,cjs}; no fast-uri@3.1.0 code anywhere in dist/.
  • the new fastUriBundlePin tests in client and server against the built output: pass on this branch (every marker names the pinned 3.1.8) and fail when the pin and the built dist/ disagree.
  • node scripts/smoke-dist-types.mjs: clean for both the ESM and the CommonJS consumer (skipLibCheck: false).
  • pnpm -r --filter '!@modelcontextprotocol/test-e2e' test: all green. Per package: server 577 passed, client 998 passed, core-internal 1525 passed.
  • pnpm run typecheck:all and pnpm run lint:all: clean (also re-run by the pre-push hook on push).

Packaging pin: client and server each gained a small fastUriBundlePin test that scans the built dist/ and asserts every fast-uri@<version> marker — rolldown's #region comments over the inlined modules and the dts shim's provenance comment — names the root resolutions pin, and that at least one marker exists (i.e. ajv/ajv-formats are still noExternal). There is no behavior change to test — same ajv, same options, patched transitive parser — but the shipped copy reaches neither the published manifest nor the lockfile, so the version that actually lands in dist/ is now pinned directly.

Deliberately not in this PR

  • Unbundling ajv into a declared dependency. DEPENDENCY_POLICY.md calls adding a runtime dependency a significant change that needs discussion first, and it would change every consumer's install tree. Happy to do it as a follow-up if you prefer that direction.
  • Bumping ajv itself. All nine advisories are in fast-uri; an ajv bump without a concrete motivation is exactly what the dependency policy rules out.
  • The issue's optional SBOM/README request. Worth doing separately if you want it.

One note on the shim: packages/core-internal/src/validators/fastUriShim.d.ts copies fast-uri's URIComponent; I verified 3.1.8's interface is field-for-field identical to 3.1.0's, so only the provenance comment changed.

@Andiii208
Andiii208 requested a review from a team as a code owner October 9, 2026 08:08
@changeset-bot

changeset-bot Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a2d39c8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@modelcontextprotocol/client Patch
@modelcontextprotocol/server Patch
@modelcontextprotocol/codemod Patch
@modelcontextprotocol/core Patch
@modelcontextprotocol/server-legacy Patch
@modelcontextprotocol/core-internal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@2973

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@2973

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@2973

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@2973

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@2973

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@2973

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@2973

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@2973

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@2973

commit: a2d39c8

@claude claude Bot added the v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes label Oct 9, 2026
@0xamlab

0xamlab commented Oct 10, 2026

Copy link
Copy Markdown

Verified this end-to-end on the PR checkout. pnpm audit reports 0 advisories for fast-uri and ajv; the lockfile moves the resolution from fast-uri@3.1.0 to 3.1.8 (pnpm-lock.yaml). The client suite passes 997 tests and the server suite passes 576 tests. After building both packages, the bundled dist contains 24 references to fast-uri@3.1.8 and zero for 3.1.0, which is the real fix since ajv/ajv-formats are marked noExternal in packages/server/tsdown.config.ts:36 and packages/client/tsdown.config.ts:36 and the root resolutions pin is at package.json:92.

The ajv copy inlined into the client and server dist resolved fast-uri
3.1.0, which carries nine published advisories (all fixed in 3.1.8).
Because the copy is inlined rather than declared, consumer
overrides/resolutions and lockfile-based scanners cannot reach it. Pin
fast-uri through resolutions — the security-vulnerability trigger in
DEPENDENCY_POLICY.md — so the bundled copy is the patched one. Patch
release: the published dependency manifests are unchanged; only dist
content changes.

The dts shim's provenance comment now names 3.1.8; the URIComponent
interface is field-for-field identical, so no type change.

Which copy ships is observable only in the built output, so each package
now pins it there: a dist-scanning test asserts every fast-uri version
marker (rolldown's #region comments and the dts shim's provenance
comment) names the pinned version, and that at least one exists — the
inlining itself is the fix, so a dropped noExternal entry or a stale pin
fails CI instead of shipping.

Fixes modelcontextprotocol#2966
@Andiii208
Andiii208 force-pushed the fix/inlined-fast-uri-advisories branch from 47aa1f0 to a2d39c8 Compare October 10, 2026 15:46

@ascswe ascswe left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused fix and the bundle-level regression tests. I reviewed the two new fastUriBundlePin.test.ts files at head a2d39c8 and noticed two small opportunities to strengthen the future regression guard:

  1. Keep a security floor independent of the configured pin. pinnedFastUri() currently checks only that the root resolution is a valid x.y.z version. If that resolution and the built bundles were accidentally reverted to 3.1.0, the test would still pass. Could the test also enforce fast-uri >= 3.1.8 (or the project's approved minimum), rather than only agreement with the pin?

  2. Require runtime evidence in each format. The scan combines .mjs/.cjs runtime files with .d.mts/.d.cts declarations. A fast-uri@3.1.8 string present only in the d.ts shim's provenance comment could satisfy toContain(pinned) without checking that the ESM and CJS runtime bundles contain a matching version marker. Could the test require at least one matching marker in each runtime format, while still rejecting any conflicting markers across artifacts?

These are defense-in-depth suggestions for the tests, not a claim that the current patch is ineffective. This is a static source review; I did not run the builds or test suites.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v2] @modelcontextprotocol/server inlines fast-uri 3.1.0, which has 9 published advisories

3 participants