agents 0.0.0-b24b302 → 0.0.0-b30ffda

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.
@@ -1,32 +1,49 @@
1
1
  import * as zod from 'zod';
2
- import { Tool, Prompt as Prompt$1, Resource, ResourceTemplate, ServerCapabilities, ClientCapabilities, CallToolRequest, CallToolResultSchema, CompatibilityCallToolResultSchema, ReadResourceRequest, GetPromptRequest } from '@modelcontextprotocol/sdk/types.js';
2
+ import { ClientCapabilities, Tool, Prompt, Resource, ResourceTemplate, ServerCapabilities, CallToolRequest, CallToolResultSchema, CompatibilityCallToolResultSchema, ReadResourceRequest, GetPromptRequest } from '@modelcontextprotocol/sdk/types.js';
3
3
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
4
- import { SSEClientTransport, SSEClientTransportOptions } from '@modelcontextprotocol/sdk/client/sse.js';
4
+ import { SSEClientTransportOptions } from '@modelcontextprotocol/sdk/client/sse.js';
5
+ import { AgentsOAuthProvider } from './do-oauth-client-provider.js';
5
6
  import { RequestOptions } from '@modelcontextprotocol/sdk/shared/protocol.js';
7
+ import '@modelcontextprotocol/sdk/client/auth.js';
8
+ import '@modelcontextprotocol/sdk/shared/auth.js';
6
9
 
7
10
  declare class MCPClientConnection {
8
- private info;
11
+ url: URL;
12
+ options: {
13
+ transport: SSEClientTransportOptions & {
14
+ authProvider?: AgentsOAuthProvider;
15
+ };
16
+ client: ConstructorParameters<typeof Client>[1];
17
+ capabilities: ClientCapabilities;
18
+ };
9
19
  client: Client;
10
- transport: SSEClientTransport;
11
- connected: boolean;
20
+ connectionState: "authenticating" | "connecting" | "ready" | "discovering" | "failed";
12
21
  instructions?: string;
13
22
  tools: Tool[];
14
- prompts: Prompt$1[];
23
+ prompts: Prompt[];
15
24
  resources: Resource[];
16
25
  resourceTemplates: ResourceTemplate[];
17
26
  serverCapabilities: ServerCapabilities | undefined;
18
- constructor(url: URL, info: ConstructorParameters<typeof Client>[0], opts?: {
19
- transport: SSEClientTransportOptions;
27
+ constructor(url: URL, info: ConstructorParameters<typeof Client>[0], options?: {
28
+ transport: SSEClientTransportOptions & {
29
+ authProvider?: AgentsOAuthProvider;
30
+ };
20
31
  client: ConstructorParameters<typeof Client>[1];
21
32
  capabilities: ClientCapabilities;
22
33
  });
23
- init(): Promise<void>;
34
+ /**
35
+ * Initialize a client connection
36
+ *
37
+ * @param code Optional OAuth code to initialize the connection with if auth hasn't been initialized
38
+ * @returns
39
+ */
40
+ init(code?: string, clientId?: string): Promise<void>;
24
41
  /**
25
42
  * Notification handler registration
26
43
  */
27
44
  registerTools(): Promise<Tool[]>;
28
45
  registerResources(): Promise<Resource[]>;
29
- registerPrompts(): Promise<Prompt$1[]>;
46
+ registerPrompts(): Promise<Prompt[]>;
30
47
  registerResourceTemplates(): Promise<ResourceTemplate[]>;
31
48
  fetchTools(): Promise<{
32
49
  [x: string]: unknown;
@@ -71,7 +88,16 @@ declare class MCPClientConnection {
71
88
  * Utility class that aggregates multiple MCP clients into one
72
89
  */
73
90
  declare class MCPClientManager {
91
+ private name;
92
+ private version;
74
93
  mcpConnections: Record<string, MCPClientConnection>;
94
+ private callbackUrls;
95
+ /**
96
+ * @param name Name of the MCP client
97
+ * @param version Version of the MCP Client
98
+ * @param auth Auth paramters if being used to create a DurableObjectOAuthClientProvider
99
+ */
100
+ constructor(name: string, version: string);
75
101
  /**
76
102
  * Connect to and register an MCP server
77
103
  *
@@ -79,11 +105,25 @@ declare class MCPClientManager {
79
105
  * @param clientConfig Client config
80
106
  * @param capabilities Client capabilities (i.e. if the client supports roots/sampling)
81
107
  */
82
- connectToServer(url: URL, info: ConstructorParameters<typeof Client>[0], opts?: {
83
- transport: SSEClientTransportOptions;
84
- client: ConstructorParameters<typeof Client>[1];
85
- capabilities: ClientCapabilities;
86
- }): Promise<void>;
108
+ connect(url: string, options?: {
109
+ reconnect?: {
110
+ id: string;
111
+ oauthClientId?: string;
112
+ oauthCode?: string;
113
+ };
114
+ transport?: SSEClientTransportOptions & {
115
+ authProvider?: AgentsOAuthProvider;
116
+ };
117
+ client?: ConstructorParameters<typeof Client>[1];
118
+ capabilities?: ClientCapabilities;
119
+ }): Promise<{
120
+ id: string;
121
+ authUrl: string | undefined;
122
+ }>;
123
+ isCallbackRequest(req: Request): boolean;
124
+ handleCallbackRequest(req: Request): Promise<{
125
+ serverId: string;
126
+ }>;
87
127
  /**
88
128
  * @returns namespaced list of tools
89
129
  */
@@ -104,10 +144,10 @@ declare class MCPClientManager {
104
144
  * Namespaced version of callTool
105
145
  */
106
146
  callTool(params: CallToolRequest["params"] & {
107
- serverName: string;
108
- }, resultSchema: typeof CallToolResultSchema | typeof CompatibilityCallToolResultSchema, options: RequestOptions): Promise<zod.objectOutputType<zod.objectUtil.extendShape<{
147
+ serverId: string;
148
+ }, resultSchema: typeof CallToolResultSchema | typeof CompatibilityCallToolResultSchema, options: RequestOptions): Promise<zod.objectOutputType<{
109
149
  _meta: zod.ZodOptional<zod.ZodObject<{}, "passthrough", zod.ZodTypeAny, zod.objectOutputType<{}, zod.ZodTypeAny, "passthrough">, zod.objectInputType<{}, zod.ZodTypeAny, "passthrough">>>;
110
- }, {
150
+ } & {
111
151
  content: zod.ZodArray<zod.ZodUnion<[zod.ZodObject<{
112
152
  type: zod.ZodLiteral<"text">;
113
153
  text: zod.ZodString;
@@ -129,6 +169,18 @@ declare class MCPClientManager {
129
169
  type: zod.ZodLiteral<"image">;
130
170
  data: zod.ZodString;
131
171
  mimeType: zod.ZodString;
172
+ }, zod.ZodTypeAny, "passthrough">>, zod.ZodObject<{
173
+ type: zod.ZodLiteral<"audio">;
174
+ data: zod.ZodString;
175
+ mimeType: zod.ZodString;
176
+ }, "passthrough", zod.ZodTypeAny, zod.objectOutputType<{
177
+ type: zod.ZodLiteral<"audio">;
178
+ data: zod.ZodString;
179
+ mimeType: zod.ZodString;
180
+ }, zod.ZodTypeAny, "passthrough">, zod.objectInputType<{
181
+ type: zod.ZodLiteral<"audio">;
182
+ data: zod.ZodString;
183
+ mimeType: zod.ZodString;
132
184
  }, zod.ZodTypeAny, "passthrough">>, zod.ZodObject<{
133
185
  type: zod.ZodLiteral<"resource">;
134
186
  resource: zod.ZodUnion<[zod.ZodObject<zod.objectUtil.extendShape<{
@@ -230,19 +282,19 @@ declare class MCPClientManager {
230
282
  }>, zod.ZodTypeAny, "passthrough">>]>;
231
283
  }, zod.ZodTypeAny, "passthrough">>]>, "many">;
232
284
  isError: zod.ZodOptional<zod.ZodDefault<zod.ZodBoolean>>;
233
- }>, zod.ZodTypeAny, "passthrough"> | zod.objectOutputType<zod.objectUtil.extendShape<{
285
+ }, zod.ZodTypeAny, "passthrough"> | zod.objectOutputType<{
234
286
  _meta: zod.ZodOptional<zod.ZodObject<{}, "passthrough", zod.ZodTypeAny, zod.objectOutputType<{}, zod.ZodTypeAny, "passthrough">, zod.objectInputType<{}, zod.ZodTypeAny, "passthrough">>>;
235
- }, {
287
+ } & {
236
288
  toolResult: zod.ZodUnknown;
237
- }>, zod.ZodTypeAny, "passthrough">>;
289
+ }, zod.ZodTypeAny, "passthrough">>;
238
290
  /**
239
291
  * Namespaced version of readResource
240
292
  */
241
293
  readResource(params: ReadResourceRequest["params"] & {
242
- serverName: string;
243
- }, options: RequestOptions): Promise<zod.objectOutputType<zod.objectUtil.extendShape<{
294
+ serverId: string;
295
+ }, options: RequestOptions): Promise<zod.objectOutputType<{
244
296
  _meta: zod.ZodOptional<zod.ZodObject<{}, "passthrough", zod.ZodTypeAny, zod.objectOutputType<{}, zod.ZodTypeAny, "passthrough">, zod.objectInputType<{}, zod.ZodTypeAny, "passthrough">>>;
245
- }, {
297
+ } & {
246
298
  contents: zod.ZodArray<zod.ZodUnion<[zod.ZodObject<zod.objectUtil.extendShape<{
247
299
  uri: zod.ZodString;
248
300
  mimeType: zod.ZodOptional<zod.ZodString>;
@@ -274,15 +326,15 @@ declare class MCPClientManager {
274
326
  }, {
275
327
  blob: zod.ZodString;
276
328
  }>, zod.ZodTypeAny, "passthrough">>]>, "many">;
277
- }>, zod.ZodTypeAny, "passthrough">>;
329
+ }, zod.ZodTypeAny, "passthrough">>;
278
330
  /**
279
331
  * Namespaced version of getPrompt
280
332
  */
281
333
  getPrompt(params: GetPromptRequest["params"] & {
282
- serverName: string;
283
- }, options: RequestOptions): Promise<zod.objectOutputType<zod.objectUtil.extendShape<{
334
+ serverId: string;
335
+ }, options: RequestOptions): Promise<zod.objectOutputType<{
284
336
  _meta: zod.ZodOptional<zod.ZodObject<{}, "passthrough", zod.ZodTypeAny, zod.objectOutputType<{}, zod.ZodTypeAny, "passthrough">, zod.objectInputType<{}, zod.ZodTypeAny, "passthrough">>>;
285
- }, {
337
+ } & {
286
338
  description: zod.ZodOptional<zod.ZodString>;
287
339
  messages: zod.ZodArray<zod.ZodObject<{
288
340
  role: zod.ZodEnum<["user", "assistant"]>;
@@ -307,6 +359,18 @@ declare class MCPClientManager {
307
359
  type: zod.ZodLiteral<"image">;
308
360
  data: zod.ZodString;
309
361
  mimeType: zod.ZodString;
362
+ }, zod.ZodTypeAny, "passthrough">>, zod.ZodObject<{
363
+ type: zod.ZodLiteral<"audio">;
364
+ data: zod.ZodString;
365
+ mimeType: zod.ZodString;
366
+ }, "passthrough", zod.ZodTypeAny, zod.objectOutputType<{
367
+ type: zod.ZodLiteral<"audio">;
368
+ data: zod.ZodString;
369
+ mimeType: zod.ZodString;
370
+ }, zod.ZodTypeAny, "passthrough">, zod.objectInputType<{
371
+ type: zod.ZodLiteral<"audio">;
372
+ data: zod.ZodString;
373
+ mimeType: zod.ZodString;
310
374
  }, zod.ZodTypeAny, "passthrough">>, zod.ZodObject<{
311
375
  type: zod.ZodLiteral<"resource">;
312
376
  resource: zod.ZodUnion<[zod.ZodObject<zod.objectUtil.extendShape<{
@@ -430,6 +494,18 @@ declare class MCPClientManager {
430
494
  type: zod.ZodLiteral<"image">;
431
495
  data: zod.ZodString;
432
496
  mimeType: zod.ZodString;
497
+ }, zod.ZodTypeAny, "passthrough">>, zod.ZodObject<{
498
+ type: zod.ZodLiteral<"audio">;
499
+ data: zod.ZodString;
500
+ mimeType: zod.ZodString;
501
+ }, "passthrough", zod.ZodTypeAny, zod.objectOutputType<{
502
+ type: zod.ZodLiteral<"audio">;
503
+ data: zod.ZodString;
504
+ mimeType: zod.ZodString;
505
+ }, zod.ZodTypeAny, "passthrough">, zod.objectInputType<{
506
+ type: zod.ZodLiteral<"audio">;
507
+ data: zod.ZodString;
508
+ mimeType: zod.ZodString;
433
509
  }, zod.ZodTypeAny, "passthrough">>, zod.ZodObject<{
434
510
  type: zod.ZodLiteral<"resource">;
435
511
  resource: zod.ZodUnion<[zod.ZodObject<zod.objectUtil.extendShape<{
@@ -553,6 +629,18 @@ declare class MCPClientManager {
553
629
  type: zod.ZodLiteral<"image">;
554
630
  data: zod.ZodString;
555
631
  mimeType: zod.ZodString;
632
+ }, zod.ZodTypeAny, "passthrough">>, zod.ZodObject<{
633
+ type: zod.ZodLiteral<"audio">;
634
+ data: zod.ZodString;
635
+ mimeType: zod.ZodString;
636
+ }, "passthrough", zod.ZodTypeAny, zod.objectOutputType<{
637
+ type: zod.ZodLiteral<"audio">;
638
+ data: zod.ZodString;
639
+ mimeType: zod.ZodString;
640
+ }, zod.ZodTypeAny, "passthrough">, zod.objectInputType<{
641
+ type: zod.ZodLiteral<"audio">;
642
+ data: zod.ZodString;
643
+ mimeType: zod.ZodString;
556
644
  }, zod.ZodTypeAny, "passthrough">>, zod.ZodObject<{
557
645
  type: zod.ZodLiteral<"resource">;
558
646
  resource: zod.ZodUnion<[zod.ZodObject<zod.objectUtil.extendShape<{
@@ -654,20 +742,20 @@ declare class MCPClientManager {
654
742
  }>, zod.ZodTypeAny, "passthrough">>]>;
655
743
  }, zod.ZodTypeAny, "passthrough">>]>;
656
744
  }, zod.ZodTypeAny, "passthrough">>, "many">;
657
- }>, zod.ZodTypeAny, "passthrough">>;
745
+ }, zod.ZodTypeAny, "passthrough">>;
658
746
  }
659
747
  type NamespacedData = {
660
748
  tools: (Tool & {
661
- serverName: string;
749
+ serverId: string;
662
750
  })[];
663
751
  prompts: (Prompt & {
664
- serverName: string;
752
+ serverId: string;
665
753
  })[];
666
754
  resources: (Resource & {
667
- serverName: string;
755
+ serverId: string;
668
756
  })[];
669
757
  resourceTemplates: (ResourceTemplate & {
670
- serverName: string;
758
+ serverId: string;
671
759
  })[];
672
760
  };
673
761
  declare function getNamespacedData<T extends keyof NamespacedData>(mcpClients: Record<string, MCPClientConnection>, type: T): NamespacedData[T];
@@ -0,0 +1,408 @@
1
+ import "../chunk-HMLY7DHA.js";
2
+
3
+ // src/mcp/sse-edge.ts
4
+ import {
5
+ SSEClientTransport
6
+ } from "@modelcontextprotocol/sdk/client/sse.js";
7
+ var SSEEdgeClientTransport = class extends SSEClientTransport {
8
+ /**
9
+ * Creates a new EdgeSSEClientTransport, which overrides fetch to be compatible with the CF workers environment
10
+ */
11
+ constructor(url, options) {
12
+ const fetchOverride = async (fetchUrl, fetchInit = {}) => {
13
+ const headers = await this.authHeaders();
14
+ const workerOptions = {
15
+ ...fetchInit,
16
+ headers: {
17
+ ...fetchInit?.headers,
18
+ ...headers
19
+ }
20
+ };
21
+ delete workerOptions.mode;
22
+ return fetch(fetchUrl, workerOptions);
23
+ };
24
+ super(url, {
25
+ ...options,
26
+ eventSourceInit: {
27
+ fetch: fetchOverride
28
+ }
29
+ });
30
+ this.authProvider = options.authProvider;
31
+ }
32
+ async authHeaders() {
33
+ if (this.authProvider) {
34
+ const tokens = await this.authProvider.tokens();
35
+ if (tokens) {
36
+ return {
37
+ Authorization: `Bearer ${tokens.access_token}`
38
+ };
39
+ }
40
+ }
41
+ }
42
+ };
43
+
44
+ // src/mcp/client-connection.ts
45
+ import {
46
+ ToolListChangedNotificationSchema,
47
+ ResourceListChangedNotificationSchema,
48
+ PromptListChangedNotificationSchema
49
+ } from "@modelcontextprotocol/sdk/types.js";
50
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
51
+ var MCPClientConnection = class {
52
+ constructor(url, info, options = { transport: {}, client: {}, capabilities: {} }) {
53
+ this.url = url;
54
+ this.options = options;
55
+ this.connectionState = "connecting";
56
+ this.tools = [];
57
+ this.prompts = [];
58
+ this.resources = [];
59
+ this.resourceTemplates = [];
60
+ this.client = new Client(info, options.client);
61
+ this.client.registerCapabilities(options.capabilities);
62
+ }
63
+ /**
64
+ * Initialize a client connection
65
+ *
66
+ * @param code Optional OAuth code to initialize the connection with if auth hasn't been initialized
67
+ * @returns
68
+ */
69
+ async init(code, clientId) {
70
+ try {
71
+ const transport = new SSEEdgeClientTransport(
72
+ this.url,
73
+ this.options.transport
74
+ );
75
+ if (code) {
76
+ await transport.finishAuth(code);
77
+ }
78
+ await this.client.connect(transport);
79
+ } catch (e) {
80
+ if (e.toString().includes("Unauthorized")) {
81
+ this.connectionState = "authenticating";
82
+ return;
83
+ }
84
+ this.connectionState = "failed";
85
+ throw e;
86
+ }
87
+ this.connectionState = "discovering";
88
+ this.serverCapabilities = await this.client.getServerCapabilities();
89
+ if (!this.serverCapabilities) {
90
+ throw new Error("The MCP Server failed to return server capabilities");
91
+ }
92
+ const [instructions, tools, resources, prompts, resourceTemplates] = await Promise.all([
93
+ this.client.getInstructions(),
94
+ this.registerTools(),
95
+ this.registerResources(),
96
+ this.registerPrompts(),
97
+ this.registerResourceTemplates()
98
+ ]);
99
+ this.instructions = instructions;
100
+ this.tools = tools;
101
+ this.resources = resources;
102
+ this.prompts = prompts;
103
+ this.resourceTemplates = resourceTemplates;
104
+ this.connectionState = "ready";
105
+ }
106
+ /**
107
+ * Notification handler registration
108
+ */
109
+ async registerTools() {
110
+ if (!this.serverCapabilities || !this.serverCapabilities.tools) {
111
+ return [];
112
+ }
113
+ if (this.serverCapabilities.tools.listChanged) {
114
+ this.client.setNotificationHandler(
115
+ ToolListChangedNotificationSchema,
116
+ async (_notification) => {
117
+ this.tools = await this.fetchTools();
118
+ }
119
+ );
120
+ }
121
+ return this.fetchTools();
122
+ }
123
+ async registerResources() {
124
+ if (!this.serverCapabilities || !this.serverCapabilities.resources) {
125
+ return [];
126
+ }
127
+ if (this.serverCapabilities.resources.listChanged) {
128
+ this.client.setNotificationHandler(
129
+ ResourceListChangedNotificationSchema,
130
+ async (_notification) => {
131
+ this.resources = await this.fetchResources();
132
+ }
133
+ );
134
+ }
135
+ return this.fetchResources();
136
+ }
137
+ async registerPrompts() {
138
+ if (!this.serverCapabilities || !this.serverCapabilities.prompts) {
139
+ return [];
140
+ }
141
+ if (this.serverCapabilities.prompts.listChanged) {
142
+ this.client.setNotificationHandler(
143
+ PromptListChangedNotificationSchema,
144
+ async (_notification) => {
145
+ this.prompts = await this.fetchPrompts();
146
+ }
147
+ );
148
+ }
149
+ return this.fetchPrompts();
150
+ }
151
+ async registerResourceTemplates() {
152
+ if (!this.serverCapabilities || !this.serverCapabilities.resources) {
153
+ return [];
154
+ }
155
+ return this.fetchResourceTemplates();
156
+ }
157
+ async fetchTools() {
158
+ let toolsAgg = [];
159
+ let toolsResult = { tools: [] };
160
+ do {
161
+ toolsResult = await this.client.listTools({
162
+ cursor: toolsResult.nextCursor
163
+ }).catch(capabilityErrorHandler({ tools: [] }, "tools/list"));
164
+ toolsAgg = toolsAgg.concat(toolsResult.tools);
165
+ } while (toolsResult.nextCursor);
166
+ return toolsAgg;
167
+ }
168
+ async fetchResources() {
169
+ let resourcesAgg = [];
170
+ let resourcesResult = { resources: [] };
171
+ do {
172
+ resourcesResult = await this.client.listResources({
173
+ cursor: resourcesResult.nextCursor
174
+ }).catch(capabilityErrorHandler({ resources: [] }, "resources/list"));
175
+ resourcesAgg = resourcesAgg.concat(resourcesResult.resources);
176
+ } while (resourcesResult.nextCursor);
177
+ return resourcesAgg;
178
+ }
179
+ async fetchPrompts() {
180
+ let promptsAgg = [];
181
+ let promptsResult = { prompts: [] };
182
+ do {
183
+ promptsResult = await this.client.listPrompts({
184
+ cursor: promptsResult.nextCursor
185
+ }).catch(capabilityErrorHandler({ prompts: [] }, "prompts/list"));
186
+ promptsAgg = promptsAgg.concat(promptsResult.prompts);
187
+ } while (promptsResult.nextCursor);
188
+ return promptsAgg;
189
+ }
190
+ async fetchResourceTemplates() {
191
+ let templatesAgg = [];
192
+ let templatesResult = {
193
+ resourceTemplates: []
194
+ };
195
+ do {
196
+ templatesResult = await this.client.listResourceTemplates({
197
+ cursor: templatesResult.nextCursor
198
+ }).catch(
199
+ capabilityErrorHandler(
200
+ { resourceTemplates: [] },
201
+ "resources/templates/list"
202
+ )
203
+ );
204
+ templatesAgg = templatesAgg.concat(templatesResult.resourceTemplates);
205
+ } while (templatesResult.nextCursor);
206
+ return templatesAgg;
207
+ }
208
+ };
209
+ function capabilityErrorHandler(empty, method) {
210
+ return (e) => {
211
+ if (e.code === -32601) {
212
+ console.error(
213
+ `The server advertised support for the capability ${method.split("/")[0]}, but returned "Method not found" for '${method}'.`
214
+ );
215
+ return empty;
216
+ }
217
+ throw e;
218
+ };
219
+ }
220
+
221
+ // src/mcp/client.ts
222
+ var MCPClientManager = class {
223
+ /**
224
+ * @param name Name of the MCP client
225
+ * @param version Version of the MCP Client
226
+ * @param auth Auth paramters if being used to create a DurableObjectOAuthClientProvider
227
+ */
228
+ constructor(name, version) {
229
+ this.name = name;
230
+ this.version = version;
231
+ this.mcpConnections = {};
232
+ this.callbackUrls = [];
233
+ }
234
+ /**
235
+ * Connect to and register an MCP server
236
+ *
237
+ * @param transportConfig Transport config
238
+ * @param clientConfig Client config
239
+ * @param capabilities Client capabilities (i.e. if the client supports roots/sampling)
240
+ */
241
+ async connect(url, options = {}) {
242
+ const id = options.reconnect?.id ?? crypto.randomUUID();
243
+ if (!options.transport?.authProvider) {
244
+ console.warn(
245
+ "No authProvider provided in the transport options. This client will only support unauthenticated remote MCP Servers"
246
+ );
247
+ } else {
248
+ options.transport.authProvider.serverId = id;
249
+ }
250
+ this.mcpConnections[id] = new MCPClientConnection(
251
+ new URL(url),
252
+ {
253
+ name: this.name,
254
+ version: this.version
255
+ },
256
+ {
257
+ transport: options.transport ?? {},
258
+ client: options.client ?? {},
259
+ capabilities: options.client ?? {}
260
+ }
261
+ );
262
+ await this.mcpConnections[id].init(
263
+ options.reconnect?.oauthCode,
264
+ options.reconnect?.oauthClientId
265
+ );
266
+ const authUrl = options.transport?.authProvider?.authUrl;
267
+ if (authUrl && options.transport?.authProvider?.redirectUrl) {
268
+ this.callbackUrls.push(
269
+ options.transport.authProvider.redirectUrl.toString()
270
+ );
271
+ }
272
+ return {
273
+ id,
274
+ authUrl
275
+ };
276
+ }
277
+ isCallbackRequest(req) {
278
+ return req.method === "GET" && !!this.callbackUrls.find((url) => {
279
+ return req.url.startsWith(url);
280
+ });
281
+ }
282
+ async handleCallbackRequest(req) {
283
+ const url = new URL(req.url);
284
+ const urlMatch = this.callbackUrls.find((url2) => {
285
+ return req.url.startsWith(url2);
286
+ });
287
+ if (!urlMatch) {
288
+ throw new Error(
289
+ `No callback URI match found for the request url: ${req.url}. Was the request matched with \`isCallbackRequest()\`?`
290
+ );
291
+ }
292
+ const code = url.searchParams.get("code");
293
+ const clientId = url.searchParams.get("state");
294
+ const urlParams = urlMatch.split("/");
295
+ const serverId = urlParams[urlParams.length - 1];
296
+ if (!code) {
297
+ throw new Error("Unauthorized: no code provided");
298
+ }
299
+ if (!clientId) {
300
+ throw new Error("Unauthorized: no state provided");
301
+ }
302
+ if (this.mcpConnections[serverId] === void 0) {
303
+ throw new Error(`Could not find serverId: ${serverId}`);
304
+ }
305
+ if (this.mcpConnections[serverId].connectionState !== "authenticating") {
306
+ throw new Error(
307
+ "Failed to authenticate: the client isn't in the `authenticating` state"
308
+ );
309
+ }
310
+ const conn = this.mcpConnections[serverId];
311
+ if (!conn.options.transport.authProvider) {
312
+ throw new Error(
313
+ "Trying to finalize authentication for a server connection without an authProvider"
314
+ );
315
+ }
316
+ conn.options.transport.authProvider.clientId = clientId;
317
+ conn.options.transport.authProvider.serverId = serverId;
318
+ const serverUrl = conn.url.toString();
319
+ await this.connect(serverUrl, {
320
+ reconnect: {
321
+ id: serverId,
322
+ oauthClientId: clientId,
323
+ oauthCode: code
324
+ },
325
+ ...conn.options
326
+ });
327
+ if (this.mcpConnections[serverId].connectionState === "authenticating") {
328
+ throw new Error("Failed to authenticate: client failed to initialize");
329
+ }
330
+ return { serverId };
331
+ }
332
+ /**
333
+ * @returns namespaced list of tools
334
+ */
335
+ listTools() {
336
+ return getNamespacedData(this.mcpConnections, "tools");
337
+ }
338
+ /**
339
+ * @returns namespaced list of prompts
340
+ */
341
+ listPrompts() {
342
+ return getNamespacedData(this.mcpConnections, "prompts");
343
+ }
344
+ /**
345
+ * @returns namespaced list of tools
346
+ */
347
+ listResources() {
348
+ return getNamespacedData(this.mcpConnections, "resources");
349
+ }
350
+ /**
351
+ * @returns namespaced list of resource templates
352
+ */
353
+ listResourceTemplates() {
354
+ return getNamespacedData(this.mcpConnections, "resourceTemplates");
355
+ }
356
+ /**
357
+ * Namespaced version of callTool
358
+ */
359
+ callTool(params, resultSchema, options) {
360
+ const unqualifiedName = params.name.replace(`${params.serverId}.`, "");
361
+ return this.mcpConnections[params.serverId].client.callTool(
362
+ {
363
+ ...params,
364
+ name: unqualifiedName
365
+ },
366
+ resultSchema,
367
+ options
368
+ );
369
+ }
370
+ /**
371
+ * Namespaced version of readResource
372
+ */
373
+ readResource(params, options) {
374
+ return this.mcpConnections[params.serverId].client.readResource(
375
+ params,
376
+ options
377
+ );
378
+ }
379
+ /**
380
+ * Namespaced version of getPrompt
381
+ */
382
+ getPrompt(params, options) {
383
+ return this.mcpConnections[params.serverId].client.getPrompt(
384
+ params,
385
+ options
386
+ );
387
+ }
388
+ };
389
+ function getNamespacedData(mcpClients, type) {
390
+ const sets = Object.entries(mcpClients).map(([name, conn]) => {
391
+ return { name, data: conn[type] };
392
+ });
393
+ const namespacedData = sets.flatMap(({ name: serverId, data }) => {
394
+ return data.map((item) => {
395
+ return {
396
+ ...item,
397
+ // we add a serverId so we can easily pull it out and send the tool call to the right server
398
+ serverId
399
+ };
400
+ });
401
+ });
402
+ return namespacedData;
403
+ }
404
+ export {
405
+ MCPClientManager,
406
+ getNamespacedData
407
+ };
408
+ //# sourceMappingURL=client.js.map