@ai-sdk/mcp 0.0.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/CHANGELOG.md +21 -0
- package/LICENSE +13 -0
- package/dist/index.d.mts +301 -0
- package/dist/index.d.ts +301 -0
- package/dist/index.js +1754 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1727 -0
- package/dist/index.mjs.map +1 -0
- package/dist/mcp-stdio/index.d.mts +89 -0
- package/dist/mcp-stdio/index.d.ts +89 -0
- package/dist/mcp-stdio/index.js +351 -0
- package/dist/mcp-stdio/index.js.map +1 -0
- package/dist/mcp-stdio/index.mjs +324 -0
- package/dist/mcp-stdio/index.mjs.map +1 -0
- package/package.json +74 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1754 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name3 in all)
|
|
10
|
+
__defProp(target, name3, { get: all[name3], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
UnauthorizedError: () => UnauthorizedError,
|
|
34
|
+
auth: () => auth,
|
|
35
|
+
experimental_createMCPClient: () => createMCPClient
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(src_exports);
|
|
38
|
+
|
|
39
|
+
// src/tool/mcp-client.ts
|
|
40
|
+
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
41
|
+
|
|
42
|
+
// src/error/mcp-client-error.ts
|
|
43
|
+
var import_provider = require("@ai-sdk/provider");
|
|
44
|
+
var name = "AI_MCPClientError";
|
|
45
|
+
var marker = `vercel.ai.error.${name}`;
|
|
46
|
+
var symbol = Symbol.for(marker);
|
|
47
|
+
var _a, _b;
|
|
48
|
+
var MCPClientError = class extends (_b = import_provider.AISDKError, _a = symbol, _b) {
|
|
49
|
+
constructor({
|
|
50
|
+
name: name3 = "MCPClientError",
|
|
51
|
+
message,
|
|
52
|
+
cause,
|
|
53
|
+
data,
|
|
54
|
+
code
|
|
55
|
+
}) {
|
|
56
|
+
super({ name: name3, message, cause });
|
|
57
|
+
this[_a] = true;
|
|
58
|
+
this.data = data;
|
|
59
|
+
this.code = code;
|
|
60
|
+
}
|
|
61
|
+
static isInstance(error) {
|
|
62
|
+
return import_provider.AISDKError.hasMarker(error, marker);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/tool/mcp-sse-transport.ts
|
|
67
|
+
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
68
|
+
|
|
69
|
+
// src/tool/json-rpc-message.ts
|
|
70
|
+
var import_v42 = require("zod/v4");
|
|
71
|
+
|
|
72
|
+
// src/tool/types.ts
|
|
73
|
+
var import_v4 = require("zod/v4");
|
|
74
|
+
var LATEST_PROTOCOL_VERSION = "2025-06-18";
|
|
75
|
+
var SUPPORTED_PROTOCOL_VERSIONS = [
|
|
76
|
+
LATEST_PROTOCOL_VERSION,
|
|
77
|
+
"2025-03-26",
|
|
78
|
+
"2024-11-05"
|
|
79
|
+
];
|
|
80
|
+
var ClientOrServerImplementationSchema = import_v4.z.looseObject({
|
|
81
|
+
name: import_v4.z.string(),
|
|
82
|
+
version: import_v4.z.string()
|
|
83
|
+
});
|
|
84
|
+
var BaseParamsSchema = import_v4.z.looseObject({
|
|
85
|
+
_meta: import_v4.z.optional(import_v4.z.object({}).loose())
|
|
86
|
+
});
|
|
87
|
+
var ResultSchema = BaseParamsSchema;
|
|
88
|
+
var RequestSchema = import_v4.z.object({
|
|
89
|
+
method: import_v4.z.string(),
|
|
90
|
+
params: import_v4.z.optional(BaseParamsSchema)
|
|
91
|
+
});
|
|
92
|
+
var ServerCapabilitiesSchema = import_v4.z.looseObject({
|
|
93
|
+
experimental: import_v4.z.optional(import_v4.z.object({}).loose()),
|
|
94
|
+
logging: import_v4.z.optional(import_v4.z.object({}).loose()),
|
|
95
|
+
prompts: import_v4.z.optional(
|
|
96
|
+
import_v4.z.looseObject({
|
|
97
|
+
listChanged: import_v4.z.optional(import_v4.z.boolean())
|
|
98
|
+
})
|
|
99
|
+
),
|
|
100
|
+
resources: import_v4.z.optional(
|
|
101
|
+
import_v4.z.looseObject({
|
|
102
|
+
subscribe: import_v4.z.optional(import_v4.z.boolean()),
|
|
103
|
+
listChanged: import_v4.z.optional(import_v4.z.boolean())
|
|
104
|
+
})
|
|
105
|
+
),
|
|
106
|
+
tools: import_v4.z.optional(
|
|
107
|
+
import_v4.z.looseObject({
|
|
108
|
+
listChanged: import_v4.z.optional(import_v4.z.boolean())
|
|
109
|
+
})
|
|
110
|
+
)
|
|
111
|
+
});
|
|
112
|
+
var InitializeResultSchema = ResultSchema.extend({
|
|
113
|
+
protocolVersion: import_v4.z.string(),
|
|
114
|
+
capabilities: ServerCapabilitiesSchema,
|
|
115
|
+
serverInfo: ClientOrServerImplementationSchema,
|
|
116
|
+
instructions: import_v4.z.optional(import_v4.z.string())
|
|
117
|
+
});
|
|
118
|
+
var PaginatedResultSchema = ResultSchema.extend({
|
|
119
|
+
nextCursor: import_v4.z.optional(import_v4.z.string())
|
|
120
|
+
});
|
|
121
|
+
var ToolSchema = import_v4.z.object({
|
|
122
|
+
name: import_v4.z.string(),
|
|
123
|
+
description: import_v4.z.optional(import_v4.z.string()),
|
|
124
|
+
inputSchema: import_v4.z.object({
|
|
125
|
+
type: import_v4.z.literal("object"),
|
|
126
|
+
properties: import_v4.z.optional(import_v4.z.object({}).loose())
|
|
127
|
+
}).loose()
|
|
128
|
+
}).loose();
|
|
129
|
+
var ListToolsResultSchema = PaginatedResultSchema.extend({
|
|
130
|
+
tools: import_v4.z.array(ToolSchema)
|
|
131
|
+
});
|
|
132
|
+
var TextContentSchema = import_v4.z.object({
|
|
133
|
+
type: import_v4.z.literal("text"),
|
|
134
|
+
text: import_v4.z.string()
|
|
135
|
+
}).loose();
|
|
136
|
+
var ImageContentSchema = import_v4.z.object({
|
|
137
|
+
type: import_v4.z.literal("image"),
|
|
138
|
+
data: import_v4.z.base64(),
|
|
139
|
+
mimeType: import_v4.z.string()
|
|
140
|
+
}).loose();
|
|
141
|
+
var ResourceContentsSchema = import_v4.z.object({
|
|
142
|
+
/**
|
|
143
|
+
* The URI of this resource.
|
|
144
|
+
*/
|
|
145
|
+
uri: import_v4.z.string(),
|
|
146
|
+
/**
|
|
147
|
+
* The MIME type of this resource, if known.
|
|
148
|
+
*/
|
|
149
|
+
mimeType: import_v4.z.optional(import_v4.z.string())
|
|
150
|
+
}).loose();
|
|
151
|
+
var TextResourceContentsSchema = ResourceContentsSchema.extend({
|
|
152
|
+
text: import_v4.z.string()
|
|
153
|
+
});
|
|
154
|
+
var BlobResourceContentsSchema = ResourceContentsSchema.extend({
|
|
155
|
+
blob: import_v4.z.base64()
|
|
156
|
+
});
|
|
157
|
+
var EmbeddedResourceSchema = import_v4.z.object({
|
|
158
|
+
type: import_v4.z.literal("resource"),
|
|
159
|
+
resource: import_v4.z.union([TextResourceContentsSchema, BlobResourceContentsSchema])
|
|
160
|
+
}).loose();
|
|
161
|
+
var CallToolResultSchema = ResultSchema.extend({
|
|
162
|
+
content: import_v4.z.array(
|
|
163
|
+
import_v4.z.union([TextContentSchema, ImageContentSchema, EmbeddedResourceSchema])
|
|
164
|
+
),
|
|
165
|
+
isError: import_v4.z.boolean().default(false).optional()
|
|
166
|
+
}).or(
|
|
167
|
+
ResultSchema.extend({
|
|
168
|
+
toolResult: import_v4.z.unknown()
|
|
169
|
+
})
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
// src/tool/json-rpc-message.ts
|
|
173
|
+
var JSONRPC_VERSION = "2.0";
|
|
174
|
+
var JSONRPCRequestSchema = import_v42.z.object({
|
|
175
|
+
jsonrpc: import_v42.z.literal(JSONRPC_VERSION),
|
|
176
|
+
id: import_v42.z.union([import_v42.z.string(), import_v42.z.number().int()])
|
|
177
|
+
}).merge(RequestSchema).strict();
|
|
178
|
+
var JSONRPCResponseSchema = import_v42.z.object({
|
|
179
|
+
jsonrpc: import_v42.z.literal(JSONRPC_VERSION),
|
|
180
|
+
id: import_v42.z.union([import_v42.z.string(), import_v42.z.number().int()]),
|
|
181
|
+
result: ResultSchema
|
|
182
|
+
}).strict();
|
|
183
|
+
var JSONRPCErrorSchema = import_v42.z.object({
|
|
184
|
+
jsonrpc: import_v42.z.literal(JSONRPC_VERSION),
|
|
185
|
+
id: import_v42.z.union([import_v42.z.string(), import_v42.z.number().int()]),
|
|
186
|
+
error: import_v42.z.object({
|
|
187
|
+
code: import_v42.z.number().int(),
|
|
188
|
+
message: import_v42.z.string(),
|
|
189
|
+
data: import_v42.z.optional(import_v42.z.unknown())
|
|
190
|
+
})
|
|
191
|
+
}).strict();
|
|
192
|
+
var JSONRPCNotificationSchema = import_v42.z.object({
|
|
193
|
+
jsonrpc: import_v42.z.literal(JSONRPC_VERSION)
|
|
194
|
+
}).merge(
|
|
195
|
+
import_v42.z.object({
|
|
196
|
+
method: import_v42.z.string(),
|
|
197
|
+
params: import_v42.z.optional(BaseParamsSchema)
|
|
198
|
+
})
|
|
199
|
+
).strict();
|
|
200
|
+
var JSONRPCMessageSchema = import_v42.z.union([
|
|
201
|
+
JSONRPCRequestSchema,
|
|
202
|
+
JSONRPCNotificationSchema,
|
|
203
|
+
JSONRPCResponseSchema,
|
|
204
|
+
JSONRPCErrorSchema
|
|
205
|
+
]);
|
|
206
|
+
|
|
207
|
+
// src/version.ts
|
|
208
|
+
var VERSION = typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : "0.0.0-test";
|
|
209
|
+
|
|
210
|
+
// src/tool/oauth.ts
|
|
211
|
+
var import_pkce_challenge = __toESM(require("pkce-challenge"));
|
|
212
|
+
|
|
213
|
+
// src/tool/oauth-types.ts
|
|
214
|
+
var import_v43 = require("zod/v4");
|
|
215
|
+
var OAuthTokensSchema = import_v43.z.object({
|
|
216
|
+
access_token: import_v43.z.string(),
|
|
217
|
+
id_token: import_v43.z.string().optional(),
|
|
218
|
+
// Optional for OAuth 2.1, but necessary in OpenID Connect
|
|
219
|
+
token_type: import_v43.z.string(),
|
|
220
|
+
expires_in: import_v43.z.number().optional(),
|
|
221
|
+
scope: import_v43.z.string().optional(),
|
|
222
|
+
refresh_token: import_v43.z.string().optional()
|
|
223
|
+
}).strip();
|
|
224
|
+
var SafeUrlSchema = import_v43.z.string().url().superRefine((val, ctx) => {
|
|
225
|
+
if (!URL.canParse(val)) {
|
|
226
|
+
ctx.addIssue({
|
|
227
|
+
code: import_v43.z.ZodIssueCode.custom,
|
|
228
|
+
message: "URL must be parseable",
|
|
229
|
+
fatal: true
|
|
230
|
+
});
|
|
231
|
+
return import_v43.z.NEVER;
|
|
232
|
+
}
|
|
233
|
+
}).refine(
|
|
234
|
+
(url) => {
|
|
235
|
+
const u = new URL(url);
|
|
236
|
+
return u.protocol !== "javascript:" && u.protocol !== "data:" && u.protocol !== "vbscript:";
|
|
237
|
+
},
|
|
238
|
+
{ message: "URL cannot use javascript:, data:, or vbscript: scheme" }
|
|
239
|
+
);
|
|
240
|
+
var OAuthProtectedResourceMetadataSchema = import_v43.z.object({
|
|
241
|
+
resource: import_v43.z.string().url(),
|
|
242
|
+
authorization_servers: import_v43.z.array(SafeUrlSchema).optional(),
|
|
243
|
+
jwks_uri: import_v43.z.string().url().optional(),
|
|
244
|
+
scopes_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
245
|
+
bearer_methods_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
246
|
+
resource_signing_alg_values_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
247
|
+
resource_name: import_v43.z.string().optional(),
|
|
248
|
+
resource_documentation: import_v43.z.string().optional(),
|
|
249
|
+
resource_policy_uri: import_v43.z.string().url().optional(),
|
|
250
|
+
resource_tos_uri: import_v43.z.string().url().optional(),
|
|
251
|
+
tls_client_certificate_bound_access_tokens: import_v43.z.boolean().optional(),
|
|
252
|
+
authorization_details_types_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
253
|
+
dpop_signing_alg_values_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
254
|
+
dpop_bound_access_tokens_required: import_v43.z.boolean().optional()
|
|
255
|
+
}).passthrough();
|
|
256
|
+
var OAuthMetadataSchema = import_v43.z.object({
|
|
257
|
+
issuer: import_v43.z.string(),
|
|
258
|
+
authorization_endpoint: SafeUrlSchema,
|
|
259
|
+
token_endpoint: SafeUrlSchema,
|
|
260
|
+
registration_endpoint: SafeUrlSchema.optional(),
|
|
261
|
+
scopes_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
262
|
+
response_types_supported: import_v43.z.array(import_v43.z.string()),
|
|
263
|
+
grant_types_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
264
|
+
code_challenge_methods_supported: import_v43.z.array(import_v43.z.string()),
|
|
265
|
+
token_endpoint_auth_methods_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
266
|
+
token_endpoint_auth_signing_alg_values_supported: import_v43.z.array(import_v43.z.string()).optional()
|
|
267
|
+
}).passthrough();
|
|
268
|
+
var OpenIdProviderMetadataSchema = import_v43.z.object({
|
|
269
|
+
issuer: import_v43.z.string(),
|
|
270
|
+
authorization_endpoint: SafeUrlSchema,
|
|
271
|
+
token_endpoint: SafeUrlSchema,
|
|
272
|
+
userinfo_endpoint: SafeUrlSchema.optional(),
|
|
273
|
+
jwks_uri: SafeUrlSchema,
|
|
274
|
+
registration_endpoint: SafeUrlSchema.optional(),
|
|
275
|
+
scopes_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
276
|
+
response_types_supported: import_v43.z.array(import_v43.z.string()),
|
|
277
|
+
grant_types_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
278
|
+
subject_types_supported: import_v43.z.array(import_v43.z.string()),
|
|
279
|
+
id_token_signing_alg_values_supported: import_v43.z.array(import_v43.z.string()),
|
|
280
|
+
claims_supported: import_v43.z.array(import_v43.z.string()).optional(),
|
|
281
|
+
token_endpoint_auth_methods_supported: import_v43.z.array(import_v43.z.string()).optional()
|
|
282
|
+
}).passthrough();
|
|
283
|
+
var OpenIdProviderDiscoveryMetadataSchema = OpenIdProviderMetadataSchema.merge(
|
|
284
|
+
OAuthMetadataSchema.pick({
|
|
285
|
+
code_challenge_methods_supported: true
|
|
286
|
+
})
|
|
287
|
+
);
|
|
288
|
+
var OAuthClientInformationSchema = import_v43.z.object({
|
|
289
|
+
client_id: import_v43.z.string(),
|
|
290
|
+
client_secret: import_v43.z.string().optional(),
|
|
291
|
+
client_id_issued_at: import_v43.z.number().optional(),
|
|
292
|
+
client_secret_expires_at: import_v43.z.number().optional()
|
|
293
|
+
}).strip();
|
|
294
|
+
var OAuthClientMetadataSchema = import_v43.z.object({
|
|
295
|
+
redirect_uris: import_v43.z.array(SafeUrlSchema),
|
|
296
|
+
token_endpoint_auth_method: import_v43.z.string().optional(),
|
|
297
|
+
grant_types: import_v43.z.array(import_v43.z.string()).optional(),
|
|
298
|
+
response_types: import_v43.z.array(import_v43.z.string()).optional(),
|
|
299
|
+
client_name: import_v43.z.string().optional(),
|
|
300
|
+
client_uri: SafeUrlSchema.optional(),
|
|
301
|
+
logo_uri: SafeUrlSchema.optional(),
|
|
302
|
+
scope: import_v43.z.string().optional(),
|
|
303
|
+
contacts: import_v43.z.array(import_v43.z.string()).optional(),
|
|
304
|
+
tos_uri: SafeUrlSchema.optional(),
|
|
305
|
+
policy_uri: import_v43.z.string().optional(),
|
|
306
|
+
jwks_uri: SafeUrlSchema.optional(),
|
|
307
|
+
jwks: import_v43.z.any().optional(),
|
|
308
|
+
software_id: import_v43.z.string().optional(),
|
|
309
|
+
software_version: import_v43.z.string().optional(),
|
|
310
|
+
software_statement: import_v43.z.string().optional()
|
|
311
|
+
}).strip();
|
|
312
|
+
var OAuthErrorResponseSchema = import_v43.z.object({
|
|
313
|
+
error: import_v43.z.string(),
|
|
314
|
+
error_description: import_v43.z.string().optional(),
|
|
315
|
+
error_uri: import_v43.z.string().optional()
|
|
316
|
+
});
|
|
317
|
+
var OAuthClientInformationFullSchema = OAuthClientMetadataSchema.merge(
|
|
318
|
+
OAuthClientInformationSchema
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
// src/error/oauth-error.ts
|
|
322
|
+
var import_provider2 = require("@ai-sdk/provider");
|
|
323
|
+
var name2 = "AI_MCPClientOAuthError";
|
|
324
|
+
var marker2 = `vercel.ai.error.${name2}`;
|
|
325
|
+
var symbol2 = Symbol.for(marker2);
|
|
326
|
+
var _a2, _b2;
|
|
327
|
+
var MCPClientOAuthError = class extends (_b2 = import_provider2.AISDKError, _a2 = symbol2, _b2) {
|
|
328
|
+
constructor({
|
|
329
|
+
name: name3 = "MCPClientOAuthError",
|
|
330
|
+
message,
|
|
331
|
+
cause
|
|
332
|
+
}) {
|
|
333
|
+
super({ name: name3, message, cause });
|
|
334
|
+
this[_a2] = true;
|
|
335
|
+
}
|
|
336
|
+
static isInstance(error) {
|
|
337
|
+
return import_provider2.AISDKError.hasMarker(error, marker2);
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
var ServerError = class extends MCPClientOAuthError {
|
|
341
|
+
};
|
|
342
|
+
ServerError.errorCode = "server_error";
|
|
343
|
+
var InvalidClientError = class extends MCPClientOAuthError {
|
|
344
|
+
};
|
|
345
|
+
InvalidClientError.errorCode = "invalid_client";
|
|
346
|
+
var InvalidGrantError = class extends MCPClientOAuthError {
|
|
347
|
+
};
|
|
348
|
+
InvalidGrantError.errorCode = "invalid_grant";
|
|
349
|
+
var UnauthorizedClientError = class extends MCPClientOAuthError {
|
|
350
|
+
};
|
|
351
|
+
UnauthorizedClientError.errorCode = "unauthorized_client";
|
|
352
|
+
var OAUTH_ERRORS = {
|
|
353
|
+
[ServerError.errorCode]: ServerError,
|
|
354
|
+
[InvalidClientError.errorCode]: InvalidClientError,
|
|
355
|
+
[InvalidGrantError.errorCode]: InvalidGrantError,
|
|
356
|
+
[UnauthorizedClientError.errorCode]: UnauthorizedClientError
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
// src/util/oauth-util.ts
|
|
360
|
+
function resourceUrlFromServerUrl(url) {
|
|
361
|
+
const resourceURL = typeof url === "string" ? new URL(url) : new URL(url.href);
|
|
362
|
+
resourceURL.hash = "";
|
|
363
|
+
return resourceURL;
|
|
364
|
+
}
|
|
365
|
+
function checkResourceAllowed({
|
|
366
|
+
requestedResource,
|
|
367
|
+
configuredResource
|
|
368
|
+
}) {
|
|
369
|
+
const requested = typeof requestedResource === "string" ? new URL(requestedResource) : new URL(requestedResource.href);
|
|
370
|
+
const configured = typeof configuredResource === "string" ? new URL(configuredResource) : new URL(configuredResource.href);
|
|
371
|
+
if (requested.origin !== configured.origin) {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
if (requested.pathname.length < configured.pathname.length) {
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
const requestedPath = requested.pathname.endsWith("/") ? requested.pathname : requested.pathname + "/";
|
|
378
|
+
const configuredPath = configured.pathname.endsWith("/") ? configured.pathname : configured.pathname + "/";
|
|
379
|
+
return requestedPath.startsWith(configuredPath);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// src/tool/oauth.ts
|
|
383
|
+
var UnauthorizedError = class extends Error {
|
|
384
|
+
constructor(message = "Unauthorized") {
|
|
385
|
+
super(message);
|
|
386
|
+
this.name = "UnauthorizedError";
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
function extractResourceMetadataUrl(response) {
|
|
390
|
+
var _a3;
|
|
391
|
+
const header = (_a3 = response.headers.get("www-authenticate")) != null ? _a3 : response.headers.get("WWW-Authenticate");
|
|
392
|
+
if (!header) {
|
|
393
|
+
return void 0;
|
|
394
|
+
}
|
|
395
|
+
const [type, scheme] = header.split(" ");
|
|
396
|
+
if (type.toLowerCase() !== "bearer" || !scheme) {
|
|
397
|
+
return void 0;
|
|
398
|
+
}
|
|
399
|
+
const regex = /resource_metadata="([^"]*)"/;
|
|
400
|
+
const match = header.match(regex);
|
|
401
|
+
if (!match) {
|
|
402
|
+
return void 0;
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
return new URL(match[1]);
|
|
406
|
+
} catch (e) {
|
|
407
|
+
return void 0;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
function buildWellKnownPath(wellKnownPrefix, pathname = "", options = {}) {
|
|
411
|
+
if (pathname.endsWith("/")) {
|
|
412
|
+
pathname = pathname.slice(0, -1);
|
|
413
|
+
}
|
|
414
|
+
return options.prependPathname ? `${pathname}/.well-known/${wellKnownPrefix}` : `/.well-known/${wellKnownPrefix}${pathname}`;
|
|
415
|
+
}
|
|
416
|
+
async function fetchWithCorsRetry(url, headers, fetchFn = fetch) {
|
|
417
|
+
try {
|
|
418
|
+
return await fetchFn(url, { headers });
|
|
419
|
+
} catch (error) {
|
|
420
|
+
if (error instanceof TypeError) {
|
|
421
|
+
if (headers) {
|
|
422
|
+
return fetchWithCorsRetry(url, void 0, fetchFn);
|
|
423
|
+
} else {
|
|
424
|
+
return void 0;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
throw error;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
async function tryMetadataDiscovery(url, protocolVersion, fetchFn = fetch) {
|
|
431
|
+
const headers = {
|
|
432
|
+
"MCP-Protocol-Version": protocolVersion
|
|
433
|
+
};
|
|
434
|
+
return await fetchWithCorsRetry(url, headers, fetchFn);
|
|
435
|
+
}
|
|
436
|
+
function shouldAttemptFallback(response, pathname) {
|
|
437
|
+
return !response || response.status >= 400 && response.status < 500 && pathname !== "/";
|
|
438
|
+
}
|
|
439
|
+
async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, opts) {
|
|
440
|
+
var _a3, _b3;
|
|
441
|
+
const issuer = new URL(serverUrl);
|
|
442
|
+
const protocolVersion = (_a3 = opts == null ? void 0 : opts.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION;
|
|
443
|
+
let url;
|
|
444
|
+
if (opts == null ? void 0 : opts.metadataUrl) {
|
|
445
|
+
url = new URL(opts.metadataUrl);
|
|
446
|
+
} else {
|
|
447
|
+
const wellKnownPath = buildWellKnownPath(wellKnownType, issuer.pathname);
|
|
448
|
+
url = new URL(wellKnownPath, (_b3 = opts == null ? void 0 : opts.metadataServerUrl) != null ? _b3 : issuer);
|
|
449
|
+
url.search = issuer.search;
|
|
450
|
+
}
|
|
451
|
+
let response = await tryMetadataDiscovery(url, protocolVersion, fetchFn);
|
|
452
|
+
if (!(opts == null ? void 0 : opts.metadataUrl) && shouldAttemptFallback(response, issuer.pathname)) {
|
|
453
|
+
const rootUrl = new URL(`/.well-known/${wellKnownType}`, issuer);
|
|
454
|
+
response = await tryMetadataDiscovery(rootUrl, protocolVersion, fetchFn);
|
|
455
|
+
}
|
|
456
|
+
return response;
|
|
457
|
+
}
|
|
458
|
+
async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn = fetch) {
|
|
459
|
+
const response = await discoverMetadataWithFallback(
|
|
460
|
+
serverUrl,
|
|
461
|
+
"oauth-protected-resource",
|
|
462
|
+
fetchFn,
|
|
463
|
+
{
|
|
464
|
+
protocolVersion: opts == null ? void 0 : opts.protocolVersion,
|
|
465
|
+
metadataUrl: opts == null ? void 0 : opts.resourceMetadataUrl
|
|
466
|
+
}
|
|
467
|
+
);
|
|
468
|
+
if (!response || response.status === 404) {
|
|
469
|
+
throw new Error(
|
|
470
|
+
`Resource server does not implement OAuth 2.0 Protected Resource Metadata.`
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
if (!response.ok) {
|
|
474
|
+
throw new Error(
|
|
475
|
+
`HTTP ${response.status} trying to load well-known OAuth protected resource metadata.`
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
return OAuthProtectedResourceMetadataSchema.parse(await response.json());
|
|
479
|
+
}
|
|
480
|
+
function buildDiscoveryUrls(authorizationServerUrl) {
|
|
481
|
+
const url = typeof authorizationServerUrl === "string" ? new URL(authorizationServerUrl) : authorizationServerUrl;
|
|
482
|
+
const hasPath = url.pathname !== "/";
|
|
483
|
+
const urlsToTry = [];
|
|
484
|
+
if (!hasPath) {
|
|
485
|
+
urlsToTry.push({
|
|
486
|
+
url: new URL("/.well-known/oauth-authorization-server", url.origin),
|
|
487
|
+
type: "oauth"
|
|
488
|
+
});
|
|
489
|
+
urlsToTry.push({
|
|
490
|
+
url: new URL("/.well-known/openid-configuration", url.origin),
|
|
491
|
+
type: "oidc"
|
|
492
|
+
});
|
|
493
|
+
return urlsToTry;
|
|
494
|
+
}
|
|
495
|
+
let pathname = url.pathname;
|
|
496
|
+
if (pathname.endsWith("/")) {
|
|
497
|
+
pathname = pathname.slice(0, -1);
|
|
498
|
+
}
|
|
499
|
+
urlsToTry.push({
|
|
500
|
+
url: new URL(
|
|
501
|
+
`/.well-known/oauth-authorization-server${pathname}`,
|
|
502
|
+
url.origin
|
|
503
|
+
),
|
|
504
|
+
type: "oauth"
|
|
505
|
+
});
|
|
506
|
+
urlsToTry.push({
|
|
507
|
+
url: new URL("/.well-known/oauth-authorization-server", url.origin),
|
|
508
|
+
type: "oauth"
|
|
509
|
+
});
|
|
510
|
+
urlsToTry.push({
|
|
511
|
+
url: new URL(`/.well-known/openid-configuration${pathname}`, url.origin),
|
|
512
|
+
type: "oidc"
|
|
513
|
+
});
|
|
514
|
+
urlsToTry.push({
|
|
515
|
+
url: new URL(`${pathname}/.well-known/openid-configuration`, url.origin),
|
|
516
|
+
type: "oidc"
|
|
517
|
+
});
|
|
518
|
+
return urlsToTry;
|
|
519
|
+
}
|
|
520
|
+
async function discoverAuthorizationServerMetadata(authorizationServerUrl, {
|
|
521
|
+
fetchFn = fetch,
|
|
522
|
+
protocolVersion = LATEST_PROTOCOL_VERSION
|
|
523
|
+
} = {}) {
|
|
524
|
+
var _a3;
|
|
525
|
+
const headers = { "MCP-Protocol-Version": protocolVersion };
|
|
526
|
+
const urlsToTry = buildDiscoveryUrls(authorizationServerUrl);
|
|
527
|
+
for (const { url: endpointUrl, type } of urlsToTry) {
|
|
528
|
+
const response = await fetchWithCorsRetry(endpointUrl, headers, fetchFn);
|
|
529
|
+
if (!response) {
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
if (!response.ok) {
|
|
533
|
+
if (response.status >= 400 && response.status < 500) {
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
throw new Error(
|
|
537
|
+
`HTTP ${response.status} trying to load ${type === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
if (type === "oauth") {
|
|
541
|
+
return OAuthMetadataSchema.parse(await response.json());
|
|
542
|
+
} else {
|
|
543
|
+
const metadata = OpenIdProviderDiscoveryMetadataSchema.parse(
|
|
544
|
+
await response.json()
|
|
545
|
+
);
|
|
546
|
+
if (!((_a3 = metadata.code_challenge_methods_supported) == null ? void 0 : _a3.includes("S256"))) {
|
|
547
|
+
throw new Error(
|
|
548
|
+
`Incompatible OIDC provider at ${endpointUrl}: does not support S256 code challenge method required by MCP specification`
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
return metadata;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
return void 0;
|
|
555
|
+
}
|
|
556
|
+
async function startAuthorization(authorizationServerUrl, {
|
|
557
|
+
metadata,
|
|
558
|
+
clientInformation,
|
|
559
|
+
redirectUrl,
|
|
560
|
+
scope,
|
|
561
|
+
state,
|
|
562
|
+
resource
|
|
563
|
+
}) {
|
|
564
|
+
const responseType = "code";
|
|
565
|
+
const codeChallengeMethod = "S256";
|
|
566
|
+
let authorizationUrl;
|
|
567
|
+
if (metadata) {
|
|
568
|
+
authorizationUrl = new URL(metadata.authorization_endpoint);
|
|
569
|
+
if (!metadata.response_types_supported.includes(responseType)) {
|
|
570
|
+
throw new Error(
|
|
571
|
+
`Incompatible auth server: does not support response type ${responseType}`
|
|
572
|
+
);
|
|
573
|
+
}
|
|
574
|
+
if (!metadata.code_challenge_methods_supported || !metadata.code_challenge_methods_supported.includes(codeChallengeMethod)) {
|
|
575
|
+
throw new Error(
|
|
576
|
+
`Incompatible auth server: does not support code challenge method ${codeChallengeMethod}`
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
} else {
|
|
580
|
+
authorizationUrl = new URL("/authorize", authorizationServerUrl);
|
|
581
|
+
}
|
|
582
|
+
const challenge = await (0, import_pkce_challenge.default)();
|
|
583
|
+
const codeVerifier = challenge.code_verifier;
|
|
584
|
+
const codeChallenge = challenge.code_challenge;
|
|
585
|
+
authorizationUrl.searchParams.set("response_type", responseType);
|
|
586
|
+
authorizationUrl.searchParams.set("client_id", clientInformation.client_id);
|
|
587
|
+
authorizationUrl.searchParams.set("code_challenge", codeChallenge);
|
|
588
|
+
authorizationUrl.searchParams.set(
|
|
589
|
+
"code_challenge_method",
|
|
590
|
+
codeChallengeMethod
|
|
591
|
+
);
|
|
592
|
+
authorizationUrl.searchParams.set("redirect_uri", String(redirectUrl));
|
|
593
|
+
if (state) {
|
|
594
|
+
authorizationUrl.searchParams.set("state", state);
|
|
595
|
+
}
|
|
596
|
+
if (scope) {
|
|
597
|
+
authorizationUrl.searchParams.set("scope", scope);
|
|
598
|
+
}
|
|
599
|
+
if (scope == null ? void 0 : scope.includes("offline_access")) {
|
|
600
|
+
authorizationUrl.searchParams.append("prompt", "consent");
|
|
601
|
+
}
|
|
602
|
+
if (resource) {
|
|
603
|
+
authorizationUrl.searchParams.set("resource", resource.href);
|
|
604
|
+
}
|
|
605
|
+
return { authorizationUrl, codeVerifier };
|
|
606
|
+
}
|
|
607
|
+
function selectClientAuthMethod(clientInformation, supportedMethods) {
|
|
608
|
+
const hasClientSecret = clientInformation.client_secret !== void 0;
|
|
609
|
+
if (supportedMethods.length === 0) {
|
|
610
|
+
return hasClientSecret ? "client_secret_post" : "none";
|
|
611
|
+
}
|
|
612
|
+
if (hasClientSecret && supportedMethods.includes("client_secret_basic")) {
|
|
613
|
+
return "client_secret_basic";
|
|
614
|
+
}
|
|
615
|
+
if (hasClientSecret && supportedMethods.includes("client_secret_post")) {
|
|
616
|
+
return "client_secret_post";
|
|
617
|
+
}
|
|
618
|
+
if (supportedMethods.includes("none")) {
|
|
619
|
+
return "none";
|
|
620
|
+
}
|
|
621
|
+
return hasClientSecret ? "client_secret_post" : "none";
|
|
622
|
+
}
|
|
623
|
+
function applyClientAuthentication(method, clientInformation, headers, params) {
|
|
624
|
+
const { client_id, client_secret } = clientInformation;
|
|
625
|
+
switch (method) {
|
|
626
|
+
case "client_secret_basic":
|
|
627
|
+
applyBasicAuth(client_id, client_secret, headers);
|
|
628
|
+
return;
|
|
629
|
+
case "client_secret_post":
|
|
630
|
+
applyPostAuth(client_id, client_secret, params);
|
|
631
|
+
return;
|
|
632
|
+
case "none":
|
|
633
|
+
applyPublicAuth(client_id, params);
|
|
634
|
+
return;
|
|
635
|
+
default:
|
|
636
|
+
throw new Error(`Unsupported client authentication method: ${method}`);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
function applyBasicAuth(clientId, clientSecret, headers) {
|
|
640
|
+
if (!clientSecret) {
|
|
641
|
+
throw new Error(
|
|
642
|
+
"client_secret_basic authentication requires a client_secret"
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
const credentials = btoa(`${clientId}:${clientSecret}`);
|
|
646
|
+
headers.set("Authorization", `Basic ${credentials}`);
|
|
647
|
+
}
|
|
648
|
+
function applyPostAuth(clientId, clientSecret, params) {
|
|
649
|
+
params.set("client_id", clientId);
|
|
650
|
+
if (clientSecret) {
|
|
651
|
+
params.set("client_secret", clientSecret);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
function applyPublicAuth(clientId, params) {
|
|
655
|
+
params.set("client_id", clientId);
|
|
656
|
+
}
|
|
657
|
+
async function parseErrorResponse(input) {
|
|
658
|
+
const statusCode = input instanceof Response ? input.status : void 0;
|
|
659
|
+
const body = input instanceof Response ? await input.text() : input;
|
|
660
|
+
try {
|
|
661
|
+
const result = OAuthErrorResponseSchema.parse(JSON.parse(body));
|
|
662
|
+
const { error, error_description, error_uri } = result;
|
|
663
|
+
const errorClass = OAUTH_ERRORS[error] || ServerError;
|
|
664
|
+
return new errorClass({
|
|
665
|
+
message: error_description || "",
|
|
666
|
+
cause: error_uri
|
|
667
|
+
});
|
|
668
|
+
} catch (error) {
|
|
669
|
+
const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}Invalid OAuth error response: ${error}. Raw body: ${body}`;
|
|
670
|
+
return new ServerError({ message: errorMessage });
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
async function exchangeAuthorization(authorizationServerUrl, {
|
|
674
|
+
metadata,
|
|
675
|
+
clientInformation,
|
|
676
|
+
authorizationCode,
|
|
677
|
+
codeVerifier,
|
|
678
|
+
redirectUri,
|
|
679
|
+
resource,
|
|
680
|
+
addClientAuthentication,
|
|
681
|
+
fetchFn
|
|
682
|
+
}) {
|
|
683
|
+
var _a3;
|
|
684
|
+
const grantType = "authorization_code";
|
|
685
|
+
const tokenUrl = (metadata == null ? void 0 : metadata.token_endpoint) ? new URL(metadata.token_endpoint) : new URL("/token", authorizationServerUrl);
|
|
686
|
+
if ((metadata == null ? void 0 : metadata.grant_types_supported) && !metadata.grant_types_supported.includes(grantType)) {
|
|
687
|
+
throw new Error(
|
|
688
|
+
`Incompatible auth server: does not support grant type ${grantType}`
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
const headers = new Headers({
|
|
692
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
693
|
+
Accept: "application/json"
|
|
694
|
+
});
|
|
695
|
+
const params = new URLSearchParams({
|
|
696
|
+
grant_type: grantType,
|
|
697
|
+
code: authorizationCode,
|
|
698
|
+
code_verifier: codeVerifier,
|
|
699
|
+
redirect_uri: String(redirectUri)
|
|
700
|
+
});
|
|
701
|
+
if (addClientAuthentication) {
|
|
702
|
+
addClientAuthentication(headers, params, authorizationServerUrl, metadata);
|
|
703
|
+
} else {
|
|
704
|
+
const supportedMethods = (_a3 = metadata == null ? void 0 : metadata.token_endpoint_auth_methods_supported) != null ? _a3 : [];
|
|
705
|
+
const authMethod = selectClientAuthMethod(
|
|
706
|
+
clientInformation,
|
|
707
|
+
supportedMethods
|
|
708
|
+
);
|
|
709
|
+
applyClientAuthentication(authMethod, clientInformation, headers, params);
|
|
710
|
+
}
|
|
711
|
+
if (resource) {
|
|
712
|
+
params.set("resource", resource.href);
|
|
713
|
+
}
|
|
714
|
+
const response = await (fetchFn != null ? fetchFn : fetch)(tokenUrl, {
|
|
715
|
+
method: "POST",
|
|
716
|
+
headers,
|
|
717
|
+
body: params
|
|
718
|
+
});
|
|
719
|
+
if (!response.ok) {
|
|
720
|
+
throw await parseErrorResponse(response);
|
|
721
|
+
}
|
|
722
|
+
return OAuthTokensSchema.parse(await response.json());
|
|
723
|
+
}
|
|
724
|
+
async function refreshAuthorization(authorizationServerUrl, {
|
|
725
|
+
metadata,
|
|
726
|
+
clientInformation,
|
|
727
|
+
refreshToken,
|
|
728
|
+
resource,
|
|
729
|
+
addClientAuthentication,
|
|
730
|
+
fetchFn
|
|
731
|
+
}) {
|
|
732
|
+
var _a3;
|
|
733
|
+
const grantType = "refresh_token";
|
|
734
|
+
let tokenUrl;
|
|
735
|
+
if (metadata) {
|
|
736
|
+
tokenUrl = new URL(metadata.token_endpoint);
|
|
737
|
+
if (metadata.grant_types_supported && !metadata.grant_types_supported.includes(grantType)) {
|
|
738
|
+
throw new Error(
|
|
739
|
+
`Incompatible auth server: does not support grant type ${grantType}`
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
} else {
|
|
743
|
+
tokenUrl = new URL("/token", authorizationServerUrl);
|
|
744
|
+
}
|
|
745
|
+
const headers = new Headers({
|
|
746
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
747
|
+
});
|
|
748
|
+
const params = new URLSearchParams({
|
|
749
|
+
grant_type: grantType,
|
|
750
|
+
refresh_token: refreshToken
|
|
751
|
+
});
|
|
752
|
+
if (addClientAuthentication) {
|
|
753
|
+
addClientAuthentication(headers, params, authorizationServerUrl, metadata);
|
|
754
|
+
} else {
|
|
755
|
+
const supportedMethods = (_a3 = metadata == null ? void 0 : metadata.token_endpoint_auth_methods_supported) != null ? _a3 : [];
|
|
756
|
+
const authMethod = selectClientAuthMethod(
|
|
757
|
+
clientInformation,
|
|
758
|
+
supportedMethods
|
|
759
|
+
);
|
|
760
|
+
applyClientAuthentication(authMethod, clientInformation, headers, params);
|
|
761
|
+
}
|
|
762
|
+
if (resource) {
|
|
763
|
+
params.set("resource", resource.href);
|
|
764
|
+
}
|
|
765
|
+
const response = await (fetchFn != null ? fetchFn : fetch)(tokenUrl, {
|
|
766
|
+
method: "POST",
|
|
767
|
+
headers,
|
|
768
|
+
body: params
|
|
769
|
+
});
|
|
770
|
+
if (!response.ok) {
|
|
771
|
+
throw await parseErrorResponse(response);
|
|
772
|
+
}
|
|
773
|
+
return OAuthTokensSchema.parse({
|
|
774
|
+
refresh_token: refreshToken,
|
|
775
|
+
...await response.json()
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
async function registerClient(authorizationServerUrl, {
|
|
779
|
+
metadata,
|
|
780
|
+
clientMetadata,
|
|
781
|
+
fetchFn
|
|
782
|
+
}) {
|
|
783
|
+
let registrationUrl;
|
|
784
|
+
if (metadata) {
|
|
785
|
+
if (!metadata.registration_endpoint) {
|
|
786
|
+
throw new Error(
|
|
787
|
+
"Incompatible auth server: does not support dynamic client registration"
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
registrationUrl = new URL(metadata.registration_endpoint);
|
|
791
|
+
} else {
|
|
792
|
+
registrationUrl = new URL("/register", authorizationServerUrl);
|
|
793
|
+
}
|
|
794
|
+
const response = await (fetchFn != null ? fetchFn : fetch)(registrationUrl, {
|
|
795
|
+
method: "POST",
|
|
796
|
+
headers: {
|
|
797
|
+
"Content-Type": "application/json"
|
|
798
|
+
},
|
|
799
|
+
body: JSON.stringify(clientMetadata)
|
|
800
|
+
});
|
|
801
|
+
if (!response.ok) {
|
|
802
|
+
throw await parseErrorResponse(response);
|
|
803
|
+
}
|
|
804
|
+
return OAuthClientInformationFullSchema.parse(await response.json());
|
|
805
|
+
}
|
|
806
|
+
async function auth(provider, options) {
|
|
807
|
+
var _a3, _b3;
|
|
808
|
+
try {
|
|
809
|
+
return await authInternal(provider, options);
|
|
810
|
+
} catch (error) {
|
|
811
|
+
if (error instanceof InvalidClientError || error instanceof UnauthorizedClientError) {
|
|
812
|
+
await ((_a3 = provider.invalidateCredentials) == null ? void 0 : _a3.call(provider, "all"));
|
|
813
|
+
return await authInternal(provider, options);
|
|
814
|
+
} else if (error instanceof InvalidGrantError) {
|
|
815
|
+
await ((_b3 = provider.invalidateCredentials) == null ? void 0 : _b3.call(provider, "tokens"));
|
|
816
|
+
return await authInternal(provider, options);
|
|
817
|
+
}
|
|
818
|
+
throw error;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
async function selectResourceURL(serverUrl, provider, resourceMetadata) {
|
|
822
|
+
const defaultResource = resourceUrlFromServerUrl(serverUrl);
|
|
823
|
+
if (provider.validateResourceURL) {
|
|
824
|
+
return await provider.validateResourceURL(
|
|
825
|
+
defaultResource,
|
|
826
|
+
resourceMetadata == null ? void 0 : resourceMetadata.resource
|
|
827
|
+
);
|
|
828
|
+
}
|
|
829
|
+
if (!resourceMetadata) {
|
|
830
|
+
return void 0;
|
|
831
|
+
}
|
|
832
|
+
if (!checkResourceAllowed({
|
|
833
|
+
requestedResource: defaultResource,
|
|
834
|
+
configuredResource: resourceMetadata.resource
|
|
835
|
+
})) {
|
|
836
|
+
throw new Error(
|
|
837
|
+
`Protected resource ${resourceMetadata.resource} does not match expected ${defaultResource} (or origin)`
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
return new URL(resourceMetadata.resource);
|
|
841
|
+
}
|
|
842
|
+
async function authInternal(provider, {
|
|
843
|
+
serverUrl,
|
|
844
|
+
authorizationCode,
|
|
845
|
+
scope,
|
|
846
|
+
resourceMetadataUrl,
|
|
847
|
+
fetchFn
|
|
848
|
+
}) {
|
|
849
|
+
let resourceMetadata;
|
|
850
|
+
let authorizationServerUrl;
|
|
851
|
+
try {
|
|
852
|
+
resourceMetadata = await discoverOAuthProtectedResourceMetadata(
|
|
853
|
+
serverUrl,
|
|
854
|
+
{ resourceMetadataUrl },
|
|
855
|
+
fetchFn
|
|
856
|
+
);
|
|
857
|
+
if (resourceMetadata.authorization_servers && resourceMetadata.authorization_servers.length > 0) {
|
|
858
|
+
authorizationServerUrl = resourceMetadata.authorization_servers[0];
|
|
859
|
+
}
|
|
860
|
+
} catch (e) {
|
|
861
|
+
}
|
|
862
|
+
if (!authorizationServerUrl) {
|
|
863
|
+
authorizationServerUrl = serverUrl;
|
|
864
|
+
}
|
|
865
|
+
const resource = await selectResourceURL(
|
|
866
|
+
serverUrl,
|
|
867
|
+
provider,
|
|
868
|
+
resourceMetadata
|
|
869
|
+
);
|
|
870
|
+
const metadata = await discoverAuthorizationServerMetadata(
|
|
871
|
+
authorizationServerUrl,
|
|
872
|
+
{
|
|
873
|
+
fetchFn
|
|
874
|
+
}
|
|
875
|
+
);
|
|
876
|
+
let clientInformation = await Promise.resolve(provider.clientInformation());
|
|
877
|
+
if (!clientInformation) {
|
|
878
|
+
if (authorizationCode !== void 0) {
|
|
879
|
+
throw new Error(
|
|
880
|
+
"Existing OAuth client information is required when exchanging an authorization code"
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
if (!provider.saveClientInformation) {
|
|
884
|
+
throw new Error(
|
|
885
|
+
"OAuth client information must be saveable for dynamic registration"
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
const fullInformation = await registerClient(authorizationServerUrl, {
|
|
889
|
+
metadata,
|
|
890
|
+
clientMetadata: provider.clientMetadata,
|
|
891
|
+
fetchFn
|
|
892
|
+
});
|
|
893
|
+
await provider.saveClientInformation(fullInformation);
|
|
894
|
+
clientInformation = fullInformation;
|
|
895
|
+
}
|
|
896
|
+
if (authorizationCode !== void 0) {
|
|
897
|
+
const codeVerifier2 = await provider.codeVerifier();
|
|
898
|
+
const tokens2 = await exchangeAuthorization(authorizationServerUrl, {
|
|
899
|
+
metadata,
|
|
900
|
+
clientInformation,
|
|
901
|
+
authorizationCode,
|
|
902
|
+
codeVerifier: codeVerifier2,
|
|
903
|
+
redirectUri: provider.redirectUrl,
|
|
904
|
+
resource,
|
|
905
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
906
|
+
fetchFn
|
|
907
|
+
});
|
|
908
|
+
await provider.saveTokens(tokens2);
|
|
909
|
+
return "AUTHORIZED";
|
|
910
|
+
}
|
|
911
|
+
const tokens = await provider.tokens();
|
|
912
|
+
if (tokens == null ? void 0 : tokens.refresh_token) {
|
|
913
|
+
try {
|
|
914
|
+
const newTokens = await refreshAuthorization(authorizationServerUrl, {
|
|
915
|
+
metadata,
|
|
916
|
+
clientInformation,
|
|
917
|
+
refreshToken: tokens.refresh_token,
|
|
918
|
+
resource,
|
|
919
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
920
|
+
fetchFn
|
|
921
|
+
});
|
|
922
|
+
await provider.saveTokens(newTokens);
|
|
923
|
+
return "AUTHORIZED";
|
|
924
|
+
} catch (error) {
|
|
925
|
+
if (
|
|
926
|
+
// If this is a ServerError, or an unknown type, log it out and try to continue. Otherwise, escalate so we can fix things and retry.
|
|
927
|
+
!(error instanceof MCPClientOAuthError) || error instanceof ServerError
|
|
928
|
+
) {
|
|
929
|
+
} else {
|
|
930
|
+
throw error;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
const state = provider.state ? await provider.state() : void 0;
|
|
935
|
+
const { authorizationUrl, codeVerifier } = await startAuthorization(
|
|
936
|
+
authorizationServerUrl,
|
|
937
|
+
{
|
|
938
|
+
metadata,
|
|
939
|
+
clientInformation,
|
|
940
|
+
state,
|
|
941
|
+
redirectUrl: provider.redirectUrl,
|
|
942
|
+
scope: scope || provider.clientMetadata.scope,
|
|
943
|
+
resource
|
|
944
|
+
}
|
|
945
|
+
);
|
|
946
|
+
await provider.saveCodeVerifier(codeVerifier);
|
|
947
|
+
await provider.redirectToAuthorization(authorizationUrl);
|
|
948
|
+
return "REDIRECT";
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// src/tool/mcp-sse-transport.ts
|
|
952
|
+
var SseMCPTransport = class {
|
|
953
|
+
constructor({
|
|
954
|
+
url,
|
|
955
|
+
headers,
|
|
956
|
+
authProvider
|
|
957
|
+
}) {
|
|
958
|
+
this.connected = false;
|
|
959
|
+
this.url = new URL(url);
|
|
960
|
+
this.headers = headers;
|
|
961
|
+
this.authProvider = authProvider;
|
|
962
|
+
}
|
|
963
|
+
async commonHeaders(base) {
|
|
964
|
+
const headers = {
|
|
965
|
+
...this.headers,
|
|
966
|
+
...base,
|
|
967
|
+
"mcp-protocol-version": LATEST_PROTOCOL_VERSION
|
|
968
|
+
};
|
|
969
|
+
if (this.authProvider) {
|
|
970
|
+
const tokens = await this.authProvider.tokens();
|
|
971
|
+
if (tokens == null ? void 0 : tokens.access_token) {
|
|
972
|
+
headers["Authorization"] = `Bearer ${tokens.access_token}`;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
return (0, import_provider_utils.withUserAgentSuffix)(
|
|
976
|
+
headers,
|
|
977
|
+
`ai-sdk/${VERSION}`,
|
|
978
|
+
(0, import_provider_utils.getRuntimeEnvironmentUserAgent)()
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
async start() {
|
|
982
|
+
return new Promise((resolve, reject) => {
|
|
983
|
+
if (this.connected) {
|
|
984
|
+
return resolve();
|
|
985
|
+
}
|
|
986
|
+
this.abortController = new AbortController();
|
|
987
|
+
const establishConnection = async (triedAuth = false) => {
|
|
988
|
+
var _a3, _b3, _c, _d, _e;
|
|
989
|
+
try {
|
|
990
|
+
const headers = await this.commonHeaders({
|
|
991
|
+
Accept: "text/event-stream"
|
|
992
|
+
});
|
|
993
|
+
const response = await fetch(this.url.href, {
|
|
994
|
+
headers,
|
|
995
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
996
|
+
});
|
|
997
|
+
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
998
|
+
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
999
|
+
try {
|
|
1000
|
+
const result = await auth(this.authProvider, {
|
|
1001
|
+
serverUrl: this.url,
|
|
1002
|
+
resourceMetadataUrl: this.resourceMetadataUrl
|
|
1003
|
+
});
|
|
1004
|
+
if (result !== "AUTHORIZED") {
|
|
1005
|
+
const error = new UnauthorizedError();
|
|
1006
|
+
(_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
|
|
1007
|
+
return reject(error);
|
|
1008
|
+
}
|
|
1009
|
+
} catch (error) {
|
|
1010
|
+
(_c = this.onerror) == null ? void 0 : _c.call(this, error);
|
|
1011
|
+
return reject(error);
|
|
1012
|
+
}
|
|
1013
|
+
return establishConnection(true);
|
|
1014
|
+
}
|
|
1015
|
+
if (!response.ok || !response.body) {
|
|
1016
|
+
let errorMessage = `MCP SSE Transport Error: ${response.status} ${response.statusText}`;
|
|
1017
|
+
if (response.status === 405) {
|
|
1018
|
+
errorMessage += ". This server does not support SSE transport. Try using `http` transport instead";
|
|
1019
|
+
}
|
|
1020
|
+
const error = new MCPClientError({
|
|
1021
|
+
message: errorMessage
|
|
1022
|
+
});
|
|
1023
|
+
(_d = this.onerror) == null ? void 0 : _d.call(this, error);
|
|
1024
|
+
return reject(error);
|
|
1025
|
+
}
|
|
1026
|
+
const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new import_provider_utils.EventSourceParserStream());
|
|
1027
|
+
const reader = stream.getReader();
|
|
1028
|
+
const processEvents = async () => {
|
|
1029
|
+
var _a4, _b4, _c2;
|
|
1030
|
+
try {
|
|
1031
|
+
while (true) {
|
|
1032
|
+
const { done, value } = await reader.read();
|
|
1033
|
+
if (done) {
|
|
1034
|
+
if (this.connected) {
|
|
1035
|
+
this.connected = false;
|
|
1036
|
+
throw new MCPClientError({
|
|
1037
|
+
message: "MCP SSE Transport Error: Connection closed unexpectedly"
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
const { event, data } = value;
|
|
1043
|
+
if (event === "endpoint") {
|
|
1044
|
+
this.endpoint = new URL(data, this.url);
|
|
1045
|
+
if (this.endpoint.origin !== this.url.origin) {
|
|
1046
|
+
throw new MCPClientError({
|
|
1047
|
+
message: `MCP SSE Transport Error: Endpoint origin does not match connection origin: ${this.endpoint.origin}`
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
this.connected = true;
|
|
1051
|
+
resolve();
|
|
1052
|
+
} else if (event === "message") {
|
|
1053
|
+
try {
|
|
1054
|
+
const message = JSONRPCMessageSchema.parse(
|
|
1055
|
+
JSON.parse(data)
|
|
1056
|
+
);
|
|
1057
|
+
(_a4 = this.onmessage) == null ? void 0 : _a4.call(this, message);
|
|
1058
|
+
} catch (error) {
|
|
1059
|
+
const e = new MCPClientError({
|
|
1060
|
+
message: "MCP SSE Transport Error: Failed to parse message",
|
|
1061
|
+
cause: error
|
|
1062
|
+
});
|
|
1063
|
+
(_b4 = this.onerror) == null ? void 0 : _b4.call(this, e);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
} catch (error) {
|
|
1068
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
(_c2 = this.onerror) == null ? void 0 : _c2.call(this, error);
|
|
1072
|
+
reject(error);
|
|
1073
|
+
}
|
|
1074
|
+
};
|
|
1075
|
+
this.sseConnection = {
|
|
1076
|
+
close: () => reader.cancel()
|
|
1077
|
+
};
|
|
1078
|
+
processEvents();
|
|
1079
|
+
} catch (error) {
|
|
1080
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
(_e = this.onerror) == null ? void 0 : _e.call(this, error);
|
|
1084
|
+
reject(error);
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
void establishConnection();
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
async close() {
|
|
1091
|
+
var _a3, _b3, _c;
|
|
1092
|
+
this.connected = false;
|
|
1093
|
+
(_a3 = this.sseConnection) == null ? void 0 : _a3.close();
|
|
1094
|
+
(_b3 = this.abortController) == null ? void 0 : _b3.abort();
|
|
1095
|
+
(_c = this.onclose) == null ? void 0 : _c.call(this);
|
|
1096
|
+
}
|
|
1097
|
+
async send(message) {
|
|
1098
|
+
if (!this.endpoint || !this.connected) {
|
|
1099
|
+
throw new MCPClientError({
|
|
1100
|
+
message: "MCP SSE Transport Error: Not connected"
|
|
1101
|
+
});
|
|
1102
|
+
}
|
|
1103
|
+
const endpoint = this.endpoint;
|
|
1104
|
+
const attempt = async (triedAuth = false) => {
|
|
1105
|
+
var _a3, _b3, _c, _d, _e;
|
|
1106
|
+
try {
|
|
1107
|
+
const headers = await this.commonHeaders({
|
|
1108
|
+
"Content-Type": "application/json"
|
|
1109
|
+
});
|
|
1110
|
+
const init = {
|
|
1111
|
+
method: "POST",
|
|
1112
|
+
headers,
|
|
1113
|
+
body: JSON.stringify(message),
|
|
1114
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1115
|
+
};
|
|
1116
|
+
const response = await fetch(endpoint, init);
|
|
1117
|
+
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1118
|
+
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
1119
|
+
try {
|
|
1120
|
+
const result = await auth(this.authProvider, {
|
|
1121
|
+
serverUrl: this.url,
|
|
1122
|
+
resourceMetadataUrl: this.resourceMetadataUrl
|
|
1123
|
+
});
|
|
1124
|
+
if (result !== "AUTHORIZED") {
|
|
1125
|
+
const error = new UnauthorizedError();
|
|
1126
|
+
(_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
|
|
1127
|
+
return;
|
|
1128
|
+
}
|
|
1129
|
+
} catch (error) {
|
|
1130
|
+
(_c = this.onerror) == null ? void 0 : _c.call(this, error);
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
return attempt(true);
|
|
1134
|
+
}
|
|
1135
|
+
if (!response.ok) {
|
|
1136
|
+
const text = await response.text().catch(() => null);
|
|
1137
|
+
const error = new MCPClientError({
|
|
1138
|
+
message: `MCP SSE Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}`
|
|
1139
|
+
});
|
|
1140
|
+
(_d = this.onerror) == null ? void 0 : _d.call(this, error);
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
1143
|
+
} catch (error) {
|
|
1144
|
+
(_e = this.onerror) == null ? void 0 : _e.call(this, error);
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1148
|
+
await attempt();
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
|
|
1152
|
+
// src/tool/mcp-http-transport.ts
|
|
1153
|
+
var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
|
1154
|
+
var HttpMCPTransport = class {
|
|
1155
|
+
constructor({
|
|
1156
|
+
url,
|
|
1157
|
+
headers,
|
|
1158
|
+
authProvider
|
|
1159
|
+
}) {
|
|
1160
|
+
this.inboundReconnectAttempts = 0;
|
|
1161
|
+
this.reconnectionOptions = {
|
|
1162
|
+
initialReconnectionDelay: 1e3,
|
|
1163
|
+
maxReconnectionDelay: 3e4,
|
|
1164
|
+
reconnectionDelayGrowFactor: 1.5,
|
|
1165
|
+
maxRetries: 2
|
|
1166
|
+
};
|
|
1167
|
+
this.url = new URL(url);
|
|
1168
|
+
this.headers = headers;
|
|
1169
|
+
this.authProvider = authProvider;
|
|
1170
|
+
}
|
|
1171
|
+
async commonHeaders(base) {
|
|
1172
|
+
const headers = {
|
|
1173
|
+
...this.headers,
|
|
1174
|
+
...base,
|
|
1175
|
+
"mcp-protocol-version": LATEST_PROTOCOL_VERSION
|
|
1176
|
+
};
|
|
1177
|
+
if (this.sessionId) {
|
|
1178
|
+
headers["mcp-session-id"] = this.sessionId;
|
|
1179
|
+
}
|
|
1180
|
+
if (this.authProvider) {
|
|
1181
|
+
const tokens = await this.authProvider.tokens();
|
|
1182
|
+
if (tokens == null ? void 0 : tokens.access_token) {
|
|
1183
|
+
headers["Authorization"] = `Bearer ${tokens.access_token}`;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
return (0, import_provider_utils2.withUserAgentSuffix)(
|
|
1187
|
+
headers,
|
|
1188
|
+
`ai-sdk/${VERSION}`,
|
|
1189
|
+
(0, import_provider_utils2.getRuntimeEnvironmentUserAgent)()
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1192
|
+
async start() {
|
|
1193
|
+
if (this.abortController) {
|
|
1194
|
+
throw new MCPClientError({
|
|
1195
|
+
message: "MCP HTTP Transport Error: Transport already started. Note: client.connect() calls start() automatically."
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
this.abortController = new AbortController();
|
|
1199
|
+
void this.openInboundSse();
|
|
1200
|
+
}
|
|
1201
|
+
async close() {
|
|
1202
|
+
var _a3, _b3, _c;
|
|
1203
|
+
(_a3 = this.inboundSseConnection) == null ? void 0 : _a3.close();
|
|
1204
|
+
try {
|
|
1205
|
+
if (this.sessionId && this.abortController && !this.abortController.signal.aborted) {
|
|
1206
|
+
const headers = await this.commonHeaders({});
|
|
1207
|
+
await fetch(this.url, {
|
|
1208
|
+
method: "DELETE",
|
|
1209
|
+
headers,
|
|
1210
|
+
signal: this.abortController.signal
|
|
1211
|
+
}).catch(() => void 0);
|
|
1212
|
+
}
|
|
1213
|
+
} catch (e) {
|
|
1214
|
+
}
|
|
1215
|
+
(_b3 = this.abortController) == null ? void 0 : _b3.abort();
|
|
1216
|
+
(_c = this.onclose) == null ? void 0 : _c.call(this);
|
|
1217
|
+
}
|
|
1218
|
+
async send(message) {
|
|
1219
|
+
const attempt = async (triedAuth = false) => {
|
|
1220
|
+
var _a3, _b3, _c, _d, _e, _f, _g;
|
|
1221
|
+
try {
|
|
1222
|
+
const headers = await this.commonHeaders({
|
|
1223
|
+
"Content-Type": "application/json",
|
|
1224
|
+
Accept: "application/json, text/event-stream"
|
|
1225
|
+
});
|
|
1226
|
+
const init = {
|
|
1227
|
+
method: "POST",
|
|
1228
|
+
headers,
|
|
1229
|
+
body: JSON.stringify(message),
|
|
1230
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1231
|
+
};
|
|
1232
|
+
const response = await fetch(this.url, init);
|
|
1233
|
+
const sessionId = response.headers.get("mcp-session-id");
|
|
1234
|
+
if (sessionId) {
|
|
1235
|
+
this.sessionId = sessionId;
|
|
1236
|
+
}
|
|
1237
|
+
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1238
|
+
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
1239
|
+
try {
|
|
1240
|
+
const result = await auth(this.authProvider, {
|
|
1241
|
+
serverUrl: this.url,
|
|
1242
|
+
resourceMetadataUrl: this.resourceMetadataUrl
|
|
1243
|
+
});
|
|
1244
|
+
if (result !== "AUTHORIZED") {
|
|
1245
|
+
const error2 = new UnauthorizedError();
|
|
1246
|
+
throw error2;
|
|
1247
|
+
}
|
|
1248
|
+
} catch (error2) {
|
|
1249
|
+
(_b3 = this.onerror) == null ? void 0 : _b3.call(this, error2);
|
|
1250
|
+
throw error2;
|
|
1251
|
+
}
|
|
1252
|
+
return attempt(true);
|
|
1253
|
+
}
|
|
1254
|
+
if (response.status === 202) {
|
|
1255
|
+
if (!this.inboundSseConnection) {
|
|
1256
|
+
void this.openInboundSse();
|
|
1257
|
+
}
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
if (!response.ok) {
|
|
1261
|
+
const text = await response.text().catch(() => null);
|
|
1262
|
+
let errorMessage = `MCP HTTP Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}`;
|
|
1263
|
+
if (response.status === 404) {
|
|
1264
|
+
errorMessage += ". This server does not support HTTP transport. Try using `sse` transport instead";
|
|
1265
|
+
}
|
|
1266
|
+
const error2 = new MCPClientError({
|
|
1267
|
+
message: errorMessage
|
|
1268
|
+
});
|
|
1269
|
+
(_c = this.onerror) == null ? void 0 : _c.call(this, error2);
|
|
1270
|
+
throw error2;
|
|
1271
|
+
}
|
|
1272
|
+
const contentType = response.headers.get("content-type") || "";
|
|
1273
|
+
if (contentType.includes("application/json")) {
|
|
1274
|
+
const data = await response.json();
|
|
1275
|
+
const messages = Array.isArray(data) ? data.map((m) => JSONRPCMessageSchema.parse(m)) : [JSONRPCMessageSchema.parse(data)];
|
|
1276
|
+
for (const m of messages) (_d = this.onmessage) == null ? void 0 : _d.call(this, m);
|
|
1277
|
+
return;
|
|
1278
|
+
}
|
|
1279
|
+
if (contentType.includes("text/event-stream")) {
|
|
1280
|
+
if (!response.body) {
|
|
1281
|
+
const error2 = new MCPClientError({
|
|
1282
|
+
message: "MCP HTTP Transport Error: text/event-stream response without body"
|
|
1283
|
+
});
|
|
1284
|
+
(_e = this.onerror) == null ? void 0 : _e.call(this, error2);
|
|
1285
|
+
throw error2;
|
|
1286
|
+
}
|
|
1287
|
+
const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new import_provider_utils2.EventSourceParserStream());
|
|
1288
|
+
const reader = stream.getReader();
|
|
1289
|
+
const processEvents = async () => {
|
|
1290
|
+
var _a4, _b4, _c2;
|
|
1291
|
+
try {
|
|
1292
|
+
while (true) {
|
|
1293
|
+
const { done, value } = await reader.read();
|
|
1294
|
+
if (done) return;
|
|
1295
|
+
const { event, data } = value;
|
|
1296
|
+
if (event === "message") {
|
|
1297
|
+
try {
|
|
1298
|
+
const msg = JSONRPCMessageSchema.parse(JSON.parse(data));
|
|
1299
|
+
(_a4 = this.onmessage) == null ? void 0 : _a4.call(this, msg);
|
|
1300
|
+
} catch (error2) {
|
|
1301
|
+
const e = new MCPClientError({
|
|
1302
|
+
message: "MCP HTTP Transport Error: Failed to parse message",
|
|
1303
|
+
cause: error2
|
|
1304
|
+
});
|
|
1305
|
+
(_b4 = this.onerror) == null ? void 0 : _b4.call(this, e);
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
} catch (error2) {
|
|
1310
|
+
if (error2 instanceof Error && error2.name === "AbortError") {
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
(_c2 = this.onerror) == null ? void 0 : _c2.call(this, error2);
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
processEvents();
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
const error = new MCPClientError({
|
|
1320
|
+
message: `MCP HTTP Transport Error: Unexpected content type: ${contentType}`
|
|
1321
|
+
});
|
|
1322
|
+
(_f = this.onerror) == null ? void 0 : _f.call(this, error);
|
|
1323
|
+
throw error;
|
|
1324
|
+
} catch (error) {
|
|
1325
|
+
(_g = this.onerror) == null ? void 0 : _g.call(this, error);
|
|
1326
|
+
throw error;
|
|
1327
|
+
}
|
|
1328
|
+
};
|
|
1329
|
+
await attempt();
|
|
1330
|
+
}
|
|
1331
|
+
getNextReconnectionDelay(attempt) {
|
|
1332
|
+
const {
|
|
1333
|
+
initialReconnectionDelay,
|
|
1334
|
+
reconnectionDelayGrowFactor,
|
|
1335
|
+
maxReconnectionDelay
|
|
1336
|
+
} = this.reconnectionOptions;
|
|
1337
|
+
return Math.min(
|
|
1338
|
+
initialReconnectionDelay * Math.pow(reconnectionDelayGrowFactor, attempt),
|
|
1339
|
+
maxReconnectionDelay
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
scheduleInboundSseReconnection() {
|
|
1343
|
+
var _a3;
|
|
1344
|
+
const { maxRetries } = this.reconnectionOptions;
|
|
1345
|
+
if (maxRetries > 0 && this.inboundReconnectAttempts >= maxRetries) {
|
|
1346
|
+
(_a3 = this.onerror) == null ? void 0 : _a3.call(
|
|
1347
|
+
this,
|
|
1348
|
+
new MCPClientError({
|
|
1349
|
+
message: `MCP HTTP Transport Error: Maximum reconnection attempts (${maxRetries}) exceeded.`
|
|
1350
|
+
})
|
|
1351
|
+
);
|
|
1352
|
+
return;
|
|
1353
|
+
}
|
|
1354
|
+
const delay = this.getNextReconnectionDelay(this.inboundReconnectAttempts);
|
|
1355
|
+
this.inboundReconnectAttempts += 1;
|
|
1356
|
+
setTimeout(async () => {
|
|
1357
|
+
var _a4;
|
|
1358
|
+
if ((_a4 = this.abortController) == null ? void 0 : _a4.signal.aborted) return;
|
|
1359
|
+
await this.openInboundSse(false, this.lastInboundEventId);
|
|
1360
|
+
}, delay);
|
|
1361
|
+
}
|
|
1362
|
+
// Open optional inbound SSE stream; best-effort and resumable
|
|
1363
|
+
async openInboundSse(triedAuth = false, resumeToken) {
|
|
1364
|
+
var _a3, _b3, _c, _d, _e, _f;
|
|
1365
|
+
try {
|
|
1366
|
+
const headers = await this.commonHeaders({
|
|
1367
|
+
Accept: "text/event-stream"
|
|
1368
|
+
});
|
|
1369
|
+
if (resumeToken) {
|
|
1370
|
+
headers["last-event-id"] = resumeToken;
|
|
1371
|
+
}
|
|
1372
|
+
const response = await fetch(this.url.href, {
|
|
1373
|
+
method: "GET",
|
|
1374
|
+
headers,
|
|
1375
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1376
|
+
});
|
|
1377
|
+
const sessionId = response.headers.get("mcp-session-id");
|
|
1378
|
+
if (sessionId) {
|
|
1379
|
+
this.sessionId = sessionId;
|
|
1380
|
+
}
|
|
1381
|
+
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1382
|
+
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
1383
|
+
try {
|
|
1384
|
+
const result = await auth(this.authProvider, {
|
|
1385
|
+
serverUrl: this.url,
|
|
1386
|
+
resourceMetadataUrl: this.resourceMetadataUrl
|
|
1387
|
+
});
|
|
1388
|
+
if (result !== "AUTHORIZED") {
|
|
1389
|
+
const error = new UnauthorizedError();
|
|
1390
|
+
(_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
} catch (error) {
|
|
1394
|
+
(_c = this.onerror) == null ? void 0 : _c.call(this, error);
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1397
|
+
return this.openInboundSse(true, resumeToken);
|
|
1398
|
+
}
|
|
1399
|
+
if (response.status === 405) {
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
if (!response.ok || !response.body) {
|
|
1403
|
+
const error = new MCPClientError({
|
|
1404
|
+
message: `MCP HTTP Transport Error: GET SSE failed: ${response.status} ${response.statusText}`
|
|
1405
|
+
});
|
|
1406
|
+
(_d = this.onerror) == null ? void 0 : _d.call(this, error);
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new import_provider_utils2.EventSourceParserStream());
|
|
1410
|
+
const reader = stream.getReader();
|
|
1411
|
+
const processEvents = async () => {
|
|
1412
|
+
var _a4, _b4, _c2, _d2;
|
|
1413
|
+
try {
|
|
1414
|
+
while (true) {
|
|
1415
|
+
const { done, value } = await reader.read();
|
|
1416
|
+
if (done) return;
|
|
1417
|
+
const { event, data, id } = value;
|
|
1418
|
+
if (id) {
|
|
1419
|
+
this.lastInboundEventId = id;
|
|
1420
|
+
}
|
|
1421
|
+
if (event === "message") {
|
|
1422
|
+
try {
|
|
1423
|
+
const msg = JSONRPCMessageSchema.parse(JSON.parse(data));
|
|
1424
|
+
(_a4 = this.onmessage) == null ? void 0 : _a4.call(this, msg);
|
|
1425
|
+
} catch (error) {
|
|
1426
|
+
const e = new MCPClientError({
|
|
1427
|
+
message: "MCP HTTP Transport Error: Failed to parse message",
|
|
1428
|
+
cause: error
|
|
1429
|
+
});
|
|
1430
|
+
(_b4 = this.onerror) == null ? void 0 : _b4.call(this, e);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
} catch (error) {
|
|
1435
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1438
|
+
(_c2 = this.onerror) == null ? void 0 : _c2.call(this, error);
|
|
1439
|
+
if (!((_d2 = this.abortController) == null ? void 0 : _d2.signal.aborted)) {
|
|
1440
|
+
this.scheduleInboundSseReconnection();
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
};
|
|
1444
|
+
this.inboundSseConnection = {
|
|
1445
|
+
close: () => reader.cancel()
|
|
1446
|
+
};
|
|
1447
|
+
this.inboundReconnectAttempts = 0;
|
|
1448
|
+
processEvents();
|
|
1449
|
+
} catch (error) {
|
|
1450
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1453
|
+
(_e = this.onerror) == null ? void 0 : _e.call(this, error);
|
|
1454
|
+
if (!((_f = this.abortController) == null ? void 0 : _f.signal.aborted)) {
|
|
1455
|
+
this.scheduleInboundSseReconnection();
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
};
|
|
1460
|
+
|
|
1461
|
+
// src/tool/mcp-transport.ts
|
|
1462
|
+
function createMcpTransport(config) {
|
|
1463
|
+
switch (config.type) {
|
|
1464
|
+
case "sse":
|
|
1465
|
+
return new SseMCPTransport(config);
|
|
1466
|
+
case "http":
|
|
1467
|
+
return new HttpMCPTransport(config);
|
|
1468
|
+
default:
|
|
1469
|
+
throw new MCPClientError({
|
|
1470
|
+
message: "Unsupported or invalid transport configuration. If you are using a custom transport, make sure it implements the MCPTransport interface."
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
function isCustomMcpTransport(transport) {
|
|
1475
|
+
return "start" in transport && typeof transport.start === "function" && "send" in transport && typeof transport.send === "function" && "close" in transport && typeof transport.close === "function";
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
// src/tool/mcp-client.ts
|
|
1479
|
+
var CLIENT_VERSION = "1.0.0";
|
|
1480
|
+
async function createMCPClient(config) {
|
|
1481
|
+
const client = new DefaultMCPClient(config);
|
|
1482
|
+
await client.init();
|
|
1483
|
+
return client;
|
|
1484
|
+
}
|
|
1485
|
+
var DefaultMCPClient = class {
|
|
1486
|
+
constructor({
|
|
1487
|
+
transport: transportConfig,
|
|
1488
|
+
name: name3 = "ai-sdk-mcp-client",
|
|
1489
|
+
onUncaughtError
|
|
1490
|
+
}) {
|
|
1491
|
+
this.requestMessageId = 0;
|
|
1492
|
+
this.responseHandlers = /* @__PURE__ */ new Map();
|
|
1493
|
+
this.serverCapabilities = {};
|
|
1494
|
+
this.isClosed = true;
|
|
1495
|
+
this.onUncaughtError = onUncaughtError;
|
|
1496
|
+
if (isCustomMcpTransport(transportConfig)) {
|
|
1497
|
+
this.transport = transportConfig;
|
|
1498
|
+
} else {
|
|
1499
|
+
this.transport = createMcpTransport(transportConfig);
|
|
1500
|
+
}
|
|
1501
|
+
this.transport.onclose = () => this.onClose();
|
|
1502
|
+
this.transport.onerror = (error) => this.onError(error);
|
|
1503
|
+
this.transport.onmessage = (message) => {
|
|
1504
|
+
if ("method" in message) {
|
|
1505
|
+
this.onError(
|
|
1506
|
+
new MCPClientError({
|
|
1507
|
+
message: "Unsupported message type"
|
|
1508
|
+
})
|
|
1509
|
+
);
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
this.onResponse(message);
|
|
1513
|
+
};
|
|
1514
|
+
this.clientInfo = {
|
|
1515
|
+
name: name3,
|
|
1516
|
+
version: CLIENT_VERSION
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
async init() {
|
|
1520
|
+
try {
|
|
1521
|
+
await this.transport.start();
|
|
1522
|
+
this.isClosed = false;
|
|
1523
|
+
const result = await this.request({
|
|
1524
|
+
request: {
|
|
1525
|
+
method: "initialize",
|
|
1526
|
+
params: {
|
|
1527
|
+
protocolVersion: LATEST_PROTOCOL_VERSION,
|
|
1528
|
+
capabilities: {},
|
|
1529
|
+
clientInfo: this.clientInfo
|
|
1530
|
+
}
|
|
1531
|
+
},
|
|
1532
|
+
resultSchema: InitializeResultSchema
|
|
1533
|
+
});
|
|
1534
|
+
if (result === void 0) {
|
|
1535
|
+
throw new MCPClientError({
|
|
1536
|
+
message: "Server sent invalid initialize result"
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
if (!SUPPORTED_PROTOCOL_VERSIONS.includes(result.protocolVersion)) {
|
|
1540
|
+
throw new MCPClientError({
|
|
1541
|
+
message: `Server's protocol version is not supported: ${result.protocolVersion}`
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
this.serverCapabilities = result.capabilities;
|
|
1545
|
+
await this.notification({
|
|
1546
|
+
method: "notifications/initialized"
|
|
1547
|
+
});
|
|
1548
|
+
return this;
|
|
1549
|
+
} catch (error) {
|
|
1550
|
+
await this.close();
|
|
1551
|
+
throw error;
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
async close() {
|
|
1555
|
+
var _a3;
|
|
1556
|
+
if (this.isClosed) return;
|
|
1557
|
+
await ((_a3 = this.transport) == null ? void 0 : _a3.close());
|
|
1558
|
+
this.onClose();
|
|
1559
|
+
}
|
|
1560
|
+
assertCapability(method) {
|
|
1561
|
+
switch (method) {
|
|
1562
|
+
case "initialize":
|
|
1563
|
+
break;
|
|
1564
|
+
case "tools/list":
|
|
1565
|
+
case "tools/call":
|
|
1566
|
+
if (!this.serverCapabilities.tools) {
|
|
1567
|
+
throw new MCPClientError({
|
|
1568
|
+
message: `Server does not support tools`
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
break;
|
|
1572
|
+
default:
|
|
1573
|
+
throw new MCPClientError({
|
|
1574
|
+
message: `Unsupported method: ${method}`
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
async request({
|
|
1579
|
+
request,
|
|
1580
|
+
resultSchema,
|
|
1581
|
+
options
|
|
1582
|
+
}) {
|
|
1583
|
+
return new Promise((resolve, reject) => {
|
|
1584
|
+
if (this.isClosed) {
|
|
1585
|
+
return reject(
|
|
1586
|
+
new MCPClientError({
|
|
1587
|
+
message: "Attempted to send a request from a closed client"
|
|
1588
|
+
})
|
|
1589
|
+
);
|
|
1590
|
+
}
|
|
1591
|
+
this.assertCapability(request.method);
|
|
1592
|
+
const signal = options == null ? void 0 : options.signal;
|
|
1593
|
+
signal == null ? void 0 : signal.throwIfAborted();
|
|
1594
|
+
const messageId = this.requestMessageId++;
|
|
1595
|
+
const jsonrpcRequest = {
|
|
1596
|
+
...request,
|
|
1597
|
+
jsonrpc: "2.0",
|
|
1598
|
+
id: messageId
|
|
1599
|
+
};
|
|
1600
|
+
const cleanup = () => {
|
|
1601
|
+
this.responseHandlers.delete(messageId);
|
|
1602
|
+
};
|
|
1603
|
+
this.responseHandlers.set(messageId, (response) => {
|
|
1604
|
+
if (signal == null ? void 0 : signal.aborted) {
|
|
1605
|
+
return reject(
|
|
1606
|
+
new MCPClientError({
|
|
1607
|
+
message: "Request was aborted",
|
|
1608
|
+
cause: signal.reason
|
|
1609
|
+
})
|
|
1610
|
+
);
|
|
1611
|
+
}
|
|
1612
|
+
if (response instanceof Error) {
|
|
1613
|
+
return reject(response);
|
|
1614
|
+
}
|
|
1615
|
+
try {
|
|
1616
|
+
const result = resultSchema.parse(response.result);
|
|
1617
|
+
resolve(result);
|
|
1618
|
+
} catch (error) {
|
|
1619
|
+
const parseError = new MCPClientError({
|
|
1620
|
+
message: "Failed to parse server response",
|
|
1621
|
+
cause: error
|
|
1622
|
+
});
|
|
1623
|
+
reject(parseError);
|
|
1624
|
+
}
|
|
1625
|
+
});
|
|
1626
|
+
this.transport.send(jsonrpcRequest).catch((error) => {
|
|
1627
|
+
cleanup();
|
|
1628
|
+
reject(error);
|
|
1629
|
+
});
|
|
1630
|
+
});
|
|
1631
|
+
}
|
|
1632
|
+
async listTools({
|
|
1633
|
+
params,
|
|
1634
|
+
options
|
|
1635
|
+
} = {}) {
|
|
1636
|
+
try {
|
|
1637
|
+
return this.request({
|
|
1638
|
+
request: { method: "tools/list", params },
|
|
1639
|
+
resultSchema: ListToolsResultSchema,
|
|
1640
|
+
options
|
|
1641
|
+
});
|
|
1642
|
+
} catch (error) {
|
|
1643
|
+
throw error;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
async callTool({
|
|
1647
|
+
name: name3,
|
|
1648
|
+
args,
|
|
1649
|
+
options
|
|
1650
|
+
}) {
|
|
1651
|
+
try {
|
|
1652
|
+
return this.request({
|
|
1653
|
+
request: { method: "tools/call", params: { name: name3, arguments: args } },
|
|
1654
|
+
resultSchema: CallToolResultSchema,
|
|
1655
|
+
options: {
|
|
1656
|
+
signal: options == null ? void 0 : options.abortSignal
|
|
1657
|
+
}
|
|
1658
|
+
});
|
|
1659
|
+
} catch (error) {
|
|
1660
|
+
throw error;
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
async notification(notification) {
|
|
1664
|
+
const jsonrpcNotification = {
|
|
1665
|
+
...notification,
|
|
1666
|
+
jsonrpc: "2.0"
|
|
1667
|
+
};
|
|
1668
|
+
await this.transport.send(jsonrpcNotification);
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* Returns a set of AI SDK tools from the MCP server
|
|
1672
|
+
* @returns A record of tool names to their implementations
|
|
1673
|
+
*/
|
|
1674
|
+
async tools({
|
|
1675
|
+
schemas = "automatic"
|
|
1676
|
+
} = {}) {
|
|
1677
|
+
var _a3;
|
|
1678
|
+
const tools = {};
|
|
1679
|
+
try {
|
|
1680
|
+
const listToolsResult = await this.listTools();
|
|
1681
|
+
for (const { name: name3, description, inputSchema } of listToolsResult.tools) {
|
|
1682
|
+
if (schemas !== "automatic" && !(name3 in schemas)) {
|
|
1683
|
+
continue;
|
|
1684
|
+
}
|
|
1685
|
+
const self = this;
|
|
1686
|
+
const execute = async (args, options) => {
|
|
1687
|
+
var _a4;
|
|
1688
|
+
(_a4 = options == null ? void 0 : options.abortSignal) == null ? void 0 : _a4.throwIfAborted();
|
|
1689
|
+
return self.callTool({ name: name3, args, options });
|
|
1690
|
+
};
|
|
1691
|
+
const toolWithExecute = schemas === "automatic" ? (0, import_provider_utils3.dynamicTool)({
|
|
1692
|
+
description,
|
|
1693
|
+
inputSchema: (0, import_provider_utils3.jsonSchema)({
|
|
1694
|
+
...inputSchema,
|
|
1695
|
+
properties: (_a3 = inputSchema.properties) != null ? _a3 : {},
|
|
1696
|
+
additionalProperties: false
|
|
1697
|
+
}),
|
|
1698
|
+
execute
|
|
1699
|
+
}) : (0, import_provider_utils3.tool)({
|
|
1700
|
+
description,
|
|
1701
|
+
inputSchema: schemas[name3].inputSchema,
|
|
1702
|
+
execute
|
|
1703
|
+
});
|
|
1704
|
+
tools[name3] = toolWithExecute;
|
|
1705
|
+
}
|
|
1706
|
+
return tools;
|
|
1707
|
+
} catch (error) {
|
|
1708
|
+
throw error;
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
onClose() {
|
|
1712
|
+
if (this.isClosed) return;
|
|
1713
|
+
this.isClosed = true;
|
|
1714
|
+
const error = new MCPClientError({
|
|
1715
|
+
message: "Connection closed"
|
|
1716
|
+
});
|
|
1717
|
+
for (const handler of this.responseHandlers.values()) {
|
|
1718
|
+
handler(error);
|
|
1719
|
+
}
|
|
1720
|
+
this.responseHandlers.clear();
|
|
1721
|
+
}
|
|
1722
|
+
onError(error) {
|
|
1723
|
+
if (this.onUncaughtError) {
|
|
1724
|
+
this.onUncaughtError(error);
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
onResponse(response) {
|
|
1728
|
+
const messageId = Number(response.id);
|
|
1729
|
+
const handler = this.responseHandlers.get(messageId);
|
|
1730
|
+
if (handler === void 0) {
|
|
1731
|
+
throw new MCPClientError({
|
|
1732
|
+
message: `Protocol error: Received a response for an unknown message ID: ${JSON.stringify(
|
|
1733
|
+
response
|
|
1734
|
+
)}`
|
|
1735
|
+
});
|
|
1736
|
+
}
|
|
1737
|
+
this.responseHandlers.delete(messageId);
|
|
1738
|
+
handler(
|
|
1739
|
+
"result" in response ? response : new MCPClientError({
|
|
1740
|
+
message: response.error.message,
|
|
1741
|
+
code: response.error.code,
|
|
1742
|
+
data: response.error.data,
|
|
1743
|
+
cause: response.error
|
|
1744
|
+
})
|
|
1745
|
+
);
|
|
1746
|
+
}
|
|
1747
|
+
};
|
|
1748
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1749
|
+
0 && (module.exports = {
|
|
1750
|
+
UnauthorizedError,
|
|
1751
|
+
auth,
|
|
1752
|
+
experimental_createMCPClient
|
|
1753
|
+
});
|
|
1754
|
+
//# sourceMappingURL=index.js.map
|