[v2] Мonorepo, sdk-client, sdk-server, sdk-core package split (#1279)

This commit is contained in:
Konstantin Konstantinov 2025-12-19 15:19:02 +02:00 • committed by GitHub
commit 71ae3acee0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
221 changed files with 12067 additions and 4817 deletions

6
.changeset/README.md Normal file
View file

@ -0,0 +1,6 @@
# Changesets
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it
[in our repository](https://github.com/changesets/changesets)
We have a quick list of common questions to get you started engaging with this project in [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

11
.changeset/config.json Normal file
View file

@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json",
"changelog": ["@changesets/changelog-github", { "repo": "@modelcontextprotocol/typescript-sdk" }],
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["@modelcontextprotocol/examples-client", "@modelcontextprotocol/examples-server", "@modelcontextprotocol/examples-shared"]
}

View file

@ -0,0 +1,6 @@
---
'@modelcontextprotocol/client': patch
'@modelcontextprotocol/server': patch
---
Initial 2.0.0-alpha.0 client and server package

View file

@ -16,32 +16,47 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@v4
id: pnpm-install
with:
run_install: false
- uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: npm ci
- run: npm run check
- run: npm run build
- run: pnpm install
- run: pnpm run check:all
- run: pnpm run build:all
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [18, 24]
node-version: [20, 22, 24]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@v4
id: pnpm-install
with:
run_install: false
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- run: npm ci
- run: npm test
- run: pnpm install
- run: pnpm test:all
publish:
runs-on: ubuntu-latest
@ -55,13 +70,19 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v4
id: pnpm-install
with:
run_install: false
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: pnpm install
- name: Determine npm tag
id: npm-tag
@ -84,6 +105,6 @@ jobs:
echo "tag=" >> $GITHUB_OUTPUT
fi
- run: npm publish --provenance --access public ${{ steps.npm-tag.outputs.tag }}
- run: pnpm publish --provenance --access public ${{ steps.npm-tag.outputs.tag }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View file

@ -1,6 +1,8 @@
name: Publish Any Commit
permissions:
contents: read
on:
pull_request:
push:
@ -14,14 +16,26 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
run_install: false
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- name: Build
run: npm run build
- name: Publish
run: npx pkg-pr-new publish
- name: Install dependencies
run: pnpm install
- name: Build packages
run: pnpm run build:all
- name: Publish preview packages
run: pnpm dlx pkg-pr-new publish --packageManager=npm --pnpm './packages/server' './packages/client'

45
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,45 @@
name: Release
permissions:
contents: write
pull-requests: write
on:
push:
branches:
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@v4
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: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
with:
publish: pnpm run build:all && pnpm changeset publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View file

@ -15,27 +15,35 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@v4
id: pnpm-install
with:
run_install: false
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: '24'
node-version: 24
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- name: Install dependencies
run: npm ci
run: pnpm install
- name: Fetch latest spec types
run: npm run fetch:spec-types
run: pnpm run fetch:spec-types
- name: Check for changes
id: check_changes
run: |
if git diff --quiet src/spec.types.ts; then
if git diff --quiet packages/core/src/types/spec.types.ts; then
echo "has_changes=false" >> $GITHUB_OUTPUT
else
echo "has_changes=true" >> $GITHUB_OUTPUT
LATEST_SHA=$(grep "Last updated from commit:" src/spec.types.ts | cut -d: -f2 | tr -d ' ')
LATEST_SHA=$(grep "Last updated from commit:" packages/core/src/types/spec.types.ts | cut -d: -f2 | tr -d ' ')
echo "sha=$LATEST_SHA" >> $GITHUB_OUTPUT
fi
@ -48,12 +56,12 @@ jobs:
git config user.email "github-actions[bot]@users.noreply.github.com"
git checkout -B update-spec-types
git add src/spec.types.ts
git add packages/core/src/types/spec.types.ts
git commit -m "chore: update spec.types.ts from upstream"
git push -f origin update-spec-types
# Create PR if it doesn't exist, or update if it does
PR_BODY="This PR updates \`src/spec.types.ts\` from the Model Context Protocol specification.
PR_BODY="This PR updates \`packages/core/src/types/spec.types.ts\` from the Model Context Protocol specification.
Source file: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/${{ steps.check_changes.outputs.sha }}/schema/draft/schema.ts

View file

@ -5,14 +5,21 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Build & Test Commands
```sh
npm run build # Build ESM and CJS versions
npm run lint # Run ESLint and Prettier check
npm run lint:fix # Auto-fix lint and formatting issues
npm test # Run all tests (vitest)
npm run test:watch # Run tests in watch mode
npx vitest path/to/file.test.ts # Run specific test file
npx vitest -t "test name" # Run tests matching pattern
npm run typecheck # Type-check without emitting
pnpm install # Install all workspace dependencies
pnpm build:all # Build all packages
pnpm lint:all # Run ESLint + Prettier checks across all packages
pnpm lint:fix:all # Auto-fix lint and formatting issues across all packages
pnpm typecheck:all # Type-check all packages
pnpm test:all # Run all tests (vitest) across all packages
pnpm check:all # typecheck + lint across all packages
# Run a single package script (examples)
# Run a single package script from the repo root with pnpm filter
pnpm --filter @modelcontextprotocol/core test # vitest run (core)
pnpm --filter @modelcontextprotocol/core test:watch # vitest (watch)
pnpm --filter @modelcontextprotocol/core test -- path/to/file.test.ts
pnpm --filter @modelcontextprotocol/core test -- -t "test name"
```
## Code Style Guidelines
@ -31,64 +38,64 @@ npm run typecheck # Type-check without emitting
The SDK is organized into three main layers:
1. **Types Layer** (`src/types.ts`) - Protocol types generated from the MCP specification. All JSON-RPC message types, schemas, and protocol constants are defined here using Zod v4.
1. **Types Layer** (`packages/core/src/types/types.ts`) - Protocol types generated from the MCP specification. All JSON-RPC message types, schemas, and protocol constants are defined here using Zod v4.
2. **Protocol Layer** (`src/shared/protocol.ts`) - The abstract `Protocol` class that handles JSON-RPC message routing, request/response correlation, capability negotiation, and transport management. Both `Client` and `Server` extend this class.
2. **Protocol Layer** (`packages/core/src/shared/protocol.ts`) - The abstract `Protocol` class that handles JSON-RPC message routing, request/response correlation, capability negotiation, and transport management. Both `Client` and `Server` extend this class.
3. **High-Level APIs**:
- `Client` (`src/client/index.ts`) - Low-level client extending Protocol with typed methods for all MCP operations
- `Server` (`src/server/index.ts`) - Low-level server extending Protocol with request handler registration
- `McpServer` (`src/server/mcp.ts`) - High-level server API with simplified resource/tool/prompt registration
- `Client` (`packages/client/src/client/client.ts`) - Client implementation extending Protocol with typed methods for MCP operations
- `Server` (`packages/server/src/server/server.ts`) - Server implementation extending Protocol with request handler registration
- `McpServer` (`packages/server/src/server/mcp.ts`) - High-level server API with simplified resource/tool/prompt registration
### Transport System
Transports (`src/shared/transport.ts`) provide the communication layer:
Transports (`packages/core/src/shared/transport.ts`) provide the communication layer:
- **Streamable HTTP** (`src/server/streamableHttp.ts`, `src/client/streamableHttp.ts`) - Recommended transport for remote servers, supports SSE for streaming
- **SSE** (`src/server/sse.ts`, `src/client/sse.ts`) - Legacy HTTP+SSE transport for backwards compatibility
- **stdio** (`src/server/stdio.ts`, `src/client/stdio.ts`) - For local process-spawned integrations
- **Streamable HTTP** (`packages/server/src/server/streamableHttp.ts`, `packages/client/src/client/streamableHttp.ts`) - Recommended transport for remote servers, supports SSE for streaming
- **SSE** (`packages/server/src/server/sse.ts`, `packages/client/src/client/sse.ts`) - Legacy HTTP+SSE transport for backwards compatibility
- **stdio** (`packages/server/src/server/stdio.ts`, `packages/client/src/client/stdio.ts`) - For local process-spawned integrations
### Server-Side Features
- **Tools/Resources/Prompts**: Registered via `McpServer.tool()`, `.resource()`, `.prompt()` methods
- **OAuth/Auth**: Full OAuth 2.0 server implementation in `src/server/auth/`
- **Completions**: Auto-completion support via `src/server/completable.ts`
- **OAuth/Auth**: Full OAuth 2.0 server implementation in `packages/server/src/server/auth/`
- **Completions**: Auto-completion support via `packages/server/src/server/completable.ts`
### Client-Side Features
- **Auth**: OAuth client support in `src/client/auth.ts` and `src/client/auth-extensions.ts`
- **Middleware**: Request middleware in `src/client/middleware.ts`
- **Auth**: OAuth client support in `packages/client/src/client/auth.ts` and `packages/client/src/client/auth-extensions.ts`
- **Middleware**: Request middleware in `packages/client/src/client/middleware.ts`
- **Sampling**: Clients can handle `sampling/createMessage` requests from servers (LLM completions)
- **Elicitation**: Clients can handle `elicitation/create` requests for user input (form or URL mode)
- **Roots**: Clients can expose filesystem roots to servers via `roots/list`
### Experimental Features
Located in `src/experimental/`:
Located in `packages/*/src/experimental/`:
- **Tasks**: Long-running task support with polling/resumption (`src/experimental/tasks/`)
- **Tasks**: Long-running task support with polling/resumption (`packages/core/src/experimental/tasks/`)
### Zod Compatibility
The SDK uses `zod/v4` internally but supports both v3 and v4 APIs. Compatibility utilities:
- `src/server/zod-compat.ts` - Schema parsing helpers that work across versions
- `src/server/zod-json-schema-compat.ts` - Converts Zod schemas to JSON Schema
- `packages/core/src/util/zod-compat.ts` - Schema parsing helpers that work across versions
- `packages/core/src/util/zod-json-schema-compat.ts` - Converts Zod schemas to JSON Schema
### Validation
Pluggable JSON Schema validation (`src/validation/`):
Pluggable JSON Schema validation (`packages/core/src/validation/`):
- `ajv-provider.ts` - Default Ajv-based validator
- `cfworker-provider.ts` - Cloudflare Workers-compatible alternative
### Examples
Runnable examples in `src/examples/`:
Runnable examples in `examples/`:
- `server/` - Various server configurations (stateful, stateless, OAuth, etc.)
- `client/` - Client examples (basic, OAuth, parallel calls, etc.)
- `shared/` - Shared utilities like in-memory event store
- `examples/server/src/` - Various server configurations (stateful, stateless, OAuth, etc.)
- `examples/client/src/` - Client examples (basic, OAuth, parallel calls, etc.)
- `examples/shared/src/` - Shared utilities (OAuth demo provider, etc.)
## Message Flow (Bidirectional Protocol)
@ -98,9 +105,9 @@ MCP is bidirectional: both client and server can send requests. Understanding th
```
Protocol (abstract base)
├── Client (src/client/index.ts) - can send requests TO server, handle requests FROM server
└── Server (src/server/index.ts) - can send requests TO client, handle requests FROM client
└── McpServer (src/server/mcp.ts) - high-level wrapper around Server
├── Client (packages/client/src/client/client.ts) - can send requests TO server, handle requests FROM server
└── Server (packages/server/src/server/server.ts) - can send requests TO client, handle requests FROM client
└── McpServer (packages/server/src/server/mcp.ts) - high-level wrapper around Server
```
### Outbound Flow: Sending Requests

179
README.md
View file

@ -1,13 +1,14 @@
# 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%server) ![NPM Version](https://img.shields.io/npm/v/%40modelcontextprotocol%client) ![MIT licensed](https://img.shields.io/npm/l/%40modelcontextprotocol%server)
<details>
<summary>Table of Contents</summary>
- [Overview](#overview)
- [Packages](#packages)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Core Concepts](#core-concepts)
- [Examples](#examples)
- [Quick Start (runnable examples)](#quick-start-runnable-examples)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [License](#license)
@ -16,142 +17,83 @@
## Overview
The Model Context Protocol allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction. This TypeScript SDK implements
[the full MCP specification](https://modelcontextprotocol.io/specification/draft), making it easy to:
The Model Context Protocol (MCP) allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction.
- Create MCP servers that expose resources, prompts and tools
- Build MCP clients that can connect to any MCP server
- Use standard transports like stdio and Streamable HTTP
This repository contains the TypeScript SDK implementation of the MCP specification and ships:
- MCP **server** libraries (tools/resources/prompts, Streamable HTTP, stdio, auth helpers)
- MCP **client** libraries (transports, high-level helpers, OAuth helpers)
- Runnable **examples** (under [`examples/`](examples/))
## Packages
This monorepo publishes split packages:
- **`@modelcontextprotocol/server`**: build MCP servers
- **`@modelcontextprotocol/client`**: build MCP clients
Both packages have a **required peer dependency** on `zod` for schema validation. The SDK internally imports from `zod/v4`, but remains compatible with projects using Zod v3.25+.
## Installation
### Server
```bash
npm install @modelcontextprotocol/sdk zod
npm install @modelcontextprotocol/server zod
```
This SDK has a **required peer dependency** on `zod` for schema validation. The SDK internally imports from `zod/v4`, but maintains backwards compatibility with projects using Zod v3.25 or later. You can use either API in your code by importing from `zod/v3` or `zod/v4`:
### Client
## Quick Start
```bash
npm install @modelcontextprotocol/client zod
```
To see the SDK in action end-to-end, start from the runnable examples in `src/examples`:
## Quick Start (runnable examples)
1. **Install dependencies** (from the SDK repo root):
The runnable examples live under `examples/` and are kept in sync with the docs.
```bash
npm install
```
1. **Install dependencies** (from repo root):
2. **Run the example Streamable HTTP server**:
```bash
pnpm install
```
```bash
npx tsx src/examples/server/simpleStreamableHttp.ts
```
2. **Run a Streamable HTTP example server**:
```bash
pnpm --filter @modelcontextprotocol/examples-server exec tsx src/simpleStreamableHttp.ts
```
Alternatively, from within the example package:
```bash
cd examples/server
pnpm tsx src/simpleStreamableHttp.ts
```
3. **Run the interactive client in another terminal**:
```bash
npx tsx src/examples/client/simpleStreamableHttp.ts
```
```bash
pnpm --filter @modelcontextprotocol/examples-client exec tsx src/simpleStreamableHttp.ts
```
This pair of examples demonstrates tools, resources, prompts, sampling, elicitation, tasks and logging. For a guided walkthrough and variations (stateless servers, JSON-only responses, SSE compatibility, OAuth, etc.), see [docs/server.md](docs/server.md) and
[docs/client.md](docs/client.md).
Alternatively, from within the example package:
## Core Concepts
```bash
cd examples/client
pnpm tsx src/simpleStreamableHttp.ts
```
### Servers and transports
Next steps:
An MCP server is typically created with `McpServer` and connected to a transport such as Streamable HTTP or stdio. The SDK supports:
- **Streamable HTTP** for remote servers (recommended).
- **HTTP + SSE** for backwards compatibility only.
- **stdio** for local, process-spawned integrations.
Runnable server examples live under `src/examples/server` and are documented in [docs/server.md](docs/server.md).
### Tools, resources, prompts
- **Tools** let LLMs ask your server to take actions (computation, side effects, network calls).
- **Resources** expose read-only data that clients can surface to users or models.
- **Prompts** are reusable templates that help users talk to models in a consistent way.
The detailed APIs, including `ResourceTemplate`, completions, and display-name metadata, are covered in [docs/server.md](docs/server.md#tools-resources-and-prompts), with runnable implementations in [`simpleStreamableHttp.ts`](src/examples/server/simpleStreamableHttp.ts).
### Capabilities: sampling, elicitation, and tasks
The SDK includes higher-level capabilities for richer workflows:
- **Sampling**: server-side tools can ask connected clients to run LLM completions.
- **Form elicitation**: tools can request non-sensitive input via structured forms.
- **URL elicitation**: servers can ask users to complete secure flows in a browser (e.g., API key entry, payments, OAuth).
- **Tasks (experimental)**: long-running tool calls can be turned into tasks that you poll or resume later.
Conceptual overviews and links to runnable examples are in:
- [docs/capabilities.md](docs/capabilities.md)
Key example servers include:
- [`toolWithSampleServer.ts`](src/examples/server/toolWithSampleServer.ts)
- [`elicitationFormExample.ts`](src/examples/server/elicitationFormExample.ts)
- [`elicitationUrlExample.ts`](src/examples/server/elicitationUrlExample.ts)
### Clients
The high-level `Client` class connects to MCP servers over different transports and exposes helpers like `listTools`, `callTool`, `listResources`, `readResource`, `listPrompts`, and `getPrompt`.
Runnable clients live under `src/examples/client` and are described in [docs/client.md](docs/client.md), including:
- Interactive Streamable HTTP client ([`simpleStreamableHttp.ts`](src/examples/client/simpleStreamableHttp.ts))
- Streamable HTTP client with SSE fallback ([`streamableHttpWithSseFallbackClient.ts`](src/examples/client/streamableHttpWithSseFallbackClient.ts))
- OAuth-enabled clients and polling/parallel examples
### Node.js Web Crypto (globalThis.crypto) compatibility
Some parts of the SDK (for example, JWT-based client authentication in `auth-extensions.ts` via `jose`) rely on the Web Crypto API exposed as `globalThis.crypto`.
See [docs/faq.md](docs/faq.md) for details on supported Node.js versions and how to polyfill `globalThis.crypto` when running on older Node.js runtimes.
## Examples
The SDK ships runnable examples under `src/examples`. Use these tables to find the scenario you care about and jump straight to the corresponding code and docs.
### Server examples
| Scenario | Description | Example file(s) | Related docs |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| Streamable HTTP server (stateful) | Feature-rich server with tools, resources, prompts, logging, tasks, sampling, and optional OAuth. | [`simpleStreamableHttp.ts`](src/examples/server/simpleStreamableHttp.ts) | [`server.md`](docs/server.md), [`capabilities.md`](docs/capabilities.md) |
| Streamable HTTP server (stateless) | No session tracking; good for simple API-style servers. | [`simpleStatelessStreamableHttp.ts`](src/examples/server/simpleStatelessStreamableHttp.ts) | [`server.md`](docs/server.md) |
| JSON response mode (no SSE) | Streamable HTTP with JSON responses only and limited notifications. | [`jsonResponseStreamableHttp.ts`](src/examples/server/jsonResponseStreamableHttp.ts) | [`server.md`](docs/server.md) |
| Server notifications over Streamable HTTP | Demonstrates server-initiated notifications using SSE with Streamable HTTP. | [`standaloneSseWithGetStreamableHttp.ts`](src/examples/server/standaloneSseWithGetStreamableHttp.ts) | [`server.md`](docs/server.md) |
| Deprecated HTTP+SSE server | Legacy HTTP+SSE transport for backwards-compatibility testing. | [`simpleSseServer.ts`](src/examples/server/simpleSseServer.ts) | [`server.md`](docs/server.md) |
| Backwards-compatible server (Streamable HTTP + SSE) | Single server that supports both Streamable HTTP and legacy SSE clients. | [`sseAndStreamableHttpCompatibleServer.ts`](src/examples/server/sseAndStreamableHttpCompatibleServer.ts) | [`server.md`](docs/server.md) |
| Form elicitation server | Uses form elicitation to collect non-sensitive user input. | [`elicitationFormExample.ts`](src/examples/server/elicitationFormExample.ts) | [`capabilities.md`](docs/capabilities.md#elicitation) |
| URL elicitation server | Demonstrates URL-mode elicitation in an OAuth-protected server. | [`elicitationUrlExample.ts`](src/examples/server/elicitationUrlExample.ts) | [`capabilities.md`](docs/capabilities.md#elicitation) |
| Sampling and tasks server | Combines tools, logging, sampling, and experimental task-based execution. | [`toolWithSampleServer.ts`](src/examples/server/toolWithSampleServer.ts) | [`capabilities.md`](docs/capabilities.md) |
| OAuth demo authorization server | In-memory OAuth provider used with the example servers. | [`demoInMemoryOAuthProvider.ts`](src/examples/server/demoInMemoryOAuthProvider.ts) | [`server.md`](docs/server.md) |
### Client examples
| Scenario | Description | Example file(s) | Related docs |
| --------------------------------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| Interactive Streamable HTTP client | CLI client that exercises tools, resources, prompts, elicitation, and tasks. | [`simpleStreamableHttp.ts`](src/examples/client/simpleStreamableHttp.ts) | [`client.md`](docs/client.md) |
| Backwards-compatible client (Streamable HTTP → SSE) | Tries Streamable HTTP first, then falls back to SSE on 4xx responses. | [`streamableHttpWithSseFallbackClient.ts`](src/examples/client/streamableHttpWithSseFallbackClient.ts) | [`client.md`](docs/client.md), [`server.md`](docs/server.md) |
| SSE polling client | Polls a legacy SSE server and demonstrates notification handling. | [`ssePollingClient.ts`](src/examples/client/ssePollingClient.ts) | [`client.md`](docs/client.md) |
| Parallel tool calls client | Shows how to run multiple tool calls in parallel. | [`parallelToolCallsClient.ts`](src/examples/client/parallelToolCallsClient.ts) | [`client.md`](docs/client.md) |
| Multiple clients in parallel | Demonstrates connecting multiple clients concurrently to the same server. | [`multipleClientsParallel.ts`](src/examples/client/multipleClientsParallel.ts) | [`client.md`](docs/client.md) |
| OAuth clients | Examples of client_credentials (basic and private_key_jwt) and reusable providers. | [`simpleOAuthClient.ts`](src/examples/client/simpleOAuthClient.ts), [`simpleOAuthClientProvider.ts`](src/examples/client/simpleOAuthClientProvider.ts), [`simpleClientCredentials.ts`](src/examples/client/simpleClientCredentials.ts) | [`client.md`](docs/client.md) |
| URL elicitation client | Works with the URL elicitation server to drive secure browser flows. | [`elicitationUrlExample.ts`](src/examples/client/elicitationUrlExample.ts) | [`capabilities.md`](docs/capabilities.md#elicitation) |
Shared utilities:
- In-memory event store for resumability: [`inMemoryEventStore.ts`](src/examples/shared/inMemoryEventStore.ts) (see [`server.md`](docs/server.md)).
For more details on how to run these examples (including recommended commands and deployment diagrams), see `src/examples/README.md`.
- Server examples index: [`examples/server/README.md`](examples/server/README.md)
- Client examples index: [`examples/client/README.md`](examples/client/README.md)
- Guided walkthroughs: [`docs/server.md`](docs/server.md) and [`docs/client.md`](docs/client.md)
## Documentation
- Local SDK docs:
- [docs/server.md](docs/server.md) – building and running MCP servers, transports, tools/resources/prompts, CORS, DNS rebinding, and multi-node deployment.
- [docs/server.md](docs/server.md) – building MCP servers, transports, tools/resources/prompts, CORS, DNS rebinding, and deployment patterns.
- [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/faq.md](docs/faq.md) – environment and troubleshooting FAQs (including Node.js Web Crypto support).
@ -160,6 +102,11 @@ For more details on how to run these examples (including recommended commands an
- [MCP Specification](https://spec.modelcontextprotocol.io)
- [Example Servers](https://github.com/modelcontextprotocol/servers)
## v1 (legacy) documentation and fixes
If you are using the **v1** generation of the SDK, the **v1 documentation** (and any v1-specific fixes) live on the long-lived [`v1.x` branch](https://github.com/modelcontextprotocol/typescript-sdk/tree/v1.x). See:
[`https://github.com/modelcontextprotocol/typescript-sdk/tree/v1.x`](https://github.com/modelcontextprotocol/typescript-sdk/tree/v1.x).
## Contributing
Issues and pull requests are welcome on GitHub at <https://github.com/modelcontextprotocol/typescript-sdk>.

View file

@ -0,0 +1,81 @@
// @ts-check
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import eslint from '@eslint/js';
import { defineConfig } from 'eslint/config';
import eslintConfigPrettier from 'eslint-config-prettier/flat';
import importPlugin from 'eslint-plugin-import';
import nodePlugin from 'eslint-plugin-n';
import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
import { configs } from 'typescript-eslint';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default defineConfig(
eslint.configs.recommended,
...configs.recommended,
importPlugin.flatConfigs.recommended,
importPlugin.flatConfigs.typescript,
{
languageOptions: {
parserOptions: {
// Ensure consumers of this shared config get a stable tsconfig root
tsconfigRootDir: __dirname
}
},
linterOptions: {
reportUnusedDisableDirectives: false
},
plugins: {
n: nodePlugin,
'simple-import-sort': simpleImportSortPlugin
},
settings: {
'import/resolver': {
typescript: {
// Let the TS resolver handle NodeNext-style imports like "./foo.js"
extensions: ['.js', '.jsx', '.ts', '.tsx', '.d.ts'],
// Use the tsconfig in each package root (when running ESLint from that package)
project: 'tsconfig.json'
}
}
},
rules: {
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'n/prefer-node-protocol': 'error',
'@typescript-eslint/consistent-type-imports': ['error', { disallowTypeAnnotations: false }],
'simple-import-sort/imports': 'warn',
'simple-import-sort/exports': 'warn',
'import/no-extraneous-dependencies': [
'error',
{
devDependencies: [
'**/test/**',
'**/*.test.ts',
'**/*.test.tsx',
'**/scripts/**',
'**/vitest.config.*',
'**/tsdown.config.*',
'**/eslint.config.*',
'**/vitest.setup.*'
],
optionalDependencies: false,
peerDependencies: true
}
]
}
},
{
// Ignore generated protocol types everywhere
ignores: ['**/spec.types.ts']
},
{
files: ['packages/client/**/*.ts', 'packages/server/**/*.ts'],
ignores: ['**/*.test.ts'],
rules: {
'no-console': 'error'
}
},
eslintConfigPrettier
);

View file

@ -0,0 +1,36 @@
{
"name": "@modelcontextprotocol/eslint-config",
"private": true,
"main": "eslint.config.mjs",
"type": "module",
"exports": {
".": "./eslint.config.mjs"
},
"dependencies": {
"typescript": "catalog:devTools"
},
"repository": {
"type": "git",
"url": "https://github.com/modelcontextprotocol/typescript-sdk.git"
},
"bugs": {
"url": "https://github.com/modelcontextprotocol/typescript-sdk/issues"
},
"homepage": "https://github.com/modelcontextprotocol/typescript-sdk/tree/develop/common/eslint-config",
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
},
"version": "2.0.0",
"devDependencies": {
"@eslint/js": "catalog:devTools",
"eslint": "catalog:devTools",
"eslint-config-prettier": "catalog:devTools",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-n": "catalog:devTools",
"eslint-plugin-simple-import-sort": "^12.1.1",
"prettier": "catalog:devTools",
"typescript": "catalog:devTools",
"typescript-eslint": "catalog:devTools"
}
}

View file

@ -0,0 +1,21 @@
{
"name": "@modelcontextprotocol/tsconfig",
"private": true,
"main": "tsconfig.json",
"type": "module",
"dependencies": {
"typescript": "catalog:devTools"
},
"repository": {
"type": "git",
"url": "https://github.com/modelcontextprotocol/typescript-sdk.git"
},
"bugs": {
"url": "https://github.com/modelcontextprotocol/typescript-sdk/issues"
},
"homepage": "https://github.com/modelcontextprotocol/typescript-sdk/tree/develop/common/ts-config",
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
},
"version": "2.0.0"
}

View file

@ -0,0 +1,31 @@
{
"compilerOptions": {
"target": "esnext",
"lib": ["esnext"],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"libReplacement": false,
"noImplicitReturns": true,
"incremental": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"strict": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"skipLibCheck": true,
"paths": {
"pkce-challenge": ["./node_modules/pkce-challenge/dist/index.node"]
},
"types": ["node", "vitest/globals"]
}
}

View file

@ -0,0 +1,28 @@
{
"name": "@modelcontextprotocol/vitest-config",
"private": true,
"main": "vitest.config.mjs",
"type": "module",
"exports": {
".": "./vitest.config.js"
},
"dependencies": {
"typescript": "catalog:devTools"
},
"repository": {
"type": "git",
"url": "https://github.com/modelcontextprotocol/typescript-sdk.git"
},
"bugs": {
"url": "https://github.com/modelcontextprotocol/typescript-sdk/issues"
},
"homepage": "https://github.com/modelcontextprotocol/typescript-sdk/tree/develop/common/vitest-config",
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
},
"version": "2.0.0",
"devDependencies": {
"@modelcontextprotocol/tsconfig": "workspace:^",
"vite-tsconfig-paths": "catalog:devTools"
}
}

View file

@ -0,0 +1,8 @@
{
"include": ["./"],
"extends": "@modelcontextprotocol/tsconfig",
"compilerOptions": {
"noEmit": true,
"allowJs": true
}
}

View file

@ -0,0 +1,25 @@
import { defineConfig } from 'vitest/config';
import tsconfigPaths from 'vite-tsconfig-paths';
import path from 'node:path';
import url from 'node:url';
const ignorePatterns = ['**/dist/**'];
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
export default defineConfig({
test: {
globals: true,
environment: 'node',
include: ['test/**/*.test.ts'],
exclude: ignorePatterns,
deps: {
moduleDirectories: ['node_modules', path.resolve(__dirname, '../../packages'), path.resolve(__dirname, '../../common')]
},
poolOptions: {
threads: {
useAtomics: true
}
}
},
plugins: [tsconfigPaths()]
});

View file

@ -4,7 +4,7 @@ MCP servers can request LLM completions from connected clients that support the
For a runnable server that combines tools, logging and tasks, see:
- [`toolWithSampleServer.ts`](../src/examples/server/toolWithSampleServer.ts)
- [`toolWithSampleServer.ts`](../examples/server/src/toolWithSampleServer.ts)
In practice you will:
@ -22,8 +22,8 @@ Form elicitation lets a tool ask the user for additional, **non‑sensitive** in
Runnable example:
- Server: [`elicitationFormExample.ts`](../src/examples/server/elicitationFormExample.ts)
- Client‑side handling: [`simpleStreamableHttp.ts`](../src/examples/client/simpleStreamableHttp.ts)
- Server: [`elicitationFormExample.ts`](../examples/server/src/elicitationFormExample.ts)
- Client‑side handling: [`simpleStreamableHttp.ts`](../examples/client/src/simpleStreamableHttp.ts)
The `simpleStreamableHttp` server also includes a `collect-user-info` tool that demonstrates how to drive elicitation from a tool and handle the response.
@ -33,8 +33,8 @@ URL elicitation is designed for sensitive data and secure web‑based flows (e.g
Runnable example:
- Server: [`elicitationUrlExample.ts`](../src/examples/server/elicitationUrlExample.ts)
- Client: [`elicitationUrlExample.ts`](../src/examples/client/elicitationUrlExample.ts)
- Server: [`elicitationUrlExample.ts`](../examples/server/src/elicitationUrlExample.ts)
- Client: [`elicitationUrlExample.ts`](../examples/client/src/elicitationUrlExample.ts)
Key points:
@ -62,8 +62,8 @@ On the server you will:
For a runnable example that uses the in-memory store shipped with the SDK, see:
- [`toolWithSampleServer.ts`](../src/examples/server/toolWithSampleServer.ts)
- `src/experimental/tasks/stores/in-memory.ts`
- [`toolWithSampleServer.ts`](../examples/server/src/toolWithSampleServer.ts)
- `packages/core/src/experimental/tasks/stores/in-memory.ts`
### Client-side usage
@ -74,7 +74,7 @@ On the client, you use:
The interactive client in:
- [`simpleStreamableHttp.ts`](../src/examples/client/simpleStreamableHttp.ts)
- [`simpleStreamableHttp.ts`](../examples/client/src/simpleStreamableHttp.ts)
includes commands to demonstrate calling tools that support tasks and handling their lifecycle.

View file

@ -8,11 +8,11 @@ The SDK provides a high-level `Client` class that connects to MCP servers over d
Runnable client examples live under:
- [`simpleStreamableHttp.ts`](../src/examples/client/simpleStreamableHttp.ts)
- [`streamableHttpWithSseFallbackClient.ts`](../src/examples/client/streamableHttpWithSseFallbackClient.ts)
- [`ssePollingClient.ts`](../src/examples/client/ssePollingClient.ts)
- [`multipleClientsParallel.ts`](../src/examples/client/multipleClientsParallel.ts)
- [`parallelToolCallsClient.ts`](../src/examples/client/parallelToolCallsClient.ts)
- [`simpleStreamableHttp.ts`](../examples/client/src/simpleStreamableHttp.ts)
- [`streamableHttpWithSseFallbackClient.ts`](../examples/client/src/streamableHttpWithSseFallbackClient.ts)
- [`ssePollingClient.ts`](../examples/client/src/ssePollingClient.ts)
- [`multipleClientsParallel.ts`](../examples/client/src/multipleClientsParallel.ts)
- [`parallelToolCallsClient.ts`](../examples/client/src/parallelToolCallsClient.ts)
## Connecting and basic operations
@ -25,7 +25,7 @@ A typical flow:
- `listPrompts`, `getPrompt`
- `listResources`, `readResource`
See [`simpleStreamableHttp.ts`](../src/examples/client/simpleStreamableHttp.ts) for an interactive CLI client that exercises these methods and shows how to handle notifications, elicitation and tasks.
See [`simpleStreamableHttp.ts`](../examples/client/src/simpleStreamableHttp.ts) for an interactive CLI client that exercises these methods and shows how to handle notifications, elicitation and tasks.
## Transports and backwards compatibility
@ -36,7 +36,7 @@ To support both modern Streamable HTTP and legacy SSE servers, use a client that
Runnable example:
- [`streamableHttpWithSseFallbackClient.ts`](../src/examples/client/streamableHttpWithSseFallbackClient.ts)
- [`streamableHttpWithSseFallbackClient.ts`](../examples/client/src/streamableHttpWithSseFallbackClient.ts)
## OAuth client authentication helpers
@ -48,10 +48,10 @@ For OAuth-secured MCP servers, the client `auth` module exposes:
Examples:
- [`simpleOAuthClient.ts`](../src/examples/client/simpleOAuthClient.ts)
- [`simpleOAuthClientProvider.ts`](../src/examples/client/simpleOAuthClientProvider.ts)
- [`simpleClientCredentials.ts`](../src/examples/client/simpleClientCredentials.ts)
- Server-side auth demo: [`demoInMemoryOAuthProvider.ts`](../src/examples/server/demoInMemoryOAuthProvider.ts) (tests live under `test/examples/server/demoInMemoryOAuthProvider.test.ts`)
- [`simpleOAuthClient.ts`](../examples/client/src/simpleOAuthClient.ts)
- [`simpleOAuthClientProvider.ts`](../examples/client/src/simpleOAuthClientProvider.ts)
- [`simpleClientCredentials.ts`](../examples/client/src/simpleClientCredentials.ts)
- Server-side auth demo: [`demoInMemoryOAuthProvider.ts`](../examples/shared/src/demoInMemoryOAuthProvider.ts) (tests live under `examples/shared/test/demoInMemoryOAuthProvider.test.ts`)
These examples show how to:

View file

@ -6,6 +6,7 @@
- [General](#general)
- [Clients](#clients)
- [Servers](#servers)
- [v1 (legacy)](#v1-legacy)
</details>
@ -13,7 +14,8 @@
### Why do I see `TS2589: Type instantiation is excessively deep and possibly infinite` after upgrading the SDK?
This TypeScript error can appear when upgrading to newer SDK versions that support Zod v4 (for example, from `@modelcontextprotocol/sdk` `1.22.0` to `1.23.0`) **and** your project ends up with multiple `zod` versions in the dependency tree.
This TypeScript error can appear when upgrading to newer SDK versions that support Zod v4 (for example, from older `@modelcontextprotocol/sdk` releases to newer `@modelcontextprotocol/client` / `@modelcontextprotocol/server` releases) **and** your project ends up with multiple
`zod` versions in the dependency tree.
When there are multiple copies or versions of `zod`, TypeScript may try to instantiate very complex, cross-version types and hit its recursion limits, resulting in `TS2589`. This scenario is discussed in GitHub issue
[#1180](https://github.com/modelcontextprotocol/typescript-sdk/issues/1180#event-21236550401).
@ -34,12 +36,12 @@ Once your project is using a single, compatible `zod` version, the `TS2589` erro
### How do I enable Web Crypto (`globalThis.crypto`) for client authentication in older Node.js versions?
The SDK’s OAuth client authentication helpers (for example, those in `src/client/auth-extensions.ts` that use `jose`) rely on the Web Crypto API exposed as `globalThis.crypto`. This is especially important for **client credentials** and **JWT-based** authentication flows used by
MCP clients.
The SDK’s OAuth client authentication helpers (for example, those in `packages/client/src/client/auth-extensions.ts` that use `jose`) rely on the Web Crypto API exposed as `globalThis.crypto`. This is especially important for **client credentials** and **JWT-based**
authentication flows used by MCP clients.
- **Node.js v19.0.0 and later**: `globalThis.crypto` is available by default.
- **Node.js v18.x**: `globalThis.crypto` may not be defined by default. In this repository we polyfill it for tests (see `vitest.setup.ts`), and you should do the same in your app if it is missing – or alternatively, run Node with `--experimental-global-webcrypto` as per your
Node version documentation. (See https://nodejs.org/dist/latest-v18.x/docs/api/globals.html#crypto )
- **Node.js v18.x**: `globalThis.crypto` may not be defined by default. In this repository we polyfill it for tests (see `packages/client/vitest.setup.js`), and you should do the same in your app if it is missing – or alternatively, run Node with `--experimental-global-webcrypto`
as per your Node version documentation. (See https://nodejs.org/dist/latest-v18.x/docs/api/globals.html#crypto )
If you run clients on Node.js versions where `globalThis.crypto` is missing, you can polyfill it using the built-in `node:crypto` module, similar to the SDK's own `vitest.setup.ts`:
@ -61,5 +63,10 @@ For production use, you can either:
### Where can I find runnable server examples?
The SDK ships several runnable server examples under `src/examples/server`. The root `README.md` contains a curated **Server examples** table that links to each scenario (stateful/stateless Streamable HTTP, JSON-only mode, SSE/backwards compatibility, elicitation, sampling,
tasks, and OAuth demos), and `src/examples/README.md` includes commands and deployment diagrams for running them.
The SDK ships several runnable server examples under `examples/server/src`. Start from the server examples index in [`examples/server/README.md`](../examples/server/README.md) and the entry-point quick start in the root [`README.md`](../README.md).
## v1 (legacy)
### Where do v1 documentation and v1-specific fixes live?
The v1 generation of this SDK is maintained on the long-lived [`v1.x` branch](https://github.com/modelcontextprotocol/typescript-sdk/tree/v1.x). If you’re using v1, refer to that branch for documentation and any v1-specific fixes.

View file

@ -1,6 +1,6 @@
## Server overview
This SDK lets you build MCP servers in TypeScript and connect them to different transports. For most use cases you will use `McpServer` from `@modelcontextprotocol/sdk/server/mcp.js` and choose one of:
This SDK lets you build MCP servers in TypeScript and connect them to different transports. For most use cases you will use `McpServer` from `@modelcontextprotocol/server` and choose one of:
- **Streamable HTTP** (recommended for remote servers)
- **HTTP + SSE** (deprecated, for backwards compatibility only)
@ -8,11 +8,11 @@ This SDK lets you build MCP servers in TypeScript and connect them to different
For a complete, runnable example server, see:
- [`simpleStreamableHttp.ts`](../src/examples/server/simpleStreamableHttp.ts) – feature‑rich Streamable HTTP server
- [`jsonResponseStreamableHttp.ts`](../src/examples/server/jsonResponseStreamableHttp.ts) – Streamable HTTP with JSON response mode
- [`simpleStatelessStreamableHttp.ts`](../src/examples/server/simpleStatelessStreamableHttp.ts) – stateless Streamable HTTP server
- [`simpleSseServer.ts`](../src/examples/server/simpleSseServer.ts) – deprecated HTTP+SSE transport
- [`sseAndStreamableHttpCompatibleServer.ts`](../src/examples/server/sseAndStreamableHttpCompatibleServer.ts) – backwards‑compatible server for old and new clients
- [`simpleStreamableHttp.ts`](../examples/server/src/simpleStreamableHttp.ts) – feature‑rich Streamable HTTP server
- [`jsonResponseStreamableHttp.ts`](../examples/server/src/jsonResponseStreamableHttp.ts) – Streamable HTTP with JSON response mode
- [`simpleStatelessStreamableHttp.ts`](../examples/server/src/simpleStatelessStreamableHttp.ts) – stateless Streamable HTTP server
- [`simpleSseServer.ts`](../examples/server/src/simpleSseServer.ts) – deprecated HTTP+SSE transport
- [`sseAndStreamableHttpCompatibleServer.ts`](../examples/server/src/sseAndStreamableHttpCompatibleServer.ts) – backwards‑compatible server for old and new clients
## Transports
@ -27,9 +27,9 @@ Streamable HTTP is the modern, fully featured transport. It supports:
Key examples:
- [`simpleStreamableHttp.ts`](../src/examples/server/simpleStreamableHttp.ts) – sessions, logging, tasks, elicitation, auth hooks
- [`jsonResponseStreamableHttp.ts`](../src/examples/server/jsonResponseStreamableHttp.ts) – `enableJsonResponse: true`, no SSE
- [`standaloneSseWithGetStreamableHttp.ts`](../src/examples/server/standaloneSseWithGetStreamableHttp.ts) – notifications with Streamable HTTP GET + SSE
- [`simpleStreamableHttp.ts`](../examples/server/src/simpleStreamableHttp.ts) – sessions, logging, tasks, elicitation, auth hooks
- [`jsonResponseStreamableHttp.ts`](../examples/server/src/jsonResponseStreamableHttp.ts) – `enableJsonResponse: true`, no SSE
- [`standaloneSseWithGetStreamableHttp.ts`](../examples/server/src/standaloneSseWithGetStreamableHttp.ts) – notifications with Streamable HTTP GET + SSE
See the MCP spec for full transport details: `https://modelcontextprotocol.io/specification/2025-11-25/basic/transports`
@ -42,8 +42,8 @@ Streamable HTTP can run:
Examples:
- Stateless Streamable HTTP: [`simpleStatelessStreamableHttp.ts`](../src/examples/server/simpleStatelessStreamableHttp.ts)
- Stateful with resumability: [`simpleStreamableHttp.ts`](../src/examples/server/simpleStreamableHttp.ts)
- Stateless Streamable HTTP: [`simpleStatelessStreamableHttp.ts`](../examples/server/src/simpleStatelessStreamableHttp.ts)
- Stateful with resumability: [`simpleStreamableHttp.ts`](../examples/server/src/simpleStreamableHttp.ts)
### Deprecated HTTP + SSE
@ -51,15 +51,15 @@ The older HTTP+SSE transport (protocol version 2024‑11‑05) is supported only
Examples:
- Legacy SSE server: [`simpleSseServer.ts`](../src/examples/server/simpleSseServer.ts)
- Legacy SSE server: [`simpleSseServer.ts`](../examples/server/src/simpleSseServer.ts)
- Backwards‑compatible server (Streamable HTTP + SSE):
[`sseAndStreamableHttpCompatibleServer.ts`](../src/examples/server/sseAndStreamableHttpCompatibleServer.ts)
[`sseAndStreamableHttpCompatibleServer.ts`](../examples/server/src/sseAndStreamableHttpCompatibleServer.ts)
## Running your server
For a minimal “getting started” experience:
1. Start from [`simpleStreamableHttp.ts`](../src/examples/server/simpleStreamableHttp.ts).
1. Start from [`simpleStreamableHttp.ts`](../examples/server/src/simpleStreamableHttp.ts).
2. Remove features you do not need (tasks, advanced logging, OAuth, etc.).
3. Register your own tools, resources and prompts.
@ -70,7 +70,7 @@ For more detailed patterns (stateless vs stateful, JSON response mode, CORS, DNS
MCP servers running on localhost are vulnerable to DNS rebinding attacks. Use `createMcpExpressApp()` to create an Express app with DNS rebinding protection enabled by default:
```typescript
import { createMcpExpressApp } from '@modelcontextprotocol/sdk/server/express.js';
import { createMcpExpressApp } from '@modelcontextprotocol/server';
// Protection auto-enabled (default host is 127.0.0.1)
const app = createMcpExpressApp();
@ -78,19 +78,19 @@ const app = createMcpExpressApp();
// Protection auto-enabled for localhost
const app = createMcpExpressApp({ host: 'localhost' });
// No auto protection when binding to all interfaces
// No auto protection when binding to all interfaces, unless you provide allowedHosts
const app = createMcpExpressApp({ host: '0.0.0.0' });
```
For custom host validation, use the middleware directly:
When binding to `0.0.0.0` / `::`, provide an allow-list of hosts:
```typescript
import express from 'express';
import { hostHeaderValidation } from '@modelcontextprotocol/sdk/server/middleware/hostHeaderValidation.js';
import { createMcpExpressApp } from '@modelcontextprotocol/server';
const app = express();
app.use(express.json());
app.use(hostHeaderValidation(['localhost', '127.0.0.1', 'myhost.local']));
const app = createMcpExpressApp({
host: '0.0.0.0',
allowedHosts: ['localhost', '127.0.0.1', 'myhost.local']
});
```
## Tools, resources, and prompts
@ -125,14 +125,14 @@ server.registerTool(
This snippet is illustrative only; for runnable servers that expose tools, see:
- [`simpleStreamableHttp.ts`](../src/examples/server/simpleStreamableHttp.ts)
- [`toolWithSampleServer.ts`](../src/examples/server/toolWithSampleServer.ts)
- [`simpleStreamableHttp.ts`](../examples/server/src/simpleStreamableHttp.ts)
- [`toolWithSampleServer.ts`](../examples/server/src/toolWithSampleServer.ts)
#### ResourceLink outputs
Tools can return `resource_link` content items to reference large resources without embedding them directly, allowing clients to fetch only what they need.
The README’s `list-files` example shows the pattern conceptually; for concrete usage, see the Streamable HTTP examples in `src/examples/server`.
The README’s `list-files` example shows the pattern conceptually; for concrete usage, see the Streamable HTTP examples in `examples/server/src`.
### Resources
@ -157,7 +157,7 @@ server.registerResource(
Dynamic resources use `ResourceTemplate` and can support completions on path parameters. For full runnable examples of resources:
- [`simpleStreamableHttp.ts`](../src/examples/server/simpleStreamableHttp.ts)
- [`simpleStreamableHttp.ts`](../examples/server/src/simpleStreamableHttp.ts)
### Prompts
@ -189,37 +189,33 @@ server.registerPrompt(
For prompts integrated into a full server, see:
- [`simpleStreamableHttp.ts`](../src/examples/server/simpleStreamableHttp.ts)
- [`simpleStreamableHttp.ts`](../examples/server/src/simpleStreamableHttp.ts)
### Completions
Both prompts and resources can support argument completions. On the client side, you use `client.complete()` with a reference to the prompt or resource and the partially‑typed argument.
See the MCP spec sections on prompts and resources for complete details, and [`simpleStreamableHttp.ts`](../src/examples/client/simpleStreamableHttp.ts) for client‑side usage patterns.
See the MCP spec sections on prompts and resources for complete details, and [`simpleStreamableHttp.ts`](../examples/client/src/simpleStreamableHttp.ts) for client‑side usage patterns.
### Display names and metadata
Tools, resources and prompts support a `title` field for human‑readable names. Older APIs can also attach `annotations.title`. To compute the correct display name on the client, use:
- `getDisplayName` from `@modelcontextprotocol/sdk/shared/metadataUtils.js`
- `getDisplayName` from `@modelcontextprotocol/client`
## Multi‑node deployment patterns
The SDK supports multi‑node deployments using Streamable HTTP. The high‑level patterns are documented in [`README.md`](../src/examples/README.md):
The SDK supports multi‑node deployments using Streamable HTTP. The high‑level patterns and diagrams live with the runnable server examples:
- Stateless mode (any node can handle any request)
- Persistent storage mode (shared database for session state)
- Local state with message routing (message queue + pub/sub)
Those deployment diagrams are kept in [`README.md`](../src/examples/README.md) so the examples and documentation stay aligned.
- [`examples/server/README.md`](../examples/server/README.md#multi-node-deployment-patterns)
## Backwards compatibility
To handle both modern and legacy clients:
- Run a backwards‑compatible server:
- [`sseAndStreamableHttpCompatibleServer.ts`](../src/examples/server/sseAndStreamableHttpCompatibleServer.ts)
- [`sseAndStreamableHttpCompatibleServer.ts`](../examples/server/src/sseAndStreamableHttpCompatibleServer.ts)
- Use a client that falls back from Streamable HTTP to SSE:
- [`streamableHttpWithSseFallbackClient.ts`](../src/examples/client/streamableHttpWithSseFallbackClient.ts)
- [`streamableHttpWithSseFallbackClient.ts`](../examples/client/src/streamableHttpWithSseFallbackClient.ts)
For the detailed protocol rules, see the “Backwards compatibility” section of the MCP spec.

Some files were not shown because too many files have changed in this diff Show more