@mcp-ts/sdk 2.4.4 → 2.5.0
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/dist/adapters/agui-adapter.d.mts +3 -3
- package/dist/adapters/agui-adapter.d.ts +3 -3
- package/dist/adapters/agui-adapter.js.map +1 -1
- package/dist/adapters/agui-adapter.mjs.map +1 -1
- package/dist/adapters/agui-middleware.d.mts +3 -3
- package/dist/adapters/agui-middleware.d.ts +3 -3
- package/dist/adapters/agui-middleware.js.map +1 -1
- package/dist/adapters/agui-middleware.mjs.map +1 -1
- package/dist/adapters/ai-adapter.d.mts +3 -3
- package/dist/adapters/ai-adapter.d.ts +3 -3
- package/dist/adapters/ai-adapter.js.map +1 -1
- package/dist/adapters/ai-adapter.mjs.map +1 -1
- package/dist/adapters/langchain-adapter.d.mts +3 -3
- package/dist/adapters/langchain-adapter.d.ts +3 -3
- package/dist/adapters/langchain-adapter.js +2 -2
- package/dist/adapters/langchain-adapter.js.map +1 -1
- package/dist/adapters/langchain-adapter.mjs +2 -2
- package/dist/adapters/langchain-adapter.mjs.map +1 -1
- package/dist/adapters/mastra-adapter.d.mts +2 -2
- package/dist/adapters/mastra-adapter.d.ts +2 -2
- package/dist/adapters/mastra-adapter.js +2 -2
- package/dist/adapters/mastra-adapter.js.map +1 -1
- package/dist/adapters/mastra-adapter.mjs +2 -2
- package/dist/adapters/mastra-adapter.mjs.map +1 -1
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +6 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +6 -0
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/react.d.mts +15 -4
- package/dist/client/react.d.ts +15 -4
- package/dist/client/react.js +36 -6
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs +36 -6
- package/dist/client/react.mjs.map +1 -1
- package/dist/client/vue.d.mts +4 -4
- package/dist/client/vue.d.ts +4 -4
- package/dist/client/vue.js +6 -0
- package/dist/client/vue.js.map +1 -1
- package/dist/client/vue.mjs +6 -0
- package/dist/client/vue.mjs.map +1 -1
- package/dist/{index-CkM3p0eE.d.mts → index-CTURVnom.d.mts} +5 -1
- package/dist/{index-CZk2gu2E.d.ts → index-sVcqrhf7.d.ts} +5 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +374 -130
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +370 -130
- package/dist/index.mjs.map +1 -1
- package/dist/{multi-session-client-ChQrBZhF.d.mts → multi-session-client-CSPSHHla.d.ts} +14 -2
- package/dist/{multi-session-client-QOOPdEVp.d.ts → multi-session-client-DMZGVABI.d.mts} +14 -2
- package/dist/server/index.d.mts +13 -4
- package/dist/server/index.d.ts +13 -4
- package/dist/server/index.js +368 -130
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +364 -130
- package/dist/server/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +4 -4
- package/dist/shared/index.d.ts +4 -4
- package/dist/shared/index.js +2 -6
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +2 -6
- package/dist/shared/index.mjs.map +1 -1
- package/dist/{tool-router-DQ-HrD7W.d.ts → tool-router-CS9l0w4a.d.ts} +1 -1
- package/dist/{tool-router-CGs3IDOJ.d.mts → tool-router-CVLBaCwH.d.mts} +1 -1
- package/dist/{types-Bf-7GOLW.d.mts → types-DK_NGWd4.d.mts} +37 -3
- package/dist/{types-Bf-7GOLW.d.ts → types-DK_NGWd4.d.ts} +37 -3
- package/migrations/neon/20260513010000_install_mcp_sessions.sql +1 -0
- package/migrations/supabase/20260330195700_install_mcp_sessions.sql +1 -0
- package/package.json +1 -1
- package/src/adapters/agui-adapter.ts +6 -2
- package/src/adapters/ai-adapter.ts +3 -1
- package/src/adapters/langchain-adapter.ts +5 -3
- package/src/adapters/mastra-adapter.ts +5 -3
- package/src/client/core/sse-client.ts +17 -0
- package/src/client/react/use-mcp.ts +63 -0
- package/src/server/handlers/sse-handler.ts +117 -10
- package/src/server/mcp/multi-session-client.ts +7 -3
- package/src/server/mcp/oauth-client.ts +78 -55
- package/src/server/mcp/tool-policy-gateway.ts +90 -0
- package/src/server/storage/index.ts +1 -1
- package/src/server/storage/neon-backend.ts +65 -60
- package/src/server/storage/session-lifecycle.ts +5 -0
- package/src/server/storage/supabase-backend.ts +27 -15
- package/src/server/storage/tool-policy.ts +89 -0
- package/src/server/storage/types.ts +11 -0
- package/src/shared/types.ts +48 -1
- package/src/shared/utils.ts +16 -14
package/dist/index.mjs
CHANGED
|
@@ -113,13 +113,9 @@ var init_redis = __esm({
|
|
|
113
113
|
}
|
|
114
114
|
});
|
|
115
115
|
var OAUTH_STATE_SEPARATOR = ".";
|
|
116
|
-
var
|
|
117
|
-
"
|
|
118
|
-
|
|
119
|
-
);
|
|
120
|
-
var rest = customAlphabet(
|
|
121
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
|
122
|
-
11
|
|
116
|
+
var serverIdAlphabet = customAlphabet(
|
|
117
|
+
"abcdefghijklmnopqrstuvwxyz0123456789",
|
|
118
|
+
12
|
|
123
119
|
);
|
|
124
120
|
function sanitizeServerLabel(name) {
|
|
125
121
|
let sanitized = name.replace(/[^a-zA-Z0-9-_]/g, "_").replace(/_{2,}/g, "_").toLowerCase();
|
|
@@ -129,7 +125,10 @@ function sanitizeServerLabel(name) {
|
|
|
129
125
|
return sanitized;
|
|
130
126
|
}
|
|
131
127
|
function generateSessionId() {
|
|
132
|
-
return
|
|
128
|
+
return "sess_" + nanoid(21);
|
|
129
|
+
}
|
|
130
|
+
function generateServerId() {
|
|
131
|
+
return serverIdAlphabet();
|
|
133
132
|
}
|
|
134
133
|
function formatOAuthState(nonce, sessionId) {
|
|
135
134
|
return `${nonce}${OAUTH_STATE_SEPARATOR}${sessionId}`;
|
|
@@ -163,6 +162,59 @@ var SOFTWARE_VERSION = "2.3.4";
|
|
|
163
162
|
var MCP_CLIENT_NAME = "mcp-ts-oauth-client";
|
|
164
163
|
var MCP_CLIENT_VERSION = "2.0";
|
|
165
164
|
|
|
165
|
+
// src/server/storage/tool-policy.ts
|
|
166
|
+
function createToolId(serverId, toolName) {
|
|
167
|
+
return `${serverId}::${toolName}`;
|
|
168
|
+
}
|
|
169
|
+
function normalizeToolIds(input) {
|
|
170
|
+
if (!Array.isArray(input)) return [];
|
|
171
|
+
return Array.from(new Set(
|
|
172
|
+
input.filter((id) => typeof id === "string").map((id) => id.trim()).filter(Boolean)
|
|
173
|
+
));
|
|
174
|
+
}
|
|
175
|
+
function normalizeToolPolicy(input, now = Date.now()) {
|
|
176
|
+
if (!input || typeof input !== "object") {
|
|
177
|
+
return void 0;
|
|
178
|
+
}
|
|
179
|
+
const mode = input.mode === "allowlist" || input.mode === "denylist" ? input.mode : "all";
|
|
180
|
+
const updatedAt = typeof input.updatedAt === "number" && Number.isFinite(input.updatedAt) ? input.updatedAt : now;
|
|
181
|
+
if (mode === "all") {
|
|
182
|
+
return { mode: "all", toolIds: [], updatedAt };
|
|
183
|
+
}
|
|
184
|
+
return { mode, toolIds: normalizeToolIds(input.toolIds), updatedAt };
|
|
185
|
+
}
|
|
186
|
+
function normalizeToolPolicyForUpdate(input, now = Date.now()) {
|
|
187
|
+
return normalizeToolPolicy(input, now) ?? { mode: "all", toolIds: [], updatedAt: now };
|
|
188
|
+
}
|
|
189
|
+
function isToolAllowed(policy, toolName, serverId) {
|
|
190
|
+
if (!policy || policy.mode === "all") return true;
|
|
191
|
+
if (!serverId) return false;
|
|
192
|
+
const toolId = createToolId(serverId, toolName);
|
|
193
|
+
if (policy.mode === "allowlist") {
|
|
194
|
+
return policy.toolIds.includes(toolId);
|
|
195
|
+
}
|
|
196
|
+
return !policy.toolIds.includes(toolId);
|
|
197
|
+
}
|
|
198
|
+
function assertToolAllowed(policy, toolName, serverId) {
|
|
199
|
+
if (isToolAllowed(policy, toolName, serverId)) return;
|
|
200
|
+
throw new Error(`Tool "${toolName}" is not allowed for this MCP session`);
|
|
201
|
+
}
|
|
202
|
+
function filterToolsByPolicy(tools, policy, serverId) {
|
|
203
|
+
if (!policy || policy.mode === "all") return tools;
|
|
204
|
+
return tools.filter((tool) => isToolAllowed(policy, tool.name, serverId));
|
|
205
|
+
}
|
|
206
|
+
function validateToolPolicyAgainstTools(policy, tools, serverId) {
|
|
207
|
+
if (policy.mode === "all") return;
|
|
208
|
+
if (!serverId) {
|
|
209
|
+
throw new Error("Cannot validate MCP tool policy without a serverId");
|
|
210
|
+
}
|
|
211
|
+
const availableIds = new Set(tools.map((tool) => createToolId(serverId, tool.name)));
|
|
212
|
+
const unknownIds = policy.toolIds.filter((id) => !availableIds.has(id));
|
|
213
|
+
if (unknownIds.length > 0) {
|
|
214
|
+
throw new Error(`Unknown tool id(s) for this MCP session: ${unknownIds.join(", ")}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
166
218
|
// src/server/storage/session-lifecycle.ts
|
|
167
219
|
function resolveSessionExpiresAt(status = "pending", referenceTime = Date.now()) {
|
|
168
220
|
return status === "active" ? null : referenceTime + STATE_EXPIRATION_MS;
|
|
@@ -179,7 +231,8 @@ function normalizeNewSession(session, now = Date.now()) {
|
|
|
179
231
|
status,
|
|
180
232
|
createdAt,
|
|
181
233
|
updatedAt,
|
|
182
|
-
expiresAt: resolveSessionExpiresAt(status, status === "active" ? updatedAt : createdAt)
|
|
234
|
+
expiresAt: resolveSessionExpiresAt(status, status === "active" ? updatedAt : createdAt),
|
|
235
|
+
toolPolicy: normalizeToolPolicy(session.toolPolicy, updatedAt)
|
|
183
236
|
};
|
|
184
237
|
}
|
|
185
238
|
function mergeSessionUpdate(current, data, now = Date.now()) {
|
|
@@ -193,7 +246,8 @@ function mergeSessionUpdate(current, data, now = Date.now()) {
|
|
|
193
246
|
return {
|
|
194
247
|
...updated,
|
|
195
248
|
status,
|
|
196
|
-
expiresAt: resolveSessionExpiresAt(status, updatedAt)
|
|
249
|
+
expiresAt: resolveSessionExpiresAt(status, updatedAt),
|
|
250
|
+
toolPolicy: normalizeToolPolicy(updated.toolPolicy, updatedAt)
|
|
197
251
|
};
|
|
198
252
|
}
|
|
199
253
|
function normalizeStoredSession(session) {
|
|
@@ -206,7 +260,8 @@ function normalizeStoredSession(session) {
|
|
|
206
260
|
status,
|
|
207
261
|
createdAt,
|
|
208
262
|
updatedAt,
|
|
209
|
-
expiresAt
|
|
263
|
+
expiresAt,
|
|
264
|
+
toolPolicy: normalizeToolPolicy(session.toolPolicy, updatedAt)
|
|
210
265
|
};
|
|
211
266
|
}
|
|
212
267
|
function isSessionExpired(session, now = Date.now()) {
|
|
@@ -1064,7 +1119,8 @@ var SupabaseStorageBackend = class {
|
|
|
1064
1119
|
userId: row.user_id,
|
|
1065
1120
|
headers: decryptObject(row.headers),
|
|
1066
1121
|
authUrl: row.auth_url,
|
|
1067
|
-
status: row.status ?? "pending"
|
|
1122
|
+
status: row.status ?? "pending",
|
|
1123
|
+
toolPolicy: normalizeToolPolicy(row.tool_policy)
|
|
1068
1124
|
};
|
|
1069
1125
|
}
|
|
1070
1126
|
mapRowToCredentials(row, userId, sessionId) {
|
|
@@ -1088,7 +1144,7 @@ var SupabaseStorageBackend = class {
|
|
|
1088
1144
|
const createdAt = new Date(session.createdAt || Date.now()).toISOString();
|
|
1089
1145
|
const updatedAt = new Date(session.updatedAt ?? session.createdAt ?? Date.now()).toISOString();
|
|
1090
1146
|
const expiresAt = resolveSessionExpiresAt(status, new Date(createdAt).getTime());
|
|
1091
|
-
const
|
|
1147
|
+
const insertData = {
|
|
1092
1148
|
session_id: sessionId,
|
|
1093
1149
|
user_id: userId,
|
|
1094
1150
|
server_id: session.serverId,
|
|
@@ -1102,7 +1158,12 @@ var SupabaseStorageBackend = class {
|
|
|
1102
1158
|
auth_url: session.authUrl ?? null,
|
|
1103
1159
|
status,
|
|
1104
1160
|
expires_at: expiresAt === null ? null : new Date(expiresAt).toISOString()
|
|
1105
|
-
}
|
|
1161
|
+
};
|
|
1162
|
+
const toolPolicy = normalizeToolPolicy(session.toolPolicy);
|
|
1163
|
+
if (toolPolicy) {
|
|
1164
|
+
insertData.tool_policy = toolPolicy;
|
|
1165
|
+
}
|
|
1166
|
+
const { error } = await this.supabase.from("mcp_sessions").insert(insertData);
|
|
1106
1167
|
if (error) {
|
|
1107
1168
|
if (error.code === "23505") {
|
|
1108
1169
|
throw new Error(`Session ${sessionId} already exists`);
|
|
@@ -1127,6 +1188,7 @@ var SupabaseStorageBackend = class {
|
|
|
1127
1188
|
}
|
|
1128
1189
|
if ("headers" in data) updateData.headers = encryptObject(data.headers);
|
|
1129
1190
|
if ("authUrl" in data) updateData.auth_url = data.authUrl ?? null;
|
|
1191
|
+
if ("toolPolicy" in data) updateData.tool_policy = normalizeToolPolicy(data.toolPolicy);
|
|
1130
1192
|
const shouldUpdateSession = Object.keys(updateData).some((key) => key !== "updated_at");
|
|
1131
1193
|
let updatedRows = null;
|
|
1132
1194
|
if (shouldUpdateSession) {
|
|
@@ -1299,7 +1361,8 @@ var NeonStorageBackend = class {
|
|
|
1299
1361
|
userId: row.user_id,
|
|
1300
1362
|
headers: decryptObject(row.headers),
|
|
1301
1363
|
authUrl: row.auth_url ?? void 0,
|
|
1302
|
-
status: row.status ?? "pending"
|
|
1364
|
+
status: row.status ?? "pending",
|
|
1365
|
+
toolPolicy: normalizeToolPolicy(row.tool_policy)
|
|
1303
1366
|
};
|
|
1304
1367
|
}
|
|
1305
1368
|
mapRowToCredentials(row, userId, sessionId) {
|
|
@@ -1322,42 +1385,48 @@ var NeonStorageBackend = class {
|
|
|
1322
1385
|
const status = session.status ?? "pending";
|
|
1323
1386
|
const createdAt = new Date(session.createdAt || Date.now()).toISOString();
|
|
1324
1387
|
const updatedAt = new Date(session.updatedAt ?? session.createdAt ?? Date.now()).toISOString();
|
|
1325
|
-
const
|
|
1388
|
+
const createdAtMs = new Date(createdAt).getTime();
|
|
1389
|
+
const expiresAt = resolveSessionExpiresAt(status, createdAtMs);
|
|
1390
|
+
const toolPolicy = normalizeToolPolicy(session.toolPolicy, createdAtMs);
|
|
1391
|
+
const columns = [
|
|
1392
|
+
"session_id",
|
|
1393
|
+
"user_id",
|
|
1394
|
+
"server_id",
|
|
1395
|
+
"server_name",
|
|
1396
|
+
"server_url",
|
|
1397
|
+
"transport_type",
|
|
1398
|
+
"callback_url",
|
|
1399
|
+
"created_at",
|
|
1400
|
+
"updated_at",
|
|
1401
|
+
"headers",
|
|
1402
|
+
"auth_url",
|
|
1403
|
+
"status",
|
|
1404
|
+
"expires_at"
|
|
1405
|
+
];
|
|
1406
|
+
const values = [
|
|
1407
|
+
sessionId,
|
|
1408
|
+
userId,
|
|
1409
|
+
session.serverId,
|
|
1410
|
+
session.serverName,
|
|
1411
|
+
session.serverUrl,
|
|
1412
|
+
session.transportType,
|
|
1413
|
+
session.callbackUrl,
|
|
1414
|
+
createdAt,
|
|
1415
|
+
updatedAt,
|
|
1416
|
+
encryptObject(session.headers),
|
|
1417
|
+
session.authUrl ?? null,
|
|
1418
|
+
status,
|
|
1419
|
+
expiresAt === null ? null : new Date(expiresAt).toISOString()
|
|
1420
|
+
];
|
|
1421
|
+
if (toolPolicy) {
|
|
1422
|
+
columns.push("tool_policy");
|
|
1423
|
+
values.push(toolPolicy);
|
|
1424
|
+
}
|
|
1425
|
+
const placeholders = values.map((_, i) => `$${i + 1}`);
|
|
1326
1426
|
try {
|
|
1327
1427
|
await this.sql.query(
|
|
1328
|
-
`INSERT INTO ${this.tableName} (
|
|
1329
|
-
|
|
1330
|
-
user_id,
|
|
1331
|
-
server_id,
|
|
1332
|
-
server_name,
|
|
1333
|
-
server_url,
|
|
1334
|
-
transport_type,
|
|
1335
|
-
callback_url,
|
|
1336
|
-
created_at,
|
|
1337
|
-
updated_at,
|
|
1338
|
-
headers,
|
|
1339
|
-
auth_url,
|
|
1340
|
-
status,
|
|
1341
|
-
expires_at
|
|
1342
|
-
) VALUES (
|
|
1343
|
-
$1, $2, $3, $4, $5, $6, $7, $8,
|
|
1344
|
-
$9, $10, $11, $12, $13
|
|
1345
|
-
)`,
|
|
1346
|
-
[
|
|
1347
|
-
sessionId,
|
|
1348
|
-
userId,
|
|
1349
|
-
session.serverId,
|
|
1350
|
-
session.serverName,
|
|
1351
|
-
session.serverUrl,
|
|
1352
|
-
session.transportType,
|
|
1353
|
-
session.callbackUrl,
|
|
1354
|
-
createdAt,
|
|
1355
|
-
updatedAt,
|
|
1356
|
-
encryptObject(session.headers),
|
|
1357
|
-
session.authUrl ?? null,
|
|
1358
|
-
status,
|
|
1359
|
-
expiresAt === null ? null : new Date(expiresAt).toISOString()
|
|
1360
|
-
]
|
|
1428
|
+
`INSERT INTO ${this.tableName} (${columns.join(", ")}) VALUES (${placeholders.join(", ")})`,
|
|
1429
|
+
values
|
|
1361
1430
|
);
|
|
1362
1431
|
} catch (error) {
|
|
1363
1432
|
if (error.code === "23505") {
|
|
@@ -1374,36 +1443,36 @@ var NeonStorageBackend = class {
|
|
|
1374
1443
|
const updatedSession = { ...currentSession, ...data };
|
|
1375
1444
|
const status = updatedSession.status ?? "pending";
|
|
1376
1445
|
const expiresAt = resolveSessionExpiresAt(status);
|
|
1377
|
-
const shouldUpdateSession = "serverId" in data || "serverName" in data || "serverUrl" in data || "transportType" in data || "callbackUrl" in data || "status" in data || "headers" in data || "authUrl" in data;
|
|
1446
|
+
const shouldUpdateSession = "serverId" in data || "serverName" in data || "serverUrl" in data || "transportType" in data || "callbackUrl" in data || "status" in data || "headers" in data || "authUrl" in data || "toolPolicy" in data;
|
|
1378
1447
|
if (shouldUpdateSession) {
|
|
1448
|
+
const setClauses = [];
|
|
1449
|
+
const values = [];
|
|
1450
|
+
let paramIndex = 1;
|
|
1451
|
+
const addSet = (column, value) => {
|
|
1452
|
+
setClauses.push(`${column} = $${paramIndex++}`);
|
|
1453
|
+
values.push(value);
|
|
1454
|
+
};
|
|
1455
|
+
addSet("server_id", updatedSession.serverId);
|
|
1456
|
+
addSet("server_name", updatedSession.serverName);
|
|
1457
|
+
addSet("server_url", updatedSession.serverUrl);
|
|
1458
|
+
addSet("transport_type", updatedSession.transportType);
|
|
1459
|
+
addSet("callback_url", updatedSession.callbackUrl);
|
|
1460
|
+
addSet("status", status);
|
|
1461
|
+
addSet("headers", encryptObject(updatedSession.headers));
|
|
1462
|
+
addSet("auth_url", updatedSession.authUrl ?? null);
|
|
1463
|
+
addSet("expires_at", expiresAt === null ? null : new Date(expiresAt).toISOString());
|
|
1464
|
+
if ("toolPolicy" in data) {
|
|
1465
|
+
const policyUpdatedAt = updatedSession.updatedAt ?? Date.now();
|
|
1466
|
+
const toolPolicy = normalizeToolPolicy(updatedSession.toolPolicy, policyUpdatedAt) ?? { mode: "all", toolIds: [], updatedAt: policyUpdatedAt };
|
|
1467
|
+
addSet("tool_policy", toolPolicy);
|
|
1468
|
+
}
|
|
1469
|
+
setClauses.push("updated_at = now()");
|
|
1379
1470
|
const updatedRows = await this.sql.query(
|
|
1380
1471
|
`UPDATE ${this.tableName}
|
|
1381
|
-
SET
|
|
1382
|
-
|
|
1383
|
-
server_name = $2,
|
|
1384
|
-
server_url = $3,
|
|
1385
|
-
transport_type = $4,
|
|
1386
|
-
callback_url = $5,
|
|
1387
|
-
status = $6,
|
|
1388
|
-
headers = $7,
|
|
1389
|
-
auth_url = $8,
|
|
1390
|
-
expires_at = $9,
|
|
1391
|
-
updated_at = now()
|
|
1392
|
-
WHERE user_id = $10 AND session_id = $11
|
|
1472
|
+
SET ${setClauses.join(", ")}
|
|
1473
|
+
WHERE user_id = $${paramIndex++} AND session_id = $${paramIndex++}
|
|
1393
1474
|
RETURNING id`,
|
|
1394
|
-
[
|
|
1395
|
-
updatedSession.serverId,
|
|
1396
|
-
updatedSession.serverName,
|
|
1397
|
-
updatedSession.serverUrl,
|
|
1398
|
-
updatedSession.transportType,
|
|
1399
|
-
updatedSession.callbackUrl,
|
|
1400
|
-
status,
|
|
1401
|
-
encryptObject(updatedSession.headers),
|
|
1402
|
-
updatedSession.authUrl ?? null,
|
|
1403
|
-
expiresAt === null ? null : new Date(expiresAt).toISOString(),
|
|
1404
|
-
userId,
|
|
1405
|
-
sessionId
|
|
1406
|
-
]
|
|
1475
|
+
[...values, userId, sessionId]
|
|
1407
1476
|
);
|
|
1408
1477
|
if (updatedRows.length === 0) {
|
|
1409
1478
|
throw new Error(`Session ${sessionId} not found for userId ${userId}`);
|
|
@@ -2386,7 +2455,15 @@ var MCPClient = class {
|
|
|
2386
2455
|
if (!existingSession && this.serverId && this.serverUrl && this.callbackUrl) {
|
|
2387
2456
|
this.createdAt = Date.now();
|
|
2388
2457
|
const updatedAt = this.createdAt;
|
|
2389
|
-
|
|
2458
|
+
this._onObservabilityEvent.fire({
|
|
2459
|
+
type: "mcp:client:session_created",
|
|
2460
|
+
level: "info",
|
|
2461
|
+
message: `Creating pending session ${this.sessionId} for connection setup`,
|
|
2462
|
+
sessionId: this.sessionId,
|
|
2463
|
+
serverId: this.serverId,
|
|
2464
|
+
timestamp: Date.now(),
|
|
2465
|
+
id: nanoid()
|
|
2466
|
+
});
|
|
2390
2467
|
await sessions.create({
|
|
2391
2468
|
sessionId: this.sessionId,
|
|
2392
2469
|
userId: this.userId,
|
|
@@ -2516,7 +2593,15 @@ var MCPClient = class {
|
|
|
2516
2593
|
this.transportType = transportType;
|
|
2517
2594
|
this.emitStateChange("CONNECTED");
|
|
2518
2595
|
this.emitProgress("Connected successfully");
|
|
2519
|
-
|
|
2596
|
+
this._onObservabilityEvent.fire({
|
|
2597
|
+
type: "mcp:client:session_saved",
|
|
2598
|
+
level: "info",
|
|
2599
|
+
message: `Saving active session ${this.sessionId} (connect success)`,
|
|
2600
|
+
sessionId: this.sessionId,
|
|
2601
|
+
serverId: this.serverId,
|
|
2602
|
+
timestamp: Date.now(),
|
|
2603
|
+
id: nanoid()
|
|
2604
|
+
});
|
|
2520
2605
|
await this.saveSession("active");
|
|
2521
2606
|
} catch (error) {
|
|
2522
2607
|
if (error instanceof UnauthorizedError$1 || error instanceof Error && error.message.toLowerCase().includes("unauthorized")) {
|
|
@@ -2533,7 +2618,15 @@ var MCPClient = class {
|
|
|
2533
2618
|
throw new Error(message);
|
|
2534
2619
|
}
|
|
2535
2620
|
this.emitStateChange("AUTHENTICATING");
|
|
2536
|
-
|
|
2621
|
+
this._onObservabilityEvent.fire({
|
|
2622
|
+
type: "mcp:client:session_saved",
|
|
2623
|
+
level: "info",
|
|
2624
|
+
message: `Saving pending OAuth session ${this.sessionId}`,
|
|
2625
|
+
sessionId: this.sessionId,
|
|
2626
|
+
serverId: this.serverId,
|
|
2627
|
+
timestamp: Date.now(),
|
|
2628
|
+
id: nanoid()
|
|
2629
|
+
});
|
|
2537
2630
|
await this.saveSession("pending");
|
|
2538
2631
|
if (this.serverId) {
|
|
2539
2632
|
this._onConnectionEvent.fire({
|
|
@@ -2608,27 +2701,25 @@ var MCPClient = class {
|
|
|
2608
2701
|
this.emitStateChange("AUTHENTICATED");
|
|
2609
2702
|
authenticatedStateEmitted = true;
|
|
2610
2703
|
}
|
|
2611
|
-
this.emitProgress("Creating authenticated client...");
|
|
2612
|
-
this.client = new Client(
|
|
2613
|
-
{
|
|
2614
|
-
name: MCP_CLIENT_NAME,
|
|
2615
|
-
version: MCP_CLIENT_VERSION
|
|
2616
|
-
},
|
|
2617
|
-
{
|
|
2618
|
-
capabilities: {
|
|
2619
|
-
extensions: {
|
|
2620
|
-
"io.modelcontextprotocol/ui": {
|
|
2621
|
-
mimeTypes: ["text/html+mcp"]
|
|
2622
|
-
}
|
|
2623
|
-
}
|
|
2624
|
-
}
|
|
2625
|
-
}
|
|
2626
|
-
);
|
|
2627
2704
|
this.emitStateChange("CONNECTING");
|
|
2705
|
+
if (this.client.transport) {
|
|
2706
|
+
try {
|
|
2707
|
+
await this.client.close();
|
|
2708
|
+
} catch {
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2628
2711
|
await this.client.connect(this.transport);
|
|
2629
2712
|
this.transportType = currentType;
|
|
2630
2713
|
this.emitStateChange("CONNECTED");
|
|
2631
|
-
|
|
2714
|
+
this._onObservabilityEvent.fire({
|
|
2715
|
+
type: "mcp:client:session_saved",
|
|
2716
|
+
level: "info",
|
|
2717
|
+
message: `Saving active session ${this.sessionId} (OAuth complete)`,
|
|
2718
|
+
sessionId: this.sessionId,
|
|
2719
|
+
serverId: this.serverId,
|
|
2720
|
+
timestamp: Date.now(),
|
|
2721
|
+
id: nanoid()
|
|
2722
|
+
});
|
|
2632
2723
|
await this.saveSession("active");
|
|
2633
2724
|
return;
|
|
2634
2725
|
} catch (error) {
|
|
@@ -2663,24 +2754,28 @@ var MCPClient = class {
|
|
|
2663
2754
|
throw lastError;
|
|
2664
2755
|
}
|
|
2665
2756
|
}
|
|
2757
|
+
/**
|
|
2758
|
+
* Lists all available tools from the connected MCP server without emitting discovery events.
|
|
2759
|
+
* Gateways use this to apply policy before publishing tools to agents or UI state.
|
|
2760
|
+
*/
|
|
2761
|
+
async fetchTools() {
|
|
2762
|
+
const request = {
|
|
2763
|
+
method: "tools/list",
|
|
2764
|
+
params: {}
|
|
2765
|
+
};
|
|
2766
|
+
return await this.withRetry(
|
|
2767
|
+
() => this.client.request(request, ListToolsResultSchema)
|
|
2768
|
+
);
|
|
2769
|
+
}
|
|
2666
2770
|
/**
|
|
2667
2771
|
* Lists all available tools from the connected MCP server
|
|
2668
2772
|
* @returns List of tools with their schemas and descriptions
|
|
2669
2773
|
* @throws {Error} When client is not connected
|
|
2670
2774
|
*/
|
|
2671
2775
|
async listTools() {
|
|
2672
|
-
if (!this.client) {
|
|
2673
|
-
throw new Error("Not connected to server");
|
|
2674
|
-
}
|
|
2675
2776
|
this.emitStateChange("DISCOVERING");
|
|
2676
2777
|
try {
|
|
2677
|
-
const
|
|
2678
|
-
method: "tools/list",
|
|
2679
|
-
params: {}
|
|
2680
|
-
};
|
|
2681
|
-
const result = await this.withRetry(
|
|
2682
|
-
() => this.client.request(request, ListToolsResultSchema)
|
|
2683
|
-
);
|
|
2778
|
+
const result = await this.fetchTools();
|
|
2684
2779
|
if (this.serverId) {
|
|
2685
2780
|
this._onConnectionEvent.fire({
|
|
2686
2781
|
type: "tools_discovered",
|
|
@@ -2709,9 +2804,6 @@ var MCPClient = class {
|
|
|
2709
2804
|
* @throws {Error} When client is not connected
|
|
2710
2805
|
*/
|
|
2711
2806
|
async callTool(toolName, toolArgs) {
|
|
2712
|
-
if (!this.client) {
|
|
2713
|
-
throw new Error("Not connected to server");
|
|
2714
|
-
}
|
|
2715
2807
|
const request = {
|
|
2716
2808
|
method: "tools/call",
|
|
2717
2809
|
params: {
|
|
@@ -2765,9 +2857,6 @@ var MCPClient = class {
|
|
|
2765
2857
|
* @throws {Error} When client is not connected
|
|
2766
2858
|
*/
|
|
2767
2859
|
async listPrompts() {
|
|
2768
|
-
if (!this.client) {
|
|
2769
|
-
throw new Error("Not connected to server");
|
|
2770
|
-
}
|
|
2771
2860
|
this.emitStateChange("DISCOVERING");
|
|
2772
2861
|
try {
|
|
2773
2862
|
const request = {
|
|
@@ -2795,9 +2884,6 @@ var MCPClient = class {
|
|
|
2795
2884
|
* @throws {Error} When client is not connected
|
|
2796
2885
|
*/
|
|
2797
2886
|
async getPrompt(name, args) {
|
|
2798
|
-
if (!this.client) {
|
|
2799
|
-
throw new Error("Not connected to server");
|
|
2800
|
-
}
|
|
2801
2887
|
const request = {
|
|
2802
2888
|
method: "prompts/get",
|
|
2803
2889
|
params: {
|
|
@@ -2815,9 +2901,6 @@ var MCPClient = class {
|
|
|
2815
2901
|
* @throws {Error} When client is not connected
|
|
2816
2902
|
*/
|
|
2817
2903
|
async listResources() {
|
|
2818
|
-
if (!this.client) {
|
|
2819
|
-
throw new Error("Not connected to server");
|
|
2820
|
-
}
|
|
2821
2904
|
this.emitStateChange("DISCOVERING");
|
|
2822
2905
|
try {
|
|
2823
2906
|
const request = {
|
|
@@ -2844,9 +2927,6 @@ var MCPClient = class {
|
|
|
2844
2927
|
* @throws {Error} When client is not connected
|
|
2845
2928
|
*/
|
|
2846
2929
|
async readResource(uri) {
|
|
2847
|
-
if (!this.client) {
|
|
2848
|
-
throw new Error("Not connected to server");
|
|
2849
|
-
}
|
|
2850
2930
|
const request = {
|
|
2851
2931
|
method: "resources/read",
|
|
2852
2932
|
params: {
|
|
@@ -2902,7 +2982,16 @@ var MCPClient = class {
|
|
|
2902
2982
|
try {
|
|
2903
2983
|
await this.ensureSession();
|
|
2904
2984
|
} catch (error) {
|
|
2905
|
-
|
|
2985
|
+
this._onObservabilityEvent.fire({
|
|
2986
|
+
type: "mcp:client:error",
|
|
2987
|
+
level: "warn",
|
|
2988
|
+
message: "Initialization failed during clearSession",
|
|
2989
|
+
sessionId: this.sessionId,
|
|
2990
|
+
serverId: this.serverId,
|
|
2991
|
+
payload: { error: String(error) },
|
|
2992
|
+
timestamp: Date.now(),
|
|
2993
|
+
id: nanoid()
|
|
2994
|
+
});
|
|
2906
2995
|
}
|
|
2907
2996
|
if (this.oauthProvider) {
|
|
2908
2997
|
await this.oauthProvider.invalidateCredentials("all");
|
|
@@ -3013,6 +3102,66 @@ var MCPClient = class {
|
|
|
3013
3102
|
}
|
|
3014
3103
|
};
|
|
3015
3104
|
|
|
3105
|
+
// src/server/mcp/tool-policy-gateway.ts
|
|
3106
|
+
var ToolPolicyGateway = class {
|
|
3107
|
+
constructor(userId, sessionId, client) {
|
|
3108
|
+
this.userId = userId;
|
|
3109
|
+
this.sessionId = sessionId;
|
|
3110
|
+
this.client = client;
|
|
3111
|
+
}
|
|
3112
|
+
isConnected() {
|
|
3113
|
+
return this.client.isConnected();
|
|
3114
|
+
}
|
|
3115
|
+
getServerId() {
|
|
3116
|
+
return this.client.getServerId?.();
|
|
3117
|
+
}
|
|
3118
|
+
getServerName() {
|
|
3119
|
+
return this.client.getServerName?.();
|
|
3120
|
+
}
|
|
3121
|
+
getServerUrl() {
|
|
3122
|
+
return this.client.getServerUrl?.();
|
|
3123
|
+
}
|
|
3124
|
+
getSessionId() {
|
|
3125
|
+
return this.client.getSessionId?.() ?? this.sessionId;
|
|
3126
|
+
}
|
|
3127
|
+
async listTools() {
|
|
3128
|
+
const session = await this.getSession();
|
|
3129
|
+
const result = await this.client.fetchTools();
|
|
3130
|
+
const tools = this.filterTools(session, result.tools);
|
|
3131
|
+
return {
|
|
3132
|
+
...result,
|
|
3133
|
+
tools
|
|
3134
|
+
};
|
|
3135
|
+
}
|
|
3136
|
+
async listAllTools() {
|
|
3137
|
+
return await this.client.fetchTools();
|
|
3138
|
+
}
|
|
3139
|
+
async callTool(name, args) {
|
|
3140
|
+
const session = await this.getSession();
|
|
3141
|
+
this.assertAllowed(session, name);
|
|
3142
|
+
return await this.client.callTool(name, args);
|
|
3143
|
+
}
|
|
3144
|
+
filterTools(session, tools) {
|
|
3145
|
+
return filterToolsByPolicy(tools, session.toolPolicy, this.getPolicyServerId(session));
|
|
3146
|
+
}
|
|
3147
|
+
assertAllowed(session, toolName) {
|
|
3148
|
+
assertToolAllowed(session.toolPolicy, toolName, this.getPolicyServerId(session));
|
|
3149
|
+
}
|
|
3150
|
+
async getSession() {
|
|
3151
|
+
const session = await sessions.get(this.userId, this.sessionId);
|
|
3152
|
+
if (!session) {
|
|
3153
|
+
throw new Error("Session not found");
|
|
3154
|
+
}
|
|
3155
|
+
return session;
|
|
3156
|
+
}
|
|
3157
|
+
getPolicyServerId(session) {
|
|
3158
|
+
return this.client.getServerId?.() ?? session.serverId;
|
|
3159
|
+
}
|
|
3160
|
+
};
|
|
3161
|
+
function createToolPolicyGateway(userId, sessionId, client) {
|
|
3162
|
+
return new ToolPolicyGateway(userId, sessionId, client);
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3016
3165
|
// src/server/mcp/multi-session-client.ts
|
|
3017
3166
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
3018
3167
|
var DEFAULT_MAX_RETRIES = 2;
|
|
@@ -3078,7 +3227,9 @@ var MultiSessionClient = class {
|
|
|
3078
3227
|
* or to route a tool call to the right client by `serverId`.
|
|
3079
3228
|
*/
|
|
3080
3229
|
getClients() {
|
|
3081
|
-
return this.clients
|
|
3230
|
+
return this.clients.map(
|
|
3231
|
+
(client) => createToolPolicyGateway(this.userId, client.getSessionId(), client)
|
|
3232
|
+
);
|
|
3082
3233
|
}
|
|
3083
3234
|
/**
|
|
3084
3235
|
* Removes and disconnects a single session by ID.
|
|
@@ -3313,6 +3464,12 @@ var SSEConnectionManager = class {
|
|
|
3313
3464
|
case "listTools":
|
|
3314
3465
|
result = await this.listTools(request.params);
|
|
3315
3466
|
break;
|
|
3467
|
+
case "setToolPolicy":
|
|
3468
|
+
result = await this.setToolPolicy(request.params);
|
|
3469
|
+
break;
|
|
3470
|
+
case "getToolPolicy":
|
|
3471
|
+
result = await this.getToolPolicy(request.params);
|
|
3472
|
+
break;
|
|
3316
3473
|
case "callTool":
|
|
3317
3474
|
result = await this.callTool(request.params);
|
|
3318
3475
|
break;
|
|
@@ -3369,7 +3526,8 @@ var SSEConnectionManager = class {
|
|
|
3369
3526
|
transport: s.transportType,
|
|
3370
3527
|
createdAt: s.createdAt,
|
|
3371
3528
|
updatedAt: s.updatedAt ?? s.createdAt,
|
|
3372
|
-
status: s.status ?? "pending"
|
|
3529
|
+
status: s.status ?? "pending",
|
|
3530
|
+
toolPolicy: s.toolPolicy
|
|
3373
3531
|
}))
|
|
3374
3532
|
};
|
|
3375
3533
|
}
|
|
@@ -3379,7 +3537,7 @@ var SSEConnectionManager = class {
|
|
|
3379
3537
|
async connect(params) {
|
|
3380
3538
|
const { serverName, serverUrl, callbackUrl, transportType } = params;
|
|
3381
3539
|
const headers = normalizeHeaders(params.headers);
|
|
3382
|
-
const serverId = params.serverId && params.serverId.length <= 12 ? params.serverId :
|
|
3540
|
+
const serverId = params.serverId && params.serverId.length <= 12 ? params.serverId : generateServerId();
|
|
3383
3541
|
const existingSessions = await sessions.list(this.userId);
|
|
3384
3542
|
const duplicate = existingSessions.find(
|
|
3385
3543
|
(s) => s.serverId === serverId || s.serverUrl === serverUrl
|
|
@@ -3417,7 +3575,7 @@ var SSEConnectionManager = class {
|
|
|
3417
3575
|
this.sendEvent(event);
|
|
3418
3576
|
});
|
|
3419
3577
|
await client.connect();
|
|
3420
|
-
await
|
|
3578
|
+
await this.listPolicyFilteredTools(sessionId);
|
|
3421
3579
|
return {
|
|
3422
3580
|
sessionId,
|
|
3423
3581
|
success: true
|
|
@@ -3488,22 +3646,98 @@ var SSEConnectionManager = class {
|
|
|
3488
3646
|
this.clients.set(sessionId, client);
|
|
3489
3647
|
return client;
|
|
3490
3648
|
}
|
|
3649
|
+
async listPolicyFilteredTools(sessionId) {
|
|
3650
|
+
const session = await sessions.get(this.userId, sessionId);
|
|
3651
|
+
if (!session) {
|
|
3652
|
+
throw new Error("Session not found");
|
|
3653
|
+
}
|
|
3654
|
+
const client = await this.getOrCreateClient(sessionId);
|
|
3655
|
+
const gateway = createToolPolicyGateway(this.userId, sessionId, client);
|
|
3656
|
+
const result = await gateway.listTools();
|
|
3657
|
+
this.emitConnectionEvent({
|
|
3658
|
+
type: "tools_discovered",
|
|
3659
|
+
sessionId,
|
|
3660
|
+
serverId: session.serverId ?? "unknown",
|
|
3661
|
+
toolCount: result.tools.length,
|
|
3662
|
+
tools: result.tools,
|
|
3663
|
+
timestamp: Date.now()
|
|
3664
|
+
});
|
|
3665
|
+
return { session, result };
|
|
3666
|
+
}
|
|
3491
3667
|
/**
|
|
3492
3668
|
* List tools from a session
|
|
3493
3669
|
*/
|
|
3494
3670
|
async listTools(params) {
|
|
3495
3671
|
const { sessionId } = params;
|
|
3496
|
-
const
|
|
3497
|
-
const result = await client.listTools();
|
|
3672
|
+
const { result } = await this.listPolicyFilteredTools(sessionId);
|
|
3498
3673
|
return { tools: result.tools };
|
|
3499
3674
|
}
|
|
3675
|
+
/**
|
|
3676
|
+
* Get all raw tools with effective access state for management UI.
|
|
3677
|
+
*/
|
|
3678
|
+
async getToolPolicy(params) {
|
|
3679
|
+
const { sessionId } = params;
|
|
3680
|
+
const session = await sessions.get(this.userId, sessionId);
|
|
3681
|
+
if (!session) {
|
|
3682
|
+
throw new Error("Session not found");
|
|
3683
|
+
}
|
|
3684
|
+
const client = await this.getOrCreateClient(sessionId);
|
|
3685
|
+
const allTools = await client.fetchTools();
|
|
3686
|
+
const toolPolicy = session.toolPolicy ?? {
|
|
3687
|
+
mode: "all",
|
|
3688
|
+
toolIds: [],
|
|
3689
|
+
updatedAt: session.updatedAt ?? session.createdAt
|
|
3690
|
+
};
|
|
3691
|
+
const serverId = session.serverId ?? "unknown";
|
|
3692
|
+
const tools = allTools.tools.map((tool) => ({
|
|
3693
|
+
...tool,
|
|
3694
|
+
toolId: createToolId(serverId, tool.name),
|
|
3695
|
+
allowed: isToolAllowed(toolPolicy, tool.name, session.serverId)
|
|
3696
|
+
}));
|
|
3697
|
+
return {
|
|
3698
|
+
toolPolicy,
|
|
3699
|
+
tools,
|
|
3700
|
+
toolCount: tools.length,
|
|
3701
|
+
allowedToolCount: tools.filter((tool) => tool.allowed).length
|
|
3702
|
+
};
|
|
3703
|
+
}
|
|
3704
|
+
/**
|
|
3705
|
+
* Update per-session tool access policy.
|
|
3706
|
+
*/
|
|
3707
|
+
async setToolPolicy(params) {
|
|
3708
|
+
const { sessionId } = params;
|
|
3709
|
+
const session = await sessions.get(this.userId, sessionId);
|
|
3710
|
+
if (!session) {
|
|
3711
|
+
throw new Error("Session not found");
|
|
3712
|
+
}
|
|
3713
|
+
const client = await this.getOrCreateClient(sessionId);
|
|
3714
|
+
const allTools = await client.fetchTools();
|
|
3715
|
+
const toolPolicy = normalizeToolPolicyForUpdate(params.toolPolicy);
|
|
3716
|
+
validateToolPolicyAgainstTools(toolPolicy, allTools.tools, session.serverId);
|
|
3717
|
+
await sessions.update(this.userId, sessionId, { toolPolicy });
|
|
3718
|
+
const filteredTools = createToolPolicyGateway(this.userId, sessionId, client).filterTools({ ...session, toolPolicy }, allTools.tools);
|
|
3719
|
+
this.emitConnectionEvent({
|
|
3720
|
+
type: "tools_discovered",
|
|
3721
|
+
sessionId,
|
|
3722
|
+
serverId: session.serverId ?? "unknown",
|
|
3723
|
+
toolCount: filteredTools.length,
|
|
3724
|
+
tools: filteredTools,
|
|
3725
|
+
timestamp: Date.now()
|
|
3726
|
+
});
|
|
3727
|
+
return {
|
|
3728
|
+
success: true,
|
|
3729
|
+
toolPolicy,
|
|
3730
|
+
tools: filteredTools,
|
|
3731
|
+
toolCount: filteredTools.length
|
|
3732
|
+
};
|
|
3733
|
+
}
|
|
3500
3734
|
/**
|
|
3501
3735
|
* Call a tool on the MCP server
|
|
3502
3736
|
*/
|
|
3503
3737
|
async callTool(params) {
|
|
3504
3738
|
const { sessionId, toolName, toolArgs } = params;
|
|
3505
3739
|
const client = await this.getOrCreateClient(sessionId);
|
|
3506
|
-
const result = await client.callTool(toolName, toolArgs);
|
|
3740
|
+
const result = await createToolPolicyGateway(this.userId, sessionId, client).callTool(toolName, toolArgs);
|
|
3507
3741
|
const meta = result._meta || {};
|
|
3508
3742
|
return {
|
|
3509
3743
|
...result,
|
|
@@ -3553,7 +3787,7 @@ var SSEConnectionManager = class {
|
|
|
3553
3787
|
client.onObservabilityEvent((event) => this.sendEvent(event));
|
|
3554
3788
|
await client.connect();
|
|
3555
3789
|
this.clients.set(sessionId, client);
|
|
3556
|
-
const tools = await
|
|
3790
|
+
const { result: tools } = await this.listPolicyFilteredTools(sessionId);
|
|
3557
3791
|
return { success: true, toolCount: tools.tools.length };
|
|
3558
3792
|
} catch (error) {
|
|
3559
3793
|
this.emitConnectionEvent({
|
|
@@ -3601,7 +3835,7 @@ var SSEConnectionManager = class {
|
|
|
3601
3835
|
client.onConnectionEvent((event) => this.emitConnectionEvent(event));
|
|
3602
3836
|
await client.finishAuth(code, oauthState);
|
|
3603
3837
|
this.clients.set(sessionId, client);
|
|
3604
|
-
const tools = await
|
|
3838
|
+
const { result: tools } = await this.listPolicyFilteredTools(sessionId);
|
|
3605
3839
|
return { success: true, toolCount: tools.tools.length };
|
|
3606
3840
|
} catch (error) {
|
|
3607
3841
|
this.emitConnectionEvent({
|
|
@@ -3893,6 +4127,12 @@ var SSEClient = class {
|
|
|
3893
4127
|
async disconnectFromServer(sessionId) {
|
|
3894
4128
|
return this.sendRequest("disconnect", { sessionId });
|
|
3895
4129
|
}
|
|
4130
|
+
async setToolPolicy(sessionId, toolPolicy) {
|
|
4131
|
+
return this.sendRequest("setToolPolicy", { sessionId, toolPolicy });
|
|
4132
|
+
}
|
|
4133
|
+
async getToolPolicy(sessionId) {
|
|
4134
|
+
return this.sendRequest("getToolPolicy", { sessionId });
|
|
4135
|
+
}
|
|
3896
4136
|
async listTools(sessionId) {
|
|
3897
4137
|
return this.sendRequest("listTools", { sessionId });
|
|
3898
4138
|
}
|