[v2] Мonorepo, sdk-client, sdk-server, sdk-core package split (#1279)
This commit is contained in:
parent
384311b9b8
commit
71ae3acee0
221 changed files with 12067 additions and 4817 deletions
6
.changeset/README.md
Normal file
6
.changeset/README.md
Normal 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
11
.changeset/config.json
Normal 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"]
|
||||
}
|
||||
6
.changeset/tender-snails-fold.md
Normal file
6
.changeset/tender-snails-fold.md
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
'@modelcontextprotocol/client': patch
|
||||
'@modelcontextprotocol/server': patch
|
||||
---
|
||||
|
||||
Initial 2.0.0-alpha.0 client and server package
|
||||
53
.github/workflows/main.yml
vendored
53
.github/workflows/main.yml
vendored
|
|
@ -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 }}
|
||||
|
|
|
|||
30
.github/workflows/publish.yml
vendored
30
.github/workflows/publish.yml
vendored
|
|
@ -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
45
.github/workflows/release.yml
vendored
Normal 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 }}
|
||||
26
.github/workflows/update-spec-types.yml
vendored
26
.github/workflows/update-spec-types.yml
vendored
|
|
@ -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
|
||||
|
||||
|
|
|
|||
73
CLAUDE.md
73
CLAUDE.md
|
|
@ -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
179
README.md
|
|
@ -1,13 +1,14 @@
|
|||
# MCP TypeScript SDK  
|
||||
# MCP TypeScript SDK
|
||||
|
||||
  
|
||||
|
||||
<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>.
|
||||
|
|
|
|||
81
common/eslint-config/eslint.config.mjs
Normal file
81
common/eslint-config/eslint.config.mjs
Normal 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
|
||||
);
|
||||
36
common/eslint-config/package.json
Normal file
36
common/eslint-config/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
21
common/tsconfig/package.json
Normal file
21
common/tsconfig/package.json
Normal 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"
|
||||
}
|
||||
31
common/tsconfig/tsconfig.json
Normal file
31
common/tsconfig/tsconfig.json
Normal 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"]
|
||||
}
|
||||
}
|
||||
28
common/vitest-config/package.json
Normal file
28
common/vitest-config/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
8
common/vitest-config/tsconfig.json
Normal file
8
common/vitest-config/tsconfig.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"include": ["./"],
|
||||
"extends": "@modelcontextprotocol/tsconfig",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"allowJs": true
|
||||
}
|
||||
}
|
||||
25
common/vitest-config/vitest.config.js
Normal file
25
common/vitest-config/vitest.config.js
Normal 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()]
|
||||
});
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
21
docs/faq.md
21
docs/faq.md
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in a new issue