@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 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
- this.endpoint = new URL(data, this.url);
1137
- if (this.endpoint.origin !== this.url.origin) {
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: ${this.endpoint.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 === "message") {
1155
+ } else if (isMessageEvent(event)) {
1145
1156
  try {
1146
1157
  const message = await parseJSONRPCMessage(data);
1147
- (_a4 = this.onmessage) == null ? void 0 : _a4.call(this, message);
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
- (_b4 = this.onerror) == null ? void 0 : _b4.call(this, e);
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
- (_c2 = this.onerror) == null ? void 0 : _c2.call(this, error);
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 === "message") {
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 === "message") {
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 in schemas)) {
1881
+ if (schemas !== "automatic" && !Object.prototype.hasOwnProperty.call(schemas, name3)) {
1867
1882
  continue;
1868
1883
  }
1869
1884
  const self = this;