Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
45c5a0c
client: persist interactive OAuth metadata across redirects
Mar 29, 2026
5276439
fix(stdio): always set windowsHide on Windows, not just in Electron (…
felixweinberger Mar 30, 2026
6711ed9
feat(client): add reconnectionScheduler to StreamableHTTPClientTransp…
felixweinberger Mar 30, 2026
9d08392
SEP-2207: Refresh token guidance (#1523)
wdawson Mar 30, 2026
9d924b1
docs: note type vs interface for structuredContent (#1784)
felixweinberger Mar 30, 2026
48aba0d
fix(core): add explicit | undefined to Transport interface optional p…
felixweinberger Mar 30, 2026
d0505c1
chore(v2): pnpm audit fix (#1789)
felixweinberger Mar 30, 2026
9efecc2
ci: format fetch-spec-types output with prettier (#1782)
felixweinberger Mar 30, 2026
4aec5f7
Private key jwt scopes (#1443)
NSeydoux Mar 30, 2026
045c62a
feat!: remove WebSocketClientTransport (#1783)
felixweinberger Mar 30, 2026
d99f3ee
fix: continue OAuth metadata discovery on 5xx responses (#1632)
matantsach Mar 30, 2026
a39a9eb
test: add compile-time key-parity assertions for spec type checks (#1…
rechedev9 Mar 30, 2026
d6a02c8
fix(core): ensure standardSchemaToJsonSchema emits type:object (#1796)
felixweinberger Mar 30, 2026
8822c96
fix(examples): return 404 for unknown session IDs, 400 for missing (#…
felixweinberger Mar 30, 2026
89fb094
fix(core): consolidate per-request cleanup in _requestWithSchema (#1790)
felixweinberger Mar 30, 2026
fcde488
chore: drop zod from peerDependencies (kept as direct dependency) (#1…
felixweinberger Mar 31, 2026
9bc9abc
Fix: Handle error responses in Streamable HTTP SSE streams (#1390)
DePasqualeOrg Mar 31, 2026
f73a5af
Add _meta support to registerPrompt (#1629)
chughtapan Mar 31, 2026
2fd7f5f
`v2`: Web standards Request object in ctx (#1822)
KKonstantinov Mar 31, 2026
5f32a90
fix(core): make fromJsonSchema() use runtime-aware default validator …
KKonstantinov Mar 31, 2026
81e4b2a
Adds Fastify Middleware for v2 (#1536)
andyfleming Mar 31, 2026
0fabc27
chore: enter alpha prerelease mode (#1823)
felixweinberger Mar 31, 2026
689148d
fix(server): propagate negotiated protocol version to transport (#1660)
rechedev9 Mar 31, 2026
babaa50
chore(ci): remove dead publish job from main.yml (#1829)
felixweinberger Mar 31, 2026
38d6cd2
chore(fastify): remove stray packageManager field from subpackage (#1…
felixweinberger Apr 1, 2026
54fa96e
Version Packages (alpha) (#1420)
github-actions[bot] Apr 1, 2026
53fb84b
fix(ci): split release.yml into version + publish jobs (#1836)
felixweinberger Apr 1, 2026
424cbae
v2 tsdown fix (#1840)
KKonstantinov Apr 1, 2026
0021561
Version Packages (alpha) (#1841)
github-actions[bot] Apr 1, 2026
866c08d
fix(core): allow additional JSON Schema properties in elicitInput req…
felixweinberger Apr 2, 2026
1eb3123
fix(client): preserve custom Accept headers in StreamableHTTPClientTr…
nielskaspers Apr 2, 2026
653c5d0
Rewrite `docs/server.md` as a code-heavy, prose-light how-to guide (#…
jonathanhefner Apr 2, 2026
df4b6cc
fix: prevent stack overflow in transport close with re-entrancy guard…
claygeo Apr 2, 2026
a408ca7
feat(client): add OAuthProvider for preserving discovery state across…
Apr 3, 2026
317fec5
merge: resolve streamableHttp.ts conflict, keep OAuth implementation
Apr 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/add-fastify-middleware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/fastify': minor
---

Add Fastify middleware adapter for MCP servers, following the same pattern as the Express and Hono adapters.
9 changes: 9 additions & 0 deletions .changeset/drop-zod-peer-dep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@modelcontextprotocol/client': patch
'@modelcontextprotocol/server': patch
---

Drop `zod` from `peerDependencies` (kept as direct dependency)

Since Standard Schema support landed, `zod` is purely an internal runtime dependency used for protocol message parsing. User-facing schemas (`registerTool`, `registerPrompt`) accept any Standard Schema library. `zod` remains in `dependencies` and auto-installs; users no longer
need to install it alongside the SDK.
10 changes: 10 additions & 0 deletions .changeset/fast-dragons-lead.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@modelcontextprotocol/express': patch
'@modelcontextprotocol/fastify': patch
'@modelcontextprotocol/hono': patch
'@modelcontextprotocol/node': patch
'@modelcontextprotocol/client': patch
'@modelcontextprotocol/server': patch
---

tsdown exports resolution fix
5 changes: 5 additions & 0 deletions .changeset/fix-abort-listener-leak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/core': patch
---

Consolidate per-request cleanup in `_requestWithSchema` into a single `.finally()` block. This fixes an abort signal listener leak (listeners accumulated when a caller reused one `AbortSignal` across requests) and two cases where `_responseHandlers` entries leaked on send-failure paths.
5 changes: 5 additions & 0 deletions .changeset/fix-oauth-5xx-discovery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/client': patch
---

Continue OAuth metadata discovery on 502 (Bad Gateway) responses, matching the existing behavior for 4xx. This fixes MCP servers behind reverse proxies that return 502 for path-aware metadata URLs. Other 5xx errors still throw to avoid retrying against overloaded servers.
5 changes: 5 additions & 0 deletions .changeset/fix-server-protocol-version.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/server': patch
---

fix(server): propagate negotiated protocol version to transport in _oninitialize
5 changes: 5 additions & 0 deletions .changeset/fix-session-status-codes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/examples-server': patch
---

Example servers now return HTTP 404 (not 400) when a request includes an unknown session ID, so clients can correctly detect they need to start a new session. Requests missing a session ID entirely still return 400.
5 changes: 5 additions & 0 deletions .changeset/fix-stdio-windows-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/client': patch
---

Always set `windowsHide` when spawning stdio server processes on Windows, not just in Electron environments. Prevents unwanted console windows in non-Electron Windows applications.
5 changes: 5 additions & 0 deletions .changeset/fix-streamable-close-reentrant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/server': patch
---

Prevent stack overflow in StreamableHTTPServerTransport.close() with re-entrant guard
5 changes: 5 additions & 0 deletions .changeset/fix-streamable-http-error-response.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/client': patch
---

Fix StreamableHTTPClientTransport to handle error responses in SSE streams
9 changes: 9 additions & 0 deletions .changeset/fix-transport-exact-optional-property-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@modelcontextprotocol/core': patch
---

Add explicit `| undefined` to optional properties on the `Transport` interface and `TransportSendOptions` (`onclose`, `onerror`, `onmessage`, `sessionId`, `setProtocolVersion`, `setSupportedProtocolVersions`, `onresumptiontoken`).

This fixes TS2420 errors for consumers using `exactOptionalPropertyTypes: true` without `skipLibCheck`, where the emitted `.d.ts` for implementing classes included `| undefined` but the interface did not.

Workaround for older SDK versions: enable `skipLibCheck: true` in your tsconfig.
7 changes: 7 additions & 0 deletions .changeset/odd-forks-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@modelcontextprotocol/client": patch
---

fix(client): append custom Accept headers to spec-required defaults in StreamableHTTPClientTransport

Custom Accept headers provided via `requestInit.headers` are now appended to the spec-mandated Accept types instead of being overwritten. This ensures the required media types (`application/json, text/event-stream` for POST; `text/event-stream` for GET SSE) are always present while allowing users to include additional types for proxy/gateway routing.
68 changes: 68 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"mode": "pre",
"tag": "alpha",
"initialVersions": {
"@modelcontextprotocol/eslint-config": "2.0.0",
"@modelcontextprotocol/tsconfig": "2.0.0",
"@modelcontextprotocol/vitest-config": "2.0.0",
"@modelcontextprotocol/examples-client": "2.0.0-alpha.0",
"@modelcontextprotocol/examples-client-quickstart": "2.0.0-alpha.0",
"@modelcontextprotocol/examples-server": "2.0.0-alpha.0",
"@modelcontextprotocol/examples-server-quickstart": "2.0.0-alpha.0",
"@modelcontextprotocol/examples-shared": "2.0.0-alpha.0",
"@modelcontextprotocol/client": "2.0.0-alpha.0",
"@modelcontextprotocol/core": "2.0.0-alpha.0",
"@modelcontextprotocol/express": "2.0.0-alpha.0",
"@modelcontextprotocol/fastify": "2.0.0-alpha.0",
"@modelcontextprotocol/hono": "2.0.0-alpha.0",
"@modelcontextprotocol/node": "2.0.0-alpha.0",
"@modelcontextprotocol/server": "2.0.0-alpha.0",
"@modelcontextprotocol/test-conformance": "2.0.0-alpha.0",
"@modelcontextprotocol/test-helpers": "2.0.0-alpha.0",
"@modelcontextprotocol/test-integration": "2.0.0-alpha.0"
},
"changesets": [
"abort-handlers-on-close",
"add-fastify-middleware",
"add-hono-peer-dep",
"add-resource-size-field",
"brave-lions-glow",
"busy-rice-smoke",
"busy-weeks-hang",
"cyan-cycles-pump",
"drop-zod-peer-dep",
"expose-auth-server-discovery",
"extract-task-manager",
"fast-dragons-lead",
"finish-sdkerror-capability",
"fix-abort-listener-leak",
"fix-oauth-5xx-discovery",
"fix-onerror-callbacks",
"fix-server-protocol-version",
"fix-session-status-codes",
"fix-stdio-epipe-crash",
"fix-stdio-windows-hide",
"fix-streamable-http-error-response",
"fix-task-session-isolation",
"fix-transport-exact-optional-property-types",
"fix-unknown-tool-protocol-error",
"funky-baths-attack",
"heavy-walls-swim",
"oauth-error-http200",
"quick-islands-occur",
"reconnection-scheduler",
"remove-websocket-transport",
"respect-capability-negotiation",
"rich-hounds-report",
"schema-object-type-for-unions",
"shy-times-learn",
"spotty-cats-tickle",
"stdio-skip-non-json",
"support-standard-json-schema",
"tame-camels-greet",
"tender-snails-fold",
"token-provider-composable-auth",
"twelve-dodos-taste",
"use-scopes-supported-in-dcr"
]
}
5 changes: 5 additions & 0 deletions .changeset/reconnection-scheduler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/client': minor
---

Add `reconnectionScheduler` option to `StreamableHTTPClientTransport`. Lets non-persistent environments (serverless, mobile, desktop sleep/wake) override the default `setTimeout`-based SSE reconnection scheduling. The scheduler may return a cancel function that is invoked on `transport.close()`.
5 changes: 5 additions & 0 deletions .changeset/remove-websocket-transport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/client': major
---

Remove `WebSocketClientTransport`. WebSocket is not a spec-defined transport; use stdio or Streamable HTTP. The `Transport` interface remains exported for custom implementations. See #142.
5 changes: 5 additions & 0 deletions .changeset/schema-object-type-for-unions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/core': patch
---

Ensure `standardSchemaToJsonSchema` emits `type: "object"` at the root, fixing discriminated-union tool/prompt schemas that previously produced `{oneOf: [...]}` without the MCP-required top-level type. Also throws a clear error when given an explicitly non-object schema (e.g. `z.string()`). Fixes #1643.
5 changes: 5 additions & 0 deletions .changeset/spotty-cats-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/client': minor
---

The client credentials providers now support scopes being added to the token request.
5 changes: 5 additions & 0 deletions .changeset/zod-json-schema-compat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/core': patch
---

Allow additional JSON Schema properties in elicitInput's requestedSchema type by adding .catchall(z.unknown()), matching the pattern used by inputSchema. This fixes type incompatibility when using Zod v4's .toJSONSchema() output which includes extra properties like $schema and additionalProperties.
52 changes: 0 additions & 52 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ on:
- main
pull_request:
workflow_dispatch:
release:
types: [published]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down Expand Up @@ -94,53 +92,3 @@ jobs:
- name: Run ${{ matrix.runtime }} integration tests
run: pnpm --filter @modelcontextprotocol/test-integration test:integration:${{ matrix.runtime }}

publish:
runs-on: ubuntu-latest
if: github.event_name == 'release'
environment: release
needs: [build, test, test-runtimes]

permissions:
contents: read
id-token: write

steps:
- uses: actions/checkout@v6

- name: Install pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
id: pnpm-install
with:
run_install: false
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
registry-url: 'https://registry.npmjs.org'
- run: pnpm install

- name: Determine npm tag
id: npm-tag
run: |
VERSION=$(node -p "require('./package.json').version")
# Check if this is a beta release
if [[ "$VERSION" == *"-beta"* ]]; then
echo "tag=--tag beta" >> $GITHUB_OUTPUT
# Check if this release is from a non-primary branch (patch/maintenance release)
elif [[ "${{ github.event.release.target_commitish }}" != "main" && "${{ github.event.release.target_commitish }}" != "v1.x" ]]; then
# Use "release-X.Y" as tag for old branch releases (e.g., "release-1.23" for 1.23.x)
# npm tags are mutable pointers to versions (like "latest" pointing to 1.24.3).
# Using "release-1.23" means users can `npm install @modelcontextprotocol/sdk@release-1.23`
# to get the latest patch on that minor version, and the tag updates if we
# release 1.23.2, 1.23.3, etc.
# Note: Can't use "v1.23" because npm rejects tags that look like semver ranges.
MAJOR_MINOR=$(echo "$VERSION" | cut -d. -f1,2)
echo "tag=--tag release-${MAJOR_MINOR}" >> $GITHUB_OUTPUT
else
echo "tag=" >> $GITHUB_OUTPUT
fi

- run: pnpm publish --provenance --access public ${{ steps.npm-tag.outputs.tag }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ jobs:
- name: Publish preview packages
run:
pnpm dlx pkg-pr-new publish --packageManager=npm --pnpm './packages/server' './packages/client'
'./packages/middleware/express' './packages/middleware/hono' './packages/middleware/node'
'./packages/middleware/express' './packages/middleware/fastify' './packages/middleware/hono' './packages/middleware/node'
52 changes: 43 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
name: Release

permissions:
contents: write
pull-requests: write

on:
push:
branches:
Expand All @@ -12,9 +8,14 @@ on:
concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
release:
name: Release
version:
name: Version
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
outputs:
hasChangesets: ${{ steps.changesets.outputs.hasChangesets }}
steps:
- uses: actions/checkout@v6

Expand All @@ -29,17 +30,50 @@ jobs:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: pnpm install

- name: Create Release Pull Request or Publish to npm
- name: Create or update Version Packages PR
id: changesets
uses: changesets/action@6a0a831ff30acef54f2c6aa1cbbc1096b066edaf # v1
env:
GITHUB_TOKEN: ${{ github.token }}

publish:
name: Publish
needs: version
if: needs.version.outputs.hasChangesets == 'false'
runs-on: ubuntu-latest
environment: release
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v6

- name: Install pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
with:
run_install: false

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: pnpm install

- name: Publish to npm
uses: changesets/action@6a0a831ff30acef54f2c6aa1cbbc1096b066edaf # v1
with:
publish: pnpm run build:all && pnpm changeset publish
publish: pnpm run ci:publish
env:
GITHUB_TOKEN: ${{ github.token }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: 'true'
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ When a request arrives from the remote side:
3. **`Protocol._onrequest()`**:
- Looks up handler in `_requestHandlers` map (keyed by method name)
- Creates `BaseContext` with `signal`, `sessionId`, `sendNotification`, `sendRequest`, etc.
- Calls `buildContext()` to let subclasses enrich the context (e.g., Server adds `requestInfo`)
- Calls `buildContext()` to let subclasses enrich the context (e.g., Server adds HTTP request info)
- Invokes handler, sends JSON-RPC response back via transport
4. **Handler** was registered via `setRequestHandler('method', handler)`

Expand Down
Loading
Loading