0
# Client API
1
2
Client connects to MCP servers and accesses their resources, tools, and prompts.
3
4
## Creating a Client
5
6
```typescript { .api }
7
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
8
9
constructor(
10
clientInfo: Implementation,
11
options?: {
12
capabilities?: ClientCapabilities;
13
debouncedNotificationMethods?: string[];
14
}
15
);
16
17
interface Implementation { name: string; version: string; }
18
19
interface ClientCapabilities {
20
sampling?: {}; // Handle LLM completion requests from server
21
elicitation?: {}; // Handle user input requests from server
22
roots?: { listChanged?: boolean; }; // Provide root directories/files
23
}
24
```
25
26
### Example
27
28
```typescript
29
const client = new Client(
30
{ name: 'my-client', version: '1.0.0' },
31
{
32
capabilities: {
33
sampling: {},
34
roots: { listChanged: true }
35
}
36
}
37
);
38
```
39
40
## Connecting
41
42
```typescript { .api }
43
async connect(
44
transport: Transport,
45
options?: { timeout?: number; signal?: AbortSignal; }
46
): Promise<void>;
47
```
48
49
### Examples
50
51
```typescript
52
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
53
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
54
55
// Connect via stdio
56
const stdioTransport = new StdioClientTransport({ command: 'node', args: ['server.js'] });
57
await client.connect(stdioTransport);
58
59
// Connect via HTTP
60
const httpTransport = new StreamableHTTPClientTransport(new URL('http://localhost:3000/mcp'));
61
await client.connect(httpTransport);
62
```
63
64
## Tools
65
66
```typescript { .api }
67
async listTools(params?: { cursor?: string }, options?: RequestOptions): Promise<ListToolsResult>;
68
69
async callTool(
70
params: { name: string; arguments?: Record<string, unknown>; },
71
resultSchema?: typeof CallToolResultSchema | typeof CompatibilityCallToolResultSchema,
72
options?: RequestOptions
73
): Promise<CallToolResult>;
74
```
75
76
### Examples
77
78
```typescript
79
// List all tools
80
const { tools, nextCursor } = await client.listTools();
81
console.log(`Found ${tools.length} tools`);
82
tools.forEach(tool => { console.log(`- ${tool.name}: ${tool.description}`); });
83
84
// Call a tool
85
const result = await client.callTool({ name: 'add', arguments: { a: 5, b: 3 } });
86
console.log(result.structuredContent); // { result: 8 }
87
88
// Handle tool errors
89
if (result.isError) {
90
console.error('Tool failed:', result.content[0].text);
91
} else {
92
console.log('Success:', result.content[0].text);
93
}
94
```
95
96
## Resources
97
98
```typescript { .api }
99
async listResources(params?: { cursor?: string }, options?: RequestOptions): Promise<ListResourcesResult>;
100
async listResourceTemplates(params?: { cursor?: string }, options?: RequestOptions): Promise<ListResourceTemplatesResult>;
101
async readResource(params: { uri: string }, options?: RequestOptions): Promise<ReadResourceResult>;
102
async subscribeResource(params: { uri: string }, options?: RequestOptions): Promise<void>;
103
async unsubscribeResource(params: { uri: string }, options?: RequestOptions): Promise<void>;
104
```
105
106
### Examples
107
108
```typescript
109
// List resources
110
const { resources } = await client.listResources();
111
resources.forEach(resource => { console.log(`${resource.name} (${resource.uri})`); });
112
113
// Read a resource
114
const result = await client.readResource({ uri: 'config://app' });
115
const content = result.contents[0];
116
if ('text' in content) { console.log(content.text); }
117
118
// Subscribe to resource updates
119
await client.subscribeResource({ uri: 'config://app' });
120
121
// Handle resource updated notifications
122
client.setNotificationHandler(ResourceUpdatedNotificationSchema, async (notification) => {
123
console.log(`Resource updated: ${notification.params.uri}`);
124
const updated = await client.readResource({ uri: notification.params.uri });
125
});
126
```
127
128
## Prompts
129
130
```typescript { .api }
131
async listPrompts(params?: { cursor?: string }, options?: RequestOptions): Promise<ListPromptsResult>;
132
133
async getPrompt(
134
params: { name: string; arguments?: Record<string, string>; },
135
options?: RequestOptions
136
): Promise<GetPromptResult>;
137
```
138
139
### Examples
140
141
```typescript
142
// List prompts
143
const { prompts } = await client.listPrompts();
144
prompts.forEach(prompt => { console.log(`${prompt.name}: ${prompt.description}`); });
145
146
// Get a prompt
147
const result = await client.getPrompt({
148
name: 'analyze-file',
149
arguments: { filePath: '/path/to/file.ts', analysisType: 'security' }
150
});
151
152
// Use prompt messages with LLM
153
result.messages.forEach(message => { console.log(`${message.role}: ${message.content.text}`); });
154
```
155
156
## Argument Completion
157
158
```typescript { .api }
159
async complete(
160
params: {
161
ref: { type: 'ref/prompt'; name: string } | { type: 'ref/resource'; uri: string };
162
argument: { name: string; value: string; };
163
context?: { arguments?: Record<string, unknown>; };
164
},
165
options?: RequestOptions
166
): Promise<CompleteResult>;
167
```
168
169
### Example
170
171
```typescript
172
const result = await client.complete({
173
ref: { type: 'ref/prompt', name: 'team-greeting' },
174
argument: { name: 'name', value: 'Al' },
175
context: { arguments: { department: 'engineering' } }
176
});
177
178
console.log(result.completion.values); // ['Alice']
179
```
180
181
## Handling Server Requests
182
183
```typescript { .api }
184
setRequestHandler<T extends ZodType<object>>(
185
schema: T,
186
handler: (request: z.infer<T>, extra: RequestHandlerExtra) => Promise<Result>
187
): void;
188
```
189
190
### Examples
191
192
```typescript
193
import { CreateMessageRequestSchema, ElicitRequestSchema } from '@modelcontextprotocol/sdk/types.js';
194
195
// Handle sampling requests (server requesting LLM completion)
196
client.setRequestHandler(CreateMessageRequestSchema, async (request) => {
197
const completion = await myLLM.complete({
198
messages: request.params.messages,
199
maxTokens: request.params.maxTokens
200
});
201
202
return {
203
role: 'assistant',
204
content: { type: 'text', text: completion.text },
205
model: 'my-model',
206
stopReason: 'endTurn'
207
};
208
});
209
210
// Handle elicitation requests (server requesting user input)
211
client.setRequestHandler(ElicitRequestSchema, async (request) => {
212
const userInput = await showInputDialog(request.params.message, request.params.requestedSchema);
213
214
if (userInput.cancelled) {
215
return { action: 'cancel' };
216
}
217
218
return { action: 'accept', content: userInput.data };
219
});
220
```
221
222
## Server Information
223
224
```typescript { .api }
225
getServerCapabilities(): ServerCapabilities | undefined;
226
getServerVersion(): Implementation | undefined;
227
getInstructions(): string | undefined;
228
```
229
230
## Utility Methods
231
232
```typescript { .api }
233
async ping(options?: RequestOptions): Promise<void>;
234
async setLoggingLevel(level: LoggingLevel, options?: RequestOptions): Promise<void>;
235
async sendRootsListChanged(): Promise<void>;
236
async close(): Promise<void>;
237
registerCapabilities(capabilities: ClientCapabilities): void;
238
```
239
240
## Middleware
241
242
```typescript { .api }
243
import { Middleware, withOAuth, withLogging, applyMiddlewares, createMiddleware } from '@modelcontextprotocol/sdk/client/middleware.js';
244
245
type Middleware = (requestInfo: RequestInfo, next: (requestInfo: RequestInfo) => Promise<Response>) => Promise<Response>;
246
247
function withOAuth(provider: OAuthClientProvider, baseUrl?: string | URL): Middleware;
248
function withLogging(options: LoggingOptions): Middleware;
249
function applyMiddlewares(middlewares: Middleware[], fetch: FetchLike): FetchLike;
250
function createMiddleware(fn: (requestInfo: RequestInfo, next: () => Promise<Response>) => Promise<Response>): Middleware;
251
252
interface LoggingOptions {
253
logger: RequestLogger;
254
logRequests?: boolean;
255
logResponses?: boolean;
256
logErrors?: boolean;
257
}
258
259
type RequestLogger = (req: RequestInfo, res?: Response, error?: Error) => void;
260
```
261
262
### Examples
263
264
```typescript
265
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
266
import { withOAuth, withLogging, applyMiddlewares } from '@modelcontextprotocol/sdk/client/middleware.js';
267
268
// OAuth middleware (automatically applied when using authProvider)
269
const transport = new StreamableHTTPClientTransport(
270
new URL('http://localhost:3000/mcp'),
271
{ authProvider: myOAuthProvider }
272
);
273
274
// Custom logging middleware
275
const loggingMiddleware = withLogging({
276
logger: (req, res, error) => {
277
if (error) {
278
console.error('Request failed:', error);
279
} else {
280
console.log(`${req.method} ${req.url} -> ${res?.status}`);
281
}
282
},
283
logRequests: true,
284
logResponses: true,
285
logErrors: true
286
});
287
288
// Custom middleware
289
const customMiddleware = createMiddleware(async (req, next) => {
290
req.headers.set('X-Custom-Header', 'value');
291
const response = await next();
292
console.log('Response status:', response.status);
293
return response;
294
});
295
296
// Apply multiple middlewares
297
const enhancedFetch = applyMiddlewares([loggingMiddleware, customMiddleware], fetch);
298
```
299
300
## Types Reference
301
302
```typescript { .api }
303
interface RequestOptions {
304
timeout?: number; // Default: 60000ms
305
onprogress?: (progress: Progress) => void;
306
signal?: AbortSignal;
307
}
308
309
interface Progress {
310
progress: number;
311
total?: number;
312
}
313
314
interface CallToolResult {
315
content: ContentBlock[];
316
isError?: boolean;
317
structuredContent?: Record<string, unknown>;
318
_meta?: Record<string, unknown>;
319
}
320
321
interface ReadResourceResult {
322
contents: ResourceContents[];
323
_meta?: Record<string, unknown>;
324
}
325
326
interface GetPromptResult {
327
description?: string;
328
messages: PromptMessage[];
329
_meta?: Record<string, unknown>;
330
}
331
332
interface CompleteResult {
333
completion: { values: string[]; total?: number; hasMore?: boolean; };
334
_meta?: Record<string, unknown>;
335
}
336
337
type LoggingLevel = 'debug' | 'info' | 'notice' | 'warning' | 'error' | 'critical' | 'alert' | 'emergency';
338
```
339