README refactor (#1197)
This commit is contained in:
parent
ace9b62d3c
commit
74ab69ffa0
6 changed files with 486 additions and 1793 deletions
81
docs/capabilities.md
Normal file
81
docs/capabilities.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
## Sampling
|
||||
|
||||
MCP servers can request LLM completions from connected clients that support the sampling capability. This lets your tools offload summarisation or generation to the client’s model.
|
||||
|
||||
For a runnable server that combines tools, logging and tasks, see:
|
||||
|
||||
- [`toolWithSampleServer.ts`](../src/examples/server/toolWithSampleServer.ts)
|
||||
|
||||
In practice you will:
|
||||
|
||||
- Declare the sampling capability on the client.
|
||||
- Call `server.server.createMessage(...)` from within a tool handler.
|
||||
- Return the model’s response as structured content and/or text.
|
||||
|
||||
Refer to the MCP spec’s sampling section for full request/response details.
|
||||
|
||||
## Elicitation
|
||||
|
||||
### Form elicitation
|
||||
|
||||
Form elicitation lets a tool ask the user for additional, **non‑sensitive** information via a schema‑driven form. The server sends a schema and message, and the client is responsible for collecting and returning the data.
|
||||
|
||||
Runnable example:
|
||||
|
||||
- Server: [`elicitationFormExample.ts`](../src/examples/server/elicitationFormExample.ts)
|
||||
- Client‑side handling: [`simpleStreamableHttp.ts`](../src/examples/client/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.
|
||||
|
||||
### URL elicitation
|
||||
|
||||
URL elicitation is designed for sensitive data and secure web‑based flows (e.g., collecting an API key, confirming a payment, or doing third‑party OAuth). Instead of returning form data, the server asks the client to open a URL and the rest of the flow happens in the browser.
|
||||
|
||||
Runnable example:
|
||||
|
||||
- Server: [`elicitationUrlExample.ts`](../src/examples/server/elicitationUrlExample.ts)
|
||||
- Client: [`elicitationUrlExample.ts`](../src/examples/client/elicitationUrlExample.ts)
|
||||
|
||||
Key points:
|
||||
|
||||
- Use `mode: 'url'` when calling `server.server.elicitInput(...)`.
|
||||
- Implement a client‑side handler for `ElicitRequestSchema` that:
|
||||
- Shows the full URL and reason to the user.
|
||||
- Asks for explicit consent.
|
||||
- Opens the URL in the system browser.
|
||||
|
||||
Sensitive information **must not** be collected via form elicitation; always use URL elicitation or out‑of‑band flows for secrets.
|
||||
|
||||
## Task-based execution (experimental)
|
||||
|
||||
Task-based execution enables “call-now, fetch-later” patterns for long-running operations. Instead of returning a result immediately, a tool creates a task that can be polled or resumed later.
|
||||
|
||||
The APIs live under the experimental `.experimental.tasks` namespace and may change without notice.
|
||||
|
||||
### Server-side concepts
|
||||
|
||||
On the server you will:
|
||||
|
||||
- Provide a `TaskStore` implementation that persists task metadata and results.
|
||||
- Enable the `tasks` capability when constructing the server.
|
||||
- Register tools with `server.experimental.tasks.registerToolTask(...)`.
|
||||
|
||||
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`
|
||||
|
||||
### Client-side usage
|
||||
|
||||
On the client, you use:
|
||||
|
||||
- `client.experimental.tasks.callToolStream(...)` to start a tool call that may create a task and emit status updates over time.
|
||||
- `client.getTask(...)` and `client.getTaskResult(...)` to check status and fetch results after reconnecting.
|
||||
|
||||
The interactive client in:
|
||||
|
||||
- [`simpleStreamableHttp.ts`](../src/examples/client/simpleStreamableHttp.ts)
|
||||
|
||||
includes commands to demonstrate calling tools that support tasks and handling their lifecycle.
|
||||
|
||||
See the MCP spec’s tasks section and the example server/client above for a full walkthrough of the task status lifecycle and TTL handling.
|
||||
60
docs/client.md
Normal file
60
docs/client.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
## Client overview
|
||||
|
||||
The SDK provides a high-level `Client` class that connects to MCP servers over different transports:
|
||||
|
||||
- `StdioClientTransport` – for local processes you spawn.
|
||||
- `StreamableHTTPClientTransport` – for remote HTTP servers.
|
||||
- `SSEClientTransport` – for legacy HTTP+SSE servers (deprecated).
|
||||
|
||||
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)
|
||||
|
||||
## Connecting and basic operations
|
||||
|
||||
A typical flow:
|
||||
|
||||
1. Construct a `Client` with name, version and capabilities.
|
||||
2. Create a transport and call `client.connect(transport)`.
|
||||
3. Use high-level helpers:
|
||||
- `listTools`, `callTool`
|
||||
- `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.
|
||||
|
||||
## Transports and backwards compatibility
|
||||
|
||||
To support both modern Streamable HTTP and legacy SSE servers, use a client that:
|
||||
|
||||
1. Tries `StreamableHTTPClientTransport`.
|
||||
2. Falls back to `SSEClientTransport` on a 4xx response.
|
||||
|
||||
Runnable example:
|
||||
|
||||
- [`streamableHttpWithSseFallbackClient.ts`](../src/examples/client/streamableHttpWithSseFallbackClient.ts)
|
||||
|
||||
## OAuth client authentication helpers
|
||||
|
||||
For OAuth-secured MCP servers, the client `auth` module exposes:
|
||||
|
||||
- `ClientCredentialsProvider`
|
||||
- `PrivateKeyJwtProvider`
|
||||
- `StaticPrivateKeyJwtProvider`
|
||||
|
||||
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)
|
||||
|
||||
These examples show how to:
|
||||
|
||||
- Perform dynamic client registration if needed.
|
||||
- Acquire access tokens.
|
||||
- Attach OAuth credentials to Streamable HTTP requests.
|
||||
65
docs/faq.md
Normal file
65
docs/faq.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
## FAQ
|
||||
|
||||
<details>
|
||||
<summary>Table of Contents</summary>
|
||||
|
||||
- [General](#general)
|
||||
- [Clients](#clients)
|
||||
- [Servers](#servers)
|
||||
|
||||
</details>
|
||||
|
||||
## General
|
||||
|
||||
### 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.
|
||||
|
||||
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).
|
||||
|
||||
To diagnose and fix this:
|
||||
|
||||
- **Inspect your installed `zod` versions**:
|
||||
- Run `npm ls zod` or `npm explain zod`, `pnpm list zod` or `pnpm why zod`, or `yarn why zod` and check whether more than one version is installed.
|
||||
- **Align on a single `zod` version**:
|
||||
- Make sure all packages that depend on `zod` use a compatible version range so that your package manager can hoist a single copy.
|
||||
- In monorepos, consider declaring `zod` at the workspace root and using compatible ranges in individual packages.
|
||||
- **Use overrides/resolutions if necessary**:
|
||||
- With npm, Yarn, or pnpm, you can use `overrides` / `resolutions` to force a single `zod` version if some transitive dependencies pull in a different one.
|
||||
|
||||
Once your project is using a single, compatible `zod` version, the `TS2589` error should no longer occur.
|
||||
|
||||
## Clients
|
||||
|
||||
### 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.
|
||||
|
||||
- **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 )
|
||||
|
||||
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`:
|
||||
|
||||
```typescript
|
||||
import { webcrypto } from 'node:crypto';
|
||||
|
||||
if (typeof globalThis.crypto === 'undefined') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(globalThis as any).crypto = webcrypto as unknown as Crypto;
|
||||
}
|
||||
```
|
||||
|
||||
For production use, you can either:
|
||||
|
||||
- Run clients on a Node.js version where `globalThis.crypto` is available by default (recommended), or
|
||||
- Apply a similar polyfill early in your client's startup code when targeting older Node.js runtimes, so that OAuth client authentication works reliably.
|
||||
|
||||
## Servers
|
||||
|
||||
### 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.
|
||||
198
docs/server.md
Normal file
198
docs/server.md
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
## 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:
|
||||
|
||||
- **Streamable HTTP** (recommended for remote servers)
|
||||
- **HTTP + SSE** (deprecated, for backwards compatibility only)
|
||||
- **stdio** (for local, process‑spawned integrations)
|
||||
|
||||
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
|
||||
|
||||
## Transports
|
||||
|
||||
### Streamable HTTP
|
||||
|
||||
Streamable HTTP is the modern, fully featured transport. It supports:
|
||||
|
||||
- Request/response over HTTP POST
|
||||
- Server‑to‑client notifications over SSE (when enabled)
|
||||
- Optional JSON‑only response mode with no SSE
|
||||
- Session management and resumability
|
||||
|
||||
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
|
||||
|
||||
See the MCP spec for full transport details:
|
||||
`https://modelcontextprotocol.io/specification/2025-03-26/basic/transports`
|
||||
|
||||
### Stateless vs stateful sessions
|
||||
|
||||
Streamable HTTP can run:
|
||||
|
||||
- **Stateless** – no session tracking, ideal for simple API‑style servers.
|
||||
- **Stateful** – sessions have IDs, and you can enable resumability and advanced features.
|
||||
|
||||
Examples:
|
||||
|
||||
- Stateless Streamable HTTP: [`simpleStatelessStreamableHttp.ts`](../src/examples/server/simpleStatelessStreamableHttp.ts)
|
||||
- Stateful with resumability: [`simpleStreamableHttp.ts`](../src/examples/server/simpleStreamableHttp.ts)
|
||||
|
||||
### Deprecated HTTP + SSE
|
||||
|
||||
The older HTTP+SSE transport (protocol version 2024‑11‑05) is supported only for backwards compatibility. New implementations should prefer Streamable HTTP.
|
||||
|
||||
Examples:
|
||||
|
||||
- Legacy SSE server: [`simpleSseServer.ts`](../src/examples/server/simpleSseServer.ts)
|
||||
- Backwards‑compatible server (Streamable HTTP + SSE):
|
||||
[`sseAndStreamableHttpCompatibleServer.ts`](../src/examples/server/sseAndStreamableHttpCompatibleServer.ts)
|
||||
|
||||
## Running your server
|
||||
|
||||
For a minimal “getting started” experience:
|
||||
|
||||
1. Start from [`simpleStreamableHttp.ts`](../src/examples/server/simpleStreamableHttp.ts).
|
||||
2. Remove features you do not need (tasks, advanced logging, OAuth, etc.).
|
||||
3. Register your own tools, resources and prompts.
|
||||
|
||||
For more detailed patterns (stateless vs stateful, JSON response mode, CORS, DNS rebind protection), see the examples above and the MCP spec sections on transports.
|
||||
|
||||
## Tools, resources, and prompts
|
||||
|
||||
### Tools
|
||||
|
||||
Tools let MCP clients ask your server to take actions. They are usually the main way that LLMs call into your application.
|
||||
|
||||
A typical registration with `registerTool` looks like this:
|
||||
|
||||
```typescript
|
||||
server.registerTool(
|
||||
'calculate-bmi',
|
||||
{
|
||||
title: 'BMI Calculator',
|
||||
description: 'Calculate Body Mass Index',
|
||||
inputSchema: {
|
||||
weightKg: z.number(),
|
||||
heightM: z.number()
|
||||
},
|
||||
outputSchema: { bmi: z.number() }
|
||||
},
|
||||
async ({ weightKg, heightM }) => {
|
||||
const output = { bmi: weightKg / (heightM * heightM) };
|
||||
return {
|
||||
content: [{ type: 'text', text: JSON.stringify(output) }],
|
||||
structuredContent: output
|
||||
};
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
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)
|
||||
|
||||
#### 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`.
|
||||
|
||||
### Resources
|
||||
|
||||
Resources expose data to clients, but should not perform heavy computation or side‑effects. They are ideal for configuration, documents, or other reference data.
|
||||
|
||||
Conceptually, you might register resources like:
|
||||
|
||||
```typescript
|
||||
server.registerResource(
|
||||
'config',
|
||||
'config://app',
|
||||
{
|
||||
title: 'Application Config',
|
||||
description: 'Application configuration data',
|
||||
mimeType: 'text/plain'
|
||||
},
|
||||
async uri => ({
|
||||
contents: [{ uri: uri.href, text: 'App configuration here' }]
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
Dynamic resources use `ResourceTemplate` and can support completions on path parameters. For full runnable examples of resources:
|
||||
|
||||
- [`simpleStreamableHttp.ts`](../src/examples/server/simpleStreamableHttp.ts)
|
||||
|
||||
### Prompts
|
||||
|
||||
Prompts are reusable templates that help humans (or client UIs) talk to models in a consistent way. They are declared on the server and listed through MCP.
|
||||
|
||||
A minimal prompt:
|
||||
|
||||
```typescript
|
||||
server.registerPrompt(
|
||||
'review-code',
|
||||
{
|
||||
title: 'Code Review',
|
||||
description: 'Review code for best practices and potential issues',
|
||||
argsSchema: { code: z.string() }
|
||||
},
|
||||
({ code }) => ({
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: {
|
||||
type: 'text',
|
||||
text: `Please review this code:\n\n${code}`
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
For prompts integrated into a full server, see:
|
||||
|
||||
- [`simpleStreamableHttp.ts`](../src/examples/server/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.
|
||||
|
||||
### 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`
|
||||
|
||||
## 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):
|
||||
|
||||
- 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.
|
||||
|
||||
## Backwards compatibility
|
||||
|
||||
To handle both modern and legacy clients:
|
||||
|
||||
- Run a backwards‑compatible server:
|
||||
- [`sseAndStreamableHttpCompatibleServer.ts`](../src/examples/server/sseAndStreamableHttpCompatibleServer.ts)
|
||||
- Use a client that falls back from Streamable HTTP to SSE:
|
||||
- [`streamableHttpWithSseFallbackClient.ts`](../src/examples/client/streamableHttpWithSseFallbackClient.ts)
|
||||
|
||||
For the detailed protocol rules, see the “Backwards compatibility” section of the MCP spec.
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# MCP TypeScript SDK Examples
|
||||
|
||||
This directory contains example implementations of MCP clients and servers using the TypeScript SDK.
|
||||
This directory contains example implementations of MCP clients and servers using the TypeScript SDK. For a high-level index of scenarios and where they live, see the **Examples** table in the root `README.md`.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue