@ai-sdk/mcp 1.0.27 → 1.0.29
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 +12 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +31 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +28 -7
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-stdio/index.js +3 -3
- package/dist/mcp-stdio/index.mjs +1 -1
- package/package.json +2 -2
- package/src/tool/mcp-http-transport.ts +7 -0
- package/src/tool/mcp-sse-transport.ts +6 -0
- package/src/tool/mcp-transport.ts +8 -0
- package/src/tool/oauth.ts +17 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ai-sdk/mcp
|
|
2
2
|
|
|
3
|
+
## 1.0.29
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- cc8b506: feat(mcp): add `redirect` option to `MCPTransportConfig` for controlling HTTP redirect behavior
|
|
8
|
+
|
|
9
|
+
## 1.0.28
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 0c86a13: fix(mcp): validate state param in oauth flow
|
|
14
|
+
|
|
3
15
|
## 1.0.27
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -182,6 +182,8 @@ interface OAuthClientProvider {
|
|
|
182
182
|
clientInformation(): OAuthClientInformation | undefined | Promise<OAuthClientInformation | undefined>;
|
|
183
183
|
saveClientInformation?(clientInformation: OAuthClientInformation): void | Promise<void>;
|
|
184
184
|
state?(): string | Promise<string>;
|
|
185
|
+
saveState?(state: string): void | Promise<void>;
|
|
186
|
+
storedState?(): string | undefined | Promise<string | undefined>;
|
|
185
187
|
validateResourceURL?(serverUrl: string | URL, resource?: string): Promise<URL | undefined>;
|
|
186
188
|
}
|
|
187
189
|
declare class UnauthorizedError extends Error {
|
|
@@ -190,6 +192,7 @@ declare class UnauthorizedError extends Error {
|
|
|
190
192
|
declare function auth(provider: OAuthClientProvider, options: {
|
|
191
193
|
serverUrl: string | URL;
|
|
192
194
|
authorizationCode?: string;
|
|
195
|
+
callbackState?: string;
|
|
193
196
|
scope?: string;
|
|
194
197
|
resourceMetadataUrl?: URL;
|
|
195
198
|
fetchFn?: FetchFunction;
|
|
@@ -240,6 +243,13 @@ type MCPTransportConfig = {
|
|
|
240
243
|
* An optional OAuth client provider to use for authentication for MCP servers.
|
|
241
244
|
*/
|
|
242
245
|
authProvider?: OAuthClientProvider;
|
|
246
|
+
/**
|
|
247
|
+
* Controls how HTTP redirects are handled for transport requests.
|
|
248
|
+
* - `'follow'`: Follow redirects automatically (standard fetch behavior).
|
|
249
|
+
* - `'error'`: Reject any redirect response with an error.
|
|
250
|
+
* @default 'follow'
|
|
251
|
+
*/
|
|
252
|
+
redirect?: 'follow' | 'error';
|
|
243
253
|
};
|
|
244
254
|
|
|
245
255
|
/** MCP tool metadata - keys should follow MCP _meta key format specification */
|
package/dist/index.d.ts
CHANGED
|
@@ -182,6 +182,8 @@ interface OAuthClientProvider {
|
|
|
182
182
|
clientInformation(): OAuthClientInformation | undefined | Promise<OAuthClientInformation | undefined>;
|
|
183
183
|
saveClientInformation?(clientInformation: OAuthClientInformation): void | Promise<void>;
|
|
184
184
|
state?(): string | Promise<string>;
|
|
185
|
+
saveState?(state: string): void | Promise<void>;
|
|
186
|
+
storedState?(): string | undefined | Promise<string | undefined>;
|
|
185
187
|
validateResourceURL?(serverUrl: string | URL, resource?: string): Promise<URL | undefined>;
|
|
186
188
|
}
|
|
187
189
|
declare class UnauthorizedError extends Error {
|
|
@@ -190,6 +192,7 @@ declare class UnauthorizedError extends Error {
|
|
|
190
192
|
declare function auth(provider: OAuthClientProvider, options: {
|
|
191
193
|
serverUrl: string | URL;
|
|
192
194
|
authorizationCode?: string;
|
|
195
|
+
callbackState?: string;
|
|
193
196
|
scope?: string;
|
|
194
197
|
resourceMetadataUrl?: URL;
|
|
195
198
|
fetchFn?: FetchFunction;
|
|
@@ -240,6 +243,13 @@ type MCPTransportConfig = {
|
|
|
240
243
|
* An optional OAuth client provider to use for authentication for MCP servers.
|
|
241
244
|
*/
|
|
242
245
|
authProvider?: OAuthClientProvider;
|
|
246
|
+
/**
|
|
247
|
+
* Controls how HTTP redirects are handled for transport requests.
|
|
248
|
+
* - `'follow'`: Follow redirects automatically (standard fetch behavior).
|
|
249
|
+
* - `'error'`: Reject any redirect response with an error.
|
|
250
|
+
* @default 'follow'
|
|
251
|
+
*/
|
|
252
|
+
redirect?: 'follow' | 'error';
|
|
243
253
|
};
|
|
244
254
|
|
|
245
255
|
/** MCP tool metadata - keys should follow MCP _meta key format specification */
|
package/dist/index.js
CHANGED
|
@@ -28,8 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
|
|
30
30
|
// src/index.ts
|
|
31
|
-
var
|
|
32
|
-
__export(
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
33
|
ElicitResultSchema: () => ElicitResultSchema,
|
|
34
34
|
ElicitationRequestSchema: () => ElicitationRequestSchema,
|
|
35
35
|
UnauthorizedError: () => UnauthorizedError,
|
|
@@ -37,7 +37,7 @@ __export(src_exports, {
|
|
|
37
37
|
createMCPClient: () => createMCPClient,
|
|
38
38
|
experimental_createMCPClient: () => createMCPClient
|
|
39
39
|
});
|
|
40
|
-
module.exports = __toCommonJS(
|
|
40
|
+
module.exports = __toCommonJS(index_exports);
|
|
41
41
|
|
|
42
42
|
// src/tool/mcp-client.ts
|
|
43
43
|
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
@@ -949,6 +949,7 @@ async function selectResourceURL(serverUrl, provider, resourceMetadata) {
|
|
|
949
949
|
async function authInternal(provider, {
|
|
950
950
|
serverUrl,
|
|
951
951
|
authorizationCode,
|
|
952
|
+
callbackState,
|
|
952
953
|
scope,
|
|
953
954
|
resourceMetadataUrl,
|
|
954
955
|
fetchFn
|
|
@@ -1001,6 +1002,14 @@ async function authInternal(provider, {
|
|
|
1001
1002
|
clientInformation = fullInformation;
|
|
1002
1003
|
}
|
|
1003
1004
|
if (authorizationCode !== void 0) {
|
|
1005
|
+
if (provider.storedState) {
|
|
1006
|
+
const expectedState = await provider.storedState();
|
|
1007
|
+
if (expectedState !== void 0 && expectedState !== callbackState) {
|
|
1008
|
+
throw new Error(
|
|
1009
|
+
"OAuth state parameter mismatch - possible CSRF attack"
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1004
1013
|
const codeVerifier2 = await provider.codeVerifier();
|
|
1005
1014
|
const tokens2 = await exchangeAuthorization(authorizationServerUrl, {
|
|
1006
1015
|
metadata,
|
|
@@ -1039,6 +1048,9 @@ async function authInternal(provider, {
|
|
|
1039
1048
|
}
|
|
1040
1049
|
}
|
|
1041
1050
|
const state = provider.state ? await provider.state() : void 0;
|
|
1051
|
+
if (state && provider.saveState) {
|
|
1052
|
+
await provider.saveState(state);
|
|
1053
|
+
}
|
|
1042
1054
|
const { authorizationUrl, codeVerifier } = await startAuthorization(
|
|
1043
1055
|
authorizationServerUrl,
|
|
1044
1056
|
{
|
|
@@ -1060,12 +1072,14 @@ var SseMCPTransport = class {
|
|
|
1060
1072
|
constructor({
|
|
1061
1073
|
url,
|
|
1062
1074
|
headers,
|
|
1063
|
-
authProvider
|
|
1075
|
+
authProvider,
|
|
1076
|
+
redirect = "follow"
|
|
1064
1077
|
}) {
|
|
1065
1078
|
this.connected = false;
|
|
1066
1079
|
this.url = new URL(url);
|
|
1067
1080
|
this.headers = headers;
|
|
1068
1081
|
this.authProvider = authProvider;
|
|
1082
|
+
this.redirectMode = redirect;
|
|
1069
1083
|
}
|
|
1070
1084
|
async commonHeaders(base) {
|
|
1071
1085
|
const headers = {
|
|
@@ -1099,7 +1113,8 @@ var SseMCPTransport = class {
|
|
|
1099
1113
|
});
|
|
1100
1114
|
const response = await fetch(this.url.href, {
|
|
1101
1115
|
headers,
|
|
1102
|
-
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1116
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
|
|
1117
|
+
redirect: this.redirectMode
|
|
1103
1118
|
});
|
|
1104
1119
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1105
1120
|
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
@@ -1218,7 +1233,8 @@ var SseMCPTransport = class {
|
|
|
1218
1233
|
method: "POST",
|
|
1219
1234
|
headers,
|
|
1220
1235
|
body: JSON.stringify(message),
|
|
1221
|
-
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1236
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
|
|
1237
|
+
redirect: this.redirectMode
|
|
1222
1238
|
};
|
|
1223
1239
|
const response = await fetch(endpoint, init);
|
|
1224
1240
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
@@ -1262,7 +1278,8 @@ var HttpMCPTransport = class {
|
|
|
1262
1278
|
constructor({
|
|
1263
1279
|
url,
|
|
1264
1280
|
headers,
|
|
1265
|
-
authProvider
|
|
1281
|
+
authProvider,
|
|
1282
|
+
redirect = "follow"
|
|
1266
1283
|
}) {
|
|
1267
1284
|
this.inboundReconnectAttempts = 0;
|
|
1268
1285
|
this.reconnectionOptions = {
|
|
@@ -1274,6 +1291,7 @@ var HttpMCPTransport = class {
|
|
|
1274
1291
|
this.url = new URL(url);
|
|
1275
1292
|
this.headers = headers;
|
|
1276
1293
|
this.authProvider = authProvider;
|
|
1294
|
+
this.redirectMode = redirect;
|
|
1277
1295
|
}
|
|
1278
1296
|
async commonHeaders(base) {
|
|
1279
1297
|
const headers = {
|
|
@@ -1314,7 +1332,8 @@ var HttpMCPTransport = class {
|
|
|
1314
1332
|
await fetch(this.url, {
|
|
1315
1333
|
method: "DELETE",
|
|
1316
1334
|
headers,
|
|
1317
|
-
signal: this.abortController.signal
|
|
1335
|
+
signal: this.abortController.signal,
|
|
1336
|
+
redirect: this.redirectMode
|
|
1318
1337
|
}).catch(() => void 0);
|
|
1319
1338
|
}
|
|
1320
1339
|
} catch (e) {
|
|
@@ -1334,7 +1353,8 @@ var HttpMCPTransport = class {
|
|
|
1334
1353
|
method: "POST",
|
|
1335
1354
|
headers,
|
|
1336
1355
|
body: JSON.stringify(message),
|
|
1337
|
-
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1356
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
|
|
1357
|
+
redirect: this.redirectMode
|
|
1338
1358
|
};
|
|
1339
1359
|
const response = await fetch(this.url, init);
|
|
1340
1360
|
const sessionId = response.headers.get("mcp-session-id");
|
|
@@ -1483,7 +1503,8 @@ var HttpMCPTransport = class {
|
|
|
1483
1503
|
const response = await fetch(this.url.href, {
|
|
1484
1504
|
method: "GET",
|
|
1485
1505
|
headers,
|
|
1486
|
-
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
|
|
1506
|
+
signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
|
|
1507
|
+
redirect: this.redirectMode
|
|
1487
1508
|
});
|
|
1488
1509
|
const sessionId = response.headers.get("mcp-session-id");
|
|
1489
1510
|
if (sessionId) {
|