Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
6dd08ac
ci: trigger workflow on v1.x branch (#1319)
felixweinberger Dec 19, 2025
a0c9b13
fix: README badges links destinations (#907)
antonpk1 Dec 19, 2025
b392f02
fix: prevent ReDoS in UriTemplate regex patterns (v1.x backport) (#1365)
pcarleton Jan 7, 2026
12ae856
[v1.x backport] Use correct schema for client sampling validation whe…
olaservo Jan 20, 2026
6e8f7e1
fix: prevent Hono from overriding global Response object (v1.x) (#1411)
mattzcarey Jan 20, 2026
6aba065
chore: bump v1.25.3 for backport fixes (#1412)
pcarleton Jan 20, 2026
aa81a66
fix(deps): resolve npm audit vulnerabilities and bump dependencies (v…
samuv Jan 23, 2026
50d9fa3
Fix #1430: Client Credentials providers scopes support (backported) (…
NSeydoux Feb 2, 2026
a05be17
Merge commit from fork
pcarleton Feb 4, 2026
4f01e7e
fix: add non-null assertions for optional setupServer fields in state…
pcarleton Feb 4, 2026
fe9c07b
chore: bump version to 1.26.0 (#1479)
pcarleton Feb 4, 2026
b0cf837
feat: add conformance test infrastructure for v1.x (#1518)
felixweinberger Feb 11, 2026
825e9ab
feat: backport discoverOAuthServerInfo() and discovery caching to v1.…
felixweinberger Feb 13, 2026
97ab379
feat: add url property to RequestInfo interface (#1353)
valentinbeggi Feb 15, 2026
5c16ae3
[v1.x] feat(tasks): add streaming methods for elicitation and samplin…
LucaButBoring Feb 15, 2026
8cbc658
chore: bump version for v1.27.0 (#1541)
felixweinberger Feb 16, 2026
f2d2145
feat: implement auth/pre-registration conformance scenario (#1545)
felixweinberger Feb 16, 2026
2084a22
docs: add governance documentation for SEP-1730 (#1547)
felixweinberger Feb 17, 2026
342ea39
docs: comprehensive feature documentation for SEP-1730 Tier 1 (#1548)
felixweinberger Feb 17, 2026
e79d14a
fix: prevent command injection in example URL opening (v1.x backport)…
maxisbey Feb 24, 2026
09a85a8
fix: call onerror for silently swallowed transport errors (#1580)
qing-ant Feb 24, 2026
4faa8c8
chore: bump version to 1.27.1 (#1581)
felixweinberger Feb 24, 2026
351e124
docs: add links to hosted V1 and V2 API reference docs
localden Feb 25, 2026
c9b58d1
feat: use scopes_supported from resource metadata by default (fixes #…
antogyn Mar 2, 2026
4cbcec0
[v1.x backport] Default to client_secret_basic when server omits toke…
pcarleton Mar 2, 2026
93640d3
fix: reject plain JSON Schema objects passed as inputSchema (#1596)
tiluckdave Mar 23, 2026
398dc70
fix: clear _timeoutInfo in _onclose() and scope .finally() abort cont…
pcarleton Mar 23, 2026
897bc25
fix(server/auth): RFC 8252 loopback port relaxation (#1738)
poteat Mar 25, 2026
a056569
chore: bump version to 1.28.0 (#1746)
felixweinberger Mar 25, 2026
13e30f1
fix: treat v1.x as primary branch for npm latest tag (backport #1577)…
felixweinberger Mar 25, 2026
2a15851
[v1.x] fix: disallow null (infinite) requested TTL (#1339)
LucaButBoring Mar 25, 2026
ddadaa6
[v1.x] fix: add missing size field to ResourceSchema (#1575)
olaservo Mar 26, 2026
c95cc09
Add typings exports (#1623)
tdraier Mar 26, 2026
364f38c
v1.x npm audit fix (#1780)
KKonstantinov Mar 27, 2026
7213816
v1.x #1623 follow up -add missing types to package.json (#1773)
KKonstantinov Mar 27, 2026
5608e78
[v1.x backport] Allow servers / clients to advertise extensions in th…
localden Mar 30, 2026
3913fd4
fix(stdio): always set windowsHide on Windows, not just in Electron (…
jnMetaCode Mar 30, 2026
e12cbd7
chore: bump version to 1.29.0 (#1820)
felixweinberger Mar 30, 2026
9edbab7
fix(server): prioritize zod issues and format them (#1503)
mozmo15 Mar 31, 2026
bf1e022
chore(ci): switch publish to OIDC trusted publishing (#1839)
felixweinberger Apr 13, 2026
229bb15
fix(server): respect explicit listChanged: false in McpServer capabil…
Zelys-DFKH Apr 20, 2026
9bf5831
chore: fix Prettier formatting in mcp.test.ts
Zelys-DFKH Apr 20, 2026
d5e4923
fix: skip outputSchema validation when isError is true
Zelys-DFKH Apr 22, 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-extensions-capability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/sdk': minor
---

Add `extensions` field to `ClientCapabilities` and `ServerCapabilities` to allow servers and clients to advertise extension support per SEP-2133
5 changes: 5 additions & 0 deletions .changeset/add-resource-size-field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/sdk': patch
---

Add missing `size` field to `ResourceSchema` to match the MCP specification
5 changes: 5 additions & 0 deletions .changeset/add-types-export-condition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/sdk': patch
---

Add `"types"` condition to `exports` map for subpath imports (`.`, `./client`, `./server`, `./*`), enabling TypeScript to resolve type declarations with `moduleResolution: "bundler"` or `"node16"` without requiring manual `tsconfig.json` `paths` workarounds.
5 changes: 5 additions & 0 deletions .changeset/add-url-to-request-info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/sdk': patch
---

Add `url` property to `RequestInfo` interface as a `URL` type, exposing the full request URL to server handlers. The URL is unified across all HTTP transports (SSE and Streamable HTTP) to always provide the complete URL including protocol, host, and path.
5 changes: 5 additions & 0 deletions .changeset/fix-listchanged-backport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/sdk': patch
---

Respected explicit `listChanged: false` capability settings in `McpServer`. Previously, registering a tool, resource, or prompt would unconditionally overwrite `listChanged` to `true`, ignoring any explicit `false` set at construction time.
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/sdk': patch
---

Always set windowsHide to true when spawning stdio server processes on Windows, not just in Electron environments.
5 changes: 5 additions & 0 deletions .changeset/fix-zod-error-message-priority.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/sdk': patch
---

Prioritize `error.issues[].message` over `error.message` in `getParseErrorMessage` so custom Zod error messages surface correctly. In Zod v4, `error.message` is a JSON blob of all issues, not a readable string.
6 changes: 6 additions & 0 deletions .changeset/rfc8252-loopback-port-relaxation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@modelcontextprotocol/sdk': patch
---

The authorization handler now applies RFC 8252 §7.3 loopback port relaxation when validating `redirect_uri` against a client's registered URIs. For `localhost`, `127.0.0.1`, and `[::1]` hosts, any port is accepted as long as scheme, host, path, and query match. This fixes native
clients that obtain an ephemeral port from the OS but register a portless loopback URI (e.g., via CIMD / SEP-991).
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: monthly
groups:
github-actions:
patterns:
- '*'
40 changes: 40 additions & 0 deletions .github/workflows/conformance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Conformance Tests

on:
push:
branches: [v1.x]
pull_request:
branches: [v1.x]
workflow_dispatch:

concurrency:
group: conformance-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
client-conformance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run build
- run: npm run test:conformance:client:all

server-conformance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run build
- run: npm run test:conformance:server
12 changes: 6 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
on:
push:
branches:
- main
- v1.x
pull_request:
workflow_dispatch:
release:
Expand Down Expand Up @@ -59,19 +59,21 @@ jobs:
with:
node-version: 24
cache: npm
registry-url: 'https://registry.npmjs.org'

- run: npm ci

- name: Ensure npm CLI supports OIDC trusted publishing
run: npm install -g npm@11.5.1

- 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-main branch (patch/maintenance release)
elif [[ "${{ github.event.release.target_commitish }}" != "main" ]]; then
# 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`
Expand All @@ -85,5 +87,3 @@ jobs:
fi

- run: npm publish --provenance --access public ${{ steps.npm-tag.outputs.tag }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@ dist/

# IDE
.idea/
test/conformance/node_modules/
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ npm run typecheck # Type-check without emitting
- **Files**: Lowercase with hyphens, test files with `.test.ts` suffix
- **Imports**: ES module style, include `.js` extension, group imports logically
- **Formatting**: 2-space indentation, semicolons required, single quotes preferred
- **Testing**: Co-locate tests with source files, use descriptive test names
- **Testing**: Co-locate tests with source files, use descriptive test names. Use `vi.useFakeTimers()` instead of real `setTimeout`/`await` delays in tests
- **Comments**: JSDoc for public APIs, inline comments for complex logic

## Architecture Overview
Expand Down
29 changes: 29 additions & 0 deletions DEPENDENCY_POLICY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Dependency Policy

As a library consumed by downstream projects, the MCP TypeScript SDK takes a conservative approach to dependency updates. Dependencies are kept stable unless there is a specific reason to update, such as a security vulnerability, a bug fix, or a need for new functionality.

## Update Triggers

Dependencies are updated when:

- A **security vulnerability** is disclosed (via GitHub security alerts).
- A bug in a dependency directly affects the SDK.
- A new dependency feature is needed for SDK development.
- A dependency drops support for a Node.js version the SDK still targets.

Routine version bumps without a clear motivation are avoided to minimize churn for downstream consumers.

## What We Don't Do

The SDK does not run scheduled version bumps for npm dependencies. Updating a dependency can force downstream consumers to adopt that update transitively, which can be disruptive for projects with strict dependency policies.

Dependencies are only updated when there is a concrete reason, not simply because a newer version is available.

## Automated Tooling

- **GitHub security updates** are enabled at the repository level and automatically open pull requests for npm packages with known vulnerabilities. This is a GitHub repo setting, separate from the `dependabot.yml` configuration.
- **GitHub Actions versions** are kept up to date via Dependabot on a monthly schedule (see `.github/dependabot.yml`).

## Pinning and Ranges

Production dependencies use caret ranges (`^`) to allow compatible updates within a major version. Exact versions are pinned only when necessary to work around a specific issue.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# MCP TypeScript SDK ![NPM Version](https://img.shields.io/npm/v/%40modelcontextprotocol%2Fsdk) ![MIT licensed](https://img.shields.io/npm/l/%40modelcontextprotocol%2Fsdk)
# MCP TypeScript SDK [![NPM Version](https://img.shields.io/npm/v/%40modelcontextprotocol%2Fsdk)](https://www.npmjs.com/package/@modelcontextprotocol/sdk) [![MIT licensed](https://img.shields.io/npm/l/%40modelcontextprotocol%2Fsdk)](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/LICENSE)

<details>
<summary>Table of Contents</summary>
Expand Down Expand Up @@ -154,8 +154,11 @@ For more details on how to run these examples (including recommended commands an
- [docs/server.md](docs/server.md) – building and running MCP servers, transports, tools/resources/prompts, CORS, DNS rebinding, and multi-node deployment.
- [docs/client.md](docs/client.md) – using the high-level client, transports, backwards compatibility, and OAuth helpers.
- [docs/capabilities.md](docs/capabilities.md) – sampling, elicitation (form and URL), and experimental task-based execution.
- [docs/protocol.md](docs/protocol.md) – protocol features: ping, progress, cancellation, pagination, capability negotiation, and JSON Schema.
- [docs/faq.md](docs/faq.md) – environment and troubleshooting FAQs (including Node.js Web Crypto support).
- External references:
- [V1 API reference](https://modelcontextprotocol.github.io/typescript-sdk/)
- [V2 API reference](https://modelcontextprotocol.github.io/typescript-sdk/v2/)
- [Model Context Protocol documentation](https://modelcontextprotocol.io)
- [MCP Specification](https://spec.modelcontextprotocol.io)
- [Example Servers](https://github.com/modelcontextprotocol/servers)
Expand Down
22 changes: 22 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Roadmap

## Spec Implementation Tracking

The SDK tracks implementation of MCP spec components via GitHub Projects, with a dedicated project board for each spec revision. For example, see the [2025-11-25 spec revision board](https://github.com/orgs/modelcontextprotocol/projects/26).

## Current Focus Areas

### Next Spec Revision

The next MCP specification revision is being developed in the [protocol repository](https://github.com/modelcontextprotocol/modelcontextprotocol). Key areas expected in the next revision include extensions and stateless transports.

The SDK has historically implemented spec changes promptly as they are finalized, with dedicated project boards tracking component-level progress for each revision.

### v2

A major version of the SDK is in active development, tracked via [GitHub Project](https://github.com/orgs/modelcontextprotocol/projects/31). Target milestones:

- **Alpha**: ~mid-March 2026
- **Beta**: ~May 2026

The v2 release is planned to align with the next spec release, expected around mid-2026.
40 changes: 40 additions & 0 deletions VERSIONING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Versioning Policy

The MCP TypeScript SDK (`@modelcontextprotocol/sdk`) follows [Semantic Versioning 2.0.0](https://semver.org/).

## Version Format

`MAJOR.MINOR.PATCH`

- **MAJOR**: Incremented for breaking changes (see below).
- **MINOR**: Incremented for new features that are backward-compatible.
- **PATCH**: Incremented for backward-compatible bug fixes.

## What Constitutes a Breaking Change

The following changes are considered breaking and require a major version bump:

- Removing or renaming a public API export (class, function, type, or constant).
- Changing the signature of a public function or method in a way that breaks existing callers (removing parameters, changing required/optional status, changing types).
- Removing or renaming a public type or interface field.
- Changing the behavior of an existing API in a way that breaks documented contracts.
- Dropping support for a Node.js LTS version.
- Removing support for a transport type.
- Changes to the MCP protocol version that require client/server code changes.

The following are **not** considered breaking:

- Adding new optional parameters to existing functions.
- Adding new exports, types, or interfaces.
- Adding new optional fields to existing types.
- Bug fixes that correct behavior to match documented intent.
- Internal refactoring that does not affect the public API.
- Adding support for new MCP spec features.
- Changes to dev dependencies or build tooling.

## How Breaking Changes Are Communicated

1. **Changelog**: All breaking changes are documented in the GitHub release notes with migration instructions.
2. **Deprecation**: When feasible, APIs are deprecated for at least one minor release before removal using `@deprecated` JSDoc annotations, which surface warnings through TypeScript tooling and editors.
3. **Migration guide**: Major version releases include a migration guide describing what changed and how to update.
4. **PR labels**: Pull requests containing breaking changes are labeled with `breaking change`.
112 changes: 111 additions & 1 deletion docs/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,99 @@ Runnable example:

The `simpleStreamableHttp` server also includes a `collect-user-info` tool that demonstrates how to drive elicitation from a tool and handle the response.

#### Schema validation

Elicitation schemas support validation constraints on each field. The server validates responses automatically against the `requestedSchema` using the SDK's JSON Schema validator.

```typescript
const result = await server.server.elicitInput({
mode: 'form',
message: 'Enter your details:',
requestedSchema: {
type: 'object',
properties: {
email: {
type: 'string',
title: 'Email',
format: 'email',
minLength: 5
},
age: {
type: 'integer',
title: 'Age',
minimum: 0,
maximum: 150
}
},
required: ['email']
}
});
```

String fields support `minLength`, `maxLength`, and `format` (`'email'`, `'uri'`, `'date'`, `'date-time'`). Number fields support `minimum` and `maximum`.

#### Default values

Schema properties can include `default` values. When the client declares the `applyDefaults` capability, the SDK automatically fills in defaults for fields the user doesn't provide.

> **Note:** `applyDefaults` is a TypeScript SDK extension — it is not part of the MCP protocol specification.

```typescript
// Client declares applyDefaults:
const client = new Client(
{ name: 'my-client', version: '1.0.0' },
{ capabilities: { elicitation: { form: { applyDefaults: true } } } }
);

// Server schema with defaults:
requestedSchema: {
type: 'object',
properties: {
newsletter: { type: 'boolean', title: 'Newsletter', default: false },
theme: { type: 'string', title: 'Theme', default: 'dark' }
}
}
```

#### Enum values

Elicitation schemas support several enum patterns for single-select and multi-select fields:

```typescript
requestedSchema: {
type: 'object',
properties: {
// Simple enum (untitled options)
color: {
type: 'string',
title: 'Favorite Color',
enum: ['red', 'green', 'blue'],
default: 'blue'
},
// Titled enum with display labels
priority: {
type: 'string',
title: 'Priority',
oneOf: [
{ const: 'low', title: 'Low Priority' },
{ const: 'medium', title: 'Medium Priority' },
{ const: 'high', title: 'High Priority' }
]
},
// Multi-select
tags: {
type: 'array',
title: 'Tags',
items: { type: 'string', enum: ['frontend', 'backend', 'docs'] },
minItems: 1,
maxItems: 3
}
}
}
```

For a full example with validation, defaults, and enums, see [`elicitationFormExample.ts`](../src/examples/server/elicitationFormExample.ts).

### URL elicitation

URL elicitation is designed for sensitive data and secure web‑based flows (e.g., collecting an API key, confirming a payment, or doing third‑party OAuth). Instead of returning form data, the server asks the client to open a URL and the rest of the flow happens in the browser.
Expand All @@ -46,6 +139,23 @@ Key points:

Sensitive information **must not** be collected via form elicitation; always use URL elicitation or out‑of‑band flows for secrets.

#### Complete notification

When a URL elicitation flow finishes (the user completes the browser-based action), the server sends a `notifications/elicitation/complete` notification to the client. This tells the client the out-of-band flow is done and any pending UI can be dismissed.

Use `createElicitationCompletionNotifier` on the low-level server to create a callback that sends this notification:

```typescript
// Create a notifier for a specific elicitation:
const notifyComplete = server.server.createElicitationCompletionNotifier('setup-123');

// Later, when the browser flow completes (e.g. via webhook):
await notifyComplete();
// Client receives: { method: 'notifications/elicitation/complete', params: { elicitationId: 'setup-123' } }
```

See [`elicitationUrlExample.ts`](../src/examples/server/elicitationUrlExample.ts) for a full working example.

## Task-based execution (experimental)

Task-based execution enables “call-now, fetch-later” patterns for long-running operations. Instead of returning a result immediately, a tool creates a task that can be polled or resumed later.
Expand All @@ -70,7 +180,7 @@ For a runnable example that uses the in-memory store shipped with the SDK, see:
On the client, you use:

- `client.experimental.tasks.callToolStream(...)` to start a tool call that may create a task and emit status updates over time.
- `client.getTask(...)` and `client.getTaskResult(...)` to check status and fetch results after reconnecting.
- `client.experimental.tasks.getTask(...)` and `client.experimental.tasks.getTaskResult(...)` to check status and fetch results after reconnecting.

The interactive client in:

Expand Down
Loading