Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .changeset/no-dangling-declaration-maps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@modelcontextprotocol/core': patch
'@modelcontextprotocol/client': patch
'@modelcontextprotocol/server': patch
'@modelcontextprotocol/server-legacy': patch
'@modelcontextprotocol/codemod': patch
'@modelcontextprotocol/express': patch
'@modelcontextprotocol/fastify': patch
'@modelcontextprotocol/hono': patch
'@modelcontextprotocol/node': patch
---

Stop shipping broken declaration source maps (`.d.mts.map`/`.d.cts.map`). The published
packages only include `dist/`, so the declaration maps pointed at `src/` paths (and the
private `core-internal` workspace package) that do not exist in the tarball and carried no
embedded source content — declaration-map-aware tooling could only ever resolve them to
"source not found". The declaration maps and their `sourceMappingURL` references are no
longer emitted; runtime JS source maps (which embed `sourcesContent`) are unchanged.
8 changes: 8 additions & 0 deletions common/tsdown/stripDtsSourceMappingUrl.d.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Rolldown } from 'tsdown';

/**
* tsdown `inputOptions` hook that removes the trailing `//# sourceMappingURL=` comment from the
* emitted `.d.ts` / `.d.mts` / `.d.cts` chunks. See the implementation in
* `./stripDtsSourceMappingUrl.mjs` for the full rationale (#2233).
*/
export function stripDtsSourceMappingUrl(options: Rolldown.InputOptions): void;
38 changes: 38 additions & 0 deletions common/tsdown/stripDtsSourceMappingUrl.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Plain .mjs (with a sibling .d.mts) so tsdown's native config loader can import it from the
// per-package tsdown.config.ts files on every supported Node version.

const RE_DTS_CHUNK = /\.d\.[cm]?ts$/;
const RE_DTS_SOURCE_MAPPING_URL = /\n?\/\/# sourceMappingURL=\S+\s*$/;

/**
* tsdown `inputOptions` hook that removes the trailing `//# sourceMappingURL=` comment from the
* emitted `.d.ts` / `.d.mts` / `.d.cts` chunks.
*
* The published packages ship only `dist/` (`"files": ["dist"]`), and tsc cannot embed
* `sourcesContent` into declaration maps, so shipped `.d.*ts.map` files would always point at
* `src/` paths that do not exist on a consumer's machine (#2233). Setting `dts.sourcemap: false`
* stops the maps from being emitted, but the JS-level `sourcemap: true` still makes rolldown
* append a sourceMappingURL comment to the declaration chunks; this hook strips that comment so
* the shipped declaration files do not reference maps that are not there.
*
* Registered via `inputOptions` rather than `plugins` because tsdown does not forward user
* plugins to the extra CJS dts pass that emits the `.d.cts` files.
*
* @param {import('tsdown').Rolldown.InputOptions} options
* @returns {void}
*/
export function stripDtsSourceMappingUrl(options) {
options.plugins = [
options.plugins,
{
name: 'strip-dts-source-mapping-url',
generateBundle(_outputOptions, bundle) {
for (const output of Object.values(bundle)) {
if (output.type === 'chunk' && RE_DTS_CHUNK.test(output.fileName)) {
output.code = output.code.replace(RE_DTS_SOURCE_MAPPING_URL, '\n');
}
}
}
}
];
}
11 changes: 10 additions & 1 deletion packages/client/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineConfig } from 'tsdown';

import { stripDtsSourceMappingUrl } from '../../common/tsdown/stripDtsSourceMappingUrl.mjs';

export default defineConfig({
failOnWarn: 'ci-only',
entry: [
Expand All @@ -20,6 +22,11 @@ export default defineConfig({
platform: 'node',
shims: true,
dts: {
// Declaration maps would reference src/ (and, where bundled, the private
// core-internal's src/), which is not shipped ("files": ["dist"]); tsc cannot
// embed sourcesContent into .d.ts maps, so the shipped maps could never resolve
// on a consumer's machine. Don't emit them (#2233).
sourcemap: false,
resolver: 'tsc',
resolve: ['ajv', 'ajv-formats', 'json-schema-typed'],
compilerOptions: {
Expand All @@ -37,5 +44,7 @@ export default defineConfig({
// The schema modules live in @modelcontextprotocol/core (a real runtime dependency); the
// bundled core-internal shims import them via the './internal' subpath, which must stay an
// external import (explicit entry — the tsconfig paths alias would otherwise inline it).
external: ['@modelcontextprotocol/client/_shims', '@modelcontextprotocol/core/internal']
external: ['@modelcontextprotocol/client/_shims', '@modelcontextprotocol/core/internal'],
// Drop the dangling sourceMappingURL comment rolldown leaves on the (map-less) declaration output.
inputOptions: stripDtsSourceMappingUrl
});
11 changes: 10 additions & 1 deletion packages/codemod/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineConfig } from 'tsdown';

import { stripDtsSourceMappingUrl } from '../../common/tsdown/stripDtsSourceMappingUrl.mjs';

export default defineConfig({
failOnWarn: 'ci-only',
entry: ['src/cli.ts', 'src/index.ts'],
Expand All @@ -12,6 +14,13 @@ export default defineConfig({
platform: 'node',
shims: true,
dts: {
// Declaration maps would reference src/ (and, where bundled, the private
// core-internal's src/), which is not shipped ("files": ["dist"]); tsc cannot
// embed sourcesContent into .d.ts maps, so the shipped maps could never resolve
// on a consumer's machine. Don't emit them (#2233).
sourcemap: false,
resolver: 'tsc'
}
},
// Drop the dangling sourceMappingURL comment rolldown leaves on the (map-less) declaration output.
inputOptions: stripDtsSourceMappingUrl
});
11 changes: 10 additions & 1 deletion packages/core/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineConfig } from 'tsdown';

import { stripDtsSourceMappingUrl } from '../../common/tsdown/stripDtsSourceMappingUrl.mjs';

// core owns the schema source modules (src/schemas.ts, src/auth.ts, src/constants.ts) and builds
// two entries from them:
// - src/index.ts → the curated public surface (spec + OAuth `*Schema` constants only)
Expand All @@ -17,6 +19,13 @@ export default defineConfig({
target: 'esnext',
platform: 'neutral',
dts: {
// Declaration maps would reference src/ (and, where bundled, the private
// core-internal's src/), which is not shipped ("files": ["dist"]); tsc cannot
// embed sourcesContent into .d.ts maps, so the shipped maps could never resolve
// on a consumer's machine. Don't emit them (#2233).
sourcemap: false,
resolver: 'tsc'
}
},
// Drop the dangling sourceMappingURL comment rolldown leaves on the (map-less) declaration output.
inputOptions: stripDtsSourceMappingUrl
});
11 changes: 10 additions & 1 deletion packages/middleware/express/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineConfig } from 'tsdown';

import { stripDtsSourceMappingUrl } from '../../../common/tsdown/stripDtsSourceMappingUrl.mjs';

export default defineConfig({
failOnWarn: 'ci-only',
entry: ['src/index.ts'],
Expand All @@ -12,12 +14,19 @@ export default defineConfig({
platform: 'node',
shims: true,
dts: {
// Declaration maps would reference src/ (and, where bundled, the private
// core-internal's src/), which is not shipped ("files": ["dist"]); tsc cannot
// embed sourcesContent into .d.ts maps, so the shipped maps could never resolve
// on a consumer's machine. Don't emit them (#2233).
sourcemap: false,
resolver: 'tsc',
// Keep workspace deps as external imports in the bundled .d.ts instead of
// inlining their type graph — see ../node/tsdown.config.ts for the rationale.
compilerOptions: {
paths: {},
preserveSymlinks: true
}
}
},
// Drop the dangling sourceMappingURL comment rolldown leaves on the (map-less) declaration output.
inputOptions: stripDtsSourceMappingUrl
});
11 changes: 10 additions & 1 deletion packages/middleware/fastify/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineConfig } from 'tsdown';

import { stripDtsSourceMappingUrl } from '../../../common/tsdown/stripDtsSourceMappingUrl.mjs';

export default defineConfig({
failOnWarn: 'ci-only',
entry: ['src/index.ts'],
Expand All @@ -12,12 +14,19 @@ export default defineConfig({
platform: 'node',
shims: true,
dts: {
// Declaration maps would reference src/ (and, where bundled, the private
// core-internal's src/), which is not shipped ("files": ["dist"]); tsc cannot
// embed sourcesContent into .d.ts maps, so the shipped maps could never resolve
// on a consumer's machine. Don't emit them (#2233).
sourcemap: false,
resolver: 'tsc',
// Keep workspace deps as external imports in the bundled .d.ts instead of
// inlining their type graph — see ../node/tsdown.config.ts for the rationale.
compilerOptions: {
paths: {},
preserveSymlinks: true
}
}
},
// Drop the dangling sourceMappingURL comment rolldown leaves on the (map-less) declaration output.
inputOptions: stripDtsSourceMappingUrl
});
11 changes: 10 additions & 1 deletion packages/middleware/hono/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineConfig } from 'tsdown';

import { stripDtsSourceMappingUrl } from '../../../common/tsdown/stripDtsSourceMappingUrl.mjs';

export default defineConfig({
failOnWarn: 'ci-only',
entry: ['src/index.ts'],
Expand All @@ -12,12 +14,19 @@ export default defineConfig({
platform: 'node',
shims: true,
dts: {
// Declaration maps would reference src/ (and, where bundled, the private
// core-internal's src/), which is not shipped ("files": ["dist"]); tsc cannot
// embed sourcesContent into .d.ts maps, so the shipped maps could never resolve
// on a consumer's machine. Don't emit them (#2233).
sourcemap: false,
resolver: 'tsc',
// Keep workspace deps as external imports in the bundled .d.ts instead of
// inlining their type graph — see ../node/tsdown.config.ts for the rationale.
compilerOptions: {
paths: {},
preserveSymlinks: true
}
}
},
// Drop the dangling sourceMappingURL comment rolldown leaves on the (map-less) declaration output.
inputOptions: stripDtsSourceMappingUrl
});
11 changes: 10 additions & 1 deletion packages/middleware/node/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineConfig } from 'tsdown';

import { stripDtsSourceMappingUrl } from '../../../common/tsdown/stripDtsSourceMappingUrl.mjs';

export default defineConfig({
failOnWarn: 'ci-only',
// 1. Entry Points
Expand All @@ -21,6 +23,11 @@ export default defineConfig({
// 4. Type Definitions
// Bundles d.ts files into a single output
dts: {
// Declaration maps would reference src/ (and, where bundled, the private
// core-internal's src/), which is not shipped ("files": ["dist"]); tsc cannot
// embed sourcesContent into .d.ts maps, so the shipped maps could never resolve
// on a consumer's machine. Don't emit them (#2233).
sourcemap: false,
resolver: 'tsc',
// The dev tsconfig.json maps @modelcontextprotocol/* to workspace source via
// `paths` so typecheck/IDE work without a prior build. For declaration emit we
Expand All @@ -40,5 +47,7 @@ export default defineConfig({
paths: {},
preserveSymlinks: true
}
}
},
// Drop the dangling sourceMappingURL comment rolldown leaves on the (map-less) declaration output.
inputOptions: stripDtsSourceMappingUrl
});
11 changes: 10 additions & 1 deletion packages/server-legacy/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineConfig } from 'tsdown';

import { stripDtsSourceMappingUrl } from '../../common/tsdown/stripDtsSourceMappingUrl.mjs';

export default defineConfig({
failOnWarn: 'ci-only',
entry: ['src/index.ts', 'src/sse/index.ts', 'src/auth/index.ts'],
Expand All @@ -12,6 +14,11 @@ export default defineConfig({
platform: 'node',
shims: true,
dts: {
// Declaration maps would reference src/ (and, where bundled, the private
// core-internal's src/), which is not shipped ("files": ["dist"]); tsc cannot
// embed sourcesContent into .d.ts maps, so the shipped maps could never resolve
// on a consumer's machine. Don't emit them (#2233).
sourcemap: false,
resolver: 'tsc',
compilerOptions: {
baseUrl: '.',
Expand All @@ -25,5 +32,7 @@ export default defineConfig({
// The schema modules live in @modelcontextprotocol/core (a real runtime dependency); the
// bundled core-internal shims import them via the './internal' subpath, which must stay an
// external import (explicit entry — the tsconfig paths alias would otherwise inline it).
external: ['@modelcontextprotocol/core/internal']
external: ['@modelcontextprotocol/core/internal'],
// Drop the dangling sourceMappingURL comment rolldown leaves on the (map-less) declaration output.
inputOptions: stripDtsSourceMappingUrl
});
11 changes: 10 additions & 1 deletion packages/server/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineConfig } from 'tsdown';

import { stripDtsSourceMappingUrl } from '../../common/tsdown/stripDtsSourceMappingUrl.mjs';

export default defineConfig({
failOnWarn: 'ci-only',
entry: [
Expand All @@ -20,6 +22,11 @@ export default defineConfig({
platform: 'node',
shims: true,
dts: {
// Declaration maps would reference src/ (and, where bundled, the private
// core-internal's src/), which is not shipped ("files": ["dist"]); tsc cannot
// embed sourcesContent into .d.ts maps, so the shipped maps could never resolve
// on a consumer's machine. Don't emit them (#2233).
sourcemap: false,
resolver: 'tsc',
resolve: ['ajv', 'ajv-formats', 'json-schema-typed'],
compilerOptions: {
Expand All @@ -37,5 +44,7 @@ export default defineConfig({
// The schema modules live in @modelcontextprotocol/core (a real runtime dependency); the
// bundled core-internal shims import them via the './internal' subpath, which must stay an
// external import (explicit entry — the tsconfig paths alias would otherwise inline it).
external: ['@modelcontextprotocol/server/_shims', '@modelcontextprotocol/core/internal']
external: ['@modelcontextprotocol/server/_shims', '@modelcontextprotocol/core/internal'],
// Drop the dangling sourceMappingURL comment rolldown leaves on the (map-less) declaration output.
inputOptions: stripDtsSourceMappingUrl
});
Loading