1
- import { ProgressCallback , Protocol } from "../shared/protocol.js" ;
1
+ import {
2
+ ProgressCallback ,
3
+ Protocol ,
4
+ ProtocolOptions ,
5
+ } from "../shared/protocol.js" ;
2
6
import { Transport } from "../shared/transport.js" ;
3
7
import {
4
8
CallToolRequest ,
@@ -36,6 +40,13 @@ import {
36
40
UnsubscribeRequest ,
37
41
} from "../types.js" ;
38
42
43
+ export type ClientOptions = ProtocolOptions & {
44
+ /**
45
+ * Capabilities to advertise as being supported by this client.
46
+ */
47
+ capabilities : ClientCapabilities ;
48
+ } ;
49
+
39
50
/**
40
51
* An MCP client on top of a pluggable transport.
41
52
*
@@ -72,15 +83,28 @@ export class Client<
72
83
> {
73
84
private _serverCapabilities ?: ServerCapabilities ;
74
85
private _serverVersion ?: Implementation ;
86
+ private _capabilities : ClientCapabilities ;
75
87
76
88
/**
77
89
* Initializes this client with the given name and version information.
78
90
*/
79
91
constructor (
80
92
private _clientInfo : Implementation ,
81
- private _capabilities : ClientCapabilities ,
93
+ options : ClientOptions ,
82
94
) {
83
- super ( ) ;
95
+ super ( options ) ;
96
+ this . _capabilities = options . capabilities ;
97
+ }
98
+
99
+ protected assertCapability (
100
+ capability : keyof ServerCapabilities ,
101
+ method : string ,
102
+ ) : void {
103
+ if ( ! this . _serverCapabilities ?. [ capability ] ) {
104
+ throw new Error (
105
+ `Server does not support ${ capability } (required for ${ method } )` ,
106
+ ) ;
107
+ }
84
108
}
85
109
86
110
override async connect ( transport : Transport ) : Promise < void > {
@@ -136,14 +160,69 @@ export class Client<
136
160
return this . _serverVersion ;
137
161
}
138
162
139
- private assertCapability (
140
- capability : keyof ServerCapabilities ,
141
- method : string ,
142
- ) {
143
- if ( ! this . _serverCapabilities ?. [ capability ] ) {
144
- throw new Error (
145
- `Server does not support ${ capability } (required for ${ method } )` ,
146
- ) ;
163
+ protected assertCapabilityForMethod ( method : RequestT [ "method" ] ) : void {
164
+ switch ( method as ClientRequest [ "method" ] ) {
165
+ case "logging/setLevel" :
166
+ if ( ! this . _serverCapabilities ?. logging ) {
167
+ throw new Error (
168
+ "Server does not support logging (required for logging/setLevel)" ,
169
+ ) ;
170
+ }
171
+ break ;
172
+
173
+ case "prompts/get" :
174
+ case "prompts/list" :
175
+ if ( ! this . _serverCapabilities ?. prompts ) {
176
+ throw new Error (
177
+ `Server does not support prompts (required for ${ method } )` ,
178
+ ) ;
179
+ }
180
+ break ;
181
+
182
+ case "resources/list" :
183
+ case "resources/templates/list" :
184
+ case "resources/read" :
185
+ case "resources/subscribe" :
186
+ case "resources/unsubscribe" :
187
+ if ( ! this . _serverCapabilities ?. resources ) {
188
+ throw new Error (
189
+ `Server does not support resources (required for ${ method } )` ,
190
+ ) ;
191
+ }
192
+
193
+ if (
194
+ method === "resources/subscribe" &&
195
+ ! this . _serverCapabilities . resources . subscribe
196
+ ) {
197
+ throw new Error ( "Server does not support resource subscriptions" ) ;
198
+ }
199
+
200
+ break ;
201
+
202
+ case "tools/call" :
203
+ case "tools/list" :
204
+ if ( ! this . _serverCapabilities ?. tools ) {
205
+ throw new Error (
206
+ `Server does not support tools (required for ${ method } )` ,
207
+ ) ;
208
+ }
209
+ break ;
210
+
211
+ case "completion/complete" :
212
+ if ( ! this . _serverCapabilities ?. prompts ) {
213
+ throw new Error (
214
+ "Server does not support prompts (required for completion/complete)" ,
215
+ ) ;
216
+ }
217
+ break ;
218
+
219
+ case "initialize" :
220
+ // No specific capability required for initialize
221
+ break ;
222
+
223
+ case "ping" :
224
+ // No specific capability required for ping
225
+ break ;
147
226
}
148
227
}
149
228
@@ -155,7 +234,6 @@ export class Client<
155
234
params : CompleteRequest [ "params" ] ,
156
235
onprogress ?: ProgressCallback ,
157
236
) {
158
- this . assertCapability ( "prompts" , "completion/complete" ) ;
159
237
return this . request (
160
238
{ method : "completion/complete" , params } ,
161
239
CompleteResultSchema ,
@@ -164,7 +242,6 @@ export class Client<
164
242
}
165
243
166
244
async setLoggingLevel ( level : LoggingLevel ) {
167
- this . assertCapability ( "logging" , "logging/setLevel" ) ;
168
245
return this . request (
169
246
{ method : "logging/setLevel" , params : { level } } ,
170
247
EmptyResultSchema ,
@@ -175,7 +252,6 @@ export class Client<
175
252
params : GetPromptRequest [ "params" ] ,
176
253
onprogress ?: ProgressCallback ,
177
254
) {
178
- this . assertCapability ( "prompts" , "prompts/get" ) ;
179
255
return this . request (
180
256
{ method : "prompts/get" , params } ,
181
257
GetPromptResultSchema ,
@@ -187,7 +263,6 @@ export class Client<
187
263
params ?: ListPromptsRequest [ "params" ] ,
188
264
onprogress ?: ProgressCallback ,
189
265
) {
190
- this . assertCapability ( "prompts" , "prompts/list" ) ;
191
266
return this . request (
192
267
{ method : "prompts/list" , params } ,
193
268
ListPromptsResultSchema ,
@@ -199,7 +274,6 @@ export class Client<
199
274
params ?: ListResourcesRequest [ "params" ] ,
200
275
onprogress ?: ProgressCallback ,
201
276
) {
202
- this . assertCapability ( "resources" , "resources/list" ) ;
203
277
return this . request (
204
278
{ method : "resources/list" , params } ,
205
279
ListResourcesResultSchema ,
@@ -211,7 +285,6 @@ export class Client<
211
285
params ?: ListResourceTemplatesRequest [ "params" ] ,
212
286
onprogress ?: ProgressCallback ,
213
287
) {
214
- this . assertCapability ( "resources" , "resources/templates/list" ) ;
215
288
return this . request (
216
289
{ method : "resources/templates/list" , params } ,
217
290
ListResourceTemplatesResultSchema ,
@@ -223,7 +296,6 @@ export class Client<
223
296
params : ReadResourceRequest [ "params" ] ,
224
297
onprogress ?: ProgressCallback ,
225
298
) {
226
- this . assertCapability ( "resources" , "resources/read" ) ;
227
299
return this . request (
228
300
{ method : "resources/read" , params } ,
229
301
ReadResourceResultSchema ,
@@ -232,15 +304,13 @@ export class Client<
232
304
}
233
305
234
306
async subscribeResource ( params : SubscribeRequest [ "params" ] ) {
235
- this . assertCapability ( "resources" , "resources/subscribe" ) ;
236
307
return this . request (
237
308
{ method : "resources/subscribe" , params } ,
238
309
EmptyResultSchema ,
239
310
) ;
240
311
}
241
312
242
313
async unsubscribeResource ( params : UnsubscribeRequest [ "params" ] ) {
243
- this . assertCapability ( "resources" , "resources/unsubscribe" ) ;
244
314
return this . request (
245
315
{ method : "resources/unsubscribe" , params } ,
246
316
EmptyResultSchema ,
@@ -254,7 +324,6 @@ export class Client<
254
324
| typeof CompatibilityCallToolResultSchema = CallToolResultSchema ,
255
325
onprogress ?: ProgressCallback ,
256
326
) {
257
- this . assertCapability ( "tools" , "tools/call" ) ;
258
327
return this . request (
259
328
{ method : "tools/call" , params } ,
260
329
resultSchema ,
@@ -266,7 +335,6 @@ export class Client<
266
335
params ?: ListToolsRequest [ "params" ] ,
267
336
onprogress ?: ProgressCallback ,
268
337
) {
269
- this . assertCapability ( "tools" , "tools/list" ) ;
270
338
return this . request (
271
339
{ method : "tools/list" , params } ,
272
340
ListToolsResultSchema ,
0 commit comments