@opentiny/next-sdk 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/WebMcpClient.ts +522 -0
- package/WebMcpServer.ts +440 -0
- package/agent/AgentModelProvider.ts +88 -0
- package/agent/type.ts +30 -0
- package/agent/utils/aiProviderFactories.ts +7 -0
- package/agent/utils/index.ts +44 -0
- package/dist/agent/AgentModelProvider.d.ts +18 -0
- package/dist/agent/AgentModelProvider.js +87 -0
- package/dist/agent/type.d.ts +32 -0
- package/dist/agent/type.js +1 -0
- package/dist/agent/utils/aiProviderFactories.d.ts +6 -0
- package/dist/agent/utils/aiProviderFactories.js +6 -0
- package/dist/agent/utils/index.d.ts +8 -0
- package/dist/agent/utils/index.js +43 -0
- package/dist/index.cjs.js +83 -0
- package/{index.d.ts → dist/index.d.ts} +1 -0
- package/dist/index.es.js +29673 -0
- package/{index.js → dist/index.js} +1 -0
- package/dist/index.umd.js +83 -0
- package/index.ts +19 -0
- package/package.json +33 -20
- package/tsconfig.json +14 -0
- package/vite.config.ts +18 -0
- /package/{WebMcpClient.d.ts → dist/WebMcpClient.d.ts} +0 -0
- /package/{WebMcpClient.js → dist/WebMcpClient.js} +0 -0
- /package/{WebMcpServer.d.ts → dist/WebMcpServer.d.ts} +0 -0
- /package/{WebMcpServer.js → dist/WebMcpServer.js} +0 -0
package/WebMcpClient.ts
ADDED
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
|
|
2
|
+
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'
|
|
3
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
|
|
4
|
+
import { z, ZodObject, ZodLiteral, ZodType } from 'zod'
|
|
5
|
+
import {
|
|
6
|
+
ElicitRequestSchema,
|
|
7
|
+
CallToolResultSchema,
|
|
8
|
+
ListRootsRequestSchema,
|
|
9
|
+
CreateMessageRequestSchema,
|
|
10
|
+
LoggingMessageNotificationSchema,
|
|
11
|
+
ToolListChangedNotificationSchema,
|
|
12
|
+
ResourceUpdatedNotificationSchema,
|
|
13
|
+
PromptListChangedNotificationSchema,
|
|
14
|
+
ResourceListChangedNotificationSchema
|
|
15
|
+
} from '@modelcontextprotocol/sdk/types.js'
|
|
16
|
+
import {
|
|
17
|
+
MessageChannelClientTransport,
|
|
18
|
+
sseOptions,
|
|
19
|
+
streamOptions,
|
|
20
|
+
attemptConnection,
|
|
21
|
+
createStreamProxy,
|
|
22
|
+
createSseProxy,
|
|
23
|
+
AuthClientProvider
|
|
24
|
+
} from '@opentiny/next'
|
|
25
|
+
import type {
|
|
26
|
+
Result,
|
|
27
|
+
Request,
|
|
28
|
+
Notification,
|
|
29
|
+
Implementation,
|
|
30
|
+
ServerCapabilities,
|
|
31
|
+
ClientCapabilities,
|
|
32
|
+
LoggingLevel,
|
|
33
|
+
CompleteRequest,
|
|
34
|
+
CallToolRequest,
|
|
35
|
+
ListToolsRequest,
|
|
36
|
+
GetPromptRequest,
|
|
37
|
+
SubscribeRequest,
|
|
38
|
+
UnsubscribeRequest,
|
|
39
|
+
ListPromptsRequest,
|
|
40
|
+
ReadResourceRequest,
|
|
41
|
+
ListResourcesRequest,
|
|
42
|
+
ListResourceTemplatesRequest
|
|
43
|
+
} from '@modelcontextprotocol/sdk/types.js'
|
|
44
|
+
import type { ProxyOptions } from '@opentiny/next'
|
|
45
|
+
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'
|
|
46
|
+
import type { ClientOptions } from '@modelcontextprotocol/sdk/client/index.js'
|
|
47
|
+
import type { SSEClientTransportOptions } from '@modelcontextprotocol/sdk/client/sse.js'
|
|
48
|
+
import type { StreamableHTTPClientTransportOptions } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
|
|
49
|
+
import type {
|
|
50
|
+
RequestOptions,
|
|
51
|
+
NotificationOptions,
|
|
52
|
+
RequestHandlerExtra
|
|
53
|
+
} from '@modelcontextprotocol/sdk/shared/protocol.js'
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Options for configuring the server transport.
|
|
57
|
+
*/
|
|
58
|
+
export interface ClientConnectOptions {
|
|
59
|
+
url: string
|
|
60
|
+
token?: string
|
|
61
|
+
sessionId?: string
|
|
62
|
+
authProvider?: AuthClientProvider
|
|
63
|
+
type?: 'channel' | 'sse'
|
|
64
|
+
agent?: boolean
|
|
65
|
+
onError?: (error: Error) => void
|
|
66
|
+
onUnauthorized?: (connect: () => Promise<void>) => Promise<void>
|
|
67
|
+
onReconnect?: () => Promise<void>
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
type SendRequestT = Request
|
|
71
|
+
type SendNotificationT = Notification
|
|
72
|
+
type SendResultT = Result
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* An MCP client on top of a pluggable transport.
|
|
76
|
+
* The client will automatically begin the initialization flow with the server when connect() is called.
|
|
77
|
+
*/
|
|
78
|
+
export class WebMcpClient {
|
|
79
|
+
public readonly client: Client
|
|
80
|
+
public transport: Transport | undefined
|
|
81
|
+
|
|
82
|
+
constructor(clientInfo: Implementation, options?: ClientOptions) {
|
|
83
|
+
const info: Implementation = {
|
|
84
|
+
name: 'web-mcp-client',
|
|
85
|
+
version: '1.0.0'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const capabilities: ClientCapabilities = {
|
|
89
|
+
roots: { listChanged: true },
|
|
90
|
+
sampling: {},
|
|
91
|
+
elicitation: {}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
this.client = new Client(clientInfo || info, options || { capabilities })
|
|
95
|
+
|
|
96
|
+
this.client.onclose = () => {
|
|
97
|
+
this.onclose?.()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.client.onerror = (error: Error) => {
|
|
101
|
+
this.onerror?.(error)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Connects the client to a transport via the specified option.
|
|
107
|
+
*/
|
|
108
|
+
async connect(options: Transport | ClientConnectOptions): Promise<{ transport: Transport; sessionId: string }> {
|
|
109
|
+
if (typeof (options as Transport)['start'] === 'function') {
|
|
110
|
+
this.transport = options as Transport
|
|
111
|
+
this.transport.onclose = undefined
|
|
112
|
+
this.transport.onerror = undefined
|
|
113
|
+
this.transport.onmessage = undefined
|
|
114
|
+
await this.client.connect(this.transport)
|
|
115
|
+
return { transport: this.transport, sessionId: this.transport.sessionId as string }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const { url, token, sessionId, authProvider, type, agent, onError, onUnauthorized, onReconnect } =
|
|
119
|
+
options as ClientConnectOptions
|
|
120
|
+
|
|
121
|
+
if (agent === true) {
|
|
122
|
+
const proxyOptions: ProxyOptions = { client: this.client, url, token, sessionId, authProvider }
|
|
123
|
+
|
|
124
|
+
let reconnect = false
|
|
125
|
+
let response
|
|
126
|
+
|
|
127
|
+
const connectProxy = async () => {
|
|
128
|
+
const { transport, sessionId } =
|
|
129
|
+
type === 'sse' ? await createSseProxy(proxyOptions) : await createStreamProxy(proxyOptions)
|
|
130
|
+
|
|
131
|
+
transport.onerror = async (error: Error) => {
|
|
132
|
+
onError?.(error)
|
|
133
|
+
|
|
134
|
+
if (error.message === 'Unauthorized' && !reconnect) {
|
|
135
|
+
if (typeof onUnauthorized === 'function') {
|
|
136
|
+
await onUnauthorized(connectProxy)
|
|
137
|
+
} else {
|
|
138
|
+
reconnect = true
|
|
139
|
+
await connectProxy()
|
|
140
|
+
reconnect = false
|
|
141
|
+
await onReconnect?.()
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
response = { transport, sessionId }
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
await connectProxy()
|
|
150
|
+
return response as unknown as { transport: Transport; sessionId: string }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const endpoint = new URL(url)
|
|
154
|
+
let transport: Transport | undefined
|
|
155
|
+
|
|
156
|
+
if (type === 'channel') {
|
|
157
|
+
transport = new MessageChannelClientTransport(url)
|
|
158
|
+
await this.client.connect(transport)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (type === 'sse') {
|
|
162
|
+
if (authProvider) {
|
|
163
|
+
const createTransport = () => new SSEClientTransport(endpoint, { authProvider })
|
|
164
|
+
transport = await attemptConnection(this.client, authProvider.waitForOAuthCode, createTransport)
|
|
165
|
+
} else {
|
|
166
|
+
const opts = sseOptions(token, sessionId) as SSEClientTransportOptions
|
|
167
|
+
transport = new SSEClientTransport(endpoint, opts)
|
|
168
|
+
await this.client.connect(transport)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (typeof transport === 'undefined') {
|
|
173
|
+
if (authProvider) {
|
|
174
|
+
const createTransport = () => new StreamableHTTPClientTransport(endpoint, { authProvider })
|
|
175
|
+
transport = await attemptConnection(this.client, authProvider.waitForOAuthCode, createTransport)
|
|
176
|
+
} else {
|
|
177
|
+
const opts = streamOptions(token, sessionId) as StreamableHTTPClientTransportOptions
|
|
178
|
+
transport = new StreamableHTTPClientTransport(endpoint, opts)
|
|
179
|
+
await this.client.connect(transport)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
this.transport = transport
|
|
184
|
+
return { transport: this.transport, sessionId: this.transport.sessionId as string }
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Callback for when the connection is closed for any reason.
|
|
189
|
+
*
|
|
190
|
+
* This is invoked when close() is called as well.
|
|
191
|
+
*/
|
|
192
|
+
onclose?: () => void
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Callback for when an error occurs.
|
|
196
|
+
*
|
|
197
|
+
* Note that errors are not necessarily fatal; they are used for reporting any kind of exceptional condition out of band.
|
|
198
|
+
*/
|
|
199
|
+
onerror?: (error: Error) => void
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Closes the connection.
|
|
203
|
+
*/
|
|
204
|
+
async close(): Promise<void> {
|
|
205
|
+
await this.client.close()
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* After initialization has completed, this will be populated with the server's reported capabilities.
|
|
210
|
+
*/
|
|
211
|
+
getServerCapabilities(): ServerCapabilities | undefined {
|
|
212
|
+
return this.client.getServerCapabilities()
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* After initialization has completed, this will be populated with information about the server's name and version.
|
|
217
|
+
*/
|
|
218
|
+
getServerVersion(): Implementation | undefined {
|
|
219
|
+
return this.client.getServerVersion()
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* After initialization has completed, this may be populated with information about the server's instructions.
|
|
224
|
+
*/
|
|
225
|
+
getInstructions(): string | undefined {
|
|
226
|
+
return this.client.getInstructions()
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Sends a ping to the server to check if it is still connected.
|
|
231
|
+
*/
|
|
232
|
+
async ping(options?: RequestOptions) {
|
|
233
|
+
return await this.client.ping(options)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Sends a completion request to the server.
|
|
238
|
+
*/
|
|
239
|
+
async complete(params: CompleteRequest['params'], options?: RequestOptions) {
|
|
240
|
+
return await this.client.complete(params, options)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Sends a request for setting the logging level to the server.
|
|
245
|
+
*/
|
|
246
|
+
async setLoggingLevel(level: LoggingLevel, options?: RequestOptions) {
|
|
247
|
+
return await this.client.setLoggingLevel(level, options)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Gets the prompt with the given params from the server.
|
|
252
|
+
*/
|
|
253
|
+
async getPrompt(params: GetPromptRequest['params'], options?: RequestOptions) {
|
|
254
|
+
return await this.client.getPrompt(params, options)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Lists all prompts available on the server.
|
|
259
|
+
*/
|
|
260
|
+
async listPrompts(params?: ListPromptsRequest['params'], options?: RequestOptions) {
|
|
261
|
+
return await this.client.listPrompts(params, options)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Lists all resources available on the server.
|
|
266
|
+
*/
|
|
267
|
+
async listResources(params?: ListResourcesRequest['params'], options?: RequestOptions) {
|
|
268
|
+
return await this.client.listResources(params, options)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Lists all resource templates available on the server.
|
|
273
|
+
*/
|
|
274
|
+
async listResourceTemplates(params?: ListResourceTemplatesRequest['params'], options?: RequestOptions) {
|
|
275
|
+
return await this.client.listResourceTemplates(params, options)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Reads the resource with the given params from the server.
|
|
280
|
+
*/
|
|
281
|
+
async readResource(params: ReadResourceRequest['params'], options?: RequestOptions) {
|
|
282
|
+
return await this.client.readResource(params, options)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Subscribes to a resource on the server.
|
|
287
|
+
*/
|
|
288
|
+
async subscribeResource(params: SubscribeRequest['params'], options?: RequestOptions) {
|
|
289
|
+
return await this.client.subscribeResource(params, options)
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Unsubscribes from a resource on the server.
|
|
294
|
+
*/
|
|
295
|
+
async unsubscribeResource(params: UnsubscribeRequest['params'], options?: RequestOptions) {
|
|
296
|
+
return await this.client.unsubscribeResource(params, options)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Calls a tool on the server with the given parameters.
|
|
301
|
+
*/
|
|
302
|
+
async callTool(params: CallToolRequest['params'], options?: RequestOptions) {
|
|
303
|
+
return await this.client.callTool(params, CallToolResultSchema, options)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Lists all tools available on the server.
|
|
308
|
+
*/
|
|
309
|
+
async listTools(params?: ListToolsRequest['params'], options?: RequestOptions) {
|
|
310
|
+
return await this.client.listTools(params, options)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Sends a notification for the roots list changed event to the server.
|
|
315
|
+
*/
|
|
316
|
+
async sendRootsListChanged() {
|
|
317
|
+
return await this.client.sendRootsListChanged()
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Sends a request and wait for a response.
|
|
322
|
+
*
|
|
323
|
+
* Do not use this method to emit notifications! Use notification() instead.
|
|
324
|
+
*/
|
|
325
|
+
request<T extends ZodType<object>>(
|
|
326
|
+
request: SendRequestT,
|
|
327
|
+
resultSchema: T,
|
|
328
|
+
options?: RequestOptions
|
|
329
|
+
): Promise<z.infer<T>> {
|
|
330
|
+
return this.client.request(request, resultSchema, options)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Emits a notification, which is a one-way message that does not expect a response.
|
|
335
|
+
*/
|
|
336
|
+
async notification(notification: SendNotificationT, options?: NotificationOptions): Promise<void> {
|
|
337
|
+
return await this.client.notification(notification, options)
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Registers a handler to invoke when this protocol object receives a request with the given method.
|
|
342
|
+
*
|
|
343
|
+
* Note that this will replace any previous request handler for the same method.
|
|
344
|
+
*/
|
|
345
|
+
setRequestHandler<
|
|
346
|
+
T extends ZodObject<{
|
|
347
|
+
method: ZodLiteral<string>
|
|
348
|
+
}>
|
|
349
|
+
>(
|
|
350
|
+
requestSchema: T,
|
|
351
|
+
handler: (
|
|
352
|
+
request: z.infer<T>,
|
|
353
|
+
extra: RequestHandlerExtra<SendRequestT, SendNotificationT>
|
|
354
|
+
) => SendResultT | Promise<SendResultT>
|
|
355
|
+
): void {
|
|
356
|
+
this.client.setRequestHandler(requestSchema, handler)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Removes the request handler for the given method.
|
|
361
|
+
*/
|
|
362
|
+
removeRequestHandler(method: string): void {
|
|
363
|
+
this.client.removeRequestHandler(method)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Registers a handler to invoke when this protocol object receives a notification with the given method.
|
|
368
|
+
*
|
|
369
|
+
* Note that this will replace any previous notification handler for the same method.
|
|
370
|
+
*/
|
|
371
|
+
setNotificationHandler<
|
|
372
|
+
T extends ZodObject<{
|
|
373
|
+
method: ZodLiteral<string>
|
|
374
|
+
}>
|
|
375
|
+
>(notificationSchema: T, handler: (notification: z.infer<T>) => void | Promise<void>): void {
|
|
376
|
+
this.client.setNotificationHandler(notificationSchema, handler)
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Removes the notification handler for the given method.
|
|
381
|
+
*/
|
|
382
|
+
removeNotificationHandler(method: string): void {
|
|
383
|
+
this.client.removeNotificationHandler(method)
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Registers a handler for the elicitation request.
|
|
388
|
+
*/
|
|
389
|
+
onElicit(
|
|
390
|
+
handler: (
|
|
391
|
+
request: z.infer<typeof ElicitRequestSchema>,
|
|
392
|
+
extra: RequestHandlerExtra<SendRequestT, SendNotificationT>
|
|
393
|
+
) => SendResultT | Promise<SendResultT>
|
|
394
|
+
): void {
|
|
395
|
+
this.client.setRequestHandler(ElicitRequestSchema, handler)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Registers a handler for the create LLM message request.
|
|
400
|
+
*/
|
|
401
|
+
onCreateMessage(
|
|
402
|
+
handler: (
|
|
403
|
+
request: z.infer<typeof CreateMessageRequestSchema>,
|
|
404
|
+
extra: RequestHandlerExtra<SendRequestT, SendNotificationT>
|
|
405
|
+
) => SendResultT | Promise<SendResultT>
|
|
406
|
+
): void {
|
|
407
|
+
this.client.setRequestHandler(CreateMessageRequestSchema, handler)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Registers a handler for the list roots request.
|
|
412
|
+
*/
|
|
413
|
+
onListRoots(
|
|
414
|
+
handler: (
|
|
415
|
+
request: z.infer<typeof ListRootsRequestSchema>,
|
|
416
|
+
extra: RequestHandlerExtra<SendRequestT, SendNotificationT>
|
|
417
|
+
) => SendResultT | Promise<SendResultT>
|
|
418
|
+
): void {
|
|
419
|
+
this.client.setRequestHandler(ListRootsRequestSchema, handler)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Registers a handler for the tool list changed notification.
|
|
424
|
+
*/
|
|
425
|
+
onToolListChanged(
|
|
426
|
+
handler: (notification: z.infer<typeof ToolListChangedNotificationSchema>) => void | Promise<void>
|
|
427
|
+
): void {
|
|
428
|
+
this.client.setNotificationHandler(ToolListChangedNotificationSchema, handler)
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Registers a handler for the prompt list changed notification.
|
|
433
|
+
*/
|
|
434
|
+
onPromptListChanged(
|
|
435
|
+
handler: (notification: z.infer<typeof PromptListChangedNotificationSchema>) => void | Promise<void>
|
|
436
|
+
): void {
|
|
437
|
+
this.client.setNotificationHandler(PromptListChangedNotificationSchema, handler)
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Registers a handler for the resource list changed notification.
|
|
442
|
+
*/
|
|
443
|
+
onResourceListChanged(
|
|
444
|
+
handler: (notification: z.infer<typeof ResourceListChangedNotificationSchema>) => void | Promise<void>
|
|
445
|
+
): void {
|
|
446
|
+
this.client.setNotificationHandler(ResourceListChangedNotificationSchema, handler)
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Registers a handler for the resource updated notification.
|
|
451
|
+
*/
|
|
452
|
+
onResourceUpdated(
|
|
453
|
+
handler: (notification: z.infer<typeof ResourceUpdatedNotificationSchema>) => void | Promise<void>
|
|
454
|
+
): void {
|
|
455
|
+
this.client.setNotificationHandler(ResourceUpdatedNotificationSchema, handler)
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Registers a handler for the logging message notification.
|
|
460
|
+
*/
|
|
461
|
+
onLoggingMessage(
|
|
462
|
+
handler: (notification: z.infer<typeof LoggingMessageNotificationSchema>) => void | Promise<void>
|
|
463
|
+
): void {
|
|
464
|
+
this.client.setNotificationHandler(LoggingMessageNotificationSchema, handler)
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Close the transport for window.addEventListener('pagehide')
|
|
469
|
+
*/
|
|
470
|
+
async onPagehide(event: PageTransitionEvent) {
|
|
471
|
+
if (event.persisted) {
|
|
472
|
+
return
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if (isStreamableHTTPClientTransport(this.transport)) {
|
|
476
|
+
await this.transport.terminateSession()
|
|
477
|
+
} else if (this.transport && typeof this.transport['close'] === 'function') {
|
|
478
|
+
await this.transport.close()
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Creates a new SSEClientTransport instance.
|
|
485
|
+
*/
|
|
486
|
+
export const createSSEClientTransport = (url: URL, opts?: SSEClientTransportOptions) =>
|
|
487
|
+
new SSEClientTransport(url, opts)
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Creates a new StreamableHTTPClientTransport instance.
|
|
491
|
+
*/
|
|
492
|
+
export const createStreamableHTTPClientTransport = (url: URL, opts?: StreamableHTTPClientTransportOptions) =>
|
|
493
|
+
new StreamableHTTPClientTransport(url, opts)
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Creates a new MessageChannelClientTransport instance.
|
|
497
|
+
*/
|
|
498
|
+
export const createMessageChannelClientTransport = (endpoint: string, globalObject?: object) =>
|
|
499
|
+
new MessageChannelClientTransport(endpoint, globalObject)
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Checks if the transport is a SSEClientTransport.
|
|
503
|
+
*/
|
|
504
|
+
export const isSSEClientTransport = (transport: unknown): transport is SSEClientTransport =>
|
|
505
|
+
transport instanceof SSEClientTransport
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Checks if the transport is a StreamableHTTPClientTransport.
|
|
509
|
+
*/
|
|
510
|
+
export const isStreamableHTTPClientTransport = (transport: unknown): transport is StreamableHTTPClientTransport =>
|
|
511
|
+
transport instanceof StreamableHTTPClientTransport
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Checks if the transport is a MessageChannelClientTransport.
|
|
515
|
+
*/
|
|
516
|
+
export const isMessageChannelClientTransport = (transport: unknown): transport is MessageChannelClientTransport =>
|
|
517
|
+
transport instanceof MessageChannelClientTransport
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Checks if the client is an instance of MCP Client.
|
|
521
|
+
*/
|
|
522
|
+
export const isMcpClient = (client: unknown): client is Client => client instanceof Client
|