') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); fix(packaging): inline json-schema-typed in dist .d.mts; move validator-provider types to subpath-only; drop dead typesVersions.sse by felixweinberger · Pull Request #2362 · modelcontextprotocol/typescript-sdk · GitHub
Skip to content

fix(packaging): inline json-schema-typed in dist .d.mts; move validator-provider types to subpath-only; drop dead typesVersions.sse - #2362

Closed
felixweinberger wants to merge 57 commits into
mainfrom
fweinberger/packaging-dts-resolve
Closed

fix(packaging): inline json-schema-typed in dist .d.mts; move validator-provider types to subpath-only; drop dead typesVersions.sse#2362
felixweinberger wants to merge 57 commits into
mainfrom
fweinberger/packaging-dts-resolve

Conversation

@felixweinberger

@felixweinbergerfelixweinberger commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Fixes the four findings from the Tier 0.5 fresh-install smoke (fresh npm install of pkg.pr.new tarballs + tsc --noEmit with skipLibCheck: false).

Motivation and Context

The bundled dist/*.d.mts for @modelcontextprotocol/server and @modelcontextprotocol/client leak two type references that break any consumer with skipLibCheck: false (the TS default):

  • json-schema-typedcore/src/validators/types.ts does import type { JSONSchema } from 'json-schema-typed'; core is bundled into server/client but dts.resolve only listed ['ajv', 'ajv-formats'], so the import was left external. server/client don't declare it as a dep → TS2307 on the root entrypoint.
  • ajv URIComponent — ajv's published .d.ts references URIComponent from fast-uri, whose export = types the dts bundler cannot inline → dangling bare reference (TS2304) at the /validators/ajv subpath.

Fixes:

  • Add 'json-schema-typed' to dts.resolve in packages/{server,client}/tsdown.config.ts.
  • Stop re-exporting AjvJsonSchemaValidator / CfWorkerJsonSchemaValidator / CfWorkerSchemaDraft types from the package root (core/public). They remain available from the /validators/{ajv,cf-worker} subpaths. The root entrypoint no longer transitively imports ajv types at all.
  • Add packages/core/src/validators/fastUriShim.d.ts — a 24-line build-time-only URIComponent interface mapped via dts.compilerOptions.paths['fast-uri']. ajv's types reference URIComponent from fast-uri's export = namespace types, which the dts bundler cannot inline; the shim provides a named export the bundler can resolve. Type-only; no runtime impact, no added dependency.
  • packages/middleware/node/package.json: drop typesVersions.*.sse — points at a nonexistent dist/sse.d.mts.
  • packages/{server,client}/README.md: note that TS ≥6.0 needs "types": ["node"] in tsconfig.json.

How Has This Been Tested?

  • pnpm build:all — green; the pre-existing [MISSING_EXPORT] URIComponent build warning is gone.
  • Re-ran the fresh-install smoke against locally pnpm packed tarballs: npx tsc --noEmit (NodeNext, strict, skipLibCheck: false) → clean (exit 0) for both the root entrypoint andimport { AjvJsonSchemaValidator } from '@modelcontextprotocol/server/validators/ajv'. Same with moduleResolution: bundler.
  • test/integration cloudflareWorkers.test.ts (no nodejs_compat) — passes; node:module is not in any dist chunk.
  • Consumer node_modules has no json-schema-typed / ajv / fast-uri — types are fully self-contained.

Breaking Changes

AjvJsonSchemaValidator, CfWorkerJsonSchemaValidator and CfWorkerSchemaDraft are no longer re-exported from the @modelcontextprotocol/server / @modelcontextprotocol/client root entrypoints; import them from the /validators/{ajv,cf-worker} subpath instead. These are v2-only additions (not present in v1), and the codemod already routes v1 deep-path imports to the subpath, so this affects only within-alpha consumers.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

felixweinbergerand others added 30 commits June 24, 2026 13:28
Mirrors the v1.x-2026-07-28 arrangement: pull_request triggers are
unfiltered (PRs targeting the branch already get CI); this adds the
branch to the push filters so post-merge state runs CI too.
…xport isLegacyRequest; remove the handler-valued legacy option (#2316)
…era schemas, function-only WireCodec, bidirectional lint rule (#2351)
…per-dialect validation, non-object structuredContent (#2337)
@felixweinberger
felixweinberger requested a review from a team as a code ownerJune 24, 2026 15:52
@changeset-bot

changeset-botBot commented Jun 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7e8ad10

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

This PR includes changesets to release 2 packages
NameType
@modelcontextprotocol/serverPatch
@modelcontextprotocol/clientPatch

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-newBot commented Jun 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@2362

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/codemod@2362

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@2362

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server-legacy@2362

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@2362

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@2362

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@2362

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@2362

commit: 7e8ad10

@claudeclaudeBot 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.

LGTM — dts-bundling/packaging-only fix with no runtime or public-API impact; consider adding a patch changeset so the packaging fix actually ships.

Extended reasoning...

Overview

This PR is a packaging/types-bundling fix: it adds json-schema-typed to dts.resolve in the server and client tsdown.config.ts, maps fast-uri to a new dts-only shim (packages/core/src/validators/fastUriShim.d.ts) via dts.compilerOptions.paths, removes a dead typesVersions.*.sse block from @modelcontextprotocol/node (which pointed at a nonexistent dist/sse.d.mts and had no matching ./sse export), and adds a short README note about TS ≥6.0 requiring "types": ["node"].

Security risks

None. The changes only affect generated .d.mts declaration output, a dead package.json field, and README prose. The paths mapping lives under dts.compilerOptions, so runtime bundling and the published JS are unchanged. The new .d.ts shim is a plain interface with no runtime code, and @modelcontextprotocol/core is private so the shim itself is never published standalone.

Level of scrutiny

Moderate-low. This is build-configuration territory rather than protocol or transport logic, and the failure mode (broken declaration output) is caught by pnpm build:all and the author's fresh-install tsc --noEmit smoke with skipLibCheck: false, both reported green. The dead typesVersions removal is verifiably safe — the node middleware package only exports "." and never built dist/sse.d.mts.

Other factors

The bug-hunting pass found no issues. The only open item is the missing changeset (already flagged by changeset-bot): since this is a fix to what gets published, it presumably needs a patch changeset for client/server/node to actually reach npm — left to the author/maintainers to decide given the alpha release cadence.

@felixweinberger
felixweinbergerforce-pushed the fweinberger/packaging-dts-resolve branch from 1868cb0 to 2c87d9eCompareJune 24, 2026 16:25
Comment thread.changeset/validators-subpath-only.md Outdated
@felixweinberger
felixweinbergerforce-pushed the fweinberger/packaging-dts-resolve branch from 2c87d9e to f489a78CompareJune 24, 2026 16:49
Comment threadpackages/server/tsdown.config.ts
Comment threadpackages/core/src/exports/public/index.ts
@felixweinbergerfelixweinberger changed the title fix(packaging): inline json-schema-typed/fast-uri types into dist .d.mts; drop dead typesVersions.ssefix(packaging): inline json-schema-typed in dist .d.mts; move validator-provider types to subpath-only; drop dead typesVersions.sseJun 24, 2026
@felixweinberger
felixweinbergerforce-pushed the fweinberger/packaging-dts-resolve branch from f489a78 to 6211034CompareJune 24, 2026 22:46
…or provider types to subpath-only
The bundled server/client dist .d.mts files leaked two type references that
break downstream consumers with skipLibCheck:false (the TS default):
- types-*.d.mts imported 'json-schema-typed', which is not a dependency of
server/client (only of core, which is bundled). Fixed by adding
'json-schema-typed' to dts.resolve so the JSONSchema type is inlined.
- ajvProvider-*.d.mts referenced URIComponent without a declaration.
ajv@8.18.0's .d.ts does `import { URIComponent } from "fast-uri"`, but
fast-uri ships its types as `export = namespace`, which the dts bundler
cannot destructure — it drops the import and leaves the bare reference.
Fixed by removing the type-only re-exports of AjvJsonSchemaValidator /
CfWorkerJsonSchemaValidator / CfWorkerSchemaDraft from the public root
barrel: those classes/types are still exported from the dedicated
/validators/ajv and /validators/cf-worker subpaths (and the runtime
_shims conditional), so the inlined ajv type chunk is no longer reachable
from index.d.mts. The codemod already routes v1 imports to the subpaths.
Also:
- @modelcontextprotocol/node package.json: remove typesVersions.sse entry
pointing at nonexistent dist/sse.d.mts.
- server/client READMEs: note that TS >=6.0 needs "types": ["node"] in
tsconfig (TS 6 dropped implicit @types inclusion; the published .d.mts
references Buffer).
Verified: pnpm build:all + typecheck:all + docs:check green; fresh npm
install of packed tarballs + `npx tsc --noEmit` (NodeNext + bundler,
strict, skipLibCheck:false) is clean.
@felixweinberger
felixweinbergerforce-pushed the fweinberger/packaging-dts-resolve branch from 6211034 to 7e8ad10CompareJune 24, 2026 23:08

@claudeclaudeBot 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.

LGTM — prior feedback addressed (fastUriShim + paths mapping landed, changeset now covers CfWorkerSchemaDraft, breaking export move documented); only nit left is the PR description's "add fast-uri as a runtime dependency" bullet, which isn't in the diff and appears stale given the shim approach.

Extended reasoning...

Overview

Packaging-only PR touching the server/client tsdown dts configs (add json-schema-typed to dts.resolve, map fast-uri to a new 24-line fastUriShim.d.ts), removal of the validator-provider type re-exports from the curated public root barrel, removal of a dead typesVersions.sse entry in @modelcontextprotocol/node, README notes about TS ≥6.0 types: ["node"], and a changeset documenting the export-surface move. No runtime logic changes.

Security risks

None. Changes are confined to type-declaration bundling configuration, a .d.ts shim (no runtime code), package metadata, and documentation. No auth, crypto, network, or input-handling code is touched.

Level of scrutiny

Moderate. The diff affects what ships in the published packages (dist .d.mts content and the public type surface), but the only API change is removing three type-only re-exports from the root in an alpha line, which is documented in the changeset and covered by the codemod. The hand-written URIComponent shim is dts-only and matches fast-uri's published shape; worst case is a type mismatch with no runtime impact. The author reports a green pnpm build:all plus a fresh-install tsc --noEmit smoke with skipLibCheck: false on packed tarballs, which is the right end-to-end verification for this class of fix.

Other factors

All concerns from my previous review rounds were addressed in this revision: the fastUriShim.d.ts and fast-uri paths mapping that the description promised are now actually in the diff, the changeset names CfWorkerSchemaDraft alongside the two validator classes, and the PR description now carries an explicit Breaking Changes section. The bug-hunting system found no issues in this revision. The one residual nit is that the description still claims fast-uri was added as a runtime dependency of server/client, which the diff does not contain (and the shim approach makes unnecessary, since undeclared deps are bundled) — a stale prose detail the author may want to tidy, but not something that affects the shipped artifacts.

Base automatically changed from v2-2026-07-28 to mainJune 26, 2026 13:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@felixweinberger