typescript-sdk

GitHub

The official TypeScript SDK for Model Context Protocol servers and clients

AI Prompts & Endpoints

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

text
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. For v2 API docs, see /v2/.

!NPM Version !NPM Version !MIT licensed

<details>
<summary>Table of Contents</summary>

- Overview
- Packages
- Installation
- Quick Start (runnable examples)
- Documentation
- Contributing
- License

</details>

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/)

Packages

This monorepo publishes split packages:

- @modelcontextprotocol/server: build MCP servers
-
@modelcontextprotocol/client: build MCP clients

Tool and prompt schemas use Standard Schema β€” bring Zod v4, Valibot, ArkType, or any compatible library.

Middleware packages (optional)

The SDK also publishes small "middleware" packages under 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 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 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
- Client examples index:
examples/client/README.md
- Guided walkthroughs:
docs/server.md and docs/client.md

Documentation

- Local SDK docs:
- docs/server.md – building MCP servers: transports, tools, resources, prompts, server-initiated requests, and deployment
- docs/client.md – building MCP clients: connecting, tools, resources, prompts, server-initiated requests, and error handling
- docs/faq.md – frequently asked questions and troubleshooting
- External references:
- SDK API documentation
- Model Context Protocol documentation
- MCP Specification
- Example 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/. The v1 source code and any v1-specific fixes live on the long-lived
v1.x branch. V2 API docs are at /v2/`.

Contributing

Issues and pull requests are welcome on GitHub at <https://github.com/modelcontextprotocol/typescript-sdk>.

License

This project is licensed under the Apache License 2.0 for new contributions, with existing code under MIT. See the LICENSE file for details.