@ai-sdk/mcp 2.0.0-beta.5 → 2.0.0-beta.66
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 +496 -8
- package/README.md +134 -0
- package/dist/index.d.ts +146 -1
- package/dist/index.js +764 -350
- package/dist/index.js.map +1 -1
- package/dist/mcp-stdio/index.d.ts +8 -0
- package/dist/mcp-stdio/index.js +170 -172
- package/dist/mcp-stdio/index.js.map +1 -1
- package/package.json +18 -19
- package/src/error/mcp-client-error.ts +40 -0
- package/src/index.ts +16 -1
- package/src/tool/index.ts +1 -0
- package/src/tool/json-rpc-message.ts +7 -0
- package/src/tool/mcp-apps.ts +254 -0
- package/src/tool/mcp-client.ts +128 -43
- package/src/tool/mcp-http-transport.ts +78 -23
- package/src/tool/mcp-sse-transport.ts +47 -15
- package/src/tool/mcp-stdio/create-child-process.ts +2 -2
- package/src/tool/mcp-stdio/mcp-stdio-transport.ts +17 -14
- package/src/tool/mcp-transport.ts +28 -2
- package/src/tool/mock-mcp-transport.ts +8 -9
- package/src/tool/oauth-types.ts +22 -18
- package/src/tool/oauth.ts +324 -37
- package/src/tool/types.ts +27 -3
- package/src/util/oauth-util.ts +13 -0
- package/dist/index.d.mts +0 -509
- package/dist/index.mjs +0 -2128
- package/dist/index.mjs.map +0 -1
- package/dist/mcp-stdio/index.d.mts +0 -89
- package/dist/mcp-stdio/index.mjs +0 -426
- package/dist/mcp-stdio/index.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,79 +1,56 @@
|
|
|
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 index_exports = {};
|
|
32
|
-
__export(index_exports, {
|
|
33
|
-
ElicitResultSchema: () => ElicitResultSchema,
|
|
34
|
-
ElicitationRequestSchema: () => ElicitationRequestSchema,
|
|
35
|
-
UnauthorizedError: () => UnauthorizedError,
|
|
36
|
-
auth: () => auth,
|
|
37
|
-
createMCPClient: () => createMCPClient,
|
|
38
|
-
experimental_createMCPClient: () => createMCPClient
|
|
39
|
-
});
|
|
40
|
-
module.exports = __toCommonJS(index_exports);
|
|
41
|
-
|
|
42
1
|
// src/tool/mcp-client.ts
|
|
43
|
-
|
|
2
|
+
import {
|
|
3
|
+
asSchema,
|
|
4
|
+
dynamicTool,
|
|
5
|
+
jsonSchema,
|
|
6
|
+
safeParseJSON,
|
|
7
|
+
safeValidateTypes,
|
|
8
|
+
tool
|
|
9
|
+
} from "@ai-sdk/provider-utils";
|
|
44
10
|
|
|
45
11
|
// src/error/mcp-client-error.ts
|
|
46
|
-
|
|
12
|
+
import { AISDKError } from "@ai-sdk/provider";
|
|
47
13
|
var name = "AI_MCPClientError";
|
|
48
14
|
var marker = `vercel.ai.error.${name}`;
|
|
49
15
|
var symbol = Symbol.for(marker);
|
|
50
16
|
var _a, _b;
|
|
51
|
-
var MCPClientError = class extends (_b =
|
|
17
|
+
var MCPClientError = class extends (_b = AISDKError, _a = symbol, _b) {
|
|
52
18
|
constructor({
|
|
53
19
|
name: name3 = "MCPClientError",
|
|
54
20
|
message,
|
|
55
21
|
cause,
|
|
56
22
|
data,
|
|
57
|
-
code
|
|
23
|
+
code,
|
|
24
|
+
statusCode,
|
|
25
|
+
url,
|
|
26
|
+
responseBody
|
|
58
27
|
}) {
|
|
59
28
|
super({ name: name3, message, cause });
|
|
60
29
|
this[_a] = true;
|
|
61
30
|
this.data = data;
|
|
62
31
|
this.code = code;
|
|
32
|
+
this.statusCode = statusCode;
|
|
33
|
+
this.url = url;
|
|
34
|
+
this.responseBody = responseBody;
|
|
63
35
|
}
|
|
64
36
|
static isInstance(error) {
|
|
65
|
-
return
|
|
37
|
+
return AISDKError.hasMarker(error, marker);
|
|
66
38
|
}
|
|
67
39
|
};
|
|
68
40
|
|
|
69
41
|
// src/tool/mcp-sse-transport.ts
|
|
70
|
-
|
|
42
|
+
import {
|
|
43
|
+
EventSourceParserStream,
|
|
44
|
+
withUserAgentSuffix,
|
|
45
|
+
getRuntimeEnvironmentUserAgent
|
|
46
|
+
} from "@ai-sdk/provider-utils";
|
|
71
47
|
|
|
72
48
|
// src/tool/json-rpc-message.ts
|
|
73
|
-
|
|
49
|
+
import { parseJSON } from "@ai-sdk/provider-utils";
|
|
50
|
+
import { z as z2 } from "zod/v4";
|
|
74
51
|
|
|
75
52
|
// src/tool/types.ts
|
|
76
|
-
|
|
53
|
+
import { z } from "zod/v4";
|
|
77
54
|
var LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
78
55
|
var SUPPORTED_PROTOCOL_VERSIONS = [
|
|
79
56
|
LATEST_PROTOCOL_VERSION,
|
|
@@ -81,356 +58,377 @@ var SUPPORTED_PROTOCOL_VERSIONS = [
|
|
|
81
58
|
"2025-03-26",
|
|
82
59
|
"2024-11-05"
|
|
83
60
|
];
|
|
84
|
-
var ToolMetaSchema =
|
|
85
|
-
var ClientOrServerImplementationSchema =
|
|
86
|
-
name:
|
|
87
|
-
version:
|
|
61
|
+
var ToolMetaSchema = z.optional(z.record(z.string(), z.unknown()));
|
|
62
|
+
var ClientOrServerImplementationSchema = z.looseObject({
|
|
63
|
+
name: z.string(),
|
|
64
|
+
version: z.string(),
|
|
65
|
+
title: z.optional(z.string())
|
|
88
66
|
});
|
|
89
|
-
var BaseParamsSchema =
|
|
90
|
-
_meta:
|
|
67
|
+
var BaseParamsSchema = z.looseObject({
|
|
68
|
+
_meta: z.optional(z.object({}).loose())
|
|
91
69
|
});
|
|
92
70
|
var ResultSchema = BaseParamsSchema;
|
|
93
|
-
var RequestSchema =
|
|
94
|
-
method:
|
|
95
|
-
params:
|
|
71
|
+
var RequestSchema = z.object({
|
|
72
|
+
method: z.string(),
|
|
73
|
+
params: z.optional(BaseParamsSchema)
|
|
96
74
|
});
|
|
97
|
-
var ElicitationCapabilitySchema =
|
|
98
|
-
applyDefaults:
|
|
75
|
+
var ElicitationCapabilitySchema = z.object({
|
|
76
|
+
applyDefaults: z.optional(z.boolean())
|
|
99
77
|
}).loose();
|
|
100
|
-
var ServerCapabilitiesSchema =
|
|
101
|
-
experimental:
|
|
102
|
-
logging:
|
|
103
|
-
prompts:
|
|
104
|
-
|
|
105
|
-
listChanged:
|
|
78
|
+
var ServerCapabilitiesSchema = z.looseObject({
|
|
79
|
+
experimental: z.optional(z.object({}).loose()),
|
|
80
|
+
logging: z.optional(z.object({}).loose()),
|
|
81
|
+
prompts: z.optional(
|
|
82
|
+
z.looseObject({
|
|
83
|
+
listChanged: z.optional(z.boolean())
|
|
106
84
|
})
|
|
107
85
|
),
|
|
108
|
-
resources:
|
|
109
|
-
|
|
110
|
-
subscribe:
|
|
111
|
-
listChanged:
|
|
86
|
+
resources: z.optional(
|
|
87
|
+
z.looseObject({
|
|
88
|
+
subscribe: z.optional(z.boolean()),
|
|
89
|
+
listChanged: z.optional(z.boolean())
|
|
112
90
|
})
|
|
113
91
|
),
|
|
114
|
-
tools:
|
|
115
|
-
|
|
116
|
-
listChanged:
|
|
92
|
+
tools: z.optional(
|
|
93
|
+
z.looseObject({
|
|
94
|
+
listChanged: z.optional(z.boolean())
|
|
117
95
|
})
|
|
118
96
|
),
|
|
119
|
-
elicitation:
|
|
97
|
+
elicitation: z.optional(ElicitationCapabilitySchema)
|
|
120
98
|
});
|
|
121
|
-
var ClientCapabilitiesSchema =
|
|
122
|
-
elicitation:
|
|
99
|
+
var ClientCapabilitiesSchema = z.object({
|
|
100
|
+
elicitation: z.optional(ElicitationCapabilitySchema)
|
|
123
101
|
}).loose();
|
|
124
102
|
var InitializeResultSchema = ResultSchema.extend({
|
|
125
|
-
protocolVersion:
|
|
103
|
+
protocolVersion: z.string(),
|
|
126
104
|
capabilities: ServerCapabilitiesSchema,
|
|
127
105
|
serverInfo: ClientOrServerImplementationSchema,
|
|
128
|
-
instructions:
|
|
106
|
+
instructions: z.optional(z.string())
|
|
129
107
|
});
|
|
130
108
|
var PaginatedResultSchema = ResultSchema.extend({
|
|
131
|
-
nextCursor:
|
|
109
|
+
nextCursor: z.optional(z.string())
|
|
132
110
|
});
|
|
133
|
-
var ToolSchema =
|
|
134
|
-
name:
|
|
111
|
+
var ToolSchema = z.object({
|
|
112
|
+
name: z.string(),
|
|
135
113
|
/**
|
|
136
114
|
* @see https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool
|
|
137
115
|
*/
|
|
138
|
-
title:
|
|
139
|
-
description:
|
|
140
|
-
inputSchema:
|
|
141
|
-
type:
|
|
142
|
-
properties:
|
|
116
|
+
title: z.optional(z.string()),
|
|
117
|
+
description: z.optional(z.string()),
|
|
118
|
+
inputSchema: z.object({
|
|
119
|
+
type: z.literal("object"),
|
|
120
|
+
properties: z.optional(z.object({}).loose())
|
|
143
121
|
}).loose(),
|
|
144
122
|
/**
|
|
145
123
|
* @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema
|
|
146
124
|
*/
|
|
147
|
-
outputSchema:
|
|
148
|
-
annotations:
|
|
149
|
-
|
|
150
|
-
title:
|
|
125
|
+
outputSchema: z.optional(z.object({}).loose()),
|
|
126
|
+
annotations: z.optional(
|
|
127
|
+
z.object({
|
|
128
|
+
title: z.optional(z.string())
|
|
151
129
|
}).loose()
|
|
152
130
|
),
|
|
153
131
|
_meta: ToolMetaSchema
|
|
154
132
|
}).loose();
|
|
155
133
|
var ListToolsResultSchema = PaginatedResultSchema.extend({
|
|
156
|
-
tools:
|
|
134
|
+
tools: z.array(ToolSchema)
|
|
157
135
|
});
|
|
158
|
-
var TextContentSchema =
|
|
159
|
-
type:
|
|
160
|
-
text:
|
|
136
|
+
var TextContentSchema = z.object({
|
|
137
|
+
type: z.literal("text"),
|
|
138
|
+
text: z.string()
|
|
161
139
|
}).loose();
|
|
162
|
-
var ImageContentSchema =
|
|
163
|
-
type:
|
|
164
|
-
data:
|
|
165
|
-
mimeType:
|
|
140
|
+
var ImageContentSchema = z.object({
|
|
141
|
+
type: z.literal("image"),
|
|
142
|
+
data: z.base64(),
|
|
143
|
+
mimeType: z.string()
|
|
166
144
|
}).loose();
|
|
167
|
-
var ResourceSchema =
|
|
168
|
-
uri:
|
|
169
|
-
name:
|
|
170
|
-
title:
|
|
171
|
-
description:
|
|
172
|
-
mimeType:
|
|
173
|
-
size:
|
|
145
|
+
var ResourceSchema = z.object({
|
|
146
|
+
uri: z.string(),
|
|
147
|
+
name: z.string(),
|
|
148
|
+
title: z.optional(z.string()),
|
|
149
|
+
description: z.optional(z.string()),
|
|
150
|
+
mimeType: z.optional(z.string()),
|
|
151
|
+
size: z.optional(z.number())
|
|
174
152
|
}).loose();
|
|
175
153
|
var ListResourcesResultSchema = PaginatedResultSchema.extend({
|
|
176
|
-
resources:
|
|
154
|
+
resources: z.array(ResourceSchema)
|
|
177
155
|
});
|
|
178
|
-
var ResourceContentsSchema =
|
|
156
|
+
var ResourceContentsSchema = z.object({
|
|
179
157
|
/**
|
|
180
158
|
* The URI of this resource.
|
|
181
159
|
*/
|
|
182
|
-
uri:
|
|
160
|
+
uri: z.string(),
|
|
183
161
|
/**
|
|
184
162
|
* Optional display name of the resource content.
|
|
185
163
|
*/
|
|
186
|
-
name:
|
|
164
|
+
name: z.optional(z.string()),
|
|
187
165
|
/**
|
|
188
166
|
* Optional human readable title.
|
|
189
167
|
*/
|
|
190
|
-
title:
|
|
168
|
+
title: z.optional(z.string()),
|
|
191
169
|
/**
|
|
192
170
|
* The MIME type of this resource, if known.
|
|
193
171
|
*/
|
|
194
|
-
mimeType:
|
|
172
|
+
mimeType: z.optional(z.string())
|
|
195
173
|
}).loose();
|
|
196
174
|
var TextResourceContentsSchema = ResourceContentsSchema.extend({
|
|
197
|
-
text:
|
|
175
|
+
text: z.string()
|
|
198
176
|
});
|
|
199
177
|
var BlobResourceContentsSchema = ResourceContentsSchema.extend({
|
|
200
|
-
blob:
|
|
178
|
+
blob: z.base64()
|
|
201
179
|
});
|
|
202
|
-
var EmbeddedResourceSchema =
|
|
203
|
-
type:
|
|
204
|
-
resource:
|
|
180
|
+
var EmbeddedResourceSchema = z.object({
|
|
181
|
+
type: z.literal("resource"),
|
|
182
|
+
resource: z.union([TextResourceContentsSchema, BlobResourceContentsSchema])
|
|
183
|
+
}).loose();
|
|
184
|
+
var ResourceLinkContentSchema = z.object({
|
|
185
|
+
type: z.literal("resource_link"),
|
|
186
|
+
uri: z.string(),
|
|
187
|
+
name: z.string(),
|
|
188
|
+
description: z.optional(z.string()),
|
|
189
|
+
mimeType: z.optional(z.string())
|
|
205
190
|
}).loose();
|
|
206
191
|
var CallToolResultSchema = ResultSchema.extend({
|
|
207
|
-
content:
|
|
208
|
-
|
|
192
|
+
content: z.array(
|
|
193
|
+
z.union([
|
|
194
|
+
TextContentSchema,
|
|
195
|
+
ImageContentSchema,
|
|
196
|
+
EmbeddedResourceSchema,
|
|
197
|
+
ResourceLinkContentSchema
|
|
198
|
+
])
|
|
209
199
|
),
|
|
210
200
|
/**
|
|
211
201
|
* @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content
|
|
212
202
|
*/
|
|
213
|
-
structuredContent:
|
|
214
|
-
isError:
|
|
203
|
+
structuredContent: z.optional(z.unknown()),
|
|
204
|
+
isError: z.boolean().default(false).optional()
|
|
215
205
|
}).or(
|
|
216
206
|
ResultSchema.extend({
|
|
217
|
-
toolResult:
|
|
207
|
+
toolResult: z.unknown()
|
|
218
208
|
})
|
|
219
209
|
);
|
|
220
|
-
var ResourceTemplateSchema =
|
|
221
|
-
uriTemplate:
|
|
222
|
-
name:
|
|
223
|
-
title:
|
|
224
|
-
description:
|
|
225
|
-
mimeType:
|
|
210
|
+
var ResourceTemplateSchema = z.object({
|
|
211
|
+
uriTemplate: z.string(),
|
|
212
|
+
name: z.string(),
|
|
213
|
+
title: z.optional(z.string()),
|
|
214
|
+
description: z.optional(z.string()),
|
|
215
|
+
mimeType: z.optional(z.string())
|
|
226
216
|
}).loose();
|
|
227
217
|
var ListResourceTemplatesResultSchema = ResultSchema.extend({
|
|
228
|
-
resourceTemplates:
|
|
218
|
+
resourceTemplates: z.array(ResourceTemplateSchema)
|
|
229
219
|
});
|
|
230
220
|
var ReadResourceResultSchema = ResultSchema.extend({
|
|
231
|
-
contents:
|
|
232
|
-
|
|
221
|
+
contents: z.array(
|
|
222
|
+
z.union([TextResourceContentsSchema, BlobResourceContentsSchema])
|
|
233
223
|
)
|
|
234
224
|
});
|
|
235
|
-
var PromptArgumentSchema =
|
|
236
|
-
name:
|
|
237
|
-
description:
|
|
238
|
-
required:
|
|
225
|
+
var PromptArgumentSchema = z.object({
|
|
226
|
+
name: z.string(),
|
|
227
|
+
description: z.optional(z.string()),
|
|
228
|
+
required: z.optional(z.boolean())
|
|
239
229
|
}).loose();
|
|
240
|
-
var PromptSchema =
|
|
241
|
-
name:
|
|
242
|
-
title:
|
|
243
|
-
description:
|
|
244
|
-
arguments:
|
|
230
|
+
var PromptSchema = z.object({
|
|
231
|
+
name: z.string(),
|
|
232
|
+
title: z.optional(z.string()),
|
|
233
|
+
description: z.optional(z.string()),
|
|
234
|
+
arguments: z.optional(z.array(PromptArgumentSchema))
|
|
245
235
|
}).loose();
|
|
246
236
|
var ListPromptsResultSchema = PaginatedResultSchema.extend({
|
|
247
|
-
prompts:
|
|
237
|
+
prompts: z.array(PromptSchema)
|
|
248
238
|
});
|
|
249
|
-
var PromptMessageSchema =
|
|
250
|
-
role:
|
|
251
|
-
content:
|
|
239
|
+
var PromptMessageSchema = z.object({
|
|
240
|
+
role: z.union([z.literal("user"), z.literal("assistant")]),
|
|
241
|
+
content: z.union([
|
|
252
242
|
TextContentSchema,
|
|
253
243
|
ImageContentSchema,
|
|
254
|
-
EmbeddedResourceSchema
|
|
244
|
+
EmbeddedResourceSchema,
|
|
245
|
+
ResourceLinkContentSchema
|
|
255
246
|
])
|
|
256
247
|
}).loose();
|
|
257
248
|
var GetPromptResultSchema = ResultSchema.extend({
|
|
258
|
-
description:
|
|
259
|
-
messages:
|
|
249
|
+
description: z.optional(z.string()),
|
|
250
|
+
messages: z.array(PromptMessageSchema)
|
|
260
251
|
});
|
|
261
252
|
var ElicitationRequestParamsSchema = BaseParamsSchema.extend({
|
|
262
|
-
message:
|
|
263
|
-
requestedSchema:
|
|
253
|
+
message: z.string(),
|
|
254
|
+
requestedSchema: z.unknown()
|
|
264
255
|
});
|
|
265
256
|
var ElicitationRequestSchema = RequestSchema.extend({
|
|
266
|
-
method:
|
|
257
|
+
method: z.literal("elicitation/create"),
|
|
267
258
|
params: ElicitationRequestParamsSchema
|
|
268
259
|
});
|
|
269
260
|
var ElicitResultSchema = ResultSchema.extend({
|
|
270
|
-
action:
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
261
|
+
action: z.union([
|
|
262
|
+
z.literal("accept"),
|
|
263
|
+
z.literal("decline"),
|
|
264
|
+
z.literal("cancel")
|
|
274
265
|
]),
|
|
275
|
-
content:
|
|
266
|
+
content: z.optional(z.record(z.string(), z.unknown()))
|
|
276
267
|
});
|
|
277
268
|
|
|
278
269
|
// src/tool/json-rpc-message.ts
|
|
279
270
|
var JSONRPC_VERSION = "2.0";
|
|
280
|
-
var JSONRPCRequestSchema =
|
|
281
|
-
jsonrpc:
|
|
282
|
-
id:
|
|
271
|
+
var JSONRPCRequestSchema = z2.object({
|
|
272
|
+
jsonrpc: z2.literal(JSONRPC_VERSION),
|
|
273
|
+
id: z2.union([z2.string(), z2.number().int()])
|
|
283
274
|
}).merge(RequestSchema).strict();
|
|
284
|
-
var JSONRPCResponseSchema =
|
|
285
|
-
jsonrpc:
|
|
286
|
-
id:
|
|
275
|
+
var JSONRPCResponseSchema = z2.object({
|
|
276
|
+
jsonrpc: z2.literal(JSONRPC_VERSION),
|
|
277
|
+
id: z2.union([z2.string(), z2.number().int()]),
|
|
287
278
|
result: ResultSchema
|
|
288
279
|
}).strict();
|
|
289
|
-
var JSONRPCErrorSchema =
|
|
290
|
-
jsonrpc:
|
|
291
|
-
id:
|
|
292
|
-
error:
|
|
293
|
-
code:
|
|
294
|
-
message:
|
|
295
|
-
data:
|
|
280
|
+
var JSONRPCErrorSchema = z2.object({
|
|
281
|
+
jsonrpc: z2.literal(JSONRPC_VERSION),
|
|
282
|
+
id: z2.union([z2.string(), z2.number().int()]),
|
|
283
|
+
error: z2.object({
|
|
284
|
+
code: z2.number().int(),
|
|
285
|
+
message: z2.string(),
|
|
286
|
+
data: z2.optional(z2.unknown())
|
|
296
287
|
})
|
|
297
288
|
}).strict();
|
|
298
|
-
var JSONRPCNotificationSchema =
|
|
299
|
-
jsonrpc:
|
|
289
|
+
var JSONRPCNotificationSchema = z2.object({
|
|
290
|
+
jsonrpc: z2.literal(JSONRPC_VERSION)
|
|
300
291
|
}).merge(
|
|
301
|
-
|
|
302
|
-
method:
|
|
303
|
-
params:
|
|
292
|
+
z2.object({
|
|
293
|
+
method: z2.string(),
|
|
294
|
+
params: z2.optional(BaseParamsSchema)
|
|
304
295
|
})
|
|
305
296
|
).strict();
|
|
306
|
-
var JSONRPCMessageSchema =
|
|
297
|
+
var JSONRPCMessageSchema = z2.union([
|
|
307
298
|
JSONRPCRequestSchema,
|
|
308
299
|
JSONRPCNotificationSchema,
|
|
309
300
|
JSONRPCResponseSchema,
|
|
310
301
|
JSONRPCErrorSchema
|
|
311
302
|
]);
|
|
303
|
+
async function parseJSONRPCMessage(text) {
|
|
304
|
+
return JSONRPCMessageSchema.parse(await parseJSON({ text }));
|
|
305
|
+
}
|
|
312
306
|
|
|
313
307
|
// src/version.ts
|
|
314
308
|
var VERSION = typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : "0.0.0-test";
|
|
315
309
|
|
|
316
310
|
// src/tool/oauth.ts
|
|
317
|
-
|
|
311
|
+
import pkceChallenge from "pkce-challenge";
|
|
318
312
|
|
|
319
313
|
// src/tool/oauth-types.ts
|
|
320
|
-
|
|
321
|
-
var
|
|
322
|
-
access_token: import_v43.z.string(),
|
|
323
|
-
id_token: import_v43.z.string().optional(),
|
|
324
|
-
// Optional for OAuth 2.1, but necessary in OpenID Connect
|
|
325
|
-
token_type: import_v43.z.string(),
|
|
326
|
-
expires_in: import_v43.z.number().optional(),
|
|
327
|
-
scope: import_v43.z.string().optional(),
|
|
328
|
-
refresh_token: import_v43.z.string().optional()
|
|
329
|
-
}).strip();
|
|
330
|
-
var SafeUrlSchema = import_v43.z.string().url().superRefine((val, ctx) => {
|
|
314
|
+
import { z as z3 } from "zod/v4";
|
|
315
|
+
var SafeUrlSchema = z3.string().url().superRefine((val, ctx) => {
|
|
331
316
|
if (!URL.canParse(val)) {
|
|
332
317
|
ctx.addIssue({
|
|
333
|
-
code:
|
|
318
|
+
code: z3.ZodIssueCode.custom,
|
|
334
319
|
message: "URL must be parseable",
|
|
335
320
|
fatal: true
|
|
336
321
|
});
|
|
337
|
-
return
|
|
322
|
+
return z3.NEVER;
|
|
338
323
|
}
|
|
339
324
|
}).refine(
|
|
340
325
|
(url) => {
|
|
341
|
-
const
|
|
342
|
-
return
|
|
326
|
+
const parsedUrl = new URL(url);
|
|
327
|
+
return parsedUrl.protocol !== "javascript:" && parsedUrl.protocol !== "data:" && parsedUrl.protocol !== "vbscript:";
|
|
343
328
|
},
|
|
344
329
|
{ message: "URL cannot use javascript:, data:, or vbscript: scheme" }
|
|
345
330
|
);
|
|
346
|
-
var
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
331
|
+
var OAuthTokensSchema = z3.object({
|
|
332
|
+
access_token: z3.string(),
|
|
333
|
+
id_token: z3.string().optional(),
|
|
334
|
+
// Optional for OAuth 2.1, but necessary in OpenID Connect
|
|
335
|
+
token_type: z3.string(),
|
|
336
|
+
expires_in: z3.number().optional(),
|
|
337
|
+
scope: z3.string().optional(),
|
|
338
|
+
refresh_token: z3.string().optional(),
|
|
339
|
+
authorization_server: SafeUrlSchema.optional(),
|
|
340
|
+
token_endpoint: SafeUrlSchema.optional()
|
|
341
|
+
}).strip();
|
|
342
|
+
var OAuthProtectedResourceMetadataSchema = z3.object({
|
|
343
|
+
resource: z3.string().url(),
|
|
344
|
+
authorization_servers: z3.array(SafeUrlSchema).optional(),
|
|
345
|
+
jwks_uri: z3.string().url().optional(),
|
|
346
|
+
scopes_supported: z3.array(z3.string()).optional(),
|
|
347
|
+
bearer_methods_supported: z3.array(z3.string()).optional(),
|
|
348
|
+
resource_signing_alg_values_supported: z3.array(z3.string()).optional(),
|
|
349
|
+
resource_name: z3.string().optional(),
|
|
350
|
+
resource_documentation: z3.string().optional(),
|
|
351
|
+
resource_policy_uri: z3.string().url().optional(),
|
|
352
|
+
resource_tos_uri: z3.string().url().optional(),
|
|
353
|
+
tls_client_certificate_bound_access_tokens: z3.boolean().optional(),
|
|
354
|
+
authorization_details_types_supported: z3.array(z3.string()).optional(),
|
|
355
|
+
dpop_signing_alg_values_supported: z3.array(z3.string()).optional(),
|
|
356
|
+
dpop_bound_access_tokens_required: z3.boolean().optional()
|
|
361
357
|
}).passthrough();
|
|
362
|
-
var OAuthMetadataSchema =
|
|
363
|
-
issuer:
|
|
358
|
+
var OAuthMetadataSchema = z3.object({
|
|
359
|
+
issuer: z3.string(),
|
|
364
360
|
authorization_endpoint: SafeUrlSchema,
|
|
365
361
|
token_endpoint: SafeUrlSchema,
|
|
366
362
|
registration_endpoint: SafeUrlSchema.optional(),
|
|
367
|
-
scopes_supported:
|
|
368
|
-
response_types_supported:
|
|
369
|
-
grant_types_supported:
|
|
370
|
-
code_challenge_methods_supported:
|
|
371
|
-
token_endpoint_auth_methods_supported:
|
|
372
|
-
token_endpoint_auth_signing_alg_values_supported:
|
|
363
|
+
scopes_supported: z3.array(z3.string()).optional(),
|
|
364
|
+
response_types_supported: z3.array(z3.string()),
|
|
365
|
+
grant_types_supported: z3.array(z3.string()).optional(),
|
|
366
|
+
code_challenge_methods_supported: z3.array(z3.string()),
|
|
367
|
+
token_endpoint_auth_methods_supported: z3.array(z3.string()).optional(),
|
|
368
|
+
token_endpoint_auth_signing_alg_values_supported: z3.array(z3.string()).optional()
|
|
373
369
|
}).passthrough();
|
|
374
|
-
var OpenIdProviderMetadataSchema =
|
|
375
|
-
issuer:
|
|
370
|
+
var OpenIdProviderMetadataSchema = z3.object({
|
|
371
|
+
issuer: z3.string(),
|
|
376
372
|
authorization_endpoint: SafeUrlSchema,
|
|
377
373
|
token_endpoint: SafeUrlSchema,
|
|
378
374
|
userinfo_endpoint: SafeUrlSchema.optional(),
|
|
379
375
|
jwks_uri: SafeUrlSchema,
|
|
380
376
|
registration_endpoint: SafeUrlSchema.optional(),
|
|
381
|
-
scopes_supported:
|
|
382
|
-
response_types_supported:
|
|
383
|
-
grant_types_supported:
|
|
384
|
-
subject_types_supported:
|
|
385
|
-
id_token_signing_alg_values_supported:
|
|
386
|
-
claims_supported:
|
|
387
|
-
token_endpoint_auth_methods_supported:
|
|
377
|
+
scopes_supported: z3.array(z3.string()).optional(),
|
|
378
|
+
response_types_supported: z3.array(z3.string()),
|
|
379
|
+
grant_types_supported: z3.array(z3.string()).optional(),
|
|
380
|
+
subject_types_supported: z3.array(z3.string()),
|
|
381
|
+
id_token_signing_alg_values_supported: z3.array(z3.string()),
|
|
382
|
+
claims_supported: z3.array(z3.string()).optional(),
|
|
383
|
+
token_endpoint_auth_methods_supported: z3.array(z3.string()).optional()
|
|
388
384
|
}).passthrough();
|
|
389
385
|
var OpenIdProviderDiscoveryMetadataSchema = OpenIdProviderMetadataSchema.merge(
|
|
390
386
|
OAuthMetadataSchema.pick({
|
|
391
387
|
code_challenge_methods_supported: true
|
|
392
388
|
})
|
|
393
389
|
);
|
|
394
|
-
var OAuthClientInformationSchema =
|
|
395
|
-
client_id:
|
|
396
|
-
client_secret:
|
|
397
|
-
client_id_issued_at:
|
|
398
|
-
client_secret_expires_at:
|
|
390
|
+
var OAuthClientInformationSchema = z3.object({
|
|
391
|
+
client_id: z3.string(),
|
|
392
|
+
client_secret: z3.string().optional(),
|
|
393
|
+
client_id_issued_at: z3.number().optional(),
|
|
394
|
+
client_secret_expires_at: z3.number().optional(),
|
|
395
|
+
authorization_server: SafeUrlSchema.optional(),
|
|
396
|
+
token_endpoint: SafeUrlSchema.optional()
|
|
399
397
|
}).strip();
|
|
400
|
-
var OAuthClientMetadataSchema =
|
|
401
|
-
redirect_uris:
|
|
402
|
-
token_endpoint_auth_method:
|
|
403
|
-
grant_types:
|
|
404
|
-
response_types:
|
|
405
|
-
client_name:
|
|
398
|
+
var OAuthClientMetadataSchema = z3.object({
|
|
399
|
+
redirect_uris: z3.array(SafeUrlSchema),
|
|
400
|
+
token_endpoint_auth_method: z3.string().optional(),
|
|
401
|
+
grant_types: z3.array(z3.string()).optional(),
|
|
402
|
+
response_types: z3.array(z3.string()).optional(),
|
|
403
|
+
client_name: z3.string().optional(),
|
|
406
404
|
client_uri: SafeUrlSchema.optional(),
|
|
407
405
|
logo_uri: SafeUrlSchema.optional(),
|
|
408
|
-
scope:
|
|
409
|
-
contacts:
|
|
406
|
+
scope: z3.string().optional(),
|
|
407
|
+
contacts: z3.array(z3.string()).optional(),
|
|
410
408
|
tos_uri: SafeUrlSchema.optional(),
|
|
411
|
-
policy_uri:
|
|
409
|
+
policy_uri: z3.string().optional(),
|
|
412
410
|
jwks_uri: SafeUrlSchema.optional(),
|
|
413
|
-
jwks:
|
|
414
|
-
software_id:
|
|
415
|
-
software_version:
|
|
416
|
-
software_statement:
|
|
411
|
+
jwks: z3.any().optional(),
|
|
412
|
+
software_id: z3.string().optional(),
|
|
413
|
+
software_version: z3.string().optional(),
|
|
414
|
+
software_statement: z3.string().optional()
|
|
417
415
|
}).strip();
|
|
418
|
-
var OAuthErrorResponseSchema =
|
|
419
|
-
error:
|
|
420
|
-
error_description:
|
|
421
|
-
error_uri:
|
|
416
|
+
var OAuthErrorResponseSchema = z3.object({
|
|
417
|
+
error: z3.string(),
|
|
418
|
+
error_description: z3.string().optional(),
|
|
419
|
+
error_uri: z3.string().optional()
|
|
422
420
|
});
|
|
423
421
|
var OAuthClientInformationFullSchema = OAuthClientMetadataSchema.merge(
|
|
424
422
|
OAuthClientInformationSchema
|
|
425
423
|
);
|
|
426
424
|
|
|
427
425
|
// src/error/oauth-error.ts
|
|
428
|
-
|
|
426
|
+
import { AISDKError as AISDKError2 } from "@ai-sdk/provider";
|
|
429
427
|
var name2 = "AI_MCPClientOAuthError";
|
|
430
428
|
var marker2 = `vercel.ai.error.${name2}`;
|
|
431
429
|
var symbol2 = Symbol.for(marker2);
|
|
432
430
|
var _a2, _b2;
|
|
433
|
-
var MCPClientOAuthError = class extends (_b2 =
|
|
431
|
+
var MCPClientOAuthError = class extends (_b2 = AISDKError2, _a2 = symbol2, _b2) {
|
|
434
432
|
constructor({
|
|
435
433
|
name: name3 = "MCPClientOAuthError",
|
|
436
434
|
message,
|
|
@@ -440,7 +438,7 @@ var MCPClientOAuthError = class extends (_b2 = import_provider2.AISDKError, _a2
|
|
|
440
438
|
this[_a2] = true;
|
|
441
439
|
}
|
|
442
440
|
static isInstance(error) {
|
|
443
|
-
return
|
|
441
|
+
return AISDKError2.hasMarker(error, marker2);
|
|
444
442
|
}
|
|
445
443
|
};
|
|
446
444
|
var ServerError = class extends MCPClientOAuthError {
|
|
@@ -468,6 +466,13 @@ function resourceUrlFromServerUrl(url) {
|
|
|
468
466
|
resourceURL.hash = "";
|
|
469
467
|
return resourceURL;
|
|
470
468
|
}
|
|
469
|
+
function resourceUrlStripSlash(resource) {
|
|
470
|
+
const href = resource.href;
|
|
471
|
+
if (resource.pathname === "/" && href.endsWith("/")) {
|
|
472
|
+
return href.slice(0, -1);
|
|
473
|
+
}
|
|
474
|
+
return href;
|
|
475
|
+
}
|
|
471
476
|
function checkResourceAllowed({
|
|
472
477
|
requestedResource,
|
|
473
478
|
configuredResource
|
|
@@ -486,12 +491,113 @@ function checkResourceAllowed({
|
|
|
486
491
|
}
|
|
487
492
|
|
|
488
493
|
// src/tool/oauth.ts
|
|
494
|
+
import { parseJSON as parseJSON2 } from "@ai-sdk/provider-utils";
|
|
489
495
|
var UnauthorizedError = class extends Error {
|
|
490
496
|
constructor(message = "Unauthorized") {
|
|
491
497
|
super(message);
|
|
492
498
|
this.name = "UnauthorizedError";
|
|
493
499
|
}
|
|
494
500
|
};
|
|
501
|
+
function normalizeUrl(url) {
|
|
502
|
+
return new URL(url).href;
|
|
503
|
+
}
|
|
504
|
+
function createAuthorizationServerInformation(authorizationServerUrl, metadata) {
|
|
505
|
+
return {
|
|
506
|
+
authorizationServerUrl: normalizeUrl(authorizationServerUrl),
|
|
507
|
+
tokenEndpoint: normalizeUrl(
|
|
508
|
+
(metadata == null ? void 0 : metadata.token_endpoint) ? new URL(metadata.token_endpoint) : new URL("/token", authorizationServerUrl)
|
|
509
|
+
)
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
function addAuthorizationServerInformationToTokens(tokens, authorizationServerInformation) {
|
|
513
|
+
return {
|
|
514
|
+
...tokens,
|
|
515
|
+
authorization_server: authorizationServerInformation.authorizationServerUrl,
|
|
516
|
+
token_endpoint: authorizationServerInformation.tokenEndpoint
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
function addAuthorizationServerInformationToClientInformation(clientInformation, authorizationServerInformation) {
|
|
520
|
+
return {
|
|
521
|
+
...clientInformation,
|
|
522
|
+
authorization_server: authorizationServerInformation.authorizationServerUrl,
|
|
523
|
+
token_endpoint: authorizationServerInformation.tokenEndpoint
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
function getAuthorizationServerInformationFromCredentials(credentials) {
|
|
527
|
+
if (!(credentials == null ? void 0 : credentials.authorization_server) || !credentials.token_endpoint) {
|
|
528
|
+
return void 0;
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
authorizationServerUrl: normalizeUrl(credentials.authorization_server),
|
|
532
|
+
tokenEndpoint: normalizeUrl(credentials.token_endpoint)
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
async function getStoredAuthorizationServerInformation({
|
|
536
|
+
provider,
|
|
537
|
+
clientInformation,
|
|
538
|
+
tokens
|
|
539
|
+
}) {
|
|
540
|
+
var _a3;
|
|
541
|
+
const tokenAuthorizationServerInformation = getAuthorizationServerInformationFromCredentials(tokens);
|
|
542
|
+
if (tokenAuthorizationServerInformation) {
|
|
543
|
+
return tokenAuthorizationServerInformation;
|
|
544
|
+
}
|
|
545
|
+
const providerAuthorizationServerInformation = await ((_a3 = provider.authorizationServerInformation) == null ? void 0 : _a3.call(provider));
|
|
546
|
+
if (providerAuthorizationServerInformation) {
|
|
547
|
+
return {
|
|
548
|
+
authorizationServerUrl: normalizeUrl(
|
|
549
|
+
providerAuthorizationServerInformation.authorizationServerUrl
|
|
550
|
+
),
|
|
551
|
+
tokenEndpoint: normalizeUrl(
|
|
552
|
+
providerAuthorizationServerInformation.tokenEndpoint
|
|
553
|
+
)
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
return getAuthorizationServerInformationFromCredentials(clientInformation);
|
|
557
|
+
}
|
|
558
|
+
async function saveAuthorizationServerInformation({
|
|
559
|
+
provider,
|
|
560
|
+
clientInformation,
|
|
561
|
+
authorizationServerInformation
|
|
562
|
+
}) {
|
|
563
|
+
if (provider.saveAuthorizationServerInformation) {
|
|
564
|
+
await provider.saveAuthorizationServerInformation(
|
|
565
|
+
authorizationServerInformation
|
|
566
|
+
);
|
|
567
|
+
return true;
|
|
568
|
+
}
|
|
569
|
+
if (provider.saveClientInformation) {
|
|
570
|
+
await provider.saveClientInformation(
|
|
571
|
+
addAuthorizationServerInformationToClientInformation(
|
|
572
|
+
clientInformation,
|
|
573
|
+
authorizationServerInformation
|
|
574
|
+
)
|
|
575
|
+
);
|
|
576
|
+
return true;
|
|
577
|
+
}
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
580
|
+
function assertResourceMetadataUrlSameOrigin(serverUrl, resourceMetadataUrl) {
|
|
581
|
+
if (!resourceMetadataUrl) {
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
const expectedOrigin = new URL(serverUrl).origin;
|
|
585
|
+
if (resourceMetadataUrl.origin !== expectedOrigin) {
|
|
586
|
+
throw new MCPClientOAuthError({
|
|
587
|
+
message: `OAuth protected resource metadata URL ${resourceMetadataUrl.href} must have the same origin as the MCP server URL ${expectedOrigin}`
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
function assertAuthorizationServerInformationMatches({
|
|
592
|
+
storedAuthorizationServerInformation,
|
|
593
|
+
currentAuthorizationServerInformation
|
|
594
|
+
}) {
|
|
595
|
+
if (storedAuthorizationServerInformation.authorizationServerUrl !== currentAuthorizationServerInformation.authorizationServerUrl || storedAuthorizationServerInformation.tokenEndpoint !== currentAuthorizationServerInformation.tokenEndpoint) {
|
|
596
|
+
throw new MCPClientOAuthError({
|
|
597
|
+
message: "OAuth authorization server metadata does not match the metadata that issued the stored credentials"
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
}
|
|
495
601
|
function extractResourceMetadataUrl(response) {
|
|
496
602
|
var _a3;
|
|
497
603
|
const header = (_a3 = response.headers.get("www-authenticate")) != null ? _a3 : response.headers.get("WWW-Authenticate");
|
|
@@ -586,15 +692,18 @@ async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn =
|
|
|
586
692
|
function buildDiscoveryUrls(authorizationServerUrl) {
|
|
587
693
|
const url = typeof authorizationServerUrl === "string" ? new URL(authorizationServerUrl) : authorizationServerUrl;
|
|
588
694
|
const hasPath = url.pathname !== "/";
|
|
695
|
+
const rootIssuer = url.origin;
|
|
589
696
|
const urlsToTry = [];
|
|
590
697
|
if (!hasPath) {
|
|
591
698
|
urlsToTry.push({
|
|
592
699
|
url: new URL("/.well-known/oauth-authorization-server", url.origin),
|
|
593
|
-
type: "oauth"
|
|
700
|
+
type: "oauth",
|
|
701
|
+
expectedIssuer: rootIssuer
|
|
594
702
|
});
|
|
595
703
|
urlsToTry.push({
|
|
596
704
|
url: new URL("/.well-known/openid-configuration", url.origin),
|
|
597
|
-
type: "oidc"
|
|
705
|
+
type: "oidc",
|
|
706
|
+
expectedIssuer: rootIssuer
|
|
598
707
|
});
|
|
599
708
|
return urlsToTry;
|
|
600
709
|
}
|
|
@@ -602,27 +711,39 @@ function buildDiscoveryUrls(authorizationServerUrl) {
|
|
|
602
711
|
if (pathname.endsWith("/")) {
|
|
603
712
|
pathname = pathname.slice(0, -1);
|
|
604
713
|
}
|
|
714
|
+
const pathIssuer = `${url.origin}${pathname}`;
|
|
605
715
|
urlsToTry.push({
|
|
606
716
|
url: new URL(
|
|
607
717
|
`/.well-known/oauth-authorization-server${pathname}`,
|
|
608
718
|
url.origin
|
|
609
719
|
),
|
|
610
|
-
type: "oauth"
|
|
720
|
+
type: "oauth",
|
|
721
|
+
expectedIssuer: pathIssuer
|
|
611
722
|
});
|
|
612
723
|
urlsToTry.push({
|
|
613
724
|
url: new URL("/.well-known/oauth-authorization-server", url.origin),
|
|
614
|
-
type: "oauth"
|
|
725
|
+
type: "oauth",
|
|
726
|
+
expectedIssuer: rootIssuer
|
|
615
727
|
});
|
|
616
728
|
urlsToTry.push({
|
|
617
729
|
url: new URL(`/.well-known/openid-configuration${pathname}`, url.origin),
|
|
618
|
-
type: "oidc"
|
|
730
|
+
type: "oidc",
|
|
731
|
+
expectedIssuer: pathIssuer
|
|
619
732
|
});
|
|
620
733
|
urlsToTry.push({
|
|
621
734
|
url: new URL(`${pathname}/.well-known/openid-configuration`, url.origin),
|
|
622
|
-
type: "oidc"
|
|
735
|
+
type: "oidc",
|
|
736
|
+
expectedIssuer: pathIssuer
|
|
623
737
|
});
|
|
624
738
|
return urlsToTry;
|
|
625
739
|
}
|
|
740
|
+
function assertMetadataIssuerMatches(metadata, expectedIssuer) {
|
|
741
|
+
if (metadata.issuer !== expectedIssuer) {
|
|
742
|
+
throw new MCPClientOAuthError({
|
|
743
|
+
message: `OAuth authorization server metadata issuer ${metadata.issuer} does not match expected issuer ${expectedIssuer}`
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
}
|
|
626
747
|
async function discoverAuthorizationServerMetadata(authorizationServerUrl, {
|
|
627
748
|
fetchFn = fetch,
|
|
628
749
|
protocolVersion = LATEST_PROTOCOL_VERSION
|
|
@@ -630,7 +751,7 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, {
|
|
|
630
751
|
var _a3;
|
|
631
752
|
const headers = { "MCP-Protocol-Version": protocolVersion };
|
|
632
753
|
const urlsToTry = buildDiscoveryUrls(authorizationServerUrl);
|
|
633
|
-
for (const { url: endpointUrl, type } of urlsToTry) {
|
|
754
|
+
for (const { url: endpointUrl, type, expectedIssuer } of urlsToTry) {
|
|
634
755
|
const response = await fetchWithCorsRetry(endpointUrl, headers, fetchFn);
|
|
635
756
|
if (!response) {
|
|
636
757
|
continue;
|
|
@@ -644,11 +765,14 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, {
|
|
|
644
765
|
);
|
|
645
766
|
}
|
|
646
767
|
if (type === "oauth") {
|
|
647
|
-
|
|
768
|
+
const metadata = OAuthMetadataSchema.parse(await response.json());
|
|
769
|
+
assertMetadataIssuerMatches(metadata, expectedIssuer);
|
|
770
|
+
return metadata;
|
|
648
771
|
} else {
|
|
649
772
|
const metadata = OpenIdProviderDiscoveryMetadataSchema.parse(
|
|
650
773
|
await response.json()
|
|
651
774
|
);
|
|
775
|
+
assertMetadataIssuerMatches(metadata, expectedIssuer);
|
|
652
776
|
if (!((_a3 = metadata.code_challenge_methods_supported) == null ? void 0 : _a3.includes("S256"))) {
|
|
653
777
|
throw new Error(
|
|
654
778
|
`Incompatible OIDC provider at ${endpointUrl}: does not support S256 code challenge method required by MCP specification`
|
|
@@ -685,7 +809,7 @@ async function startAuthorization(authorizationServerUrl, {
|
|
|
685
809
|
} else {
|
|
686
810
|
authorizationUrl = new URL("/authorize", authorizationServerUrl);
|
|
687
811
|
}
|
|
688
|
-
const challenge = await (
|
|
812
|
+
const challenge = await pkceChallenge();
|
|
689
813
|
const codeVerifier = challenge.code_verifier;
|
|
690
814
|
const codeChallenge = challenge.code_challenge;
|
|
691
815
|
authorizationUrl.searchParams.set("response_type", responseType);
|
|
@@ -706,7 +830,10 @@ async function startAuthorization(authorizationServerUrl, {
|
|
|
706
830
|
authorizationUrl.searchParams.append("prompt", "consent");
|
|
707
831
|
}
|
|
708
832
|
if (resource) {
|
|
709
|
-
authorizationUrl.searchParams.set(
|
|
833
|
+
authorizationUrl.searchParams.set(
|
|
834
|
+
"resource",
|
|
835
|
+
resourceUrlStripSlash(resource)
|
|
836
|
+
);
|
|
710
837
|
}
|
|
711
838
|
return { authorizationUrl, codeVerifier };
|
|
712
839
|
}
|
|
@@ -764,7 +891,9 @@ async function parseErrorResponse(input) {
|
|
|
764
891
|
const statusCode = input instanceof Response ? input.status : void 0;
|
|
765
892
|
const body = input instanceof Response ? await input.text() : input;
|
|
766
893
|
try {
|
|
767
|
-
const result = OAuthErrorResponseSchema.parse(
|
|
894
|
+
const result = OAuthErrorResponseSchema.parse(
|
|
895
|
+
await parseJSON2({ text: body })
|
|
896
|
+
);
|
|
768
897
|
const { error, error_description, error_uri } = result;
|
|
769
898
|
const errorClass = OAUTH_ERRORS[error] || ServerError;
|
|
770
899
|
return new errorClass({
|
|
@@ -805,7 +934,12 @@ async function exchangeAuthorization(authorizationServerUrl, {
|
|
|
805
934
|
redirect_uri: String(redirectUri)
|
|
806
935
|
});
|
|
807
936
|
if (addClientAuthentication) {
|
|
808
|
-
addClientAuthentication(
|
|
937
|
+
await addClientAuthentication(
|
|
938
|
+
headers,
|
|
939
|
+
params,
|
|
940
|
+
authorizationServerUrl,
|
|
941
|
+
metadata
|
|
942
|
+
);
|
|
809
943
|
} else {
|
|
810
944
|
const supportedMethods = (_a3 = metadata == null ? void 0 : metadata.token_endpoint_auth_methods_supported) != null ? _a3 : [];
|
|
811
945
|
const authMethod = selectClientAuthMethod(
|
|
@@ -815,7 +949,7 @@ async function exchangeAuthorization(authorizationServerUrl, {
|
|
|
815
949
|
applyClientAuthentication(authMethod, clientInformation, headers, params);
|
|
816
950
|
}
|
|
817
951
|
if (resource) {
|
|
818
|
-
params.set("resource", resource
|
|
952
|
+
params.set("resource", resourceUrlStripSlash(resource));
|
|
819
953
|
}
|
|
820
954
|
const response = await (fetchFn != null ? fetchFn : fetch)(tokenUrl, {
|
|
821
955
|
method: "POST",
|
|
@@ -857,7 +991,12 @@ async function refreshAuthorization(authorizationServerUrl, {
|
|
|
857
991
|
refresh_token: refreshToken
|
|
858
992
|
});
|
|
859
993
|
if (addClientAuthentication) {
|
|
860
|
-
addClientAuthentication(
|
|
994
|
+
await addClientAuthentication(
|
|
995
|
+
headers,
|
|
996
|
+
params,
|
|
997
|
+
authorizationServerUrl,
|
|
998
|
+
metadata
|
|
999
|
+
);
|
|
861
1000
|
} else {
|
|
862
1001
|
const supportedMethods = (_a3 = metadata == null ? void 0 : metadata.token_endpoint_auth_methods_supported) != null ? _a3 : [];
|
|
863
1002
|
const authMethod = selectClientAuthMethod(
|
|
@@ -867,7 +1006,7 @@ async function refreshAuthorization(authorizationServerUrl, {
|
|
|
867
1006
|
applyClientAuthentication(authMethod, clientInformation, headers, params);
|
|
868
1007
|
}
|
|
869
1008
|
if (resource) {
|
|
870
|
-
params.set("resource", resource
|
|
1009
|
+
params.set("resource", resourceUrlStripSlash(resource));
|
|
871
1010
|
}
|
|
872
1011
|
const response = await (fetchFn != null ? fetchFn : fetch)(tokenUrl, {
|
|
873
1012
|
method: "POST",
|
|
@@ -954,8 +1093,10 @@ async function authInternal(provider, {
|
|
|
954
1093
|
resourceMetadataUrl,
|
|
955
1094
|
fetchFn
|
|
956
1095
|
}) {
|
|
1096
|
+
var _a3, _b3;
|
|
957
1097
|
let resourceMetadata;
|
|
958
1098
|
let authorizationServerUrl;
|
|
1099
|
+
assertResourceMetadataUrlSameOrigin(serverUrl, resourceMetadataUrl);
|
|
959
1100
|
try {
|
|
960
1101
|
resourceMetadata = await discoverOAuthProtectedResourceMetadata(
|
|
961
1102
|
serverUrl,
|
|
@@ -975,12 +1116,18 @@ async function authInternal(provider, {
|
|
|
975
1116
|
provider,
|
|
976
1117
|
resourceMetadata
|
|
977
1118
|
);
|
|
1119
|
+
await ((_a3 = provider.validateAuthorizationServerURL) == null ? void 0 : _a3.call(
|
|
1120
|
+
provider,
|
|
1121
|
+
serverUrl,
|
|
1122
|
+
authorizationServerUrl
|
|
1123
|
+
));
|
|
978
1124
|
const metadata = await discoverAuthorizationServerMetadata(
|
|
979
1125
|
authorizationServerUrl,
|
|
980
1126
|
{
|
|
981
1127
|
fetchFn
|
|
982
1128
|
}
|
|
983
1129
|
);
|
|
1130
|
+
const currentAuthorizationServerInformation = createAuthorizationServerInformation(authorizationServerUrl, metadata);
|
|
984
1131
|
let clientInformation = await Promise.resolve(provider.clientInformation());
|
|
985
1132
|
if (!clientInformation) {
|
|
986
1133
|
if (authorizationCode !== void 0) {
|
|
@@ -998,8 +1145,11 @@ async function authInternal(provider, {
|
|
|
998
1145
|
clientMetadata: provider.clientMetadata,
|
|
999
1146
|
fetchFn
|
|
1000
1147
|
});
|
|
1001
|
-
|
|
1002
|
-
|
|
1148
|
+
clientInformation = addAuthorizationServerInformationToClientInformation(
|
|
1149
|
+
fullInformation,
|
|
1150
|
+
currentAuthorizationServerInformation
|
|
1151
|
+
);
|
|
1152
|
+
await provider.saveClientInformation(clientInformation);
|
|
1003
1153
|
}
|
|
1004
1154
|
if (authorizationCode !== void 0) {
|
|
1005
1155
|
if (provider.storedState) {
|
|
@@ -1010,6 +1160,19 @@ async function authInternal(provider, {
|
|
|
1010
1160
|
);
|
|
1011
1161
|
}
|
|
1012
1162
|
}
|
|
1163
|
+
const storedAuthorizationServerInformation = await getStoredAuthorizationServerInformation({
|
|
1164
|
+
provider,
|
|
1165
|
+
clientInformation
|
|
1166
|
+
});
|
|
1167
|
+
if (!storedAuthorizationServerInformation) {
|
|
1168
|
+
throw new MCPClientOAuthError({
|
|
1169
|
+
message: "Stored OAuth authorization server metadata is required when exchanging an authorization code"
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
assertAuthorizationServerInformationMatches({
|
|
1173
|
+
storedAuthorizationServerInformation,
|
|
1174
|
+
currentAuthorizationServerInformation
|
|
1175
|
+
});
|
|
1013
1176
|
const codeVerifier2 = await provider.codeVerifier();
|
|
1014
1177
|
const tokens2 = await exchangeAuthorization(authorizationServerUrl, {
|
|
1015
1178
|
metadata,
|
|
@@ -1021,22 +1184,47 @@ async function authInternal(provider, {
|
|
|
1021
1184
|
addClientAuthentication: provider.addClientAuthentication,
|
|
1022
1185
|
fetchFn
|
|
1023
1186
|
});
|
|
1024
|
-
await provider.saveTokens(
|
|
1187
|
+
await provider.saveTokens(
|
|
1188
|
+
addAuthorizationServerInformationToTokens(
|
|
1189
|
+
tokens2,
|
|
1190
|
+
currentAuthorizationServerInformation
|
|
1191
|
+
)
|
|
1192
|
+
);
|
|
1025
1193
|
return "AUTHORIZED";
|
|
1026
1194
|
}
|
|
1027
1195
|
const tokens = await provider.tokens();
|
|
1028
1196
|
if (tokens == null ? void 0 : tokens.refresh_token) {
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1197
|
+
const storedAuthorizationServerInformation = await getStoredAuthorizationServerInformation({
|
|
1198
|
+
provider,
|
|
1199
|
+
clientInformation,
|
|
1200
|
+
tokens
|
|
1201
|
+
});
|
|
1202
|
+
if (storedAuthorizationServerInformation) {
|
|
1203
|
+
assertAuthorizationServerInformationMatches({
|
|
1204
|
+
storedAuthorizationServerInformation,
|
|
1205
|
+
currentAuthorizationServerInformation
|
|
1037
1206
|
});
|
|
1038
|
-
|
|
1039
|
-
|
|
1207
|
+
} else {
|
|
1208
|
+
await ((_b3 = provider.invalidateCredentials) == null ? void 0 : _b3.call(provider, "tokens"));
|
|
1209
|
+
}
|
|
1210
|
+
try {
|
|
1211
|
+
if (storedAuthorizationServerInformation) {
|
|
1212
|
+
const newTokens = await refreshAuthorization(authorizationServerUrl, {
|
|
1213
|
+
metadata,
|
|
1214
|
+
clientInformation,
|
|
1215
|
+
refreshToken: tokens.refresh_token,
|
|
1216
|
+
resource,
|
|
1217
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
1218
|
+
fetchFn
|
|
1219
|
+
});
|
|
1220
|
+
await provider.saveTokens(
|
|
1221
|
+
addAuthorizationServerInformationToTokens(
|
|
1222
|
+
newTokens,
|
|
1223
|
+
currentAuthorizationServerInformation
|
|
1224
|
+
)
|
|
1225
|
+
);
|
|
1226
|
+
return "AUTHORIZED";
|
|
1227
|
+
}
|
|
1040
1228
|
} catch (error) {
|
|
1041
1229
|
if (
|
|
1042
1230
|
// 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.
|
|
@@ -1062,28 +1250,49 @@ async function authInternal(provider, {
|
|
|
1062
1250
|
resource
|
|
1063
1251
|
}
|
|
1064
1252
|
);
|
|
1253
|
+
const savedAuthorizationServerInformation = await saveAuthorizationServerInformation({
|
|
1254
|
+
provider,
|
|
1255
|
+
clientInformation,
|
|
1256
|
+
authorizationServerInformation: currentAuthorizationServerInformation
|
|
1257
|
+
});
|
|
1258
|
+
if (!savedAuthorizationServerInformation) {
|
|
1259
|
+
throw new MCPClientOAuthError({
|
|
1260
|
+
message: "OAuth authorization server metadata must be saveable before starting authorization"
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1065
1263
|
await provider.saveCodeVerifier(codeVerifier);
|
|
1066
1264
|
await provider.redirectToAuthorization(authorizationUrl);
|
|
1067
1265
|
return "REDIRECT";
|
|
1068
1266
|
}
|
|
1069
1267
|
|
|
1070
1268
|
// src/tool/mcp-sse-transport.ts
|
|
1269
|
+
function isMessageEvent(event) {
|
|
1270
|
+
return event === void 0 || event === "message";
|
|
1271
|
+
}
|
|
1071
1272
|
var SseMCPTransport = class {
|
|
1072
1273
|
constructor({
|
|
1073
1274
|
url,
|
|
1074
1275
|
headers,
|
|
1075
|
-
authProvider
|
|
1276
|
+
authProvider,
|
|
1277
|
+
redirect = "error",
|
|
1278
|
+
fetch: fetchFn
|
|
1076
1279
|
}) {
|
|
1077
1280
|
this.connected = false;
|
|
1078
1281
|
this.url = new URL(url);
|
|
1079
1282
|
this.headers = headers;
|
|
1080
1283
|
this.authProvider = authProvider;
|
|
1284
|
+
this.redirectMode = redirect;
|
|
1285
|
+
this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
|
|
1286
|
+
}
|
|
1287
|
+
setProtocolVersion(version) {
|
|
1288
|
+
this.protocolVersion = version;
|
|
1081
1289
|
}
|
|
1082
1290
|
async commonHeaders(base) {
|
|
1291
|
+
var _a3;
|
|
1083
1292
|
const headers = {
|
|
1084
1293
|
...this.headers,
|
|
1085
1294
|
...base,
|
|
1086
|
-
"mcp-protocol-version": LATEST_PROTOCOL_VERSION
|
|
1295
|
+
"mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
|
|
1087
1296
|
};
|
|
1088
1297
|
if (this.authProvider) {
|
|
1089
1298
|
const tokens = await this.authProvider.tokens();
|
|
@@ -1091,10 +1300,10 @@ var SseMCPTransport = class {
|
|
|
1091
1300
|
headers["Authorization"] = `Bearer ${tokens.access_token}`;
|
|
1092
1301
|
}
|
|
1093
1302
|
}
|
|
1094
|
-
return
|
|
1303
|
+
return withUserAgentSuffix(
|
|
1095
1304
|
headers,
|
|
1096
1305
|
`ai-sdk/${VERSION}`,
|
|
1097
|
-
|
|
1306
|
+
getRuntimeEnvironmentUserAgent()
|
|
1098
1307
|
);
|
|
1099
1308
|
}
|
|
1100
1309
|
async start() {
|
|
@@ -1109,16 +1318,18 @@ var SseMCPTransport = class {
|
|
|
1109
1318
|
const headers = await this.commonHeaders({
|
|
1110
1319
|
Accept: "text/event-stream"
|
|
1111
1320
|
});
|
|
1112
|
-
const response = await
|
|
1321
|
+
const response = await this.fetchFn(this.url.href, {
|
|
1113
1322
|
headers,
|
|
1114
|
-
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1323
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
|
|
1324
|
+
redirect: this.redirectMode
|
|
1115
1325
|
});
|
|
1116
1326
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1117
1327
|
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
1118
1328
|
try {
|
|
1119
1329
|
const result = await auth(this.authProvider, {
|
|
1120
1330
|
serverUrl: this.url,
|
|
1121
|
-
resourceMetadataUrl: this.resourceMetadataUrl
|
|
1331
|
+
resourceMetadataUrl: this.resourceMetadataUrl,
|
|
1332
|
+
fetchFn: this.fetchFn
|
|
1122
1333
|
});
|
|
1123
1334
|
if (result !== "AUTHORIZED") {
|
|
1124
1335
|
const error = new UnauthorizedError();
|
|
@@ -1142,10 +1353,10 @@ var SseMCPTransport = class {
|
|
|
1142
1353
|
(_d = this.onerror) == null ? void 0 : _d.call(this, error);
|
|
1143
1354
|
return reject(error);
|
|
1144
1355
|
}
|
|
1145
|
-
const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new
|
|
1356
|
+
const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream());
|
|
1146
1357
|
const reader = stream.getReader();
|
|
1147
1358
|
const processEvents = async () => {
|
|
1148
|
-
var _a4, _b4, _c2;
|
|
1359
|
+
var _a4, _b4, _c2, _d2, _e2;
|
|
1149
1360
|
try {
|
|
1150
1361
|
while (true) {
|
|
1151
1362
|
const { done, value } = await reader.read();
|
|
@@ -1160,26 +1371,32 @@ var SseMCPTransport = class {
|
|
|
1160
1371
|
}
|
|
1161
1372
|
const { event, data } = value;
|
|
1162
1373
|
if (event === "endpoint") {
|
|
1163
|
-
|
|
1164
|
-
|
|
1374
|
+
if (this.endpoint) {
|
|
1375
|
+
continue;
|
|
1376
|
+
}
|
|
1377
|
+
const endpoint = new URL(data, this.url);
|
|
1378
|
+
if (endpoint.origin !== this.url.origin) {
|
|
1379
|
+
this.connected = false;
|
|
1380
|
+
this.endpoint = void 0;
|
|
1381
|
+
(_a4 = this.sseConnection) == null ? void 0 : _a4.close();
|
|
1382
|
+
(_b4 = this.abortController) == null ? void 0 : _b4.abort();
|
|
1165
1383
|
throw new MCPClientError({
|
|
1166
|
-
message: `MCP SSE Transport Error: Endpoint origin does not match connection origin: ${
|
|
1384
|
+
message: `MCP SSE Transport Error: Endpoint origin does not match connection origin: ${endpoint.origin}`
|
|
1167
1385
|
});
|
|
1168
1386
|
}
|
|
1387
|
+
this.endpoint = endpoint;
|
|
1169
1388
|
this.connected = true;
|
|
1170
1389
|
resolve();
|
|
1171
|
-
} else if (event
|
|
1390
|
+
} else if (isMessageEvent(event)) {
|
|
1172
1391
|
try {
|
|
1173
|
-
const message =
|
|
1174
|
-
|
|
1175
|
-
);
|
|
1176
|
-
(_a4 = this.onmessage) == null ? void 0 : _a4.call(this, message);
|
|
1392
|
+
const message = await parseJSONRPCMessage(data);
|
|
1393
|
+
(_c2 = this.onmessage) == null ? void 0 : _c2.call(this, message);
|
|
1177
1394
|
} catch (error) {
|
|
1178
1395
|
const e = new MCPClientError({
|
|
1179
1396
|
message: "MCP SSE Transport Error: Failed to parse message",
|
|
1180
1397
|
cause: error
|
|
1181
1398
|
});
|
|
1182
|
-
(
|
|
1399
|
+
(_d2 = this.onerror) == null ? void 0 : _d2.call(this, e);
|
|
1183
1400
|
}
|
|
1184
1401
|
}
|
|
1185
1402
|
}
|
|
@@ -1187,7 +1404,7 @@ var SseMCPTransport = class {
|
|
|
1187
1404
|
if (error instanceof Error && error.name === "AbortError") {
|
|
1188
1405
|
return;
|
|
1189
1406
|
}
|
|
1190
|
-
(
|
|
1407
|
+
(_e2 = this.onerror) == null ? void 0 : _e2.call(this, error);
|
|
1191
1408
|
reject(error);
|
|
1192
1409
|
}
|
|
1193
1410
|
};
|
|
@@ -1209,6 +1426,7 @@ var SseMCPTransport = class {
|
|
|
1209
1426
|
async close() {
|
|
1210
1427
|
var _a3, _b3, _c;
|
|
1211
1428
|
this.connected = false;
|
|
1429
|
+
this.endpoint = void 0;
|
|
1212
1430
|
(_a3 = this.sseConnection) == null ? void 0 : _a3.close();
|
|
1213
1431
|
(_b3 = this.abortController) == null ? void 0 : _b3.abort();
|
|
1214
1432
|
(_c = this.onclose) == null ? void 0 : _c.call(this);
|
|
@@ -1230,15 +1448,17 @@ var SseMCPTransport = class {
|
|
|
1230
1448
|
method: "POST",
|
|
1231
1449
|
headers,
|
|
1232
1450
|
body: JSON.stringify(message),
|
|
1233
|
-
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1451
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
|
|
1452
|
+
redirect: this.redirectMode
|
|
1234
1453
|
};
|
|
1235
|
-
const response = await
|
|
1454
|
+
const response = await this.fetchFn(endpoint.href, init);
|
|
1236
1455
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1237
1456
|
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
1238
1457
|
try {
|
|
1239
1458
|
const result = await auth(this.authProvider, {
|
|
1240
1459
|
serverUrl: this.url,
|
|
1241
|
-
resourceMetadataUrl: this.resourceMetadataUrl
|
|
1460
|
+
resourceMetadataUrl: this.resourceMetadataUrl,
|
|
1461
|
+
fetchFn: this.fetchFn
|
|
1242
1462
|
});
|
|
1243
1463
|
if (result !== "AUTHORIZED") {
|
|
1244
1464
|
const error = new UnauthorizedError();
|
|
@@ -1269,12 +1489,21 @@ var SseMCPTransport = class {
|
|
|
1269
1489
|
};
|
|
1270
1490
|
|
|
1271
1491
|
// src/tool/mcp-http-transport.ts
|
|
1272
|
-
|
|
1492
|
+
import {
|
|
1493
|
+
EventSourceParserStream as EventSourceParserStream2,
|
|
1494
|
+
withUserAgentSuffix as withUserAgentSuffix2,
|
|
1495
|
+
getRuntimeEnvironmentUserAgent as getRuntimeEnvironmentUserAgent2
|
|
1496
|
+
} from "@ai-sdk/provider-utils";
|
|
1497
|
+
function isMessageEvent2(event) {
|
|
1498
|
+
return event === void 0 || event === "message";
|
|
1499
|
+
}
|
|
1273
1500
|
var HttpMCPTransport = class {
|
|
1274
1501
|
constructor({
|
|
1275
1502
|
url,
|
|
1276
1503
|
headers,
|
|
1277
|
-
authProvider
|
|
1504
|
+
authProvider,
|
|
1505
|
+
redirect = "error",
|
|
1506
|
+
fetch: fetchFn
|
|
1278
1507
|
}) {
|
|
1279
1508
|
this.inboundReconnectAttempts = 0;
|
|
1280
1509
|
this.reconnectionOptions = {
|
|
@@ -1286,12 +1515,18 @@ var HttpMCPTransport = class {
|
|
|
1286
1515
|
this.url = new URL(url);
|
|
1287
1516
|
this.headers = headers;
|
|
1288
1517
|
this.authProvider = authProvider;
|
|
1518
|
+
this.redirectMode = redirect;
|
|
1519
|
+
this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
|
|
1520
|
+
}
|
|
1521
|
+
setProtocolVersion(version) {
|
|
1522
|
+
this.protocolVersion = version;
|
|
1289
1523
|
}
|
|
1290
1524
|
async commonHeaders(base) {
|
|
1525
|
+
var _a3;
|
|
1291
1526
|
const headers = {
|
|
1292
1527
|
...this.headers,
|
|
1293
1528
|
...base,
|
|
1294
|
-
"mcp-protocol-version": LATEST_PROTOCOL_VERSION
|
|
1529
|
+
"mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
|
|
1295
1530
|
};
|
|
1296
1531
|
if (this.sessionId) {
|
|
1297
1532
|
headers["mcp-session-id"] = this.sessionId;
|
|
@@ -1302,12 +1537,30 @@ var HttpMCPTransport = class {
|
|
|
1302
1537
|
headers["Authorization"] = `Bearer ${tokens.access_token}`;
|
|
1303
1538
|
}
|
|
1304
1539
|
}
|
|
1305
|
-
return (
|
|
1540
|
+
return withUserAgentSuffix2(
|
|
1306
1541
|
headers,
|
|
1307
1542
|
`ai-sdk/${VERSION}`,
|
|
1308
|
-
(
|
|
1543
|
+
getRuntimeEnvironmentUserAgent2()
|
|
1309
1544
|
);
|
|
1310
1545
|
}
|
|
1546
|
+
/**
|
|
1547
|
+
* Runs a single OAuth recovery flow for concurrent 401 responses.
|
|
1548
|
+
*/
|
|
1549
|
+
authorizeOnce(resourceMetadataUrl) {
|
|
1550
|
+
if (!this.authProvider) {
|
|
1551
|
+
return Promise.resolve("REDIRECT");
|
|
1552
|
+
}
|
|
1553
|
+
if (!this.authPromise) {
|
|
1554
|
+
this.authPromise = auth(this.authProvider, {
|
|
1555
|
+
serverUrl: this.url,
|
|
1556
|
+
resourceMetadataUrl,
|
|
1557
|
+
fetchFn: this.fetchFn
|
|
1558
|
+
}).finally(() => {
|
|
1559
|
+
this.authPromise = void 0;
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
return this.authPromise;
|
|
1563
|
+
}
|
|
1311
1564
|
async start() {
|
|
1312
1565
|
if (this.abortController) {
|
|
1313
1566
|
throw new MCPClientError({
|
|
@@ -1323,10 +1576,11 @@ var HttpMCPTransport = class {
|
|
|
1323
1576
|
try {
|
|
1324
1577
|
if (this.sessionId && this.abortController && !this.abortController.signal.aborted) {
|
|
1325
1578
|
const headers = await this.commonHeaders({});
|
|
1326
|
-
await
|
|
1579
|
+
await this.fetchFn(this.url.href, {
|
|
1327
1580
|
method: "DELETE",
|
|
1328
1581
|
headers,
|
|
1329
|
-
signal: this.abortController.signal
|
|
1582
|
+
signal: this.abortController.signal,
|
|
1583
|
+
redirect: this.redirectMode
|
|
1330
1584
|
}).catch(() => void 0);
|
|
1331
1585
|
}
|
|
1332
1586
|
} catch (e) {
|
|
@@ -1346,9 +1600,10 @@ var HttpMCPTransport = class {
|
|
|
1346
1600
|
method: "POST",
|
|
1347
1601
|
headers,
|
|
1348
1602
|
body: JSON.stringify(message),
|
|
1349
|
-
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1603
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
|
|
1604
|
+
redirect: this.redirectMode
|
|
1350
1605
|
};
|
|
1351
|
-
const response = await
|
|
1606
|
+
const response = await this.fetchFn(this.url.href, init);
|
|
1352
1607
|
const sessionId = response.headers.get("mcp-session-id");
|
|
1353
1608
|
if (sessionId) {
|
|
1354
1609
|
this.sessionId = sessionId;
|
|
@@ -1356,10 +1611,7 @@ var HttpMCPTransport = class {
|
|
|
1356
1611
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1357
1612
|
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
1358
1613
|
try {
|
|
1359
|
-
const result = await
|
|
1360
|
-
serverUrl: this.url,
|
|
1361
|
-
resourceMetadataUrl: this.resourceMetadataUrl
|
|
1362
|
-
});
|
|
1614
|
+
const result = await this.authorizeOnce(this.resourceMetadataUrl);
|
|
1363
1615
|
if (result !== "AUTHORIZED") {
|
|
1364
1616
|
const error2 = new UnauthorizedError();
|
|
1365
1617
|
throw error2;
|
|
@@ -1383,7 +1635,10 @@ var HttpMCPTransport = class {
|
|
|
1383
1635
|
errorMessage += ". This server does not support HTTP transport. Try using `sse` transport instead";
|
|
1384
1636
|
}
|
|
1385
1637
|
const error2 = new MCPClientError({
|
|
1386
|
-
message: errorMessage
|
|
1638
|
+
message: errorMessage,
|
|
1639
|
+
statusCode: response.status,
|
|
1640
|
+
url: this.url.href,
|
|
1641
|
+
responseBody: text != null ? text : void 0
|
|
1387
1642
|
});
|
|
1388
1643
|
(_c = this.onerror) == null ? void 0 : _c.call(this, error2);
|
|
1389
1644
|
throw error2;
|
|
@@ -1395,19 +1650,25 @@ var HttpMCPTransport = class {
|
|
|
1395
1650
|
const contentType = response.headers.get("content-type") || "";
|
|
1396
1651
|
if (contentType.includes("application/json")) {
|
|
1397
1652
|
const data = await response.json();
|
|
1398
|
-
const messages = Array.isArray(data) ? data.map(
|
|
1399
|
-
|
|
1653
|
+
const messages = Array.isArray(data) ? data.map(
|
|
1654
|
+
(message2) => JSONRPCMessageSchema.parse(message2)
|
|
1655
|
+
) : [JSONRPCMessageSchema.parse(data)];
|
|
1656
|
+
for (const jsonRpcMessage of messages) {
|
|
1657
|
+
(_d = this.onmessage) == null ? void 0 : _d.call(this, jsonRpcMessage);
|
|
1658
|
+
}
|
|
1400
1659
|
return;
|
|
1401
1660
|
}
|
|
1402
1661
|
if (contentType.includes("text/event-stream")) {
|
|
1403
1662
|
if (!response.body) {
|
|
1404
1663
|
const error2 = new MCPClientError({
|
|
1405
|
-
message: "MCP HTTP Transport Error: text/event-stream response without body"
|
|
1664
|
+
message: "MCP HTTP Transport Error: text/event-stream response without body",
|
|
1665
|
+
statusCode: response.status,
|
|
1666
|
+
url: this.url.href
|
|
1406
1667
|
});
|
|
1407
1668
|
(_e = this.onerror) == null ? void 0 : _e.call(this, error2);
|
|
1408
1669
|
throw error2;
|
|
1409
1670
|
}
|
|
1410
|
-
const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new
|
|
1671
|
+
const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream2());
|
|
1411
1672
|
const reader = stream.getReader();
|
|
1412
1673
|
const processEvents = async () => {
|
|
1413
1674
|
var _a4, _b4, _c2;
|
|
@@ -1416,10 +1677,10 @@ var HttpMCPTransport = class {
|
|
|
1416
1677
|
const { done, value } = await reader.read();
|
|
1417
1678
|
if (done) return;
|
|
1418
1679
|
const { event, data } = value;
|
|
1419
|
-
if (event
|
|
1680
|
+
if (isMessageEvent2(event)) {
|
|
1420
1681
|
try {
|
|
1421
|
-
const
|
|
1422
|
-
(_a4 = this.onmessage) == null ? void 0 : _a4.call(this,
|
|
1682
|
+
const jsonRpcMessage = await parseJSONRPCMessage(data);
|
|
1683
|
+
(_a4 = this.onmessage) == null ? void 0 : _a4.call(this, jsonRpcMessage);
|
|
1423
1684
|
} catch (error2) {
|
|
1424
1685
|
const e = new MCPClientError({
|
|
1425
1686
|
message: "MCP HTTP Transport Error: Failed to parse message",
|
|
@@ -1440,7 +1701,9 @@ var HttpMCPTransport = class {
|
|
|
1440
1701
|
return;
|
|
1441
1702
|
}
|
|
1442
1703
|
const error = new MCPClientError({
|
|
1443
|
-
message: `MCP HTTP Transport Error: Unexpected content type: ${contentType}
|
|
1704
|
+
message: `MCP HTTP Transport Error: Unexpected content type: ${contentType}`,
|
|
1705
|
+
statusCode: response.status,
|
|
1706
|
+
url: this.url.href
|
|
1444
1707
|
});
|
|
1445
1708
|
(_f = this.onerror) == null ? void 0 : _f.call(this, error);
|
|
1446
1709
|
throw error;
|
|
@@ -1492,10 +1755,11 @@ var HttpMCPTransport = class {
|
|
|
1492
1755
|
if (resumeToken) {
|
|
1493
1756
|
headers["last-event-id"] = resumeToken;
|
|
1494
1757
|
}
|
|
1495
|
-
const response = await
|
|
1758
|
+
const response = await this.fetchFn(this.url.href, {
|
|
1496
1759
|
method: "GET",
|
|
1497
1760
|
headers,
|
|
1498
|
-
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1761
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
|
|
1762
|
+
redirect: this.redirectMode
|
|
1499
1763
|
});
|
|
1500
1764
|
const sessionId = response.headers.get("mcp-session-id");
|
|
1501
1765
|
if (sessionId) {
|
|
@@ -1504,10 +1768,7 @@ var HttpMCPTransport = class {
|
|
|
1504
1768
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1505
1769
|
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
1506
1770
|
try {
|
|
1507
|
-
const result = await
|
|
1508
|
-
serverUrl: this.url,
|
|
1509
|
-
resourceMetadataUrl: this.resourceMetadataUrl
|
|
1510
|
-
});
|
|
1771
|
+
const result = await this.authorizeOnce(this.resourceMetadataUrl);
|
|
1511
1772
|
if (result !== "AUTHORIZED") {
|
|
1512
1773
|
const error = new UnauthorizedError();
|
|
1513
1774
|
(_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
|
|
@@ -1524,12 +1785,14 @@ var HttpMCPTransport = class {
|
|
|
1524
1785
|
}
|
|
1525
1786
|
if (!response.ok || !response.body) {
|
|
1526
1787
|
const error = new MCPClientError({
|
|
1527
|
-
message: `MCP HTTP Transport Error: GET SSE failed: ${response.status} ${response.statusText}
|
|
1788
|
+
message: `MCP HTTP Transport Error: GET SSE failed: ${response.status} ${response.statusText}`,
|
|
1789
|
+
statusCode: response.status,
|
|
1790
|
+
url: this.url.href
|
|
1528
1791
|
});
|
|
1529
1792
|
(_d = this.onerror) == null ? void 0 : _d.call(this, error);
|
|
1530
1793
|
return;
|
|
1531
1794
|
}
|
|
1532
|
-
const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new
|
|
1795
|
+
const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream2());
|
|
1533
1796
|
const reader = stream.getReader();
|
|
1534
1797
|
const processEvents = async () => {
|
|
1535
1798
|
var _a4, _b4, _c2, _d2;
|
|
@@ -1541,10 +1804,10 @@ var HttpMCPTransport = class {
|
|
|
1541
1804
|
if (id) {
|
|
1542
1805
|
this.lastInboundEventId = id;
|
|
1543
1806
|
}
|
|
1544
|
-
if (event
|
|
1807
|
+
if (isMessageEvent2(event)) {
|
|
1545
1808
|
try {
|
|
1546
|
-
const
|
|
1547
|
-
(_a4 = this.onmessage) == null ? void 0 : _a4.call(this,
|
|
1809
|
+
const jsonRpcMessage = await parseJSONRPCMessage(data);
|
|
1810
|
+
(_a4 = this.onmessage) == null ? void 0 : _a4.call(this, jsonRpcMessage);
|
|
1548
1811
|
} catch (error) {
|
|
1549
1812
|
const e = new MCPClientError({
|
|
1550
1813
|
message: "MCP HTTP Transport Error: Failed to parse message",
|
|
@@ -1598,6 +1861,112 @@ function isCustomMcpTransport(transport) {
|
|
|
1598
1861
|
return "start" in transport && typeof transport.start === "function" && "send" in transport && typeof transport.send === "function" && "close" in transport && typeof transport.close === "function";
|
|
1599
1862
|
}
|
|
1600
1863
|
|
|
1864
|
+
// src/tool/mcp-apps.ts
|
|
1865
|
+
import { isJSONObject } from "@ai-sdk/provider";
|
|
1866
|
+
import { convertBase64ToUint8Array } from "@ai-sdk/provider-utils";
|
|
1867
|
+
var MCP_APP_EXTENSION_NAME = "io.modelcontextprotocol/ui";
|
|
1868
|
+
var MCP_APP_MIME_TYPE = "text/html;profile=mcp-app";
|
|
1869
|
+
var MCP_APP_LEGACY_RESOURCE_URI_META_KEY = "ui/resourceUri";
|
|
1870
|
+
var mcpAppClientCapabilities = {
|
|
1871
|
+
extensions: {
|
|
1872
|
+
[MCP_APP_EXTENSION_NAME]: {
|
|
1873
|
+
mimeTypes: [MCP_APP_MIME_TYPE]
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
};
|
|
1877
|
+
function getToolUiMeta(meta) {
|
|
1878
|
+
const uiMeta = meta == null ? void 0 : meta.ui;
|
|
1879
|
+
return isJSONObject(uiMeta) ? uiMeta : void 0;
|
|
1880
|
+
}
|
|
1881
|
+
function getResourceUiMeta(meta) {
|
|
1882
|
+
const resourceMeta = isJSONObject(meta) ? meta : void 0;
|
|
1883
|
+
const rawUiMeta = resourceMeta == null ? void 0 : resourceMeta.ui;
|
|
1884
|
+
const uiMeta = isJSONObject(rawUiMeta) ? rawUiMeta : void 0;
|
|
1885
|
+
return uiMeta;
|
|
1886
|
+
}
|
|
1887
|
+
function parseVisibility(value) {
|
|
1888
|
+
return Array.isArray(value) ? value.filter(
|
|
1889
|
+
(v) => v === "model" || v === "app"
|
|
1890
|
+
) : void 0;
|
|
1891
|
+
}
|
|
1892
|
+
function getMCPAppToolMeta(tool2) {
|
|
1893
|
+
var _a3, _b3;
|
|
1894
|
+
const uiMeta = getToolUiMeta(tool2._meta);
|
|
1895
|
+
const resourceUri = (_b3 = uiMeta == null ? void 0 : uiMeta.resourceUri) != null ? _b3 : (_a3 = tool2._meta) == null ? void 0 : _a3[MCP_APP_LEGACY_RESOURCE_URI_META_KEY];
|
|
1896
|
+
const visibility = parseVisibility(uiMeta == null ? void 0 : uiMeta.visibility);
|
|
1897
|
+
if (resourceUri !== void 0) {
|
|
1898
|
+
if (typeof resourceUri !== "string" || !resourceUri.startsWith("ui://")) {
|
|
1899
|
+
throw new Error(
|
|
1900
|
+
`Invalid MCP App resource URI: ${JSON.stringify(resourceUri)}`
|
|
1901
|
+
);
|
|
1902
|
+
}
|
|
1903
|
+
} else if (uiMeta == null) {
|
|
1904
|
+
return void 0;
|
|
1905
|
+
}
|
|
1906
|
+
return {
|
|
1907
|
+
...uiMeta,
|
|
1908
|
+
...resourceUri != null ? { resourceUri } : {},
|
|
1909
|
+
...visibility != null ? { visibility } : {}
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
function splitMCPAppTools(definitions) {
|
|
1913
|
+
var _a3;
|
|
1914
|
+
const modelVisibleTools = [];
|
|
1915
|
+
const appVisibleTools = [];
|
|
1916
|
+
for (const tool2 of definitions.tools) {
|
|
1917
|
+
const visibility = (_a3 = getMCPAppToolMeta(tool2)) == null ? void 0 : _a3.visibility;
|
|
1918
|
+
if (visibility == null || visibility.includes("model")) {
|
|
1919
|
+
modelVisibleTools.push(tool2);
|
|
1920
|
+
}
|
|
1921
|
+
if ((visibility == null ? void 0 : visibility.includes("app")) === true) {
|
|
1922
|
+
appVisibleTools.push(tool2);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
return {
|
|
1926
|
+
modelVisible: {
|
|
1927
|
+
...definitions,
|
|
1928
|
+
tools: modelVisibleTools
|
|
1929
|
+
},
|
|
1930
|
+
appVisible: {
|
|
1931
|
+
...definitions,
|
|
1932
|
+
tools: appVisibleTools
|
|
1933
|
+
}
|
|
1934
|
+
};
|
|
1935
|
+
}
|
|
1936
|
+
function getMCPAppResourceFromReadResult({
|
|
1937
|
+
uri,
|
|
1938
|
+
resource
|
|
1939
|
+
}) {
|
|
1940
|
+
const content = resource.contents.find((content2) => content2.uri === uri);
|
|
1941
|
+
if (content == null) {
|
|
1942
|
+
throw new Error(`MCP App resource not found in read result: ${uri}`);
|
|
1943
|
+
}
|
|
1944
|
+
if (content.mimeType !== MCP_APP_MIME_TYPE) {
|
|
1945
|
+
throw new Error(
|
|
1946
|
+
`Unsupported MCP App resource MIME type: ${content.mimeType}`
|
|
1947
|
+
);
|
|
1948
|
+
}
|
|
1949
|
+
const html = "text" in content && typeof content.text === "string" ? content.text : "blob" in content && typeof content.blob === "string" ? new TextDecoder().decode(convertBase64ToUint8Array(content.blob)) : void 0;
|
|
1950
|
+
if (html == null) {
|
|
1951
|
+
throw new Error(`Unsupported MCP App resource content format: ${uri}`);
|
|
1952
|
+
}
|
|
1953
|
+
const meta = getResourceUiMeta(content._meta);
|
|
1954
|
+
return { uri, mimeType: MCP_APP_MIME_TYPE, html, meta };
|
|
1955
|
+
}
|
|
1956
|
+
async function readMCPAppResource({
|
|
1957
|
+
client,
|
|
1958
|
+
uri,
|
|
1959
|
+
options
|
|
1960
|
+
}) {
|
|
1961
|
+
if (!uri.startsWith("ui://")) {
|
|
1962
|
+
throw new Error(`Unsupported MCP App resource URI: ${uri}`);
|
|
1963
|
+
}
|
|
1964
|
+
return getMCPAppResourceFromReadResult({
|
|
1965
|
+
uri,
|
|
1966
|
+
resource: await client.readResource({ uri, options })
|
|
1967
|
+
});
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1601
1970
|
// src/tool/mcp-client.ts
|
|
1602
1971
|
var CLIENT_VERSION = "1.0.0";
|
|
1603
1972
|
function mcpToModelOutput({
|
|
@@ -1614,9 +1983,9 @@ function mcpToModelOutput({
|
|
|
1614
1983
|
}
|
|
1615
1984
|
if (part.type === "image" && "data" in part && "mimeType" in part) {
|
|
1616
1985
|
return {
|
|
1617
|
-
type: "
|
|
1618
|
-
|
|
1619
|
-
|
|
1986
|
+
type: "file",
|
|
1987
|
+
mediaType: part.mimeType,
|
|
1988
|
+
data: { type: "data", data: part.data }
|
|
1620
1989
|
};
|
|
1621
1990
|
}
|
|
1622
1991
|
return { type: "text", text: JSON.stringify(part) };
|
|
@@ -1632,7 +2001,8 @@ async function createMCPClient(config) {
|
|
|
1632
2001
|
var DefaultMCPClient = class {
|
|
1633
2002
|
constructor({
|
|
1634
2003
|
transport: transportConfig,
|
|
1635
|
-
name: name3
|
|
2004
|
+
name: name3,
|
|
2005
|
+
clientName = name3 != null ? name3 : "ai-sdk-mcp-client",
|
|
1636
2006
|
version = CLIENT_VERSION,
|
|
1637
2007
|
onUncaughtError,
|
|
1638
2008
|
capabilities
|
|
@@ -1640,6 +2010,7 @@ var DefaultMCPClient = class {
|
|
|
1640
2010
|
this.requestMessageId = 0;
|
|
1641
2011
|
this.responseHandlers = /* @__PURE__ */ new Map();
|
|
1642
2012
|
this.serverCapabilities = {};
|
|
2013
|
+
this._serverInfo = { name: "", version: "" };
|
|
1643
2014
|
this.isClosed = true;
|
|
1644
2015
|
this.onUncaughtError = onUncaughtError;
|
|
1645
2016
|
this.clientCapabilities = capabilities != null ? capabilities : {};
|
|
@@ -1666,10 +2037,16 @@ var DefaultMCPClient = class {
|
|
|
1666
2037
|
this.onResponse(message);
|
|
1667
2038
|
};
|
|
1668
2039
|
this.clientInfo = {
|
|
1669
|
-
name:
|
|
2040
|
+
name: clientName,
|
|
1670
2041
|
version
|
|
1671
2042
|
};
|
|
1672
2043
|
}
|
|
2044
|
+
get serverInfo() {
|
|
2045
|
+
return this._serverInfo;
|
|
2046
|
+
}
|
|
2047
|
+
get instructions() {
|
|
2048
|
+
return this._serverInstructions;
|
|
2049
|
+
}
|
|
1673
2050
|
async init() {
|
|
1674
2051
|
try {
|
|
1675
2052
|
await this.transport.start();
|
|
@@ -1696,6 +2073,13 @@ var DefaultMCPClient = class {
|
|
|
1696
2073
|
});
|
|
1697
2074
|
}
|
|
1698
2075
|
this.serverCapabilities = result.capabilities;
|
|
2076
|
+
this._serverInfo = result.serverInfo;
|
|
2077
|
+
if (this.transport.setProtocolVersion) {
|
|
2078
|
+
this.transport.setProtocolVersion(result.protocolVersion);
|
|
2079
|
+
} else {
|
|
2080
|
+
this.transport.protocolVersion = result.protocolVersion;
|
|
2081
|
+
}
|
|
2082
|
+
this._serverInstructions = result.instructions;
|
|
1699
2083
|
await this.notification({
|
|
1700
2084
|
method: "notifications/initialized"
|
|
1701
2085
|
});
|
|
@@ -1812,16 +2196,14 @@ var DefaultMCPClient = class {
|
|
|
1812
2196
|
}
|
|
1813
2197
|
async callTool({
|
|
1814
2198
|
name: name3,
|
|
1815
|
-
args,
|
|
2199
|
+
arguments: args = {},
|
|
1816
2200
|
options
|
|
1817
2201
|
}) {
|
|
1818
2202
|
try {
|
|
1819
2203
|
return this.request({
|
|
1820
2204
|
request: { method: "tools/call", params: { name: name3, arguments: args } },
|
|
1821
2205
|
resultSchema: CallToolResultSchema,
|
|
1822
|
-
options
|
|
1823
|
-
signal: options == null ? void 0 : options.abortSignal
|
|
1824
|
-
}
|
|
2206
|
+
options
|
|
1825
2207
|
});
|
|
1826
2208
|
} catch (error) {
|
|
1827
2209
|
throw error;
|
|
@@ -1932,33 +2314,54 @@ var DefaultMCPClient = class {
|
|
|
1932
2314
|
_meta
|
|
1933
2315
|
} of definitions.tools) {
|
|
1934
2316
|
const resolvedTitle = title != null ? title : annotations == null ? void 0 : annotations.title;
|
|
1935
|
-
if (schemas !== "automatic" && !(name3
|
|
2317
|
+
if (schemas !== "automatic" && !Object.prototype.hasOwnProperty.call(schemas, name3)) {
|
|
1936
2318
|
continue;
|
|
1937
2319
|
}
|
|
1938
2320
|
const self = this;
|
|
1939
2321
|
const outputSchema = schemas !== "automatic" ? (_a3 = schemas[name3]) == null ? void 0 : _a3.outputSchema : void 0;
|
|
2322
|
+
const appMeta = getMCPAppToolMeta({ _meta });
|
|
2323
|
+
const metadata = {
|
|
2324
|
+
clientName: this.clientInfo.name,
|
|
2325
|
+
toolName: name3,
|
|
2326
|
+
...resolvedTitle != null ? { title: resolvedTitle } : {},
|
|
2327
|
+
...(appMeta == null ? void 0 : appMeta.resourceUri) != null ? {
|
|
2328
|
+
app: {
|
|
2329
|
+
...appMeta,
|
|
2330
|
+
mimeType: MCP_APP_MIME_TYPE
|
|
2331
|
+
}
|
|
2332
|
+
} : {}
|
|
2333
|
+
};
|
|
1940
2334
|
const execute = async (args, options) => {
|
|
1941
2335
|
var _a4;
|
|
1942
2336
|
(_a4 = options == null ? void 0 : options.abortSignal) == null ? void 0 : _a4.throwIfAborted();
|
|
1943
|
-
const result = await self.callTool({
|
|
2337
|
+
const result = await self.callTool({
|
|
2338
|
+
name: name3,
|
|
2339
|
+
arguments: args,
|
|
2340
|
+
options: { signal: options == null ? void 0 : options.abortSignal }
|
|
2341
|
+
});
|
|
2342
|
+
if (result.isError) {
|
|
2343
|
+
return result;
|
|
2344
|
+
}
|
|
1944
2345
|
if (outputSchema != null) {
|
|
1945
2346
|
return self.extractStructuredContent(result, outputSchema, name3);
|
|
1946
2347
|
}
|
|
1947
2348
|
return result;
|
|
1948
2349
|
};
|
|
1949
|
-
const toolWithExecute = schemas === "automatic" ?
|
|
2350
|
+
const toolWithExecute = schemas === "automatic" ? dynamicTool({
|
|
1950
2351
|
description,
|
|
1951
2352
|
title: resolvedTitle,
|
|
1952
|
-
|
|
2353
|
+
metadata,
|
|
2354
|
+
inputSchema: jsonSchema({
|
|
1953
2355
|
...inputSchema,
|
|
1954
2356
|
properties: (_b3 = inputSchema.properties) != null ? _b3 : {},
|
|
1955
2357
|
additionalProperties: false
|
|
1956
2358
|
}),
|
|
1957
2359
|
execute,
|
|
1958
2360
|
toModelOutput: mcpToModelOutput
|
|
1959
|
-
}) :
|
|
2361
|
+
}) : tool({
|
|
1960
2362
|
description,
|
|
1961
2363
|
title: resolvedTitle,
|
|
2364
|
+
metadata,
|
|
1962
2365
|
inputSchema: schemas[name3].inputSchema,
|
|
1963
2366
|
...outputSchema != null ? { outputSchema } : {},
|
|
1964
2367
|
execute,
|
|
@@ -1973,9 +2376,9 @@ var DefaultMCPClient = class {
|
|
|
1973
2376
|
*/
|
|
1974
2377
|
async extractStructuredContent(result, outputSchema, toolName) {
|
|
1975
2378
|
if ("structuredContent" in result && result.structuredContent != null) {
|
|
1976
|
-
const validationResult = await
|
|
2379
|
+
const validationResult = await safeValidateTypes({
|
|
1977
2380
|
value: result.structuredContent,
|
|
1978
|
-
schema:
|
|
2381
|
+
schema: asSchema(outputSchema)
|
|
1979
2382
|
});
|
|
1980
2383
|
if (!validationResult.success) {
|
|
1981
2384
|
throw new MCPClientError({
|
|
@@ -1988,7 +2391,7 @@ var DefaultMCPClient = class {
|
|
|
1988
2391
|
if ("content" in result && Array.isArray(result.content)) {
|
|
1989
2392
|
const textContent = result.content.find((c) => c.type === "text");
|
|
1990
2393
|
if (textContent && "text" in textContent) {
|
|
1991
|
-
const parseResult = await
|
|
2394
|
+
const parseResult = await safeParseJSON({
|
|
1992
2395
|
text: textContent.text,
|
|
1993
2396
|
schema: outputSchema
|
|
1994
2397
|
});
|
|
@@ -2045,6 +2448,14 @@ var DefaultMCPClient = class {
|
|
|
2045
2448
|
}
|
|
2046
2449
|
async onRequestMessage(request) {
|
|
2047
2450
|
try {
|
|
2451
|
+
if (request.method === "ping") {
|
|
2452
|
+
await this.transport.send({
|
|
2453
|
+
jsonrpc: "2.0",
|
|
2454
|
+
id: request.id,
|
|
2455
|
+
result: {}
|
|
2456
|
+
});
|
|
2457
|
+
return;
|
|
2458
|
+
}
|
|
2048
2459
|
if (request.method !== "elicitation/create") {
|
|
2049
2460
|
await this.transport.send({
|
|
2050
2461
|
jsonrpc: "2.0",
|
|
@@ -2143,13 +2554,16 @@ var DefaultMCPClient = class {
|
|
|
2143
2554
|
);
|
|
2144
2555
|
}
|
|
2145
2556
|
};
|
|
2146
|
-
|
|
2147
|
-
0 && (module.exports = {
|
|
2557
|
+
export {
|
|
2148
2558
|
ElicitResultSchema,
|
|
2149
2559
|
ElicitationRequestSchema,
|
|
2560
|
+
MCP_APP_MIME_TYPE,
|
|
2150
2561
|
UnauthorizedError,
|
|
2151
2562
|
auth,
|
|
2152
2563
|
createMCPClient,
|
|
2153
|
-
experimental_createMCPClient
|
|
2154
|
-
|
|
2564
|
+
createMCPClient as experimental_createMCPClient,
|
|
2565
|
+
mcpAppClientCapabilities,
|
|
2566
|
+
readMCPAppResource,
|
|
2567
|
+
splitMCPAppTools
|
|
2568
|
+
};
|
|
2155
2569
|
//# sourceMappingURL=index.js.map
|