# Repository: modelcontextprotocol/typescript-sdk
# Stars: 12197
## CLAUDE.md
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Build & Test Commands
```sh
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"
```
## Breaking Changes
When making breaking changes, document them in **both**:
- `docs/migration.md` — human-readable guide with before/after code examples
- `docs/migration-SKILL.md` — LLM-optimized mapping tables for mechanical migration
Include what changed, why, and how to migrate. Search for related sections and group related changes together rather than adding new standalone sections.
## Code Style Guidelines
- **TypeScript**: Strict type checking, ES modules, explicit return types
- **Naming**: PascalCase for classes/types, camelCase for functions/variables
- **Files**: Lowercase with hyphens, test files with `.test.ts` suffix
- **Imports**: ES module style, include `.js` extension, group imports logically
- **Formatting**: 2-space indentation, semicolons required, single quotes preferred
- **Testing**: Co-locate tests with source files, use descriptive test names
- **Comments**: JSDoc for public APIs, inline comments for complex logic
### JSDoc `@example` Code Snippets
JSDoc `@example` tags should pull type-checked code from companion `.examples.ts` files (e.g., `client.ts` → `client.examples.ts`). Use `` ```ts source="./file.examples.ts#regionName" `` fences referencing `//#region regionName` blocks; region names follow `exportedName_variant` or `ClassName_methodName_variant` pattern (e.g., `applyMiddlewares_basicUsage`, `Client_connect_basicUsage`). For whole-file inclusion (any file type), omit the `#regionName`.
Run `pnpm sync:snippets` to sync example content into JSDoc comments and markdown files.
## Architecture Overview
### Core Layers
The SDK is organized into three main layers:
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** (`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` (`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
### Public API Exports
The SDK has a two-layer export structure to separate internal code from the public API:
- **`@modelcontextprotocol/core`** (main entry, `packages/core/src/index.ts`) — Internal barrel. Exports everything (including Zod schemas, Protocol class, stdio utils). Only consumed by sibling packages within the monorepo (`private: true`).
- **`@modelcontextprotocol/core/public`** (`packages/core/src/exports/public/index.ts`) — Curated public API. Exports only TypeScript types, error classes, constants, and guards. Re-exported by client and server packages.
- **`@modelcontextprotocol/client`** and **`@modelcontextprotocol/server`** (`packages/*/src/index.ts`) — Final public surface. Package-specific exports (named explicitly) plus re-exports from `core/public`.
When modifying exports:
- Use explicit named exports, not `export *`, in package `index.ts` files and `core/public`.
- Adding a symbol to a package `index.ts` makes it public API — do so intentionally.
- Internal helpers should stay in the core internal barrel and not be added to `core/public` or package index files.
### Transport System
Transports (`packages/core/src/shared/transport.ts`) provide the communication layer:
- **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 `packages/server/src/server/auth/`
- **Completions**: Auto-completion support via `packages/server/src/server/completable.ts`
### Client-Side Features
- **Auth**: OAuth client support in `packages/client/src/client/auth.ts` and `packages/client/src/client/auth-extensions.ts`
- **Client middleware**: Request middleware in `packages/client/src/client/middleware.ts` (unrelated to the framework adapter packages below)
- **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`
### Middleware packages (framework/runtime adapters)
The repo also ships “middleware” packages under `packages/middleware/` (e.g. `@modelcontextprotocol/express`, `@modelcontextprotocol/hono`, `@modelcontextprotocol/node`). These are thin integration layers for specific frameworks/runtimes and should not add new MCP functionality.
### Experimental Features
Located in `packages/*/src/experimental/`:
- **Tasks**: Long-running task support with polling/resumption (`packages/core/src/experimental/tasks/`)
### Zod Schemas
The SDK uses `zod/v4` internally. Schema utilities live in:
- `packages/core/src/util/schema.ts` - AnySchema alias and helpers for inspecting Zod objects
### Validation
Pluggable JSON Schema validation (`packages/core/src/validators/`):
- `ajvProvider.ts` - Default Ajv-based validator
- `cfWorkerProvider.ts` - Cloudflare Workers-compatible alternative
### Examples
Runnable examples in `examples/`:
- `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)
MCP is bidirectional: both client and server can send requests. Understanding this flow is essential when implementing new request types.
### Class Hierarchy
```
Protocol (abstract base)
├── 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
When code calls `client.callTool()` or `server.createMessage()`:
1. **High-level method** (e.g., `Client.callTool()`) calls `this.request()`
2. **`Protocol.request()`**:
- Assigns unique message ID
- Checks capabilities via `assertCapabilityForMethod()` (abstract, implemented by Client/Server)
- Creates response handler promise
- Calls `transport.send()` with JSON-RPC request
- Waits for response handler to resolve
3. **Transport** serializes and sends over wire (HTTP, stdio, etc.)
4. **`Protocol._onresponse()`** resolves the promise when response arrives
### Inbound Flow: Handling Requests
When a request arrives from the remote side:
1. **Transport** receives message, calls `transport.onmessage()`
2. **`Protocol.connect()`** routes to `_onrequest()`, `_onresponse()`, or `_onnotification()`
3. **`Protocol._onrequest()`**:
- Looks up handler in `_requestHandlers` map (keyed by method name)
- Creates `BaseContext` with `signal`, `sessionId`, `sendNotification`, `sendRequest`, etc.
- Calls `buildContext()` to let subclasses enrich the context (e.g., Server adds HTTP request info)
- Invokes handler, sends JSON-RPC response back via transport
4. **Handler** was registered via `setRequestHandler('method', handler)`
### Handler Registration
```typescript
// In Client (for server→client requests like sampling, elicitation)
client.setRequestHandler('sampling/createMessage', async (request, ctx) => {
// Handle sampling request from server
return { role: "assistant", content: {...}, model: "..." };
});
// In Server (for client→server requests like tools/call)
server.setRequestHandler('tools/call', async (request, ctx) => {
// Handle tool call from client
return { content: [...] };
});
```
### Request Handler Context
The `ctx` parameter in handlers provides a structured context:
**`BaseContext`** (common to both Server and Client), fields organized into nested groups:
- `sessionId?`: Transport session identifier
- `mcpReq`: Request-level concerns
- `id`: JSON-RPC message ID
- `method`: Request method string (e.g., 'tools/call')
- `_meta?`: Request metadata
- `signal`: AbortSignal for cancellation
- `send(request, schema, options?)`: Send related request (for bidirectional flows)
- `notify(notification)`: Send related notification back
- `http?`: HTTP transport info (undefined for stdio)
- `authInfo?`: Validated auth token info
- `task?`: Task context (`{ id?, store, requestedTtl? }`) when task storage is configured
**`ServerContext`** extends `BaseContext.mcpReq` and `BaseContext.http?` via type intersection:
- `mcpReq` adds: `log(level, data, logger?)`, `elicitInput(params, options?)`, `requestSampling(params, options?)`
- `http?` adds: `req?` (HTTP request info), `closeSSE?`, `closeStandaloneSSE?`
**`ClientContext`** is currently identical to `BaseContext`.
### Capability Checking
Both sides declare capabilities during initialization. The SDK enforces these:
- **Client→Server**: `Client.assertCapabilityForMethod()` checks `_serverCapabilities`
- **Server→Client**: `Server.assertCapabilityForMethod()` checks `_clientCapabilities`
- **Handler registration**: `assertRequestHandlerCapability()` validates local capabilities
### Adding a New Request Type
1. **Define schema** in `src/types.ts` (request params, result schema)
2. **Add capability** to `ClientCapabilities` or `ServerCapabilities` in types
3. **Implement sender** method in Client or Server class
4. **Add capability check** in the appropriate `assertCapabilityForMethod()`
5. **Register handler** on the receiving side with `setRequestHandler()`
6. **For McpServer**: Add high-level wrapper method if needed
### Server-Initiated Requests (Sampling, Elicitation)
Server can request actions from client (requires client capability):
```typescript
// Server sends sampling request to client
const result = await server.createMessage({
messages: [...],
maxTokens: 100
});
// Client must have registered handler:
client.setRequestHandler('sampling/createMessage', async (request, extra) => {
// Client-side LLM call
return { role: "assistant", content: {...} };
});
```
## Key Patterns
### Request Handler Registration (Low-Level Server)
```typescript
server.setRequestHandler('tools/call', async (request, extra) => {
// extra contains sessionId, authInfo, sendNotification, etc.
return {
/* result */
};
});
```
### Tool Registration (High-Level McpServer)
```typescript
mcpServer.tool('tool-name', { param: z.string() }, async ({ param }, extra) => {
return { content: [{ type: 'text', text: 'result' }] };
});
```
### Transport Connection
```typescript
// Server
// (Node.js IncomingMessage/ServerResponse wrapper; exported by @modelcontextprotocol/node)
const transport = new NodeStreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID() });
await server.connect(transport);
// Client
const transport = new StreamableHTTPClientTransport(new URL('http://localhost:3000/mcp'));
await client.connect(transport);
```
## README.md
# MCP TypeScript SDK
> [!IMPORTANT] **This is the `main` branch which contains v2 of the SDK (currently in development, pre-alpha).**
>
> We anticipate a stable v2 release in Q1 2026. Until then, **v1.x remains the recommended version** for production use. v1.x will continue to receive bug fixes and security updates for at least 6 months after v2 ships to give people time to upgrade.
>
> For v1 documentation, see the [V1 API docs](https://ts.sdk.modelcontextprotocol.io/). For v2 API docs, see [`/v2/`](https://ts.sdk.modelcontextprotocol.io/v2/).
  
Table of Contents
- [Overview](#overview)
- [Packages](#packages)
- [Installation](#installation)
- [Quick Start (runnable examples)](#quick-start-runnable-examples)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [License](#license)
## Overview
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.
This repository contains the TypeScript SDK implementation of the MCP specification. It runs on **Node.js**, **Bun**, and **Deno**, and ships:
- MCP **server** libraries (tools/resources/prompts, Streamable HTTP, stdio, auth helpers)
- MCP **client** libraries (transports, high-level helpers, OAuth helpers)
- Optional **middleware packages** for specific runtimes/frameworks (Express, Hono, Node.js HTTP)
- Runnable **examples** (under [`examples/`](https://github.com/modelcontextprotocol/typescript-sdk/tree/main/examples))
## Packages
This monorepo publishes split packages:
- **`@modelcontextprotocol/server`**: build MCP servers
- **`@modelcontextprotocol/client`**: build MCP clients
Tool and prompt schemas use [Standard Schema](https://standardschema.dev/) — bring Zod v4, Valibot, ArkType, or any compatible library.
### Middleware packages (optional)
The SDK also publishes small "middleware" packages under [`packages/middleware/`](https://github.com/modelcontextprotocol/typescript-sdk/tree/main/packages/middleware) that help you **wire MCP into a specific runtime or web framework**.
They are intentionally thin adapters: they should not introduce new MCP functionality or business logic. See [`packages/middleware/README.md`](packages/middleware/README.md) for details.
- **`@modelcontextprotocol/node`**: Node.js Streamable HTTP transport wrapper for `IncomingMessage` / `ServerResponse`
- **`@modelcontextprotocol/express`**: Express helpers (app defaults + Host header validation)
- **`@modelcontextprotocol/hono`**: Hono helpers (app defaults + JSON body parsing hook + Host header validation)
## Installation
### Server
```bash
npm install @modelcontextprotocol/server
# or
bun add @modelcontextprotocol/server
# or
deno add npm:@modelcontextprotocol/server
```
### Client
```bash
npm install @modelcontextprotocol/client
# or
bun add @modelcontextprotocol/client
# or
deno add npm:@modelcontextprotocol/client
```
### Optional middleware packages
The SDK also publishes optional “middleware” packages that help you **wire MCP into a specific runtime or web framework** (for example Express, Hono, or Node.js `http`).
These packages are intentionally thin adapters and should not introduce additional MCP features or business logic. See [`packages/middleware/README.md`](packages/middleware/README.md) for details.
```bash
# Node.js HTTP (IncomingMessage/ServerResponse) Streamable HTTP transport:
npm install @modelcontextprotocol/node
# Express integration:
npm install @modelcontextprotocol/express express
# Hono integration:
npm install @modelcontextprotocol/hono hono
```
## Quick Start (runnable examples)
The runnable examples live under `examples/` and are kept in sync with the docs.
1. **Install dependencies** (from repo root):
```bash
pnpm install
```
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
pnpm --filter @modelcontextprotocol/examples-client exec tsx src/simpleStreamableHttp.ts
```
Alternatively, from within the example package:
```bash
cd examples/client
pnpm tsx src/simpleStreamableHttp.ts
```
Next steps:
- 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 MCP servers: transports, tools, resources, prompts, server-initiated requests, and deployment
- [docs/client.md](docs/client.md) – building MCP clients: connecting, tools, resources, prompts, server-initiated requests, and error handling
- [docs/faq.md](docs/faq.md) – frequently asked questions and troubleshooting
- External references:
- [SDK API documentation](https://ts.sdk.modelcontextprotocol.io/)
- [Model Context Protocol documentation](https://modelcontextprotocol.io)
- [MCP Specification](https://spec.modelcontextprotocol.io)
- [Example Servers](https://github.com/modelcontextprotocol/servers)
### Building docs locally
To generate the API reference documentation locally:
```bash
pnpm docs # Generate V2 docs only (output: tmp/docs/)
pnpm docs:multi # Generate combined V1 + V2 docs (output: tmp/docs-combined/)
```
The `docs:multi` script checks out both the `v1.x` and `main` branches via git worktrees, builds each, and produces a combined site with V1 docs at the root and V2 docs under `/v2/`.
## v1 (legacy) documentation and fixes
If you are using the **v1** generation of the SDK, the **v1 API documentation** is available at [`https://ts.sdk.modelcontextprotocol.io/`](https://ts.sdk.modelcontextprotocol.io/). The v1 source code and any v1-specific fixes live on the long-lived
[`v1.x` branch](https://github.com/modelcontextprotocol/typescript-sdk/tree/v1.x). V2 API docs are at [`/v2/`](https://ts.sdk.modelcontextprotocol.io/v2/).
## Contributing
Issues and pull requests are welcome on GitHub at .
## License
This project is licensed under the Apache License 2.0 for new contributions, with existing code under MIT. See the [LICENSE](LICENSE) file for details.