diff --git a/.changeset/beta-release.md b/.changeset/beta-release.md deleted file mode 100644 index 26c711a910..0000000000 --- a/.changeset/beta-release.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -'@modelcontextprotocol/server': patch -'@modelcontextprotocol/client': patch -'@modelcontextprotocol/core': patch -'@modelcontextprotocol/server-legacy': patch -'@modelcontextprotocol/codemod': patch -'@modelcontextprotocol/express': patch -'@modelcontextprotocol/hono': patch -'@modelcontextprotocol/fastify': patch -'@modelcontextprotocol/node': patch ---- - -First beta release of SDK v2 with support for the MCP 2026-07-28 specification -revision. See the migration guides for upgrading from v1 -(`docs/migration/upgrade-to-v2.md`) and adopting the 2026-07-28 revision -(`docs/migration/support-2026-07-28.md`). diff --git a/.changeset/calltoolresult-content-default.md b/.changeset/calltoolresult-content-default.md deleted file mode 100644 index 9d0daeebbf..0000000000 --- a/.changeset/calltoolresult-content-default.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@modelcontextprotocol/core-internal': patch -'@modelcontextprotocol/client': patch -'@modelcontextprotocol/core': patch -'@modelcontextprotocol/server': patch ---- - -Restore the v1 parse tolerance for `CallToolResult.content`: an inbound legacy-era `tools/call` result without `content` defaults to `[]` instead of failing validation. Deployed servers — accepted by SDK v1 for years — return `structuredContent`-only (or otherwise content-less) results, and the strict parse turned every such call into an `INVALID_RESULT` error before application code could run. - -The silent-empty-success hazard the strictness guarded is preserved where it matters: the 2025 era's wire-seam schema refuses to default `content` for a body carrying another result family's vocabulary (`task`, `inputRequests`, `requestState` — the era is frozen, so the list is complete), and the 2026-era wire schemas stay strict — modern-revision servers have no legacy excuse. Task interop through an explicit result schema is untouched (including bodies that also stamp a foreign `resultType`), and the server-side authoring normalization refuses the same foreign-family vocabulary. - -Server-side authoring is era-independent: a handler result without `content` (dynamic/JS callers — the TypeScript surface requires it) is normalized to `content: []` before era validation on every leg, reaching the wire spec-valid. - -Conscious call: the nested sampling `ToolResultContentSchema` stays spec-strict — v1 had defaulted its `content` too, but it is params-side (tool results a caller authors into a sampling message), deliberately not restored. diff --git a/.changeset/cjs-ajv-validator-subpath.md b/.changeset/cjs-ajv-validator-subpath.md deleted file mode 100644 index ac4c48c0b6..0000000000 --- a/.changeset/cjs-ajv-validator-subpath.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@modelcontextprotocol/server': patch -'@modelcontextprotocol/client': patch ---- - -Fix the CommonJS `validators/ajv` subpath so reading the exported `Ajv` class no longer throws `ReferenceError: import_ajv is not defined`. The subpath now re-exports the bundled provider's concrete `Ajv` value in CJS output, matching the existing ESM behavior. diff --git a/.changeset/cjs-support-v2-packages.md b/.changeset/cjs-support-v2-packages.md deleted file mode 100644 index 3541e0122b..0000000000 --- a/.changeset/cjs-support-v2-packages.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@modelcontextprotocol/server': patch -'@modelcontextprotocol/client': patch -'@modelcontextprotocol/core': patch -'@modelcontextprotocol/server-legacy': patch -'@modelcontextprotocol/codemod': patch -'@modelcontextprotocol/express': patch -'@modelcontextprotocol/hono': patch -'@modelcontextprotocol/fastify': patch -'@modelcontextprotocol/node': patch ---- - -Ship CommonJS builds alongside ESM. Each package now emits both `.mjs`/`.d.mts` -and `.cjs`/`.d.cts` (via tsdown `format: ['esm', 'cjs']`), and its `exports` map -adds a `require` condition so `require('@modelcontextprotocol/…')` works from -CommonJS consumers. Output extensions are normalized across all packages -(`@modelcontextprotocol/core` moves from `.js`/`.d.ts` to `.mjs`/`.d.mts`); the -public import paths are unchanged. diff --git a/.changeset/codemod-fixed-group.md b/.changeset/codemod-fixed-group.md deleted file mode 100644 index ede27ed7ee..0000000000 --- a/.changeset/codemod-fixed-group.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/codemod': patch ---- - -Version the codemod together with the core SDK packages, matching the migration guide's shared-version guarantee. diff --git a/.changeset/codemod-iterations-5.md b/.changeset/codemod-iterations-5.md deleted file mode 100644 index fe6f5e8499..0000000000 --- a/.changeset/codemod-iterations-5.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/codemod': patch ---- - -v1-to-v2 migration fixes from continued real-world migrations (codemod iterations 5). diff --git a/.changeset/codemod-versions-from-manifests.md b/.changeset/codemod-versions-from-manifests.md deleted file mode 100644 index b0383703ad..0000000000 --- a/.changeset/codemod-versions-from-manifests.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/codemod': patch ---- - -Read the v2 package versions the codemod writes into migrated `package.json` files directly from the workspace manifests at build time, replacing the committed generated `versions.ts` (which went stale after every release and made source builds write outdated versions). diff --git a/.changeset/content-type-media-type-validation.md b/.changeset/content-type-media-type-validation.md deleted file mode 100644 index cdef983ece..0000000000 --- a/.changeset/content-type-media-type-validation.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -'@modelcontextprotocol/server': patch -'@modelcontextprotocol/client': patch -'@modelcontextprotocol/hono': patch -'@modelcontextprotocol/node': patch ---- - -POSTs whose `Content-Type` media type is not `application/json` are now -rejected with `415 Unsupported Media Type`; the header is parsed instead of -substring-matched. Previously any value merely containing the substring -passed the check (for example `text/plain; a=application/json`), case -variants were wrongly rejected, and the 2026-07-28 entry did not inspect -`Content-Type` at all — requests with a missing or non-JSON header that used -to be served on that path now also answer 415. Values with parameters -(`application/json; charset=utf-8`, including malformed parameter sections -like `application/json;`) continue to work. SDK clients always send the -correct header and are unaffected. - -The new `isJsonContentType(header)` helper is exported for transport and -framework-adapter authors — custom entries composing the exported building -blocks (`classifyInboundRequest`, `PerRequestHTTPServerTransport`) must apply -it themselves. The hono adapter's JSON body pre-parse and the client's -response dispatch now use the same parsed-media-type comparison. diff --git a/.changeset/cross-bundle-error-instanceof.md b/.changeset/cross-bundle-error-instanceof.md deleted file mode 100644 index 940ca66efc..0000000000 --- a/.changeset/cross-bundle-error-instanceof.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@modelcontextprotocol/client': patch -'@modelcontextprotocol/server': patch ---- - -`instanceof` on the SDK error classes (`ProtocolError` and its typed subclasses, `SdkError`/`SdkHttpError`, `OAuthError`, and the client's `SseError`, `UnauthorizedError`, and OAuth-client-flow error family — `OAuthClientFlowError` and its subclasses) now works across separately bundled copies of the SDK. The classes match by a stable brand (via `Symbol.hasInstance` and a registry symbol) instead of prototype identity, so a process that uses both `@modelcontextprotocol/client` and `@modelcontextprotocol/server` - a gateway, host, or in-process test - can check errors constructed by either package against the class re-exported by the other. Ordinary prototype-based `instanceof` is preserved as a fallback; user-defined subclasses keep plain prototype semantics. Notes: cross-bundle matching requires both copies to be at or after this release; brands assert identity, not field shape, across versions - keep reading fields defensively. As a side effect, a foreign-bundle `SdkError` used as an abort reason is now rethrown as-is instead of being wrapped as a `RequestTimeout`. Branded hierarchies additionally expose an explicit static guard, `X.isInstance(value)`, that reads the same brand and narrows in TypeScript — an alternative for codebases that prefer predicate-style checks over `instanceof`. Also: `UnauthorizedError` now sets `error.name` to `'UnauthorizedError'` (previously `'Error'`), and per-package conformance tests enforce that every exported error class participates in branding. Version-negotiation probing now recognizes `UnauthorizedError` (previously a dead name-string check) and propagates it unchanged, so `connect()` on an auth-gated server rejects with the original `UnauthorizedError` (previously wrapped as the `cause` of an `SdkError(EraNegotiationFailed)`) — run `finishAuth()` and reconnect, and the retry probes with the token. diff --git a/.changeset/examples-protected-wiring.md b/.changeset/examples-protected-wiring.md deleted file mode 100644 index dce27b8666..0000000000 --- a/.changeset/examples-protected-wiring.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/node': patch ---- - -Document composing the host and origin validation guards in front of `toNodeHandler` for hand-wired `node:http` servers, matching the protected wiring the examples and serving guide now demonstrate. diff --git a/.changeset/export-protocol-class.md b/.changeset/export-protocol-class.md deleted file mode 100644 index 0cb11195b0..0000000000 --- a/.changeset/export-protocol-class.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@modelcontextprotocol/core-internal': minor -'@modelcontextprotocol/client': minor -'@modelcontextprotocol/server': minor -'@modelcontextprotocol/codemod': patch ---- - -Export the `Protocol` base class and `mergeCapabilities` from the `@modelcontextprotocol/client` and `@modelcontextprotocol/server` package roots, restoring the v1 import for consumers that subclass `Protocol` (e.g. the MCP Apps SDK). The client and server packages each bundle their own compiled copy of the class, so import it from one package consistently within a process. - -The codemod now rewrites `Protocol` and `mergeCapabilities` imports from `shared/protocol.js` to the client or server package root, like the module's other symbols, instead of dropping them with an action-required marker. diff --git a/.changeset/initialize-session-hygiene.md b/.changeset/initialize-session-hygiene.md deleted file mode 100644 index b12e3c514f..0000000000 --- a/.changeset/initialize-session-hygiene.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/client': patch ---- - -The Streamable HTTP client transport no longer attaches a session ID to a POST containing an `initialize` request — a new session starts "without a session ID attached" (2025-11-25 transports §Session Management) — and it only captures the `mcp-session-id` response header from a successful initialize response, since the spec assigns the session ID "at initialization time … on the HTTP response containing the InitializeResult". Previously the transport stored the header from any response, so a legacy server answering a protocol-version probe with an error that happened to carry a session ID would poison the fallback initialize, which then went out with a session ID it should not have had. A stale session ID from a previous connection is likewise no longer leaked onto the initialize handshake, and a successful initialize response that carries no session ID now clears any stale ID the transport was holding — clients include only an ID "returned by the server during initialization", so an ID the server never returned this session is outside the session model. Ignoring `mcp-session-id` headers mid-session is the complement of the spec's one actual rotation mechanism: a server that wants a new session terminates the old one (it "MAY terminate the session at any time") and answers 404, after which the client "MUST start a new session by sending a new InitializeRequest without a session ID attached". Rotation exists as session replacement via 404 + re-initialize, never as a header swap on a live session, so a server that rotates per the spec's own flow is handled correctly by this transport. diff --git a/.changeset/lazy-ajv-engine.md b/.changeset/lazy-ajv-engine.md deleted file mode 100644 index 12ce0852ba..0000000000 --- a/.changeset/lazy-ajv-engine.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@modelcontextprotocol/client': patch -'@modelcontextprotocol/server': patch ---- - -Construct the default Ajv validation engine lazily on first validation. Creating a `Client` or `Server` no longer pays the ajv + ajv-formats instantiation cost at startup when no JSON Schema validation ever runs. diff --git a/.changeset/lazy-era-wire-schemas.md b/.changeset/lazy-era-wire-schemas.md deleted file mode 100644 index b49b5ea659..0000000000 --- a/.changeset/lazy-era-wire-schemas.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@modelcontextprotocol/client': patch -'@modelcontextprotocol/server': patch -'@modelcontextprotocol/server-legacy': patch ---- - -Build protocol-revision wire schemas lazily on first validation instead of at import. Each revision's schema set is now constructed by a module-level memoized factory, so importing the client or server package no longer pays the construction cost of both frozen wire-schema graphs up front. Method membership in the revision registries stays static, the schemas themselves are unchanged, and registry lookups keep returning reference-identical schema objects. diff --git a/.changeset/malformed-resource-uri-invalid-params.md b/.changeset/malformed-resource-uri-invalid-params.md deleted file mode 100644 index 565de8bad2..0000000000 --- a/.changeset/malformed-resource-uri-invalid-params.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/server': patch ---- - -Return JSON-RPC Invalid Params with the original URI and an `invalid_uri` reason when `resources/read` receives a syntactically malformed URI. diff --git a/.changeset/post-dispatch-32021-http-400.md b/.changeset/post-dispatch-32021-http-400.md deleted file mode 100644 index 5f51fe0d62..0000000000 --- a/.changeset/post-dispatch-32021-http-400.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@modelcontextprotocol/server': patch -'@modelcontextprotocol/core-internal': patch ---- - -Return HTTP 400 for a `MissingRequiredClientCapabilityError` (`-32021`) produced after dispatch. The spec mandates `400 Bad Request` for this error with no condition on where it arose, but only the pre-dispatch capability gate honored that; the post-handler emission — the `input_required` gate rejecting an embedded request whose required capability the caller did not declare — surfaced in-band on HTTP 200. The JSON-RPC error body is unchanged, every other error code (including a handler relaying a downstream peer's `-32020`/`-32022`) keeps the origin-keyed in-band behavior, and the mapping only applies while the response is uncommitted: an exchange that already streamed — or one hosted with `responseMode: 'sse'`, which opens its stream at dispatch end — keeps its committed 200 and carries the error in-stream. diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 75299cc4e3..0000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "mode": "exit", - "tag": "beta", - "initialVersions": { - "@modelcontextprotocol/eslint-config": "2.0.0", - "@modelcontextprotocol/tsconfig": "2.0.0", - "@modelcontextprotocol/vitest-config": "2.0.0", - "@modelcontextprotocol/examples": "2.0.0-alpha.0", - "@mcp-examples/client-quickstart": "2.0.0-alpha.0", - "@mcp-examples/server-quickstart": "2.0.0-alpha.0", - "@mcp-examples/shared": "2.0.0-alpha.0", - "@modelcontextprotocol/client": "2.0.0-alpha.4", - "@modelcontextprotocol/codemod": "2.0.0-alpha.2", - "@modelcontextprotocol/core": "2.0.0-alpha.2", - "@modelcontextprotocol/core-internal": "2.0.0-alpha.3", - "@modelcontextprotocol/express": "2.0.0-alpha.4", - "@modelcontextprotocol/fastify": "2.0.0-alpha.4", - "@modelcontextprotocol/hono": "2.0.0-alpha.4", - "@modelcontextprotocol/node": "2.0.0-alpha.4", - "@modelcontextprotocol/server": "2.0.0-alpha.4", - "@modelcontextprotocol/server-legacy": "2.0.0-alpha.4", - "@modelcontextprotocol/test-conformance": "2.0.0-alpha.1", - "@modelcontextprotocol/test-e2e": "2.0.0-alpha.1", - "@modelcontextprotocol/test-helpers": "2.0.0-alpha.0", - "@modelcontextprotocol/test-integration": "2.0.0-alpha.1" - }, - "changesets": [ - "beta-release", - "calltoolresult-content-default", - "cjs-ajv-validator-subpath", - "cjs-support-v2-packages", - "codemod-fixed-group", - "codemod-iterations-5", - "codemod-versions-from-manifests", - "content-type-media-type-validation", - "cross-bundle-error-instanceof", - "examples-protected-wiring", - "export-protocol-class", - "initialize-session-hygiene", - "lazy-ajv-engine", - "lazy-era-wire-schemas", - "malformed-resource-uri-invalid-params", - "post-dispatch-32021-http-400", - "prior-legacy-verdict", - "probe-close-handling", - "probe-window-handler-restore", - "response-cache-document-codec", - "schemas-source-home", - "silent-validators-wave", - "spec-3002-servinfo-meta", - "standard-header-ows", - "standard-schema-elicitation", - "web-standard-bearer-auth", - "web-standard-oauth-metadata", - "workerd-schema-preload" - ] -} diff --git a/.changeset/prior-legacy-verdict.md b/.changeset/prior-legacy-verdict.md deleted file mode 100644 index 0a1b7b0f73..0000000000 --- a/.changeset/prior-legacy-verdict.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/client': minor ---- - -`ConnectOptions.prior` accepts a cached era verdict — the new exported type `PriorDiscovery`. `{ kind: 'modern', discover }` adopts a previously obtained `DiscoverResult` with zero round trips; `{ kind: 'legacy' }` skips the `server/discover` probe and runs the plain `initialize` handshake directly, for servers known out-of-band to be legacy — without pinning the client to `mode: 'legacy'`: stop supplying the verdict and `connect()` falls back to the configured `versionNegotiation` mode (under `'auto'`, it re-probes and rediscovers an upgraded server). Freshness is the supplying host's responsibility — a stale legacy verdict succeeds silently against an upgraded server, so hosts must date cached legacy verdicts in their own storage and stop supplying them past their policy horizon. Persisted-blob plumbing is hardened: `prior: null` is treated as absent, the modern arm's `discover` payload is schema-validated before any connection state changes, and an unrecognized shape rejects with a typed `SdkError(EraNegotiationFailed)` instead of a `TypeError`. diff --git a/.changeset/probe-auth-status-not-era-evidence.md b/.changeset/probe-auth-status-not-era-evidence.md deleted file mode 100644 index 7f2f75d42e..0000000000 --- a/.changeset/probe-auth-status-not-era-evidence.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -'@modelcontextprotocol/client': patch ---- - -The version-negotiation probe no longer misclassifies auth-protected or -failing servers as legacy. Auth status is never era evidence: a 401 or 403 -rejection of the `server/discover` probe now surfaces as a typed -authorization failure — an `SdkHttpError` with code `ClientHttpAuthentication` -(401) or `ClientHttpForbidden` (403), carrying the HTTP status, reason -phrase, and response text — instead of triggering the legacy `initialize` -fallback (which put a doomed `initialize` on the wire) or, under `pin` mode, -the false "server did not offer pinned protocol version" diagnostic. The -codes are deliberately not `EraNegotiationFailed`, so era-recovery flows -keyed on that code cannot persist a verdict for an unauthorized exchange. A -5xx rejecting the probe is a server failure and now also rejects typed -(`SdkHttpError(EraNegotiationFailed)`) instead of demoting a mid-deploy -modern server to legacy — the legacy fallback now fires only on the 4xx -shapes the spec licenses. - -With an `authProvider`, a `401` (and a `403` `insufficient_scope` challenge) runs the transport's auth flow first — a plain `403` rejects the same as without a provider — and whatever -escapes it propagates unchanged, identity intact: the HTTP transports stamp -errors at their auth seams (the `token()` read, `onUnauthorized` including -custom callbacks, the 403 step-up flow, and their own auth-failure -constructions), so `UnauthorizedError` for `finishAuth()`, the flow's typed -failures (`OAuthError`, `InsufficientScopeError`, the -401-after-re-authentication diagnostic), and even an untyped `TypeError` -thrown inside the flow all reach the caller as thrown — never rewrapped, -never consumed by the probe's browser CORS heuristic as legacy-era evidence. diff --git a/.changeset/probe-close-handling.md b/.changeset/probe-close-handling.md deleted file mode 100644 index 5bf48d3f73..0000000000 --- a/.changeset/probe-close-handling.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/client': patch ---- - -Probe stdio servers on a disposable sibling process. Some stdio servers exit on any pre-`initialize` request (servers built on the official Rust SDK, rmcp, behave this way), so under `versionNegotiation: { mode: 'auto' }` the `server/discover` probe previously killed the server and `connect()` hard-failed. The probe now runs on a short-lived sibling spawned from the same parameters — its stderr is discarded and it is reaped once the era is known — and the caller's transport spawns exactly once, afterwards: a legacy verdict connects with the plain `initialize` handshake (byte-identical to `mode: 'legacy'`), a modern verdict is adopted directly, and the session wire never carries `server/discover`. Closing the caller's transport during the probe aborts `connect()` with the typed `SdkError(EraNegotiationFailed)` and the session child is never spawned. On HTTP — and on custom stdio-shaped transports, which probe in place — a mid-probe connection close keeps rejecting with the typed connect error, now naming the close in pin-mode and modern-only diagnostics. diff --git a/.changeset/probe-window-handler-restore.md b/.changeset/probe-window-handler-restore.md deleted file mode 100644 index 6256ba05e6..0000000000 --- a/.changeset/probe-window-handler-restore.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/client': patch ---- - -Version negotiation no longer discards transport handlers the caller set before `connect()`. The probe window now saves any pre-set `onmessage`/`onerror`/`onclose`, forwards error and close events to them while the probe is in flight, and restores them when the window closes — so `Protocol.connect()` chains them exactly as it does on a plain connect. Previously, connecting with `versionNegotiation` silently cleared pre-set handlers (e.g. an `onerror` used to detect session-expiry auth failures), leaving them permanently detached for the life of the connection. diff --git a/.changeset/response-cache-document-codec.md b/.changeset/response-cache-document-codec.md deleted file mode 100644 index 3584eaa04d..0000000000 --- a/.changeset/response-cache-document-codec.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@modelcontextprotocol/client': minor ---- - -The response cache now stores results as JSON-serialized documents (serialize on write, parse on read) instead of live object graphs isolated with `structuredClone`. Same mutation isolation, but no dependency on the `structuredClone` global — whose absence (jest+jsdom, Node < 17) previously made every cache write throw into the store-error swallow, silently disabling caching and output-schema lookups for the session. A value without a JSON representation now fails the write loudly to the error sink, and an undecodable document in an external store is reported, dropped, and read as a miss. - -Migration for custom `ResponseCacheStore` implementations: `CacheEntry.value` (and the `set()` entry value) is now `string` — persist and return it verbatim, `JSON.parse` to inspect. Entries persisted by a previous SDK version fail decode once (reported, dropped) and are rewritten on the next fetch. diff --git a/.changeset/schemas-source-home.md b/.changeset/schemas-source-home.md deleted file mode 100644 index d08753f8ec..0000000000 --- a/.changeset/schemas-source-home.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@modelcontextprotocol/core': minor -'@modelcontextprotocol/client': minor -'@modelcontextprotocol/server': minor -'@modelcontextprotocol/server-legacy': minor ---- - -Move the schema source modules (spec schemas, OAuth schemas, protocol constants) into `@modelcontextprotocol/core` and resolve them from there as a regular runtime dependency instead of bundling a private copy into each package. An application importing more than one of the packages now evaluates a single shared schema graph with shared object identity. `@modelcontextprotocol/core` gains a `./internal` subpath (SDK-internal contract; may change in any release) and the four packages now version together. diff --git a/.changeset/silent-validators-wave.md b/.changeset/silent-validators-wave.md deleted file mode 100644 index 7394c4c1ea..0000000000 --- a/.changeset/silent-validators-wave.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@modelcontextprotocol/client': patch -'@modelcontextprotocol/server': patch ---- - -Stop advertising validator provider classes from the root client/server type declarations. The provider classes remain available from the explicit validator subpaths. diff --git a/.changeset/spec-3002-servinfo-meta.md b/.changeset/spec-3002-servinfo-meta.md deleted file mode 100644 index b4eba489b4..0000000000 --- a/.changeset/spec-3002-servinfo-meta.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@modelcontextprotocol/core-internal': minor -'@modelcontextprotocol/core': minor -'@modelcontextprotocol/client': minor -'@modelcontextprotocol/server': minor ---- - -Align the 2026-07-28 wire with the final revision (spec PR #3002): `serverInfo` moves from the `DiscoverResult` body to the result `_meta`, and the per-request envelope's `clientInfo` demotes from required to SHOULD. - -Before this change the SDK shipped the pre-#3002 shape in both directions: the client hard-rejected a conforming server's `DiscoverResult` (missing body `serverInfo` failed parse, so the probe misclassified the server as legacy and attempted an `initialize` handshake against it — a hard connect failure against a modern-only server such as go-sdk v1.7.0-pre.3), and the server rejected conforming clients that omit `clientInfo`. - -Now: - -- The 2026 wire schemas are the final revision exactly: no body `serverInfo` on `DiscoverResult`, envelope `clientInfo` optional (a present-but-malformed value still fails validation). -- Servers stamp `_meta['io.modelcontextprotocol/serverInfo']` on every 2026-era response (spec SHOULD; a handler-authored value wins, the 2025-era wire is untouched). This includes the entry-built `subscriptions/listen` graceful-close results — the spec's `SubscriptionsListenResultMeta` extends `ResultMetaObject`. -- Clients keep sending `clientInfo` and read server identity from the discover result's `_meta` only. A server that stamps no identity is anonymous: `getServerVersion()` is `undefined` and the response cache partitions under a per-connection surrogate. A malformed `_meta` serverInfo value is treated as absent on receive (the spec marks the field self-reported, unverified, and display-only). -- Breaking type changes: `DiscoverResult` no longer declares `serverInfo`; `RequestMetaEnvelope`'s `clientInfo` is optional. New public constant `SERVER_INFO_META_KEY` (`'io.modelcontextprotocol/serverInfo'`). diff --git a/.changeset/standard-header-ows.md b/.changeset/standard-header-ows.md deleted file mode 100644 index 4426652246..0000000000 --- a/.changeset/standard-header-ows.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@modelcontextprotocol/server': patch -'@modelcontextprotocol/core-internal': patch ---- - -Strip RFC 9110 optional whitespace around inbound `MCP-Protocol-Version`, `Mcp-Method`, and `Mcp-Name` values before classifying and validating modern HTTP requests. This keeps valid requests portable across Fetch runtimes that expose raw leading or trailing SP/HTAB through `Headers.get()`. diff --git a/.changeset/standard-schema-elicitation.md b/.changeset/standard-schema-elicitation.md deleted file mode 100644 index bf584e5569..0000000000 --- a/.changeset/standard-schema-elicitation.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@modelcontextprotocol/core-internal': minor -'@modelcontextprotocol/server': minor ---- - -Allow `inputRequired.elicit()` to accept a Standard Schema such as a Zod object for `requestedSchema`. The builder converts it to MCP's restricted form-elicitation JSON Schema, while the same schema can validate and type the response through `acceptedContent()` on handler re-entry. Zod formats mapping to `email`, `uri`, `date`, and `date-time` are supported. Shapes the restricted schema cannot express reject before anything is sent — nested objects, `.regex()` and customized zod format patterns, exclusive number bounds (`.positive()`/`.gt()`), literal unions (use `z.enum` or `z.literal(['a', 'b'])`), and non-spec root keywords like `z.strictObject()`'s `additionalProperties`. diff --git a/.changeset/streamable-http-sse-keepalive.md b/.changeset/streamable-http-sse-keepalive.md deleted file mode 100644 index 705fa5f8f4..0000000000 --- a/.changeset/streamable-http-sse-keepalive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@modelcontextprotocol/server': minor ---- - -Add configurable SSE keep-alive comment frames to Streamable HTTP transports and apply `createMcpHandler`'s existing `keepAliveMs` option to every HTTP SSE stream it serves. diff --git a/.changeset/validator-dialect-dispatch.md b/.changeset/validator-dialect-dispatch.md deleted file mode 100644 index e715eb4f49..0000000000 --- a/.changeset/validator-dialect-dispatch.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@modelcontextprotocol/server': patch -'@modelcontextprotocol/client': patch ---- - -The default validator now honors declared 2019-09 and draft-07/06 dialects instead of rejecting them: a schema stamped `"$schema": "http://json-schema.org/draft-07/schema#"` (zod-to-json-schema's default output) validates with draft-07 semantics, and a 2019-09 stamp (zod-to-json-schema's `2019-09`/`openAi` targets) with 2019-09 semantics, on both the Ajv and Cloudflare Workers providers (with known engine differences documented in the migration guide). Schemas with no `$schema` still validate as 2020-12, and unknown dialects still produce the typed error (now listing the supported dialects: 2020-12, 2019-09, draft-07, draft-06). diff --git a/.changeset/web-standard-bearer-auth.md b/.changeset/web-standard-bearer-auth.md deleted file mode 100644 index b6bd738d4b..0000000000 --- a/.changeset/web-standard-bearer-auth.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -'@modelcontextprotocol/server': minor -'@modelcontextprotocol/express': patch -'@modelcontextprotocol/codemod': patch ---- - -Add runtime-neutral Bearer authentication to `@modelcontextprotocol/server`: -`requireBearerAuth` gates web-standard `fetch(request)` hosts (Cloudflare -Workers, Deno, Bun, Hono), built on the exported `verifyBearerToken` and -`bearerAuthChallengeResponse` pieces, with `OAuthTokenVerifier` now defined -here. The Express middleware adapts the same core and is unchanged in -behavior, except that `WWW-Authenticate` challenge values are now RFC 7235 -quoted-string sanitized (quotes and backslashes escaped, control and -non-ASCII characters replaced); `@modelcontextprotocol/express` re-exports -`OAuthTokenVerifier` as before. diff --git a/.changeset/web-standard-oauth-metadata.md b/.changeset/web-standard-oauth-metadata.md deleted file mode 100644 index 32b960fa44..0000000000 --- a/.changeset/web-standard-oauth-metadata.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@modelcontextprotocol/server': minor -'@modelcontextprotocol/express': patch ---- - -Add runtime-neutral OAuth discovery serving to `@modelcontextprotocol/server`: -`oauthMetadataResponse` serves the RFC 9728 Protected Resource Metadata and -RFC 8414 Authorization Server metadata documents from web-standard -`fetch(request)` hosts, built on the exported -`buildOAuthProtectedResourceMetadata`, with -`getOAuthProtectedResourceMetadataUrl` now defined here. The Express metadata -router adapts the same core and is unchanged in behavior; the insecure-issuer -escape hatch is an explicit `dangerouslyAllowInsecureIssuerUrl` option in the -neutral core instead of a module-scope environment read. The web-standard -matcher validates lazily so unmatched traffic always falls through, tolerates -a trailing slash, supports HEAD, and marks reflected CORS preflights with -`Vary`. diff --git a/.changeset/workerd-schema-preload.md b/.changeset/workerd-schema-preload.md deleted file mode 100644 index c0fc376c28..0000000000 --- a/.changeset/workerd-schema-preload.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@modelcontextprotocol/client': minor -'@modelcontextprotocol/server': minor ---- - -Add `preloadSchemas()`, an explicit opt-in to eager wire-schema construction, and call it automatically in the Cloudflare Workers builds. The wire schemas are built lazily by default, which is the right trade on process-per-invocation runtimes — but on isolate platforms that bill request CPU while module evaluation runs during isolate warm-up, laziness moves construction into the first request each fresh isolate serves. Calling `preloadSchemas()` at module scope (it is synchronous and idempotent) moves that one-time cost back to module evaluation; the packages' workerd export condition now does this automatically, while the Node and browser builds stay lazy. The server package gains a dedicated browser shim for this (its `browser` condition previously reused the workerd shim), so browser bundles keep lazy construction. diff --git a/packages/client/CHANGELOG.md b/packages/client/CHANGELOG.md index ecb40fc2a9..5f3dea3b2d 100644 --- a/packages/client/CHANGELOG.md +++ b/packages/client/CHANGELOG.md @@ -1,5 +1,118 @@ # @modelcontextprotocol/client +## 2.0.0 + +### Minor Changes + +- [#2501](https://github.com/modelcontextprotocol/typescript-sdk/pull/2501) [`1480241`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1480241e2a2a7f0ceee8e7723b2adcf88579bb36) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Export the `Protocol` base class and `mergeCapabilities` from the `@modelcontextprotocol/client` and `@modelcontextprotocol/server` package roots, restoring the v1 import for consumers that subclass `Protocol` (e.g. the MCP Apps SDK). The client and server packages each bundle their own compiled copy of the class, so import it from one package consistently within a process. + + The codemod now rewrites `Protocol` and `mergeCapabilities` imports from `shared/protocol.js` to the client or server package root, like the module's other symbols, instead of dropping them with an action-required marker. + +- [#2511](https://github.com/modelcontextprotocol/typescript-sdk/pull/2511) [`f60dff0`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f60dff0674954ab516739f21ad9905349c8e9249) Thanks [@felixweinberger](https://github.com/felixweinberger)! - `ConnectOptions.prior` accepts a cached era verdict — the new exported type `PriorDiscovery`. `{ kind: 'modern', discover }` adopts a previously obtained `DiscoverResult` with zero round trips; `{ kind: 'legacy' }` skips the `server/discover` probe and runs the plain `initialize` handshake directly, for servers known out-of-band to be legacy — without pinning the client to `mode: 'legacy'`: stop supplying the verdict and `connect()` falls back to the configured `versionNegotiation` mode (under `'auto'`, it re-probes and rediscovers an upgraded server). Freshness is the supplying host's responsibility — a stale legacy verdict succeeds silently against an upgraded server, so hosts must date cached legacy verdicts in their own storage and stop supplying them past their policy horizon. Persisted-blob plumbing is hardened: `prior: null` is treated as absent, the modern arm's `discover` payload is schema-validated before any connection state changes, and an unrecognized shape rejects with a typed `SdkError(EraNegotiationFailed)` instead of a `TypeError`. + +- [#2468](https://github.com/modelcontextprotocol/typescript-sdk/pull/2468) [`5db6e38`](https://github.com/modelcontextprotocol/typescript-sdk/commit/5db6e38f2bdeb5052f608121e9a2679ff8742af2) Thanks [@felixweinberger](https://github.com/felixweinberger)! - The response cache now stores results as JSON-serialized documents (serialize on write, parse on read) instead of live object graphs isolated with `structuredClone`. Same mutation isolation, but no dependency on the `structuredClone` global — whose absence (jest+jsdom, Node < 17) previously made every cache write throw into the store-error swallow, silently disabling caching and output-schema lookups for the session. A value without a JSON representation now fails the write loudly to the error sink, and an undecodable document in an external store is reported, dropped, and read as a miss. + + Migration for custom `ResponseCacheStore` implementations: `CacheEntry.value` (and the `set()` entry value) is now `string` — persist and return it verbatim, `JSON.parse` to inspect. Entries persisted by a previous SDK version fail decode once (reported, dropped) and are rewritten on the next fetch. + +- [#2477](https://github.com/modelcontextprotocol/typescript-sdk/pull/2477) [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Move the schema source modules (spec schemas, OAuth schemas, protocol constants) into `@modelcontextprotocol/core` and resolve them from there as a regular runtime dependency instead of bundling a private copy into each package. An application importing more than one of the packages now evaluates a single shared schema graph with shared object identity. `@modelcontextprotocol/core` gains a `./internal` subpath (SDK-internal contract; may change in any release) and the four packages now version together. + +- [#2513](https://github.com/modelcontextprotocol/typescript-sdk/pull/2513) [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Align the 2026-07-28 wire with the final revision (spec PR #3002): `serverInfo` moves from the `DiscoverResult` body to the result `_meta`, and the per-request envelope's `clientInfo` demotes from required to SHOULD. + + Before this change the SDK shipped the pre-#3002 shape in both directions: the client hard-rejected a conforming server's `DiscoverResult` (missing body `serverInfo` failed parse, so the probe misclassified the server as legacy and attempted an `initialize` handshake against it — a hard connect failure against a modern-only server such as go-sdk v1.7.0-pre.3), and the server rejected conforming clients that omit `clientInfo`. + + Now: + - The 2026 wire schemas are the final revision exactly: no body `serverInfo` on `DiscoverResult`, envelope `clientInfo` optional (a present-but-malformed value still fails validation). + - Servers stamp `_meta['io.modelcontextprotocol/serverInfo']` on every 2026-era response (spec SHOULD; a handler-authored value wins, the 2025-era wire is untouched). This includes the entry-built `subscriptions/listen` graceful-close results — the spec's `SubscriptionsListenResultMeta` extends `ResultMetaObject`. + - Clients keep sending `clientInfo` and read server identity from the discover result's `_meta` only. A server that stamps no identity is anonymous: `getServerVersion()` is `undefined` and the response cache partitions under a per-connection surrogate. A malformed `_meta` serverInfo value is treated as absent on receive (the spec marks the field self-reported, unverified, and display-only). + - Breaking type changes: `DiscoverResult` no longer declares `serverInfo`; `RequestMetaEnvelope`'s `clientInfo` is optional. New public constant `SERVER_INFO_META_KEY` (`'io.modelcontextprotocol/serverInfo'`). + +- [#2483](https://github.com/modelcontextprotocol/typescript-sdk/pull/2483) [`3f07a32`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3f07a325c6741b2374ce2255846dfa0c25f74d03) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Add `preloadSchemas()`, an explicit opt-in to eager wire-schema construction, and call it automatically in the Cloudflare Workers builds. The wire schemas are built lazily by default, which is the right trade on process-per-invocation runtimes — but on isolate platforms that bill request CPU while module evaluation runs during isolate warm-up, laziness moves construction into the first request each fresh isolate serves. Calling `preloadSchemas()` at module scope (it is synchronous and idempotent) moves that one-time cost back to module evaluation; the packages' workerd export condition now does this automatically, while the Node and browser builds stay lazy. The server package gains a dedicated browser shim for this (its `browser` condition previously reused the workerd shim), so browser bundles keep lazy construction. + +### Patch Changes + +- [#2402](https://github.com/modelcontextprotocol/typescript-sdk/pull/2402) [`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - First beta release of SDK v2 with support for the MCP 2026-07-28 specification + revision. See the migration guides for upgrading from v1 + (`docs/migration/upgrade-to-v2.md`) and adopting the 2026-07-28 revision + (`docs/migration/support-2026-07-28.md`). + +- [#2456](https://github.com/modelcontextprotocol/typescript-sdk/pull/2456) [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Restore the v1 parse tolerance for `CallToolResult.content`: an inbound legacy-era `tools/call` result without `content` defaults to `[]` instead of failing validation. Deployed servers — accepted by SDK v1 for years — return `structuredContent`-only (or otherwise content-less) results, and the strict parse turned every such call into an `INVALID_RESULT` error before application code could run. + + The silent-empty-success hazard the strictness guarded is preserved where it matters: the 2025 era's wire-seam schema refuses to default `content` for a body carrying another result family's vocabulary (`task`, `inputRequests`, `requestState` — the era is frozen, so the list is complete), and the 2026-era wire schemas stay strict — modern-revision servers have no legacy excuse. Task interop through an explicit result schema is untouched (including bodies that also stamp a foreign `resultType`), and the server-side authoring normalization refuses the same foreign-family vocabulary. + + Server-side authoring is era-independent: a handler result without `content` (dynamic/JS callers — the TypeScript surface requires it) is normalized to `content: []` before era validation on every leg, reaching the wire spec-valid. + + Conscious call: the nested sampling `ToolResultContentSchema` stays spec-strict — v1 had defaulted its `content` too, but it is params-side (tool results a caller authors into a sampling message), deliberately not restored. + +- [#2431](https://github.com/modelcontextprotocol/typescript-sdk/pull/2431) [`1b90c96`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1b90c96d11fd17016d2977cae9dd661de3fb84df) Thanks [@morluto](https://github.com/morluto)! - Fix the CommonJS `validators/ajv` subpath so reading the exported `Ajv` class no longer throws `ReferenceError: import_ajv is not defined`. The subpath now re-exports the bundled provider's concrete `Ajv` value in CJS output, matching the existing ESM behavior. + +- [#2405](https://github.com/modelcontextprotocol/typescript-sdk/pull/2405) [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Ship CommonJS builds alongside ESM. Each package now emits both `.mjs`/`.d.mts` + and `.cjs`/`.d.cts` (via tsdown `format: ['esm', 'cjs']`), and its `exports` map + adds a `require` condition so `require('@modelcontextprotocol/…')` works from + CommonJS consumers. Output extensions are normalized across all packages + (`@modelcontextprotocol/core` moves from `.js`/`.d.ts` to `.mjs`/`.d.mts`); the + public import paths are unchanged. + +- [#2441](https://github.com/modelcontextprotocol/typescript-sdk/pull/2441) [`561c6d8`](https://github.com/modelcontextprotocol/typescript-sdk/commit/561c6d83456ef98d6c713bbda9837e64337f22c9) Thanks [@felixweinberger](https://github.com/felixweinberger)! - POSTs whose `Content-Type` media type is not `application/json` are now + rejected with `415 Unsupported Media Type`; the header is parsed instead of + substring-matched. Previously any value merely containing the substring + passed the check (for example `text/plain; a=application/json`), case + variants were wrongly rejected, and the 2026-07-28 entry did not inspect + `Content-Type` at all — requests with a missing or non-JSON header that used + to be served on that path now also answer 415. Values with parameters + (`application/json; charset=utf-8`, including malformed parameter sections + like `application/json;`) continue to work. SDK clients always send the + correct header and are unaffected. + + The new `isJsonContentType(header)` helper is exported for transport and + framework-adapter authors — custom entries composing the exported building + blocks (`classifyInboundRequest`, `PerRequestHTTPServerTransport`) must apply + it themselves. The hono adapter's JSON body pre-parse and the client's + response dispatch now use the same parsed-media-type comparison. + +- [#2384](https://github.com/modelcontextprotocol/typescript-sdk/pull/2384) [`ce2f65d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/ce2f65db0e019506f4d2526466ec8cc7106de98e) Thanks [@felixweinberger](https://github.com/felixweinberger)! - `instanceof` on the SDK error classes (`ProtocolError` and its typed subclasses, `SdkError`/`SdkHttpError`, `OAuthError`, and the client's `SseError`, `UnauthorizedError`, and OAuth-client-flow error family — `OAuthClientFlowError` and its subclasses) now works across separately bundled copies of the SDK. The classes match by a stable brand (via `Symbol.hasInstance` and a registry symbol) instead of prototype identity, so a process that uses both `@modelcontextprotocol/client` and `@modelcontextprotocol/server` - a gateway, host, or in-process test - can check errors constructed by either package against the class re-exported by the other. Ordinary prototype-based `instanceof` is preserved as a fallback; user-defined subclasses keep plain prototype semantics. Notes: cross-bundle matching requires both copies to be at or after this release; brands assert identity, not field shape, across versions - keep reading fields defensively. As a side effect, a foreign-bundle `SdkError` used as an abort reason is now rethrown as-is instead of being wrapped as a `RequestTimeout`. Branded hierarchies additionally expose an explicit static guard, `X.isInstance(value)`, that reads the same brand and narrows in TypeScript — an alternative for codebases that prefer predicate-style checks over `instanceof`. Also: `UnauthorizedError` now sets `error.name` to `'UnauthorizedError'` (previously `'Error'`), and per-package conformance tests enforce that every exported error class participates in branding. Version-negotiation probing now recognizes `UnauthorizedError` (previously a dead name-string check) and propagates it unchanged, so `connect()` on an auth-gated server rejects with the original `UnauthorizedError` (previously wrapped as the `cause` of an `SdkError(EraNegotiationFailed)`) — run `finishAuth()` and reconnect, and the retry probes with the token. + +- [#2469](https://github.com/modelcontextprotocol/typescript-sdk/pull/2469) [`9b41b56`](https://github.com/modelcontextprotocol/typescript-sdk/commit/9b41b5685ded29c0afc194bbd91bb1902bee6f84) Thanks [@felixweinberger](https://github.com/felixweinberger)! - The Streamable HTTP client transport no longer attaches a session ID to a POST containing an `initialize` request — a new session starts "without a session ID attached" (2025-11-25 transports §Session Management) — and it only captures the `mcp-session-id` response header from a successful initialize response, since the spec assigns the session ID "at initialization time … on the HTTP response containing the InitializeResult". Previously the transport stored the header from any response, so a legacy server answering a protocol-version probe with an error that happened to carry a session ID would poison the fallback initialize, which then went out with a session ID it should not have had. A stale session ID from a previous connection is likewise no longer leaked onto the initialize handshake, and a successful initialize response that carries no session ID now clears any stale ID the transport was holding — clients include only an ID "returned by the server during initialization", so an ID the server never returned this session is outside the session model. Ignoring `mcp-session-id` headers mid-session is the complement of the spec's one actual rotation mechanism: a server that wants a new session terminates the old one (it "MAY terminate the session at any time") and answers 404, after which the client "MUST start a new session by sending a new InitializeRequest without a session ID attached". Rotation exists as session replacement via 404 + re-initialize, never as a header swap on a live session, so a server that rotates per the spec's own flow is handled correctly by this transport. + +- [#2458](https://github.com/modelcontextprotocol/typescript-sdk/pull/2458) [`7c49b47`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7c49b47fb3a58b51cec8fd0b337f656515f1a2b7) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Construct the default Ajv validation engine lazily on first validation. Creating a `Client` or `Server` no longer pays the ajv + ajv-formats instantiation cost at startup when no JSON Schema validation ever runs. + +- [#2476](https://github.com/modelcontextprotocol/typescript-sdk/pull/2476) [`e0a0ab7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e0a0ab74d9baed74572c9f435313fb6daef1b989) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Build protocol-revision wire schemas lazily on first validation instead of at import. Each revision's schema set is now constructed by a module-level memoized factory, so importing the client or server package no longer pays the construction cost of both frozen wire-schema graphs up front. Method membership in the revision registries stays static, the schemas themselves are unchanged, and registry lookups keep returning reference-identical schema objects. + +- [#2564](https://github.com/modelcontextprotocol/typescript-sdk/pull/2564) [`faa7e2b`](https://github.com/modelcontextprotocol/typescript-sdk/commit/faa7e2b47090219060c0699bfe49ebe011516bce) Thanks [@felixweinberger](https://github.com/felixweinberger)! - The version-negotiation probe no longer misclassifies auth-protected or + failing servers as legacy. Auth status is never era evidence: a 401 or 403 + rejection of the `server/discover` probe now surfaces as a typed + authorization failure — an `SdkHttpError` with code `ClientHttpAuthentication` + (401) or `ClientHttpForbidden` (403), carrying the HTTP status, reason + phrase, and response text — instead of triggering the legacy `initialize` + fallback (which put a doomed `initialize` on the wire) or, under `pin` mode, + the false "server did not offer pinned protocol version" diagnostic. The + codes are deliberately not `EraNegotiationFailed`, so era-recovery flows + keyed on that code cannot persist a verdict for an unauthorized exchange. A + 5xx rejecting the probe is a server failure and now also rejects typed + (`SdkHttpError(EraNegotiationFailed)`) instead of demoting a mid-deploy + modern server to legacy — the legacy fallback now fires only on the 4xx + shapes the spec licenses. + + With an `authProvider`, a `401` (and a `403` `insufficient_scope` challenge) runs the transport's auth flow first — a plain `403` rejects the same as without a provider — and whatever + escapes it propagates unchanged, identity intact: the HTTP transports stamp + errors at their auth seams (the `token()` read, `onUnauthorized` including + custom callbacks, the 403 step-up flow, and their own auth-failure + constructions), so `UnauthorizedError` for `finishAuth()`, the flow's typed + failures (`OAuthError`, `InsufficientScopeError`, the + 401-after-re-authentication diagnostic), and even an untyped `TypeError` + thrown inside the flow all reach the caller as thrown — never rewrapped, + never consumed by the probe's browser CORS heuristic as legacy-era evidence. + +- [#2514](https://github.com/modelcontextprotocol/typescript-sdk/pull/2514) [`6fe1963`](https://github.com/modelcontextprotocol/typescript-sdk/commit/6fe196310ddba95a9f9655facb6b7c1ab503d346) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Probe stdio servers on a disposable sibling process. Some stdio servers exit on any pre-`initialize` request (servers built on the official Rust SDK, rmcp, behave this way), so under `versionNegotiation: { mode: 'auto' }` the `server/discover` probe previously killed the server and `connect()` hard-failed. The probe now runs on a short-lived sibling spawned from the same parameters — its stderr is discarded and it is reaped once the era is known — and the caller's transport spawns exactly once, afterwards: a legacy verdict connects with the plain `initialize` handshake (byte-identical to `mode: 'legacy'`), a modern verdict is adopted directly, and the session wire never carries `server/discover`. Closing the caller's transport during the probe aborts `connect()` with the typed `SdkError(EraNegotiationFailed)` and the session child is never spawned. On HTTP — and on custom stdio-shaped transports, which probe in place — a mid-probe connection close keeps rejecting with the typed connect error, now naming the close in pin-mode and modern-only diagnostics. + +- [#2455](https://github.com/modelcontextprotocol/typescript-sdk/pull/2455) [`cc70c5e`](https://github.com/modelcontextprotocol/typescript-sdk/commit/cc70c5e6a9f9b1c15dcba0bdd019a479b81375de) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Version negotiation no longer discards transport handlers the caller set before `connect()`. The probe window now saves any pre-set `onmessage`/`onerror`/`onclose`, forwards error and close events to them while the probe is in flight, and restores them when the window closes — so `Protocol.connect()` chains them exactly as it does on a plain connect. Previously, connecting with `versionNegotiation` silently cleared pre-set handlers (e.g. an `onerror` used to detect session-expiry auth failures), leaving them permanently detached for the life of the connection. + +- [#2425](https://github.com/modelcontextprotocol/typescript-sdk/pull/2425) [`e8de519`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e8de519d3129f46b7528d2999b7641f55be1f091) Thanks [@Sehlani042](https://github.com/Sehlani042)! - Stop advertising validator provider classes from the root client/server type declarations. The provider classes remain available from the explicit validator subpaths. + +- [#2534](https://github.com/modelcontextprotocol/typescript-sdk/pull/2534) [`f130e1a`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f130e1ac5fcab34bd568f59907e0f2ce1d22074c) Thanks [@felixweinberger](https://github.com/felixweinberger)! - The default validator now honors declared 2019-09 and draft-07/06 dialects instead of rejecting them: a schema stamped `"$schema": "http://json-schema.org/draft-07/schema#"` (zod-to-json-schema's default output) validates with draft-07 semantics, and a 2019-09 stamp (zod-to-json-schema's `2019-09`/`openAi` targets) with 2019-09 semantics, on both the Ajv and Cloudflare Workers providers (with known engine differences documented in the migration guide). Schemas with no `$schema` still validate as 2020-12, and unknown dialects still produce the typed error (now listing the supported dialects: 2020-12, 2019-09, draft-07, draft-06). + +- Updated dependencies [[`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a), [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32), [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011), [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4), [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313)]: + - @modelcontextprotocol/core@2.0.0 + ## 2.0.0-beta.5 ### Minor Changes diff --git a/packages/client/package.json b/packages/client/package.json index 8e23ca819f..3ebfde64d3 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/client", - "version": "2.0.0-beta.5", + "version": "2.0.0", "description": "Model Context Protocol implementation for TypeScript - Client package", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/codemod/CHANGELOG.md b/packages/codemod/CHANGELOG.md index 1e76d334bd..3506a1e5f9 100644 --- a/packages/codemod/CHANGELOG.md +++ b/packages/codemod/CHANGELOG.md @@ -1,5 +1,41 @@ # @modelcontextprotocol/codemod +## 2.0.0 + +### Patch Changes + +- [#2402](https://github.com/modelcontextprotocol/typescript-sdk/pull/2402) [`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - First beta release of SDK v2 with support for the MCP 2026-07-28 specification + revision. See the migration guides for upgrading from v1 + (`docs/migration/upgrade-to-v2.md`) and adopting the 2026-07-28 revision + (`docs/migration/support-2026-07-28.md`). + +- [#2405](https://github.com/modelcontextprotocol/typescript-sdk/pull/2405) [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Ship CommonJS builds alongside ESM. Each package now emits both `.mjs`/`.d.mts` + and `.cjs`/`.d.cts` (via tsdown `format: ['esm', 'cjs']`), and its `exports` map + adds a `require` condition so `require('@modelcontextprotocol/…')` works from + CommonJS consumers. Output extensions are normalized across all packages + (`@modelcontextprotocol/core` moves from `.js`/`.d.ts` to `.mjs`/`.d.mts`); the + public import paths are unchanged. + +- [#2486](https://github.com/modelcontextprotocol/typescript-sdk/pull/2486) [`ee8267a`](https://github.com/modelcontextprotocol/typescript-sdk/commit/ee8267af4a55efda3cebdb35a1ebb1d797e4235d) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Version the codemod together with the core SDK packages, matching the migration guide's shared-version guarantee. + +- [#2412](https://github.com/modelcontextprotocol/typescript-sdk/pull/2412) [`ef120b2`](https://github.com/modelcontextprotocol/typescript-sdk/commit/ef120b2be0c3c3d80468c3d4a9f79be30bb0c0a3) Thanks [@felixweinberger](https://github.com/felixweinberger)! - v1-to-v2 migration fixes from continued real-world migrations (codemod iterations 5). + +- [#2419](https://github.com/modelcontextprotocol/typescript-sdk/pull/2419) [`79dc162`](https://github.com/modelcontextprotocol/typescript-sdk/commit/79dc162efcb4e1f7b820bfb6068906483cf71ec7) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Read the v2 package versions the codemod writes into migrated `package.json` files directly from the workspace manifests at build time, replacing the committed generated `versions.ts` (which went stale after every release and made source builds write outdated versions). + +- [#2501](https://github.com/modelcontextprotocol/typescript-sdk/pull/2501) [`1480241`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1480241e2a2a7f0ceee8e7723b2adcf88579bb36) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Export the `Protocol` base class and `mergeCapabilities` from the `@modelcontextprotocol/client` and `@modelcontextprotocol/server` package roots, restoring the v1 import for consumers that subclass `Protocol` (e.g. the MCP Apps SDK). The client and server packages each bundle their own compiled copy of the class, so import it from one package consistently within a process. + + The codemod now rewrites `Protocol` and `mergeCapabilities` imports from `shared/protocol.js` to the client or server package root, like the module's other symbols, instead of dropping them with an action-required marker. + +- [#2420](https://github.com/modelcontextprotocol/typescript-sdk/pull/2420) [`7635115`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7635115d0112c3f980b45a9773a4770660af8aae) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Add runtime-neutral Bearer authentication to `@modelcontextprotocol/server`: + `requireBearerAuth` gates web-standard `fetch(request)` hosts (Cloudflare + Workers, Deno, Bun, Hono), built on the exported `verifyBearerToken` and + `bearerAuthChallengeResponse` pieces, with `OAuthTokenVerifier` now defined + here. The Express middleware adapts the same core and is unchanged in + behavior, except that `WWW-Authenticate` challenge values are now RFC 7235 + quoted-string sanitized (quotes and backslashes escaped, control and + non-ASCII characters replaced); `@modelcontextprotocol/express` re-exports + `OAuthTokenVerifier` as before. + ## 2.0.0-beta.5 ### Patch Changes diff --git a/packages/codemod/package.json b/packages/codemod/package.json index 5cbaf4c826..09cabe0bcf 100644 --- a/packages/codemod/package.json +++ b/packages/codemod/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/codemod", - "version": "2.0.0-beta.5", + "version": "2.0.0", "description": "Codemod to migrate MCP TypeScript SDK code from v1 to v2", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/core-internal/CHANGELOG.md b/packages/core-internal/CHANGELOG.md index 7e24d8ccdc..450c293bf3 100644 --- a/packages/core-internal/CHANGELOG.md +++ b/packages/core-internal/CHANGELOG.md @@ -1,5 +1,42 @@ # @modelcontextprotocol/core-internal +## 2.0.0 + +### Minor Changes + +- [#2501](https://github.com/modelcontextprotocol/typescript-sdk/pull/2501) [`1480241`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1480241e2a2a7f0ceee8e7723b2adcf88579bb36) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Export the `Protocol` base class and `mergeCapabilities` from the `@modelcontextprotocol/client` and `@modelcontextprotocol/server` package roots, restoring the v1 import for consumers that subclass `Protocol` (e.g. the MCP Apps SDK). The client and server packages each bundle their own compiled copy of the class, so import it from one package consistently within a process. + + The codemod now rewrites `Protocol` and `mergeCapabilities` imports from `shared/protocol.js` to the client or server package root, like the module's other symbols, instead of dropping them with an action-required marker. + +- [#2513](https://github.com/modelcontextprotocol/typescript-sdk/pull/2513) [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Align the 2026-07-28 wire with the final revision (spec PR #3002): `serverInfo` moves from the `DiscoverResult` body to the result `_meta`, and the per-request envelope's `clientInfo` demotes from required to SHOULD. + + Before this change the SDK shipped the pre-#3002 shape in both directions: the client hard-rejected a conforming server's `DiscoverResult` (missing body `serverInfo` failed parse, so the probe misclassified the server as legacy and attempted an `initialize` handshake against it — a hard connect failure against a modern-only server such as go-sdk v1.7.0-pre.3), and the server rejected conforming clients that omit `clientInfo`. + + Now: + - The 2026 wire schemas are the final revision exactly: no body `serverInfo` on `DiscoverResult`, envelope `clientInfo` optional (a present-but-malformed value still fails validation). + - Servers stamp `_meta['io.modelcontextprotocol/serverInfo']` on every 2026-era response (spec SHOULD; a handler-authored value wins, the 2025-era wire is untouched). This includes the entry-built `subscriptions/listen` graceful-close results — the spec's `SubscriptionsListenResultMeta` extends `ResultMetaObject`. + - Clients keep sending `clientInfo` and read server identity from the discover result's `_meta` only. A server that stamps no identity is anonymous: `getServerVersion()` is `undefined` and the response cache partitions under a per-connection surrogate. A malformed `_meta` serverInfo value is treated as absent on receive (the spec marks the field self-reported, unverified, and display-only). + - Breaking type changes: `DiscoverResult` no longer declares `serverInfo`; `RequestMetaEnvelope`'s `clientInfo` is optional. New public constant `SERVER_INFO_META_KEY` (`'io.modelcontextprotocol/serverInfo'`). + +- [#2369](https://github.com/modelcontextprotocol/typescript-sdk/pull/2369) [`24be404`](https://github.com/modelcontextprotocol/typescript-sdk/commit/24be4040d454a9c5983901229068477c7a9ea796) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Allow `inputRequired.elicit()` to accept a Standard Schema such as a Zod object for `requestedSchema`. The builder converts it to MCP's restricted form-elicitation JSON Schema, while the same schema can validate and type the response through `acceptedContent()` on handler re-entry. Zod formats mapping to `email`, `uri`, `date`, and `date-time` are supported. Shapes the restricted schema cannot express reject before anything is sent — nested objects, `.regex()` and customized zod format patterns, exclusive number bounds (`.positive()`/`.gt()`), literal unions (use `z.enum` or `z.literal(['a', 'b'])`), and non-spec root keywords like `z.strictObject()`'s `additionalProperties`. + +### Patch Changes + +- [#2456](https://github.com/modelcontextprotocol/typescript-sdk/pull/2456) [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Restore the v1 parse tolerance for `CallToolResult.content`: an inbound legacy-era `tools/call` result without `content` defaults to `[]` instead of failing validation. Deployed servers — accepted by SDK v1 for years — return `structuredContent`-only (or otherwise content-less) results, and the strict parse turned every such call into an `INVALID_RESULT` error before application code could run. + + The silent-empty-success hazard the strictness guarded is preserved where it matters: the 2025 era's wire-seam schema refuses to default `content` for a body carrying another result family's vocabulary (`task`, `inputRequests`, `requestState` — the era is frozen, so the list is complete), and the 2026-era wire schemas stay strict — modern-revision servers have no legacy excuse. Task interop through an explicit result schema is untouched (including bodies that also stamp a foreign `resultType`), and the server-side authoring normalization refuses the same foreign-family vocabulary. + + Server-side authoring is era-independent: a handler result without `content` (dynamic/JS callers — the TypeScript surface requires it) is normalized to `content: []` before era validation on every leg, reaching the wire spec-valid. + + Conscious call: the nested sampling `ToolResultContentSchema` stays spec-strict — v1 had defaulted its `content` too, but it is params-side (tool results a caller authors into a sampling message), deliberately not restored. + +- [#2399](https://github.com/modelcontextprotocol/typescript-sdk/pull/2399) [`3c7ddaf`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3c7ddafa05d8f17fb52168bf4638f09251c3d0ff) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Return HTTP 400 for a `MissingRequiredClientCapabilityError` (`-32021`) produced after dispatch. The spec mandates `400 Bad Request` for this error with no condition on where it arose, but only the pre-dispatch capability gate honored that; the post-handler emission — the `input_required` gate rejecting an embedded request whose required capability the caller did not declare — surfaced in-band on HTTP 200. The JSON-RPC error body is unchanged, every other error code (including a handler relaying a downstream peer's `-32020`/`-32022`) keeps the origin-keyed in-band behavior, and the mapping only applies while the response is uncommitted: an exchange that already streamed — or one hosted with `responseMode: 'sse'`, which opens its stream at dispatch end — keeps its committed 200 and carries the error in-stream. + +- [#2453](https://github.com/modelcontextprotocol/typescript-sdk/pull/2453) [`0ab5d14`](https://github.com/modelcontextprotocol/typescript-sdk/commit/0ab5d1471d6c7375878316df2930fca77eee1d2a) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Strip RFC 9110 optional whitespace around inbound `MCP-Protocol-Version`, `Mcp-Method`, and `Mcp-Name` values before classifying and validating modern HTTP requests. This keeps valid requests portable across Fetch runtimes that expose raw leading or trailing SP/HTAB through `Headers.get()`. + +- Updated dependencies [[`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a), [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32), [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011), [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4), [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313)]: + - @modelcontextprotocol/core@2.0.0 + ## 2.0.0-beta.4 ### Minor Changes diff --git a/packages/core-internal/package.json b/packages/core-internal/package.json index 0440f98fda..44a4be1cd3 100644 --- a/packages/core-internal/package.json +++ b/packages/core-internal/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/core-internal", "private": true, - "version": "2.0.0-beta.4", + "version": "2.0.0", "description": "Model Context Protocol implementation for TypeScript - Core package", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 34b27a6f9d..d109bed7a6 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,43 @@ # @modelcontextprotocol/core +## 2.0.0 + +### Minor Changes + +- [#2477](https://github.com/modelcontextprotocol/typescript-sdk/pull/2477) [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Move the schema source modules (spec schemas, OAuth schemas, protocol constants) into `@modelcontextprotocol/core` and resolve them from there as a regular runtime dependency instead of bundling a private copy into each package. An application importing more than one of the packages now evaluates a single shared schema graph with shared object identity. `@modelcontextprotocol/core` gains a `./internal` subpath (SDK-internal contract; may change in any release) and the four packages now version together. + +- [#2513](https://github.com/modelcontextprotocol/typescript-sdk/pull/2513) [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Align the 2026-07-28 wire with the final revision (spec PR #3002): `serverInfo` moves from the `DiscoverResult` body to the result `_meta`, and the per-request envelope's `clientInfo` demotes from required to SHOULD. + + Before this change the SDK shipped the pre-#3002 shape in both directions: the client hard-rejected a conforming server's `DiscoverResult` (missing body `serverInfo` failed parse, so the probe misclassified the server as legacy and attempted an `initialize` handshake against it — a hard connect failure against a modern-only server such as go-sdk v1.7.0-pre.3), and the server rejected conforming clients that omit `clientInfo`. + + Now: + - The 2026 wire schemas are the final revision exactly: no body `serverInfo` on `DiscoverResult`, envelope `clientInfo` optional (a present-but-malformed value still fails validation). + - Servers stamp `_meta['io.modelcontextprotocol/serverInfo']` on every 2026-era response (spec SHOULD; a handler-authored value wins, the 2025-era wire is untouched). This includes the entry-built `subscriptions/listen` graceful-close results — the spec's `SubscriptionsListenResultMeta` extends `ResultMetaObject`. + - Clients keep sending `clientInfo` and read server identity from the discover result's `_meta` only. A server that stamps no identity is anonymous: `getServerVersion()` is `undefined` and the response cache partitions under a per-connection surrogate. A malformed `_meta` serverInfo value is treated as absent on receive (the spec marks the field self-reported, unverified, and display-only). + - Breaking type changes: `DiscoverResult` no longer declares `serverInfo`; `RequestMetaEnvelope`'s `clientInfo` is optional. New public constant `SERVER_INFO_META_KEY` (`'io.modelcontextprotocol/serverInfo'`). + +### Patch Changes + +- [#2402](https://github.com/modelcontextprotocol/typescript-sdk/pull/2402) [`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - First beta release of SDK v2 with support for the MCP 2026-07-28 specification + revision. See the migration guides for upgrading from v1 + (`docs/migration/upgrade-to-v2.md`) and adopting the 2026-07-28 revision + (`docs/migration/support-2026-07-28.md`). + +- [#2456](https://github.com/modelcontextprotocol/typescript-sdk/pull/2456) [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Restore the v1 parse tolerance for `CallToolResult.content`: an inbound legacy-era `tools/call` result without `content` defaults to `[]` instead of failing validation. Deployed servers — accepted by SDK v1 for years — return `structuredContent`-only (or otherwise content-less) results, and the strict parse turned every such call into an `INVALID_RESULT` error before application code could run. + + The silent-empty-success hazard the strictness guarded is preserved where it matters: the 2025 era's wire-seam schema refuses to default `content` for a body carrying another result family's vocabulary (`task`, `inputRequests`, `requestState` — the era is frozen, so the list is complete), and the 2026-era wire schemas stay strict — modern-revision servers have no legacy excuse. Task interop through an explicit result schema is untouched (including bodies that also stamp a foreign `resultType`), and the server-side authoring normalization refuses the same foreign-family vocabulary. + + Server-side authoring is era-independent: a handler result without `content` (dynamic/JS callers — the TypeScript surface requires it) is normalized to `content: []` before era validation on every leg, reaching the wire spec-valid. + + Conscious call: the nested sampling `ToolResultContentSchema` stays spec-strict — v1 had defaulted its `content` too, but it is params-side (tool results a caller authors into a sampling message), deliberately not restored. + +- [#2405](https://github.com/modelcontextprotocol/typescript-sdk/pull/2405) [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Ship CommonJS builds alongside ESM. Each package now emits both `.mjs`/`.d.mts` + and `.cjs`/`.d.cts` (via tsdown `format: ['esm', 'cjs']`), and its `exports` map + adds a `require` condition so `require('@modelcontextprotocol/…')` works from + CommonJS consumers. Output extensions are normalized across all packages + (`@modelcontextprotocol/core` moves from `.js`/`.d.ts` to `.mjs`/`.d.mts`); the + public import paths are unchanged. + ## 2.0.0-beta.5 ### Minor Changes diff --git a/packages/core/package.json b/packages/core/package.json index ec24da58e5..0e02ff8b1e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/core", - "version": "2.0.0-beta.5", + "version": "2.0.0", "description": "Model Context Protocol for TypeScript — public Zod schemas (spec + OAuth/OpenID)", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/middleware/express/CHANGELOG.md b/packages/middleware/express/CHANGELOG.md index 620177a99a..d23a21928a 100644 --- a/packages/middleware/express/CHANGELOG.md +++ b/packages/middleware/express/CHANGELOG.md @@ -1,5 +1,46 @@ # @modelcontextprotocol/express +## 2.0.0 + +### Patch Changes + +- [#2402](https://github.com/modelcontextprotocol/typescript-sdk/pull/2402) [`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - First beta release of SDK v2 with support for the MCP 2026-07-28 specification + revision. See the migration guides for upgrading from v1 + (`docs/migration/upgrade-to-v2.md`) and adopting the 2026-07-28 revision + (`docs/migration/support-2026-07-28.md`). + +- [#2405](https://github.com/modelcontextprotocol/typescript-sdk/pull/2405) [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Ship CommonJS builds alongside ESM. Each package now emits both `.mjs`/`.d.mts` + and `.cjs`/`.d.cts` (via tsdown `format: ['esm', 'cjs']`), and its `exports` map + adds a `require` condition so `require('@modelcontextprotocol/…')` works from + CommonJS consumers. Output extensions are normalized across all packages + (`@modelcontextprotocol/core` moves from `.js`/`.d.ts` to `.mjs`/`.d.mts`); the + public import paths are unchanged. + +- [#2420](https://github.com/modelcontextprotocol/typescript-sdk/pull/2420) [`7635115`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7635115d0112c3f980b45a9773a4770660af8aae) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Add runtime-neutral Bearer authentication to `@modelcontextprotocol/server`: + `requireBearerAuth` gates web-standard `fetch(request)` hosts (Cloudflare + Workers, Deno, Bun, Hono), built on the exported `verifyBearerToken` and + `bearerAuthChallengeResponse` pieces, with `OAuthTokenVerifier` now defined + here. The Express middleware adapts the same core and is unchanged in + behavior, except that `WWW-Authenticate` challenge values are now RFC 7235 + quoted-string sanitized (quotes and backslashes escaped, control and + non-ASCII characters replaced); `@modelcontextprotocol/express` re-exports + `OAuthTokenVerifier` as before. + +- [#2422](https://github.com/modelcontextprotocol/typescript-sdk/pull/2422) [`61866d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/61866d7a5ff4475663ceb525c88447c497c1b92a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Add runtime-neutral OAuth discovery serving to `@modelcontextprotocol/server`: + `oauthMetadataResponse` serves the RFC 9728 Protected Resource Metadata and + RFC 8414 Authorization Server metadata documents from web-standard + `fetch(request)` hosts, built on the exported + `buildOAuthProtectedResourceMetadata`, with + `getOAuthProtectedResourceMetadataUrl` now defined here. The Express metadata + router adapts the same core and is unchanged in behavior; the insecure-issuer + escape hatch is an explicit `dangerouslyAllowInsecureIssuerUrl` option in the + neutral core instead of a module-scope environment read. The web-standard + matcher validates lazily so unmatched traffic always falls through, tolerates + a trailing slash, supports HEAD, and marks reflected CORS preflights with + `Vary`. +- Updated dependencies [[`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a), [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32), [`1b90c96`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1b90c96d11fd17016d2977cae9dd661de3fb84df), [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011), [`561c6d8`](https://github.com/modelcontextprotocol/typescript-sdk/commit/561c6d83456ef98d6c713bbda9837e64337f22c9), [`ce2f65d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/ce2f65db0e019506f4d2526466ec8cc7106de98e), [`1480241`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1480241e2a2a7f0ceee8e7723b2adcf88579bb36), [`7c49b47`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7c49b47fb3a58b51cec8fd0b337f656515f1a2b7), [`e0a0ab7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e0a0ab74d9baed74572c9f435313fb6daef1b989), [`7e69735`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7e697354de95111ca2c70a12ac9f5d3ec96b56c3), [`3c7ddaf`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3c7ddafa05d8f17fb52168bf4638f09251c3d0ff), [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4), [`e8de519`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e8de519d3129f46b7528d2999b7641f55be1f091), [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313), [`0ab5d14`](https://github.com/modelcontextprotocol/typescript-sdk/commit/0ab5d1471d6c7375878316df2930fca77eee1d2a), [`24be404`](https://github.com/modelcontextprotocol/typescript-sdk/commit/24be4040d454a9c5983901229068477c7a9ea796), [`470678d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/470678d56b9ee2a365fcf6d3de21e3a8b32eeef5), [`f130e1a`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f130e1ac5fcab34bd568f59907e0f2ce1d22074c), [`7635115`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7635115d0112c3f980b45a9773a4770660af8aae), [`61866d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/61866d7a5ff4475663ceb525c88447c497c1b92a), [`3f07a32`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3f07a325c6741b2374ce2255846dfa0c25f74d03)]: + - @modelcontextprotocol/server@2.0.0 + ## 2.0.0-beta.5 ### Patch Changes diff --git a/packages/middleware/express/package.json b/packages/middleware/express/package.json index b15467d482..5a2602bafb 100644 --- a/packages/middleware/express/package.json +++ b/packages/middleware/express/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/express", "private": false, - "version": "2.0.0-beta.5", + "version": "2.0.0", "description": "Express adapters for the Model Context Protocol TypeScript server SDK - Express middleware", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/middleware/fastify/CHANGELOG.md b/packages/middleware/fastify/CHANGELOG.md index cf3189a35a..35823f1e73 100644 --- a/packages/middleware/fastify/CHANGELOG.md +++ b/packages/middleware/fastify/CHANGELOG.md @@ -1,5 +1,23 @@ # @modelcontextprotocol/fastify +## 2.0.0 + +### Patch Changes + +- [#2402](https://github.com/modelcontextprotocol/typescript-sdk/pull/2402) [`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - First beta release of SDK v2 with support for the MCP 2026-07-28 specification + revision. See the migration guides for upgrading from v1 + (`docs/migration/upgrade-to-v2.md`) and adopting the 2026-07-28 revision + (`docs/migration/support-2026-07-28.md`). + +- [#2405](https://github.com/modelcontextprotocol/typescript-sdk/pull/2405) [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Ship CommonJS builds alongside ESM. Each package now emits both `.mjs`/`.d.mts` + and `.cjs`/`.d.cts` (via tsdown `format: ['esm', 'cjs']`), and its `exports` map + adds a `require` condition so `require('@modelcontextprotocol/…')` works from + CommonJS consumers. Output extensions are normalized across all packages + (`@modelcontextprotocol/core` moves from `.js`/`.d.ts` to `.mjs`/`.d.mts`); the + public import paths are unchanged. +- Updated dependencies [[`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a), [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32), [`1b90c96`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1b90c96d11fd17016d2977cae9dd661de3fb84df), [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011), [`561c6d8`](https://github.com/modelcontextprotocol/typescript-sdk/commit/561c6d83456ef98d6c713bbda9837e64337f22c9), [`ce2f65d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/ce2f65db0e019506f4d2526466ec8cc7106de98e), [`1480241`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1480241e2a2a7f0ceee8e7723b2adcf88579bb36), [`7c49b47`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7c49b47fb3a58b51cec8fd0b337f656515f1a2b7), [`e0a0ab7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e0a0ab74d9baed74572c9f435313fb6daef1b989), [`7e69735`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7e697354de95111ca2c70a12ac9f5d3ec96b56c3), [`3c7ddaf`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3c7ddafa05d8f17fb52168bf4638f09251c3d0ff), [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4), [`e8de519`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e8de519d3129f46b7528d2999b7641f55be1f091), [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313), [`0ab5d14`](https://github.com/modelcontextprotocol/typescript-sdk/commit/0ab5d1471d6c7375878316df2930fca77eee1d2a), [`24be404`](https://github.com/modelcontextprotocol/typescript-sdk/commit/24be4040d454a9c5983901229068477c7a9ea796), [`470678d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/470678d56b9ee2a365fcf6d3de21e3a8b32eeef5), [`f130e1a`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f130e1ac5fcab34bd568f59907e0f2ce1d22074c), [`7635115`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7635115d0112c3f980b45a9773a4770660af8aae), [`61866d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/61866d7a5ff4475663ceb525c88447c497c1b92a), [`3f07a32`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3f07a325c6741b2374ce2255846dfa0c25f74d03)]: + - @modelcontextprotocol/server@2.0.0 + ## 2.0.0-beta.5 ### Patch Changes diff --git a/packages/middleware/fastify/package.json b/packages/middleware/fastify/package.json index 87cd4f0d33..d15134ef19 100644 --- a/packages/middleware/fastify/package.json +++ b/packages/middleware/fastify/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/fastify", "private": false, - "version": "2.0.0-beta.5", + "version": "2.0.0", "description": "Fastify adapters for the Model Context Protocol TypeScript server SDK - Fastify middleware", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/middleware/hono/CHANGELOG.md b/packages/middleware/hono/CHANGELOG.md index b5f1cc5061..060d31794e 100644 --- a/packages/middleware/hono/CHANGELOG.md +++ b/packages/middleware/hono/CHANGELOG.md @@ -1,5 +1,41 @@ # @modelcontextprotocol/hono +## 2.0.0 + +### Patch Changes + +- [#2402](https://github.com/modelcontextprotocol/typescript-sdk/pull/2402) [`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - First beta release of SDK v2 with support for the MCP 2026-07-28 specification + revision. See the migration guides for upgrading from v1 + (`docs/migration/upgrade-to-v2.md`) and adopting the 2026-07-28 revision + (`docs/migration/support-2026-07-28.md`). + +- [#2405](https://github.com/modelcontextprotocol/typescript-sdk/pull/2405) [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Ship CommonJS builds alongside ESM. Each package now emits both `.mjs`/`.d.mts` + and `.cjs`/`.d.cts` (via tsdown `format: ['esm', 'cjs']`), and its `exports` map + adds a `require` condition so `require('@modelcontextprotocol/…')` works from + CommonJS consumers. Output extensions are normalized across all packages + (`@modelcontextprotocol/core` moves from `.js`/`.d.ts` to `.mjs`/`.d.mts`); the + public import paths are unchanged. + +- [#2441](https://github.com/modelcontextprotocol/typescript-sdk/pull/2441) [`561c6d8`](https://github.com/modelcontextprotocol/typescript-sdk/commit/561c6d83456ef98d6c713bbda9837e64337f22c9) Thanks [@felixweinberger](https://github.com/felixweinberger)! - POSTs whose `Content-Type` media type is not `application/json` are now + rejected with `415 Unsupported Media Type`; the header is parsed instead of + substring-matched. Previously any value merely containing the substring + passed the check (for example `text/plain; a=application/json`), case + variants were wrongly rejected, and the 2026-07-28 entry did not inspect + `Content-Type` at all — requests with a missing or non-JSON header that used + to be served on that path now also answer 415. Values with parameters + (`application/json; charset=utf-8`, including malformed parameter sections + like `application/json;`) continue to work. SDK clients always send the + correct header and are unaffected. + + The new `isJsonContentType(header)` helper is exported for transport and + framework-adapter authors — custom entries composing the exported building + blocks (`classifyInboundRequest`, `PerRequestHTTPServerTransport`) must apply + it themselves. The hono adapter's JSON body pre-parse and the client's + response dispatch now use the same parsed-media-type comparison. + +- Updated dependencies [[`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a), [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32), [`1b90c96`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1b90c96d11fd17016d2977cae9dd661de3fb84df), [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011), [`561c6d8`](https://github.com/modelcontextprotocol/typescript-sdk/commit/561c6d83456ef98d6c713bbda9837e64337f22c9), [`ce2f65d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/ce2f65db0e019506f4d2526466ec8cc7106de98e), [`1480241`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1480241e2a2a7f0ceee8e7723b2adcf88579bb36), [`7c49b47`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7c49b47fb3a58b51cec8fd0b337f656515f1a2b7), [`e0a0ab7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e0a0ab74d9baed74572c9f435313fb6daef1b989), [`7e69735`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7e697354de95111ca2c70a12ac9f5d3ec96b56c3), [`3c7ddaf`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3c7ddafa05d8f17fb52168bf4638f09251c3d0ff), [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4), [`e8de519`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e8de519d3129f46b7528d2999b7641f55be1f091), [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313), [`0ab5d14`](https://github.com/modelcontextprotocol/typescript-sdk/commit/0ab5d1471d6c7375878316df2930fca77eee1d2a), [`24be404`](https://github.com/modelcontextprotocol/typescript-sdk/commit/24be4040d454a9c5983901229068477c7a9ea796), [`470678d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/470678d56b9ee2a365fcf6d3de21e3a8b32eeef5), [`f130e1a`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f130e1ac5fcab34bd568f59907e0f2ce1d22074c), [`7635115`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7635115d0112c3f980b45a9773a4770660af8aae), [`61866d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/61866d7a5ff4475663ceb525c88447c497c1b92a), [`3f07a32`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3f07a325c6741b2374ce2255846dfa0c25f74d03)]: + - @modelcontextprotocol/server@2.0.0 + ## 2.0.0-beta.5 ### Patch Changes diff --git a/packages/middleware/hono/package.json b/packages/middleware/hono/package.json index 04eeedfc6e..3cd2650a4a 100644 --- a/packages/middleware/hono/package.json +++ b/packages/middleware/hono/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/hono", "private": false, - "version": "2.0.0-beta.5", + "version": "2.0.0", "description": "Hono adapters for the Model Context Protocol TypeScript server SDK - Hono middleware", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/middleware/node/CHANGELOG.md b/packages/middleware/node/CHANGELOG.md index e040f873a3..32e8e337ec 100644 --- a/packages/middleware/node/CHANGELOG.md +++ b/packages/middleware/node/CHANGELOG.md @@ -1,5 +1,43 @@ # @modelcontextprotocol/node +## 2.0.0 + +### Patch Changes + +- [#2402](https://github.com/modelcontextprotocol/typescript-sdk/pull/2402) [`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - First beta release of SDK v2 with support for the MCP 2026-07-28 specification + revision. See the migration guides for upgrading from v1 + (`docs/migration/upgrade-to-v2.md`) and adopting the 2026-07-28 revision + (`docs/migration/support-2026-07-28.md`). + +- [#2405](https://github.com/modelcontextprotocol/typescript-sdk/pull/2405) [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Ship CommonJS builds alongside ESM. Each package now emits both `.mjs`/`.d.mts` + and `.cjs`/`.d.cts` (via tsdown `format: ['esm', 'cjs']`), and its `exports` map + adds a `require` condition so `require('@modelcontextprotocol/…')` works from + CommonJS consumers. Output extensions are normalized across all packages + (`@modelcontextprotocol/core` moves from `.js`/`.d.ts` to `.mjs`/`.d.mts`); the + public import paths are unchanged. + +- [#2441](https://github.com/modelcontextprotocol/typescript-sdk/pull/2441) [`561c6d8`](https://github.com/modelcontextprotocol/typescript-sdk/commit/561c6d83456ef98d6c713bbda9837e64337f22c9) Thanks [@felixweinberger](https://github.com/felixweinberger)! - POSTs whose `Content-Type` media type is not `application/json` are now + rejected with `415 Unsupported Media Type`; the header is parsed instead of + substring-matched. Previously any value merely containing the substring + passed the check (for example `text/plain; a=application/json`), case + variants were wrongly rejected, and the 2026-07-28 entry did not inspect + `Content-Type` at all — requests with a missing or non-JSON header that used + to be served on that path now also answer 415. Values with parameters + (`application/json; charset=utf-8`, including malformed parameter sections + like `application/json;`) continue to work. SDK clients always send the + correct header and are unaffected. + + The new `isJsonContentType(header)` helper is exported for transport and + framework-adapter authors — custom entries composing the exported building + blocks (`classifyInboundRequest`, `PerRequestHTTPServerTransport`) must apply + it themselves. The hono adapter's JSON body pre-parse and the client's + response dispatch now use the same parsed-media-type comparison. + +- [#2445](https://github.com/modelcontextprotocol/typescript-sdk/pull/2445) [`78fabea`](https://github.com/modelcontextprotocol/typescript-sdk/commit/78fabea44557bd49f5a050b92e57ccd22dab14ad) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Document composing the host and origin validation guards in front of `toNodeHandler` for hand-wired `node:http` servers, matching the protected wiring the examples and serving guide now demonstrate. + +- Updated dependencies [[`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a), [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32), [`1b90c96`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1b90c96d11fd17016d2977cae9dd661de3fb84df), [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011), [`561c6d8`](https://github.com/modelcontextprotocol/typescript-sdk/commit/561c6d83456ef98d6c713bbda9837e64337f22c9), [`ce2f65d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/ce2f65db0e019506f4d2526466ec8cc7106de98e), [`1480241`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1480241e2a2a7f0ceee8e7723b2adcf88579bb36), [`7c49b47`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7c49b47fb3a58b51cec8fd0b337f656515f1a2b7), [`e0a0ab7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e0a0ab74d9baed74572c9f435313fb6daef1b989), [`7e69735`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7e697354de95111ca2c70a12ac9f5d3ec96b56c3), [`3c7ddaf`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3c7ddafa05d8f17fb52168bf4638f09251c3d0ff), [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4), [`e8de519`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e8de519d3129f46b7528d2999b7641f55be1f091), [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313), [`0ab5d14`](https://github.com/modelcontextprotocol/typescript-sdk/commit/0ab5d1471d6c7375878316df2930fca77eee1d2a), [`24be404`](https://github.com/modelcontextprotocol/typescript-sdk/commit/24be4040d454a9c5983901229068477c7a9ea796), [`470678d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/470678d56b9ee2a365fcf6d3de21e3a8b32eeef5), [`f130e1a`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f130e1ac5fcab34bd568f59907e0f2ce1d22074c), [`7635115`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7635115d0112c3f980b45a9773a4770660af8aae), [`61866d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/61866d7a5ff4475663ceb525c88447c497c1b92a), [`3f07a32`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3f07a325c6741b2374ce2255846dfa0c25f74d03)]: + - @modelcontextprotocol/server@2.0.0 + ## 2.0.0-beta.5 ### Patch Changes diff --git a/packages/middleware/node/package.json b/packages/middleware/node/package.json index 642ebe2831..68ccb73ffd 100644 --- a/packages/middleware/node/package.json +++ b/packages/middleware/node/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/node", - "version": "2.0.0-beta.5", + "version": "2.0.0", "description": "Model Context Protocol implementation for TypeScript - Node.js middleware", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/packages/server-legacy/CHANGELOG.md b/packages/server-legacy/CHANGELOG.md index abe99d6033..b3d95738d1 100644 --- a/packages/server-legacy/CHANGELOG.md +++ b/packages/server-legacy/CHANGELOG.md @@ -1,5 +1,30 @@ # @modelcontextprotocol/server-legacy +## 2.0.0 + +### Minor Changes + +- [#2477](https://github.com/modelcontextprotocol/typescript-sdk/pull/2477) [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Move the schema source modules (spec schemas, OAuth schemas, protocol constants) into `@modelcontextprotocol/core` and resolve them from there as a regular runtime dependency instead of bundling a private copy into each package. An application importing more than one of the packages now evaluates a single shared schema graph with shared object identity. `@modelcontextprotocol/core` gains a `./internal` subpath (SDK-internal contract; may change in any release) and the four packages now version together. + +### Patch Changes + +- [#2402](https://github.com/modelcontextprotocol/typescript-sdk/pull/2402) [`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - First beta release of SDK v2 with support for the MCP 2026-07-28 specification + revision. See the migration guides for upgrading from v1 + (`docs/migration/upgrade-to-v2.md`) and adopting the 2026-07-28 revision + (`docs/migration/support-2026-07-28.md`). + +- [#2405](https://github.com/modelcontextprotocol/typescript-sdk/pull/2405) [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Ship CommonJS builds alongside ESM. Each package now emits both `.mjs`/`.d.mts` + and `.cjs`/`.d.cts` (via tsdown `format: ['esm', 'cjs']`), and its `exports` map + adds a `require` condition so `require('@modelcontextprotocol/…')` works from + CommonJS consumers. Output extensions are normalized across all packages + (`@modelcontextprotocol/core` moves from `.js`/`.d.ts` to `.mjs`/`.d.mts`); the + public import paths are unchanged. + +- [#2476](https://github.com/modelcontextprotocol/typescript-sdk/pull/2476) [`e0a0ab7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e0a0ab74d9baed74572c9f435313fb6daef1b989) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Build protocol-revision wire schemas lazily on first validation instead of at import. Each revision's schema set is now constructed by a module-level memoized factory, so importing the client or server package no longer pays the construction cost of both frozen wire-schema graphs up front. Method membership in the revision registries stays static, the schemas themselves are unchanged, and registry lookups keep returning reference-identical schema objects. + +- Updated dependencies [[`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a), [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32), [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011), [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4), [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313)]: + - @modelcontextprotocol/core@2.0.0 + ## 2.0.0-beta.5 ### Patch Changes diff --git a/packages/server-legacy/package.json b/packages/server-legacy/package.json index 7bc53ea6ed..9ef13dcff7 100644 --- a/packages/server-legacy/package.json +++ b/packages/server-legacy/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/server-legacy", "private": false, - "version": "2.0.0-beta.5", + "version": "2.0.0", "description": "Frozen v1 SSE transport and OAuth Authorization Server helpers for the Model Context Protocol TypeScript SDK. Deprecated; use StreamableHTTP and a dedicated OAuth server in production.", "deprecated": "This package is a frozen copy of v1's SSE transport and OAuth Authorization Server helpers for migration purposes only. Use StreamableHTTP from @modelcontextprotocol/server and a dedicated OAuth server in production. Will not receive new features.", "license": "MIT", diff --git a/packages/server/CHANGELOG.md b/packages/server/CHANGELOG.md index 1b63fb069e..c24a3604e5 100644 --- a/packages/server/CHANGELOG.md +++ b/packages/server/CHANGELOG.md @@ -1,5 +1,114 @@ # @modelcontextprotocol/server +## 2.0.0 + +### Minor Changes + +- [#2501](https://github.com/modelcontextprotocol/typescript-sdk/pull/2501) [`1480241`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1480241e2a2a7f0ceee8e7723b2adcf88579bb36) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Export the `Protocol` base class and `mergeCapabilities` from the `@modelcontextprotocol/client` and `@modelcontextprotocol/server` package roots, restoring the v1 import for consumers that subclass `Protocol` (e.g. the MCP Apps SDK). The client and server packages each bundle their own compiled copy of the class, so import it from one package consistently within a process. + + The codemod now rewrites `Protocol` and `mergeCapabilities` imports from `shared/protocol.js` to the client or server package root, like the module's other symbols, instead of dropping them with an action-required marker. + +- [#2477](https://github.com/modelcontextprotocol/typescript-sdk/pull/2477) [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Move the schema source modules (spec schemas, OAuth schemas, protocol constants) into `@modelcontextprotocol/core` and resolve them from there as a regular runtime dependency instead of bundling a private copy into each package. An application importing more than one of the packages now evaluates a single shared schema graph with shared object identity. `@modelcontextprotocol/core` gains a `./internal` subpath (SDK-internal contract; may change in any release) and the four packages now version together. + +- [#2513](https://github.com/modelcontextprotocol/typescript-sdk/pull/2513) [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Align the 2026-07-28 wire with the final revision (spec PR #3002): `serverInfo` moves from the `DiscoverResult` body to the result `_meta`, and the per-request envelope's `clientInfo` demotes from required to SHOULD. + + Before this change the SDK shipped the pre-#3002 shape in both directions: the client hard-rejected a conforming server's `DiscoverResult` (missing body `serverInfo` failed parse, so the probe misclassified the server as legacy and attempted an `initialize` handshake against it — a hard connect failure against a modern-only server such as go-sdk v1.7.0-pre.3), and the server rejected conforming clients that omit `clientInfo`. + + Now: + - The 2026 wire schemas are the final revision exactly: no body `serverInfo` on `DiscoverResult`, envelope `clientInfo` optional (a present-but-malformed value still fails validation). + - Servers stamp `_meta['io.modelcontextprotocol/serverInfo']` on every 2026-era response (spec SHOULD; a handler-authored value wins, the 2025-era wire is untouched). This includes the entry-built `subscriptions/listen` graceful-close results — the spec's `SubscriptionsListenResultMeta` extends `ResultMetaObject`. + - Clients keep sending `clientInfo` and read server identity from the discover result's `_meta` only. A server that stamps no identity is anonymous: `getServerVersion()` is `undefined` and the response cache partitions under a per-connection surrogate. A malformed `_meta` serverInfo value is treated as absent on receive (the spec marks the field self-reported, unverified, and display-only). + - Breaking type changes: `DiscoverResult` no longer declares `serverInfo`; `RequestMetaEnvelope`'s `clientInfo` is optional. New public constant `SERVER_INFO_META_KEY` (`'io.modelcontextprotocol/serverInfo'`). + +- [#2369](https://github.com/modelcontextprotocol/typescript-sdk/pull/2369) [`24be404`](https://github.com/modelcontextprotocol/typescript-sdk/commit/24be4040d454a9c5983901229068477c7a9ea796) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Allow `inputRequired.elicit()` to accept a Standard Schema such as a Zod object for `requestedSchema`. The builder converts it to MCP's restricted form-elicitation JSON Schema, while the same schema can validate and type the response through `acceptedContent()` on handler re-entry. Zod formats mapping to `email`, `uri`, `date`, and `date-time` are supported. Shapes the restricted schema cannot express reject before anything is sent — nested objects, `.regex()` and customized zod format patterns, exclusive number bounds (`.positive()`/`.gt()`), literal unions (use `z.enum` or `z.literal(['a', 'b'])`), and non-spec root keywords like `z.strictObject()`'s `additionalProperties`. + +- [#2541](https://github.com/modelcontextprotocol/typescript-sdk/pull/2541) [`470678d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/470678d56b9ee2a365fcf6d3de21e3a8b32eeef5) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Add configurable SSE keep-alive comment frames to Streamable HTTP transports and apply `createMcpHandler`'s existing `keepAliveMs` option to every HTTP SSE stream it serves. + +- [#2420](https://github.com/modelcontextprotocol/typescript-sdk/pull/2420) [`7635115`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7635115d0112c3f980b45a9773a4770660af8aae) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Add runtime-neutral Bearer authentication to `@modelcontextprotocol/server`: + `requireBearerAuth` gates web-standard `fetch(request)` hosts (Cloudflare + Workers, Deno, Bun, Hono), built on the exported `verifyBearerToken` and + `bearerAuthChallengeResponse` pieces, with `OAuthTokenVerifier` now defined + here. The Express middleware adapts the same core and is unchanged in + behavior, except that `WWW-Authenticate` challenge values are now RFC 7235 + quoted-string sanitized (quotes and backslashes escaped, control and + non-ASCII characters replaced); `@modelcontextprotocol/express` re-exports + `OAuthTokenVerifier` as before. + +- [#2422](https://github.com/modelcontextprotocol/typescript-sdk/pull/2422) [`61866d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/61866d7a5ff4475663ceb525c88447c497c1b92a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Add runtime-neutral OAuth discovery serving to `@modelcontextprotocol/server`: + `oauthMetadataResponse` serves the RFC 9728 Protected Resource Metadata and + RFC 8414 Authorization Server metadata documents from web-standard + `fetch(request)` hosts, built on the exported + `buildOAuthProtectedResourceMetadata`, with + `getOAuthProtectedResourceMetadataUrl` now defined here. The Express metadata + router adapts the same core and is unchanged in behavior; the insecure-issuer + escape hatch is an explicit `dangerouslyAllowInsecureIssuerUrl` option in the + neutral core instead of a module-scope environment read. The web-standard + matcher validates lazily so unmatched traffic always falls through, tolerates + a trailing slash, supports HEAD, and marks reflected CORS preflights with + `Vary`. + +- [#2483](https://github.com/modelcontextprotocol/typescript-sdk/pull/2483) [`3f07a32`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3f07a325c6741b2374ce2255846dfa0c25f74d03) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Add `preloadSchemas()`, an explicit opt-in to eager wire-schema construction, and call it automatically in the Cloudflare Workers builds. The wire schemas are built lazily by default, which is the right trade on process-per-invocation runtimes — but on isolate platforms that bill request CPU while module evaluation runs during isolate warm-up, laziness moves construction into the first request each fresh isolate serves. Calling `preloadSchemas()` at module scope (it is synchronous and idempotent) moves that one-time cost back to module evaluation; the packages' workerd export condition now does this automatically, while the Node and browser builds stay lazy. The server package gains a dedicated browser shim for this (its `browser` condition previously reused the workerd shim), so browser bundles keep lazy construction. + +### Patch Changes + +- [#2402](https://github.com/modelcontextprotocol/typescript-sdk/pull/2402) [`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a) Thanks [@felixweinberger](https://github.com/felixweinberger)! - First beta release of SDK v2 with support for the MCP 2026-07-28 specification + revision. See the migration guides for upgrading from v1 + (`docs/migration/upgrade-to-v2.md`) and adopting the 2026-07-28 revision + (`docs/migration/support-2026-07-28.md`). + +- [#2456](https://github.com/modelcontextprotocol/typescript-sdk/pull/2456) [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Restore the v1 parse tolerance for `CallToolResult.content`: an inbound legacy-era `tools/call` result without `content` defaults to `[]` instead of failing validation. Deployed servers — accepted by SDK v1 for years — return `structuredContent`-only (or otherwise content-less) results, and the strict parse turned every such call into an `INVALID_RESULT` error before application code could run. + + The silent-empty-success hazard the strictness guarded is preserved where it matters: the 2025 era's wire-seam schema refuses to default `content` for a body carrying another result family's vocabulary (`task`, `inputRequests`, `requestState` — the era is frozen, so the list is complete), and the 2026-era wire schemas stay strict — modern-revision servers have no legacy excuse. Task interop through an explicit result schema is untouched (including bodies that also stamp a foreign `resultType`), and the server-side authoring normalization refuses the same foreign-family vocabulary. + + Server-side authoring is era-independent: a handler result without `content` (dynamic/JS callers — the TypeScript surface requires it) is normalized to `content: []` before era validation on every leg, reaching the wire spec-valid. + + Conscious call: the nested sampling `ToolResultContentSchema` stays spec-strict — v1 had defaulted its `content` too, but it is params-side (tool results a caller authors into a sampling message), deliberately not restored. + +- [#2431](https://github.com/modelcontextprotocol/typescript-sdk/pull/2431) [`1b90c96`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1b90c96d11fd17016d2977cae9dd661de3fb84df) Thanks [@morluto](https://github.com/morluto)! - Fix the CommonJS `validators/ajv` subpath so reading the exported `Ajv` class no longer throws `ReferenceError: import_ajv is not defined`. The subpath now re-exports the bundled provider's concrete `Ajv` value in CJS output, matching the existing ESM behavior. + +- [#2405](https://github.com/modelcontextprotocol/typescript-sdk/pull/2405) [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Ship CommonJS builds alongside ESM. Each package now emits both `.mjs`/`.d.mts` + and `.cjs`/`.d.cts` (via tsdown `format: ['esm', 'cjs']`), and its `exports` map + adds a `require` condition so `require('@modelcontextprotocol/…')` works from + CommonJS consumers. Output extensions are normalized across all packages + (`@modelcontextprotocol/core` moves from `.js`/`.d.ts` to `.mjs`/`.d.mts`); the + public import paths are unchanged. + +- [#2441](https://github.com/modelcontextprotocol/typescript-sdk/pull/2441) [`561c6d8`](https://github.com/modelcontextprotocol/typescript-sdk/commit/561c6d83456ef98d6c713bbda9837e64337f22c9) Thanks [@felixweinberger](https://github.com/felixweinberger)! - POSTs whose `Content-Type` media type is not `application/json` are now + rejected with `415 Unsupported Media Type`; the header is parsed instead of + substring-matched. Previously any value merely containing the substring + passed the check (for example `text/plain; a=application/json`), case + variants were wrongly rejected, and the 2026-07-28 entry did not inspect + `Content-Type` at all — requests with a missing or non-JSON header that used + to be served on that path now also answer 415. Values with parameters + (`application/json; charset=utf-8`, including malformed parameter sections + like `application/json;`) continue to work. SDK clients always send the + correct header and are unaffected. + + The new `isJsonContentType(header)` helper is exported for transport and + framework-adapter authors — custom entries composing the exported building + blocks (`classifyInboundRequest`, `PerRequestHTTPServerTransport`) must apply + it themselves. The hono adapter's JSON body pre-parse and the client's + response dispatch now use the same parsed-media-type comparison. + +- [#2384](https://github.com/modelcontextprotocol/typescript-sdk/pull/2384) [`ce2f65d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/ce2f65db0e019506f4d2526466ec8cc7106de98e) Thanks [@felixweinberger](https://github.com/felixweinberger)! - `instanceof` on the SDK error classes (`ProtocolError` and its typed subclasses, `SdkError`/`SdkHttpError`, `OAuthError`, and the client's `SseError`, `UnauthorizedError`, and OAuth-client-flow error family — `OAuthClientFlowError` and its subclasses) now works across separately bundled copies of the SDK. The classes match by a stable brand (via `Symbol.hasInstance` and a registry symbol) instead of prototype identity, so a process that uses both `@modelcontextprotocol/client` and `@modelcontextprotocol/server` - a gateway, host, or in-process test - can check errors constructed by either package against the class re-exported by the other. Ordinary prototype-based `instanceof` is preserved as a fallback; user-defined subclasses keep plain prototype semantics. Notes: cross-bundle matching requires both copies to be at or after this release; brands assert identity, not field shape, across versions - keep reading fields defensively. As a side effect, a foreign-bundle `SdkError` used as an abort reason is now rethrown as-is instead of being wrapped as a `RequestTimeout`. Branded hierarchies additionally expose an explicit static guard, `X.isInstance(value)`, that reads the same brand and narrows in TypeScript — an alternative for codebases that prefer predicate-style checks over `instanceof`. Also: `UnauthorizedError` now sets `error.name` to `'UnauthorizedError'` (previously `'Error'`), and per-package conformance tests enforce that every exported error class participates in branding. Version-negotiation probing now recognizes `UnauthorizedError` (previously a dead name-string check) and propagates it unchanged, so `connect()` on an auth-gated server rejects with the original `UnauthorizedError` (previously wrapped as the `cause` of an `SdkError(EraNegotiationFailed)`) — run `finishAuth()` and reconnect, and the retry probes with the token. + +- [#2458](https://github.com/modelcontextprotocol/typescript-sdk/pull/2458) [`7c49b47`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7c49b47fb3a58b51cec8fd0b337f656515f1a2b7) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Construct the default Ajv validation engine lazily on first validation. Creating a `Client` or `Server` no longer pays the ajv + ajv-formats instantiation cost at startup when no JSON Schema validation ever runs. + +- [#2476](https://github.com/modelcontextprotocol/typescript-sdk/pull/2476) [`e0a0ab7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e0a0ab74d9baed74572c9f435313fb6daef1b989) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Build protocol-revision wire schemas lazily on first validation instead of at import. Each revision's schema set is now constructed by a module-level memoized factory, so importing the client or server package no longer pays the construction cost of both frozen wire-schema graphs up front. Method membership in the revision registries stays static, the schemas themselves are unchanged, and registry lookups keep returning reference-identical schema objects. + +- [#2451](https://github.com/modelcontextprotocol/typescript-sdk/pull/2451) [`7e69735`](https://github.com/modelcontextprotocol/typescript-sdk/commit/7e697354de95111ca2c70a12ac9f5d3ec96b56c3) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Return JSON-RPC Invalid Params with the original URI and an `invalid_uri` reason when `resources/read` receives a syntactically malformed URI. + +- [#2399](https://github.com/modelcontextprotocol/typescript-sdk/pull/2399) [`3c7ddaf`](https://github.com/modelcontextprotocol/typescript-sdk/commit/3c7ddafa05d8f17fb52168bf4638f09251c3d0ff) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Return HTTP 400 for a `MissingRequiredClientCapabilityError` (`-32021`) produced after dispatch. The spec mandates `400 Bad Request` for this error with no condition on where it arose, but only the pre-dispatch capability gate honored that; the post-handler emission — the `input_required` gate rejecting an embedded request whose required capability the caller did not declare — surfaced in-band on HTTP 200. The JSON-RPC error body is unchanged, every other error code (including a handler relaying a downstream peer's `-32020`/`-32022`) keeps the origin-keyed in-band behavior, and the mapping only applies while the response is uncommitted: an exchange that already streamed — or one hosted with `responseMode: 'sse'`, which opens its stream at dispatch end — keeps its committed 200 and carries the error in-stream. + +- [#2425](https://github.com/modelcontextprotocol/typescript-sdk/pull/2425) [`e8de519`](https://github.com/modelcontextprotocol/typescript-sdk/commit/e8de519d3129f46b7528d2999b7641f55be1f091) Thanks [@Sehlani042](https://github.com/Sehlani042)! - Stop advertising validator provider classes from the root client/server type declarations. The provider classes remain available from the explicit validator subpaths. + +- [#2453](https://github.com/modelcontextprotocol/typescript-sdk/pull/2453) [`0ab5d14`](https://github.com/modelcontextprotocol/typescript-sdk/commit/0ab5d1471d6c7375878316df2930fca77eee1d2a) Thanks [@mattzcarey](https://github.com/mattzcarey)! - Strip RFC 9110 optional whitespace around inbound `MCP-Protocol-Version`, `Mcp-Method`, and `Mcp-Name` values before classifying and validating modern HTTP requests. This keeps valid requests portable across Fetch runtimes that expose raw leading or trailing SP/HTAB through `Headers.get()`. + +- [#2534](https://github.com/modelcontextprotocol/typescript-sdk/pull/2534) [`f130e1a`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f130e1ac5fcab34bd568f59907e0f2ce1d22074c) Thanks [@felixweinberger](https://github.com/felixweinberger)! - The default validator now honors declared 2019-09 and draft-07/06 dialects instead of rejecting them: a schema stamped `"$schema": "http://json-schema.org/draft-07/schema#"` (zod-to-json-schema's default output) validates with draft-07 semantics, and a 2019-09 stamp (zod-to-json-schema's `2019-09`/`openAi` targets) with 2019-09 semantics, on both the Ajv and Cloudflare Workers providers (with known engine differences documented in the migration guide). Schemas with no `$schema` still validate as 2020-12, and unknown dialects still produce the typed error (now listing the supported dialects: 2020-12, 2019-09, draft-07, draft-06). + +- Updated dependencies [[`a400259`](https://github.com/modelcontextprotocol/typescript-sdk/commit/a4002596b914c675d17ac22471d1287976dbb52a), [`44797d7`](https://github.com/modelcontextprotocol/typescript-sdk/commit/44797d77792953d0ce70b68922bb6bb69e697c32), [`f172626`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f172626a8e98b2ae2f0f690e4afb4dc74dbf6011), [`8e1d2e9`](https://github.com/modelcontextprotocol/typescript-sdk/commit/8e1d2e92b1720d2520122b3a5f20ea084edaf3c4), [`f413763`](https://github.com/modelcontextprotocol/typescript-sdk/commit/f4137630c05dc9a4fb14d4d3777f5cb167bd6313)]: + - @modelcontextprotocol/core@2.0.0 + ## 2.0.0-beta.5 ### Minor Changes diff --git a/packages/server/package.json b/packages/server/package.json index 4881c9cff5..f481e019e7 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@modelcontextprotocol/server", - "version": "2.0.0-beta.5", + "version": "2.0.0", "description": "Model Context Protocol implementation for TypeScript - Server package", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/test/conformance/CHANGELOG.md b/test/conformance/CHANGELOG.md index 1c9ea88fd3..3dbbf79b03 100644 --- a/test/conformance/CHANGELOG.md +++ b/test/conformance/CHANGELOG.md @@ -1,5 +1,7 @@ # @modelcontextprotocol/test-conformance +## 2.0.0 + ## 2.0.0-alpha.1 ### Patch Changes diff --git a/test/conformance/package.json b/test/conformance/package.json index 679600a644..8558f92b50 100644 --- a/test/conformance/package.json +++ b/test/conformance/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/test-conformance", "private": true, - "version": "2.0.0-beta.0", + "version": "2.0.0", "description": "Model Context Protocol implementation for TypeScript", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/test/e2e/CHANGELOG.md b/test/e2e/CHANGELOG.md index 1bfd5dc0ba..6fa629ad34 100644 --- a/test/e2e/CHANGELOG.md +++ b/test/e2e/CHANGELOG.md @@ -1,5 +1,7 @@ # @modelcontextprotocol/test-e2e +## 2.0.0 + ## 2.0.0-alpha.1 ### Patch Changes diff --git a/test/e2e/package.json b/test/e2e/package.json index 017ffb93b1..2b052482e2 100644 --- a/test/e2e/package.json +++ b/test/e2e/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/test-e2e", "private": true, - "version": "2.0.0-beta.0", + "version": "2.0.0", "description": "Model Context Protocol implementation for TypeScript", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/test/helpers/CHANGELOG.md b/test/helpers/CHANGELOG.md new file mode 100644 index 0000000000..d7ce32c295 --- /dev/null +++ b/test/helpers/CHANGELOG.md @@ -0,0 +1,3 @@ +# @modelcontextprotocol/test-helpers + +## 2.0.0 diff --git a/test/helpers/package.json b/test/helpers/package.json index 01d369d7cd..c359fbe6c2 100644 --- a/test/helpers/package.json +++ b/test/helpers/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/test-helpers", "private": true, - "version": "2.0.0-beta.0", + "version": "2.0.0", "description": "Model Context Protocol implementation for TypeScript", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)", diff --git a/test/integration/CHANGELOG.md b/test/integration/CHANGELOG.md index 7672abd7cc..7d1ea6e749 100644 --- a/test/integration/CHANGELOG.md +++ b/test/integration/CHANGELOG.md @@ -1,5 +1,7 @@ # @modelcontextprotocol/test-integration +## 2.0.0 + ## 2.0.0-alpha.1 ### Patch Changes diff --git a/test/integration/package.json b/test/integration/package.json index 07f94eccc7..ed75fb1b0c 100644 --- a/test/integration/package.json +++ b/test/integration/package.json @@ -1,7 +1,7 @@ { "name": "@modelcontextprotocol/test-integration", "private": true, - "version": "2.0.0-beta.0", + "version": "2.0.0", "description": "Model Context Protocol implementation for TypeScript", "license": "MIT", "author": "Anthropic, PBC (https://anthropic.com)",