@ai-sdk/mcp 0.0.18 → 0.0.20
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 +25 -0
- package/dist/index.js +26 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +26 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @ai-sdk/mcp
|
|
2
2
|
|
|
3
|
+
## 0.0.20
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1673f7b: fix (mcp): handle SSE messages without explicit event fields
|
|
8
|
+
|
|
9
|
+
## 0.0.19
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- d872a7a: fix(mcp): lock first sse endpoint received via event
|
|
14
|
+
- f4cd468: fix(mcp): prevent prototype-named tools from bypassing the `schemas` allowlist
|
|
15
|
+
|
|
16
|
+
When using `client.tools({ schemas })` to expose only an explicitly allowed
|
|
17
|
+
subset of an MCP server's tools, the allowlist check used the `in` operator,
|
|
18
|
+
which also matches inherited `Object.prototype` properties. A server-advertised
|
|
19
|
+
tool named `constructor`, `toString`, `__proto__`, etc. would pass the check
|
|
20
|
+
even though the developer never defined it in `schemas`, and was then exposed to
|
|
21
|
+
the model and executable. The check now uses `Object.hasOwn`, so only
|
|
22
|
+
explicitly defined tools are returned.
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [9f67efe]
|
|
25
|
+
- Updated dependencies [eea9166]
|
|
26
|
+
- @ai-sdk/provider-utils@3.0.26
|
|
27
|
+
|
|
3
28
|
## 0.0.18
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -1041,6 +1041,9 @@ async function authInternal(provider, {
|
|
|
1041
1041
|
}
|
|
1042
1042
|
|
|
1043
1043
|
// src/tool/mcp-sse-transport.ts
|
|
1044
|
+
function isMessageEvent(event) {
|
|
1045
|
+
return event === void 0 || event === "message";
|
|
1046
|
+
}
|
|
1044
1047
|
var SseMCPTransport = class {
|
|
1045
1048
|
constructor({
|
|
1046
1049
|
url,
|
|
@@ -1118,7 +1121,7 @@ var SseMCPTransport = class {
|
|
|
1118
1121
|
const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new import_provider_utils3.EventSourceParserStream());
|
|
1119
1122
|
const reader = stream.getReader();
|
|
1120
1123
|
const processEvents = async () => {
|
|
1121
|
-
var _a4, _b4, _c2;
|
|
1124
|
+
var _a4, _b4, _c2, _d2, _e2;
|
|
1122
1125
|
try {
|
|
1123
1126
|
while (true) {
|
|
1124
1127
|
const { done, value } = await reader.read();
|
|
@@ -1133,24 +1136,32 @@ var SseMCPTransport = class {
|
|
|
1133
1136
|
}
|
|
1134
1137
|
const { event, data } = value;
|
|
1135
1138
|
if (event === "endpoint") {
|
|
1136
|
-
|
|
1137
|
-
|
|
1139
|
+
if (this.endpoint) {
|
|
1140
|
+
continue;
|
|
1141
|
+
}
|
|
1142
|
+
const endpoint = new URL(data, this.url);
|
|
1143
|
+
if (endpoint.origin !== this.url.origin) {
|
|
1144
|
+
this.connected = false;
|
|
1145
|
+
this.endpoint = void 0;
|
|
1146
|
+
(_a4 = this.sseConnection) == null ? void 0 : _a4.close();
|
|
1147
|
+
(_b4 = this.abortController) == null ? void 0 : _b4.abort();
|
|
1138
1148
|
throw new MCPClientError({
|
|
1139
|
-
message: `MCP SSE Transport Error: Endpoint origin does not match connection origin: ${
|
|
1149
|
+
message: `MCP SSE Transport Error: Endpoint origin does not match connection origin: ${endpoint.origin}`
|
|
1140
1150
|
});
|
|
1141
1151
|
}
|
|
1152
|
+
this.endpoint = endpoint;
|
|
1142
1153
|
this.connected = true;
|
|
1143
1154
|
resolve();
|
|
1144
|
-
} else if (event
|
|
1155
|
+
} else if (isMessageEvent(event)) {
|
|
1145
1156
|
try {
|
|
1146
1157
|
const message = await parseJSONRPCMessage(data);
|
|
1147
|
-
(
|
|
1158
|
+
(_c2 = this.onmessage) == null ? void 0 : _c2.call(this, message);
|
|
1148
1159
|
} catch (error) {
|
|
1149
1160
|
const e = new MCPClientError({
|
|
1150
1161
|
message: "MCP SSE Transport Error: Failed to parse message",
|
|
1151
1162
|
cause: error
|
|
1152
1163
|
});
|
|
1153
|
-
(
|
|
1164
|
+
(_d2 = this.onerror) == null ? void 0 : _d2.call(this, e);
|
|
1154
1165
|
}
|
|
1155
1166
|
}
|
|
1156
1167
|
}
|
|
@@ -1158,7 +1169,7 @@ var SseMCPTransport = class {
|
|
|
1158
1169
|
if (error instanceof Error && error.name === "AbortError") {
|
|
1159
1170
|
return;
|
|
1160
1171
|
}
|
|
1161
|
-
(
|
|
1172
|
+
(_e2 = this.onerror) == null ? void 0 : _e2.call(this, error);
|
|
1162
1173
|
reject(error);
|
|
1163
1174
|
}
|
|
1164
1175
|
};
|
|
@@ -1180,6 +1191,7 @@ var SseMCPTransport = class {
|
|
|
1180
1191
|
async close() {
|
|
1181
1192
|
var _a3, _b3, _c;
|
|
1182
1193
|
this.connected = false;
|
|
1194
|
+
this.endpoint = void 0;
|
|
1183
1195
|
(_a3 = this.sseConnection) == null ? void 0 : _a3.close();
|
|
1184
1196
|
(_b3 = this.abortController) == null ? void 0 : _b3.abort();
|
|
1185
1197
|
(_c = this.onclose) == null ? void 0 : _c.call(this);
|
|
@@ -1241,6 +1253,9 @@ var SseMCPTransport = class {
|
|
|
1241
1253
|
|
|
1242
1254
|
// src/tool/mcp-http-transport.ts
|
|
1243
1255
|
var import_provider_utils4 = require("@ai-sdk/provider-utils");
|
|
1256
|
+
function isMessageEvent2(event) {
|
|
1257
|
+
return event === void 0 || event === "message";
|
|
1258
|
+
}
|
|
1244
1259
|
var HttpMCPTransport = class {
|
|
1245
1260
|
constructor({
|
|
1246
1261
|
url,
|
|
@@ -1383,7 +1398,7 @@ var HttpMCPTransport = class {
|
|
|
1383
1398
|
const { done, value } = await reader.read();
|
|
1384
1399
|
if (done) return;
|
|
1385
1400
|
const { event, data } = value;
|
|
1386
|
-
if (event
|
|
1401
|
+
if (isMessageEvent2(event)) {
|
|
1387
1402
|
try {
|
|
1388
1403
|
const msg = await parseJSONRPCMessage(data);
|
|
1389
1404
|
(_a4 = this.onmessage) == null ? void 0 : _a4.call(this, msg);
|
|
@@ -1508,7 +1523,7 @@ var HttpMCPTransport = class {
|
|
|
1508
1523
|
if (id) {
|
|
1509
1524
|
this.lastInboundEventId = id;
|
|
1510
1525
|
}
|
|
1511
|
-
if (event
|
|
1526
|
+
if (isMessageEvent2(event)) {
|
|
1512
1527
|
try {
|
|
1513
1528
|
const msg = await parseJSONRPCMessage(data);
|
|
1514
1529
|
(_a4 = this.onmessage) == null ? void 0 : _a4.call(this, msg);
|
|
@@ -1863,7 +1878,7 @@ var DefaultMCPClient = class {
|
|
|
1863
1878
|
try {
|
|
1864
1879
|
const listToolsResult = await this.listTools();
|
|
1865
1880
|
for (const { name: name3, description, inputSchema } of listToolsResult.tools) {
|
|
1866
|
-
if (schemas !== "automatic" && !(name3
|
|
1881
|
+
if (schemas !== "automatic" && !Object.prototype.hasOwnProperty.call(schemas, name3)) {
|
|
1867
1882
|
continue;
|
|
1868
1883
|
}
|
|
1869
1884
|
const self = this;
|