@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.js
CHANGED
|
@@ -163,13 +163,9 @@ init_cjs_shims();
|
|
|
163
163
|
// src/shared/utils.ts
|
|
164
164
|
init_cjs_shims();
|
|
165
165
|
var OAUTH_STATE_SEPARATOR = ".";
|
|
166
|
-
var
|
|
167
|
-
"
|
|
168
|
-
|
|
169
|
-
);
|
|
170
|
-
var rest = nanoid.customAlphabet(
|
|
171
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
|
172
|
-
11
|
|
166
|
+
var serverIdAlphabet = nanoid.customAlphabet(
|
|
167
|
+
"abcdefghijklmnopqrstuvwxyz0123456789",
|
|
168
|
+
12
|
|
173
169
|
);
|
|
174
170
|
function sanitizeServerLabel(name) {
|
|
175
171
|
let sanitized = name.replace(/[^a-zA-Z0-9-_]/g, "_").replace(/_{2,}/g, "_").toLowerCase();
|
|
@@ -179,7 +175,10 @@ function sanitizeServerLabel(name) {
|
|
|
179
175
|
return sanitized;
|
|
180
176
|
}
|
|
181
177
|
function generateSessionId() {
|
|
182
|
-
return
|
|
178
|
+
return "sess_" + nanoid.nanoid(21);
|
|
179
|
+
}
|
|
180
|
+
function generateServerId() {
|
|
181
|
+
return serverIdAlphabet();
|
|
183
182
|
}
|
|
184
183
|
function formatOAuthState(nonce, sessionId) {
|
|
185
184
|
return `${nonce}${OAUTH_STATE_SEPARATOR}${sessionId}`;
|
|
@@ -217,6 +216,60 @@ var SOFTWARE_VERSION = "2.3.4";
|
|
|
217
216
|
var MCP_CLIENT_NAME = "mcp-ts-oauth-client";
|
|
218
217
|
var MCP_CLIENT_VERSION = "2.0";
|
|
219
218
|
|
|
219
|
+
// src/server/storage/tool-policy.ts
|
|
220
|
+
init_cjs_shims();
|
|
221
|
+
function createToolId(serverId, toolName) {
|
|
222
|
+
return `${serverId}::${toolName}`;
|
|
223
|
+
}
|
|
224
|
+
function normalizeToolIds(input) {
|
|
225
|
+
if (!Array.isArray(input)) return [];
|
|
226
|
+
return Array.from(new Set(
|
|
227
|
+
input.filter((id) => typeof id === "string").map((id) => id.trim()).filter(Boolean)
|
|
228
|
+
));
|
|
229
|
+
}
|
|
230
|
+
function normalizeToolPolicy(input, now = Date.now()) {
|
|
231
|
+
if (!input || typeof input !== "object") {
|
|
232
|
+
return void 0;
|
|
233
|
+
}
|
|
234
|
+
const mode = input.mode === "allowlist" || input.mode === "denylist" ? input.mode : "all";
|
|
235
|
+
const updatedAt = typeof input.updatedAt === "number" && Number.isFinite(input.updatedAt) ? input.updatedAt : now;
|
|
236
|
+
if (mode === "all") {
|
|
237
|
+
return { mode: "all", toolIds: [], updatedAt };
|
|
238
|
+
}
|
|
239
|
+
return { mode, toolIds: normalizeToolIds(input.toolIds), updatedAt };
|
|
240
|
+
}
|
|
241
|
+
function normalizeToolPolicyForUpdate(input, now = Date.now()) {
|
|
242
|
+
return normalizeToolPolicy(input, now) ?? { mode: "all", toolIds: [], updatedAt: now };
|
|
243
|
+
}
|
|
244
|
+
function isToolAllowed(policy, toolName, serverId) {
|
|
245
|
+
if (!policy || policy.mode === "all") return true;
|
|
246
|
+
if (!serverId) return false;
|
|
247
|
+
const toolId = createToolId(serverId, toolName);
|
|
248
|
+
if (policy.mode === "allowlist") {
|
|
249
|
+
return policy.toolIds.includes(toolId);
|
|
250
|
+
}
|
|
251
|
+
return !policy.toolIds.includes(toolId);
|
|
252
|
+
}
|
|
253
|
+
function assertToolAllowed(policy, toolName, serverId) {
|
|
254
|
+
if (isToolAllowed(policy, toolName, serverId)) return;
|
|
255
|
+
throw new Error(`Tool "${toolName}" is not allowed for this MCP session`);
|
|
256
|
+
}
|
|
257
|
+
function filterToolsByPolicy(tools, policy, serverId) {
|
|
258
|
+
if (!policy || policy.mode === "all") return tools;
|
|
259
|
+
return tools.filter((tool) => isToolAllowed(policy, tool.name, serverId));
|
|
260
|
+
}
|
|
261
|
+
function validateToolPolicyAgainstTools(policy, tools, serverId) {
|
|
262
|
+
if (policy.mode === "all") return;
|
|
263
|
+
if (!serverId) {
|
|
264
|
+
throw new Error("Cannot validate MCP tool policy without a serverId");
|
|
265
|
+
}
|
|
266
|
+
const availableIds = new Set(tools.map((tool) => createToolId(serverId, tool.name)));
|
|
267
|
+
const unknownIds = policy.toolIds.filter((id) => !availableIds.has(id));
|
|
268
|
+
if (unknownIds.length > 0) {
|
|
269
|
+
throw new Error(`Unknown tool id(s) for this MCP session: ${unknownIds.join(", ")}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
220
273
|
// src/server/storage/session-lifecycle.ts
|
|
221
274
|
function resolveSessionExpiresAt(status = "pending", referenceTime = Date.now()) {
|
|
222
275
|
return status === "active" ? null : referenceTime + STATE_EXPIRATION_MS;
|
|
@@ -233,7 +286,8 @@ function normalizeNewSession(session, now = Date.now()) {
|
|
|
233
286
|
status,
|
|
234
287
|
createdAt,
|
|
235
288
|
updatedAt,
|
|
236
|
-
expiresAt: resolveSessionExpiresAt(status, status === "active" ? updatedAt : createdAt)
|
|
289
|
+
expiresAt: resolveSessionExpiresAt(status, status === "active" ? updatedAt : createdAt),
|
|
290
|
+
toolPolicy: normalizeToolPolicy(session.toolPolicy, updatedAt)
|
|
237
291
|
};
|
|
238
292
|
}
|
|
239
293
|
function mergeSessionUpdate(current, data, now = Date.now()) {
|
|
@@ -247,7 +301,8 @@ function mergeSessionUpdate(current, data, now = Date.now()) {
|
|
|
247
301
|
return {
|
|
248
302
|
...updated,
|
|
249
303
|
status,
|
|
250
|
-
expiresAt: resolveSessionExpiresAt(status, updatedAt)
|
|
304
|
+
expiresAt: resolveSessionExpiresAt(status, updatedAt),
|
|
305
|
+
toolPolicy: normalizeToolPolicy(updated.toolPolicy, updatedAt)
|
|
251
306
|
};
|
|
252
307
|
}
|
|
253
308
|
function normalizeStoredSession(session) {
|
|
@@ -260,7 +315,8 @@ function normalizeStoredSession(session) {
|
|
|
260
315
|
status,
|
|
261
316
|
createdAt,
|
|
262
317
|
updatedAt,
|
|
263
|
-
expiresAt
|
|
318
|
+
expiresAt,
|
|
319
|
+
toolPolicy: normalizeToolPolicy(session.toolPolicy, updatedAt)
|
|
264
320
|
};
|
|
265
321
|
}
|
|
266
322
|
function isSessionExpired(session, now = Date.now()) {
|
|
@@ -1131,7 +1187,8 @@ var SupabaseStorageBackend = class {
|
|
|
1131
1187
|
userId: row.user_id,
|
|
1132
1188
|
headers: decryptObject(row.headers),
|
|
1133
1189
|
authUrl: row.auth_url,
|
|
1134
|
-
status: row.status ?? "pending"
|
|
1190
|
+
status: row.status ?? "pending",
|
|
1191
|
+
toolPolicy: normalizeToolPolicy(row.tool_policy)
|
|
1135
1192
|
};
|
|
1136
1193
|
}
|
|
1137
1194
|
mapRowToCredentials(row, userId, sessionId) {
|
|
@@ -1155,7 +1212,7 @@ var SupabaseStorageBackend = class {
|
|
|
1155
1212
|
const createdAt = new Date(session.createdAt || Date.now()).toISOString();
|
|
1156
1213
|
const updatedAt = new Date(session.updatedAt ?? session.createdAt ?? Date.now()).toISOString();
|
|
1157
1214
|
const expiresAt = resolveSessionExpiresAt(status, new Date(createdAt).getTime());
|
|
1158
|
-
const
|
|
1215
|
+
const insertData = {
|
|
1159
1216
|
session_id: sessionId,
|
|
1160
1217
|
user_id: userId,
|
|
1161
1218
|
server_id: session.serverId,
|
|
@@ -1169,7 +1226,12 @@ var SupabaseStorageBackend = class {
|
|
|
1169
1226
|
auth_url: session.authUrl ?? null,
|
|
1170
1227
|
status,
|
|
1171
1228
|
expires_at: expiresAt === null ? null : new Date(expiresAt).toISOString()
|
|
1172
|
-
}
|
|
1229
|
+
};
|
|
1230
|
+
const toolPolicy = normalizeToolPolicy(session.toolPolicy);
|
|
1231
|
+
if (toolPolicy) {
|
|
1232
|
+
insertData.tool_policy = toolPolicy;
|
|
1233
|
+
}
|
|
1234
|
+
const { error } = await this.supabase.from("mcp_sessions").insert(insertData);
|
|
1173
1235
|
if (error) {
|
|
1174
1236
|
if (error.code === "23505") {
|
|
1175
1237
|
throw new Error(`Session ${sessionId} already exists`);
|
|
@@ -1194,6 +1256,7 @@ var SupabaseStorageBackend = class {
|
|
|
1194
1256
|
}
|
|
1195
1257
|
if ("headers" in data) updateData.headers = encryptObject(data.headers);
|
|
1196
1258
|
if ("authUrl" in data) updateData.auth_url = data.authUrl ?? null;
|
|
1259
|
+
if ("toolPolicy" in data) updateData.tool_policy = normalizeToolPolicy(data.toolPolicy);
|
|
1197
1260
|
const shouldUpdateSession = Object.keys(updateData).some((key) => key !== "updated_at");
|
|
1198
1261
|
let updatedRows = null;
|
|
1199
1262
|
if (shouldUpdateSession) {
|
|
@@ -1367,7 +1430,8 @@ var NeonStorageBackend = class {
|
|
|
1367
1430
|
userId: row.user_id,
|
|
1368
1431
|
headers: decryptObject(row.headers),
|
|
1369
1432
|
authUrl: row.auth_url ?? void 0,
|
|
1370
|
-
status: row.status ?? "pending"
|
|
1433
|
+
status: row.status ?? "pending",
|
|
1434
|
+
toolPolicy: normalizeToolPolicy(row.tool_policy)
|
|
1371
1435
|
};
|
|
1372
1436
|
}
|
|
1373
1437
|
mapRowToCredentials(row, userId, sessionId) {
|
|
@@ -1390,42 +1454,48 @@ var NeonStorageBackend = class {
|
|
|
1390
1454
|
const status = session.status ?? "pending";
|
|
1391
1455
|
const createdAt = new Date(session.createdAt || Date.now()).toISOString();
|
|
1392
1456
|
const updatedAt = new Date(session.updatedAt ?? session.createdAt ?? Date.now()).toISOString();
|
|
1393
|
-
const
|
|
1457
|
+
const createdAtMs = new Date(createdAt).getTime();
|
|
1458
|
+
const expiresAt = resolveSessionExpiresAt(status, createdAtMs);
|
|
1459
|
+
const toolPolicy = normalizeToolPolicy(session.toolPolicy, createdAtMs);
|
|
1460
|
+
const columns = [
|
|
1461
|
+
"session_id",
|
|
1462
|
+
"user_id",
|
|
1463
|
+
"server_id",
|
|
1464
|
+
"server_name",
|
|
1465
|
+
"server_url",
|
|
1466
|
+
"transport_type",
|
|
1467
|
+
"callback_url",
|
|
1468
|
+
"created_at",
|
|
1469
|
+
"updated_at",
|
|
1470
|
+
"headers",
|
|
1471
|
+
"auth_url",
|
|
1472
|
+
"status",
|
|
1473
|
+
"expires_at"
|
|
1474
|
+
];
|
|
1475
|
+
const values = [
|
|
1476
|
+
sessionId,
|
|
1477
|
+
userId,
|
|
1478
|
+
session.serverId,
|
|
1479
|
+
session.serverName,
|
|
1480
|
+
session.serverUrl,
|
|
1481
|
+
session.transportType,
|
|
1482
|
+
session.callbackUrl,
|
|
1483
|
+
createdAt,
|
|
1484
|
+
updatedAt,
|
|
1485
|
+
encryptObject(session.headers),
|
|
1486
|
+
session.authUrl ?? null,
|
|
1487
|
+
status,
|
|
1488
|
+
expiresAt === null ? null : new Date(expiresAt).toISOString()
|
|
1489
|
+
];
|
|
1490
|
+
if (toolPolicy) {
|
|
1491
|
+
columns.push("tool_policy");
|
|
1492
|
+
values.push(toolPolicy);
|
|
1493
|
+
}
|
|
1494
|
+
const placeholders = values.map((_, i) => `$${i + 1}`);
|
|
1394
1495
|
try {
|
|
1395
1496
|
await this.sql.query(
|
|
1396
|
-
`INSERT INTO ${this.tableName} (
|
|
1397
|
-
|
|
1398
|
-
user_id,
|
|
1399
|
-
server_id,
|
|
1400
|
-
server_name,
|
|
1401
|
-
server_url,
|
|
1402
|
-
transport_type,
|
|
1403
|
-
callback_url,
|
|
1404
|
-
created_at,
|
|
1405
|
-
updated_at,
|
|
1406
|
-
headers,
|
|
1407
|
-
auth_url,
|
|
1408
|
-
status,
|
|
1409
|
-
expires_at
|
|
1410
|
-
) VALUES (
|
|
1411
|
-
$1, $2, $3, $4, $5, $6, $7, $8,
|
|
1412
|
-
$9, $10, $11, $12, $13
|
|
1413
|
-
)`,
|
|
1414
|
-
[
|
|
1415
|
-
sessionId,
|
|
1416
|
-
userId,
|
|
1417
|
-
session.serverId,
|
|
1418
|
-
session.serverName,
|
|
1419
|
-
session.serverUrl,
|
|
1420
|
-
session.transportType,
|
|
1421
|
-
session.callbackUrl,
|
|
1422
|
-
createdAt,
|
|
1423
|
-
updatedAt,
|
|
1424
|
-
encryptObject(session.headers),
|
|
1425
|
-
session.authUrl ?? null,
|
|
1426
|
-
status,
|
|
1427
|
-
expiresAt === null ? null : new Date(expiresAt).toISOString()
|
|
1428
|
-
]
|
|
1497
|
+
`INSERT INTO ${this.tableName} (${columns.join(", ")}) VALUES (${placeholders.join(", ")})`,
|
|
1498
|
+
values
|
|
1429
1499
|
);
|
|
1430
1500
|
} catch (error) {
|
|
1431
1501
|
if (error.code === "23505") {
|
|
@@ -1442,36 +1512,36 @@ var NeonStorageBackend = class {
|
|
|
1442
1512
|
const updatedSession = { ...currentSession, ...data };
|
|
1443
1513
|
const status = updatedSession.status ?? "pending";
|
|
1444
1514
|
const expiresAt = resolveSessionExpiresAt(status);
|
|
1445
|
-
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;
|
|
1515
|
+
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;
|
|
1446
1516
|
if (shouldUpdateSession) {
|
|
1517
|
+
const setClauses = [];
|
|
1518
|
+
const values = [];
|
|
1519
|
+
let paramIndex = 1;
|
|
1520
|
+
const addSet = (column, value) => {
|
|
1521
|
+
setClauses.push(`${column} = $${paramIndex++}`);
|
|
1522
|
+
values.push(value);
|
|
1523
|
+
};
|
|
1524
|
+
addSet("server_id", updatedSession.serverId);
|
|
1525
|
+
addSet("server_name", updatedSession.serverName);
|
|
1526
|
+
addSet("server_url", updatedSession.serverUrl);
|
|
1527
|
+
addSet("transport_type", updatedSession.transportType);
|
|
1528
|
+
addSet("callback_url", updatedSession.callbackUrl);
|
|
1529
|
+
addSet("status", status);
|
|
1530
|
+
addSet("headers", encryptObject(updatedSession.headers));
|
|
1531
|
+
addSet("auth_url", updatedSession.authUrl ?? null);
|
|
1532
|
+
addSet("expires_at", expiresAt === null ? null : new Date(expiresAt).toISOString());
|
|
1533
|
+
if ("toolPolicy" in data) {
|
|
1534
|
+
const policyUpdatedAt = updatedSession.updatedAt ?? Date.now();
|
|
1535
|
+
const toolPolicy = normalizeToolPolicy(updatedSession.toolPolicy, policyUpdatedAt) ?? { mode: "all", toolIds: [], updatedAt: policyUpdatedAt };
|
|
1536
|
+
addSet("tool_policy", toolPolicy);
|
|
1537
|
+
}
|
|
1538
|
+
setClauses.push("updated_at = now()");
|
|
1447
1539
|
const updatedRows = await this.sql.query(
|
|
1448
1540
|
`UPDATE ${this.tableName}
|
|
1449
|
-
SET
|
|
1450
|
-
|
|
1451
|
-
server_name = $2,
|
|
1452
|
-
server_url = $3,
|
|
1453
|
-
transport_type = $4,
|
|
1454
|
-
callback_url = $5,
|
|
1455
|
-
status = $6,
|
|
1456
|
-
headers = $7,
|
|
1457
|
-
auth_url = $8,
|
|
1458
|
-
expires_at = $9,
|
|
1459
|
-
updated_at = now()
|
|
1460
|
-
WHERE user_id = $10 AND session_id = $11
|
|
1541
|
+
SET ${setClauses.join(", ")}
|
|
1542
|
+
WHERE user_id = $${paramIndex++} AND session_id = $${paramIndex++}
|
|
1461
1543
|
RETURNING id`,
|
|
1462
|
-
[
|
|
1463
|
-
updatedSession.serverId,
|
|
1464
|
-
updatedSession.serverName,
|
|
1465
|
-
updatedSession.serverUrl,
|
|
1466
|
-
updatedSession.transportType,
|
|
1467
|
-
updatedSession.callbackUrl,
|
|
1468
|
-
status,
|
|
1469
|
-
encryptObject(updatedSession.headers),
|
|
1470
|
-
updatedSession.authUrl ?? null,
|
|
1471
|
-
expiresAt === null ? null : new Date(expiresAt).toISOString(),
|
|
1472
|
-
userId,
|
|
1473
|
-
sessionId
|
|
1474
|
-
]
|
|
1544
|
+
[...values, userId, sessionId]
|
|
1475
1545
|
);
|
|
1476
1546
|
if (updatedRows.length === 0) {
|
|
1477
1547
|
throw new Error(`Session ${sessionId} not found for userId ${userId}`);
|
|
@@ -2459,7 +2529,15 @@ var MCPClient = class {
|
|
|
2459
2529
|
if (!existingSession && this.serverId && this.serverUrl && this.callbackUrl) {
|
|
2460
2530
|
this.createdAt = Date.now();
|
|
2461
2531
|
const updatedAt = this.createdAt;
|
|
2462
|
-
|
|
2532
|
+
this._onObservabilityEvent.fire({
|
|
2533
|
+
type: "mcp:client:session_created",
|
|
2534
|
+
level: "info",
|
|
2535
|
+
message: `Creating pending session ${this.sessionId} for connection setup`,
|
|
2536
|
+
sessionId: this.sessionId,
|
|
2537
|
+
serverId: this.serverId,
|
|
2538
|
+
timestamp: Date.now(),
|
|
2539
|
+
id: nanoid.nanoid()
|
|
2540
|
+
});
|
|
2463
2541
|
await sessions.create({
|
|
2464
2542
|
sessionId: this.sessionId,
|
|
2465
2543
|
userId: this.userId,
|
|
@@ -2589,7 +2667,15 @@ var MCPClient = class {
|
|
|
2589
2667
|
this.transportType = transportType;
|
|
2590
2668
|
this.emitStateChange("CONNECTED");
|
|
2591
2669
|
this.emitProgress("Connected successfully");
|
|
2592
|
-
|
|
2670
|
+
this._onObservabilityEvent.fire({
|
|
2671
|
+
type: "mcp:client:session_saved",
|
|
2672
|
+
level: "info",
|
|
2673
|
+
message: `Saving active session ${this.sessionId} (connect success)`,
|
|
2674
|
+
sessionId: this.sessionId,
|
|
2675
|
+
serverId: this.serverId,
|
|
2676
|
+
timestamp: Date.now(),
|
|
2677
|
+
id: nanoid.nanoid()
|
|
2678
|
+
});
|
|
2593
2679
|
await this.saveSession("active");
|
|
2594
2680
|
} catch (error) {
|
|
2595
2681
|
if (error instanceof auth_js.UnauthorizedError || error instanceof Error && error.message.toLowerCase().includes("unauthorized")) {
|
|
@@ -2606,7 +2692,15 @@ var MCPClient = class {
|
|
|
2606
2692
|
throw new Error(message);
|
|
2607
2693
|
}
|
|
2608
2694
|
this.emitStateChange("AUTHENTICATING");
|
|
2609
|
-
|
|
2695
|
+
this._onObservabilityEvent.fire({
|
|
2696
|
+
type: "mcp:client:session_saved",
|
|
2697
|
+
level: "info",
|
|
2698
|
+
message: `Saving pending OAuth session ${this.sessionId}`,
|
|
2699
|
+
sessionId: this.sessionId,
|
|
2700
|
+
serverId: this.serverId,
|
|
2701
|
+
timestamp: Date.now(),
|
|
2702
|
+
id: nanoid.nanoid()
|
|
2703
|
+
});
|
|
2610
2704
|
await this.saveSession("pending");
|
|
2611
2705
|
if (this.serverId) {
|
|
2612
2706
|
this._onConnectionEvent.fire({
|
|
@@ -2681,27 +2775,25 @@ var MCPClient = class {
|
|
|
2681
2775
|
this.emitStateChange("AUTHENTICATED");
|
|
2682
2776
|
authenticatedStateEmitted = true;
|
|
2683
2777
|
}
|
|
2684
|
-
this.emitProgress("Creating authenticated client...");
|
|
2685
|
-
this.client = new index_js.Client(
|
|
2686
|
-
{
|
|
2687
|
-
name: MCP_CLIENT_NAME,
|
|
2688
|
-
version: MCP_CLIENT_VERSION
|
|
2689
|
-
},
|
|
2690
|
-
{
|
|
2691
|
-
capabilities: {
|
|
2692
|
-
extensions: {
|
|
2693
|
-
"io.modelcontextprotocol/ui": {
|
|
2694
|
-
mimeTypes: ["text/html+mcp"]
|
|
2695
|
-
}
|
|
2696
|
-
}
|
|
2697
|
-
}
|
|
2698
|
-
}
|
|
2699
|
-
);
|
|
2700
2778
|
this.emitStateChange("CONNECTING");
|
|
2779
|
+
if (this.client.transport) {
|
|
2780
|
+
try {
|
|
2781
|
+
await this.client.close();
|
|
2782
|
+
} catch {
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2701
2785
|
await this.client.connect(this.transport);
|
|
2702
2786
|
this.transportType = currentType;
|
|
2703
2787
|
this.emitStateChange("CONNECTED");
|
|
2704
|
-
|
|
2788
|
+
this._onObservabilityEvent.fire({
|
|
2789
|
+
type: "mcp:client:session_saved",
|
|
2790
|
+
level: "info",
|
|
2791
|
+
message: `Saving active session ${this.sessionId} (OAuth complete)`,
|
|
2792
|
+
sessionId: this.sessionId,
|
|
2793
|
+
serverId: this.serverId,
|
|
2794
|
+
timestamp: Date.now(),
|
|
2795
|
+
id: nanoid.nanoid()
|
|
2796
|
+
});
|
|
2705
2797
|
await this.saveSession("active");
|
|
2706
2798
|
return;
|
|
2707
2799
|
} catch (error) {
|
|
@@ -2736,24 +2828,28 @@ var MCPClient = class {
|
|
|
2736
2828
|
throw lastError;
|
|
2737
2829
|
}
|
|
2738
2830
|
}
|
|
2831
|
+
/**
|
|
2832
|
+
* Lists all available tools from the connected MCP server without emitting discovery events.
|
|
2833
|
+
* Gateways use this to apply policy before publishing tools to agents or UI state.
|
|
2834
|
+
*/
|
|
2835
|
+
async fetchTools() {
|
|
2836
|
+
const request = {
|
|
2837
|
+
method: "tools/list",
|
|
2838
|
+
params: {}
|
|
2839
|
+
};
|
|
2840
|
+
return await this.withRetry(
|
|
2841
|
+
() => this.client.request(request, types_js.ListToolsResultSchema)
|
|
2842
|
+
);
|
|
2843
|
+
}
|
|
2739
2844
|
/**
|
|
2740
2845
|
* Lists all available tools from the connected MCP server
|
|
2741
2846
|
* @returns List of tools with their schemas and descriptions
|
|
2742
2847
|
* @throws {Error} When client is not connected
|
|
2743
2848
|
*/
|
|
2744
2849
|
async listTools() {
|
|
2745
|
-
if (!this.client) {
|
|
2746
|
-
throw new Error("Not connected to server");
|
|
2747
|
-
}
|
|
2748
2850
|
this.emitStateChange("DISCOVERING");
|
|
2749
2851
|
try {
|
|
2750
|
-
const
|
|
2751
|
-
method: "tools/list",
|
|
2752
|
-
params: {}
|
|
2753
|
-
};
|
|
2754
|
-
const result = await this.withRetry(
|
|
2755
|
-
() => this.client.request(request, types_js.ListToolsResultSchema)
|
|
2756
|
-
);
|
|
2852
|
+
const result = await this.fetchTools();
|
|
2757
2853
|
if (this.serverId) {
|
|
2758
2854
|
this._onConnectionEvent.fire({
|
|
2759
2855
|
type: "tools_discovered",
|
|
@@ -2782,9 +2878,6 @@ var MCPClient = class {
|
|
|
2782
2878
|
* @throws {Error} When client is not connected
|
|
2783
2879
|
*/
|
|
2784
2880
|
async callTool(toolName, toolArgs) {
|
|
2785
|
-
if (!this.client) {
|
|
2786
|
-
throw new Error("Not connected to server");
|
|
2787
|
-
}
|
|
2788
2881
|
const request = {
|
|
2789
2882
|
method: "tools/call",
|
|
2790
2883
|
params: {
|
|
@@ -2838,9 +2931,6 @@ var MCPClient = class {
|
|
|
2838
2931
|
* @throws {Error} When client is not connected
|
|
2839
2932
|
*/
|
|
2840
2933
|
async listPrompts() {
|
|
2841
|
-
if (!this.client) {
|
|
2842
|
-
throw new Error("Not connected to server");
|
|
2843
|
-
}
|
|
2844
2934
|
this.emitStateChange("DISCOVERING");
|
|
2845
2935
|
try {
|
|
2846
2936
|
const request = {
|
|
@@ -2868,9 +2958,6 @@ var MCPClient = class {
|
|
|
2868
2958
|
* @throws {Error} When client is not connected
|
|
2869
2959
|
*/
|
|
2870
2960
|
async getPrompt(name, args) {
|
|
2871
|
-
if (!this.client) {
|
|
2872
|
-
throw new Error("Not connected to server");
|
|
2873
|
-
}
|
|
2874
2961
|
const request = {
|
|
2875
2962
|
method: "prompts/get",
|
|
2876
2963
|
params: {
|
|
@@ -2888,9 +2975,6 @@ var MCPClient = class {
|
|
|
2888
2975
|
* @throws {Error} When client is not connected
|
|
2889
2976
|
*/
|
|
2890
2977
|
async listResources() {
|
|
2891
|
-
if (!this.client) {
|
|
2892
|
-
throw new Error("Not connected to server");
|
|
2893
|
-
}
|
|
2894
2978
|
this.emitStateChange("DISCOVERING");
|
|
2895
2979
|
try {
|
|
2896
2980
|
const request = {
|
|
@@ -2917,9 +3001,6 @@ var MCPClient = class {
|
|
|
2917
3001
|
* @throws {Error} When client is not connected
|
|
2918
3002
|
*/
|
|
2919
3003
|
async readResource(uri) {
|
|
2920
|
-
if (!this.client) {
|
|
2921
|
-
throw new Error("Not connected to server");
|
|
2922
|
-
}
|
|
2923
3004
|
const request = {
|
|
2924
3005
|
method: "resources/read",
|
|
2925
3006
|
params: {
|
|
@@ -2975,7 +3056,16 @@ var MCPClient = class {
|
|
|
2975
3056
|
try {
|
|
2976
3057
|
await this.ensureSession();
|
|
2977
3058
|
} catch (error) {
|
|
2978
|
-
|
|
3059
|
+
this._onObservabilityEvent.fire({
|
|
3060
|
+
type: "mcp:client:error",
|
|
3061
|
+
level: "warn",
|
|
3062
|
+
message: "Initialization failed during clearSession",
|
|
3063
|
+
sessionId: this.sessionId,
|
|
3064
|
+
serverId: this.serverId,
|
|
3065
|
+
payload: { error: String(error) },
|
|
3066
|
+
timestamp: Date.now(),
|
|
3067
|
+
id: nanoid.nanoid()
|
|
3068
|
+
});
|
|
2979
3069
|
}
|
|
2980
3070
|
if (this.oauthProvider) {
|
|
2981
3071
|
await this.oauthProvider.invalidateCredentials("all");
|
|
@@ -3088,6 +3178,69 @@ var MCPClient = class {
|
|
|
3088
3178
|
|
|
3089
3179
|
// src/server/mcp/multi-session-client.ts
|
|
3090
3180
|
init_cjs_shims();
|
|
3181
|
+
|
|
3182
|
+
// src/server/mcp/tool-policy-gateway.ts
|
|
3183
|
+
init_cjs_shims();
|
|
3184
|
+
var ToolPolicyGateway = class {
|
|
3185
|
+
constructor(userId, sessionId, client) {
|
|
3186
|
+
this.userId = userId;
|
|
3187
|
+
this.sessionId = sessionId;
|
|
3188
|
+
this.client = client;
|
|
3189
|
+
}
|
|
3190
|
+
isConnected() {
|
|
3191
|
+
return this.client.isConnected();
|
|
3192
|
+
}
|
|
3193
|
+
getServerId() {
|
|
3194
|
+
return this.client.getServerId?.();
|
|
3195
|
+
}
|
|
3196
|
+
getServerName() {
|
|
3197
|
+
return this.client.getServerName?.();
|
|
3198
|
+
}
|
|
3199
|
+
getServerUrl() {
|
|
3200
|
+
return this.client.getServerUrl?.();
|
|
3201
|
+
}
|
|
3202
|
+
getSessionId() {
|
|
3203
|
+
return this.client.getSessionId?.() ?? this.sessionId;
|
|
3204
|
+
}
|
|
3205
|
+
async listTools() {
|
|
3206
|
+
const session = await this.getSession();
|
|
3207
|
+
const result = await this.client.fetchTools();
|
|
3208
|
+
const tools = this.filterTools(session, result.tools);
|
|
3209
|
+
return {
|
|
3210
|
+
...result,
|
|
3211
|
+
tools
|
|
3212
|
+
};
|
|
3213
|
+
}
|
|
3214
|
+
async listAllTools() {
|
|
3215
|
+
return await this.client.fetchTools();
|
|
3216
|
+
}
|
|
3217
|
+
async callTool(name, args) {
|
|
3218
|
+
const session = await this.getSession();
|
|
3219
|
+
this.assertAllowed(session, name);
|
|
3220
|
+
return await this.client.callTool(name, args);
|
|
3221
|
+
}
|
|
3222
|
+
filterTools(session, tools) {
|
|
3223
|
+
return filterToolsByPolicy(tools, session.toolPolicy, this.getPolicyServerId(session));
|
|
3224
|
+
}
|
|
3225
|
+
assertAllowed(session, toolName) {
|
|
3226
|
+
assertToolAllowed(session.toolPolicy, toolName, this.getPolicyServerId(session));
|
|
3227
|
+
}
|
|
3228
|
+
async getSession() {
|
|
3229
|
+
const session = await sessions.get(this.userId, this.sessionId);
|
|
3230
|
+
if (!session) {
|
|
3231
|
+
throw new Error("Session not found");
|
|
3232
|
+
}
|
|
3233
|
+
return session;
|
|
3234
|
+
}
|
|
3235
|
+
getPolicyServerId(session) {
|
|
3236
|
+
return this.client.getServerId?.() ?? session.serverId;
|
|
3237
|
+
}
|
|
3238
|
+
};
|
|
3239
|
+
function createToolPolicyGateway(userId, sessionId, client) {
|
|
3240
|
+
return new ToolPolicyGateway(userId, sessionId, client);
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3243
|
+
// src/server/mcp/multi-session-client.ts
|
|
3091
3244
|
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
3092
3245
|
var DEFAULT_MAX_RETRIES = 2;
|
|
3093
3246
|
var DEFAULT_RETRY_DELAY_MS = 1e3;
|
|
@@ -3152,7 +3305,9 @@ var MultiSessionClient = class {
|
|
|
3152
3305
|
* or to route a tool call to the right client by `serverId`.
|
|
3153
3306
|
*/
|
|
3154
3307
|
getClients() {
|
|
3155
|
-
return this.clients
|
|
3308
|
+
return this.clients.map(
|
|
3309
|
+
(client) => createToolPolicyGateway(this.userId, client.getSessionId(), client)
|
|
3310
|
+
);
|
|
3156
3311
|
}
|
|
3157
3312
|
/**
|
|
3158
3313
|
* Removes and disconnects a single session by ID.
|
|
@@ -3391,6 +3546,12 @@ var SSEConnectionManager = class {
|
|
|
3391
3546
|
case "listTools":
|
|
3392
3547
|
result = await this.listTools(request.params);
|
|
3393
3548
|
break;
|
|
3549
|
+
case "setToolPolicy":
|
|
3550
|
+
result = await this.setToolPolicy(request.params);
|
|
3551
|
+
break;
|
|
3552
|
+
case "getToolPolicy":
|
|
3553
|
+
result = await this.getToolPolicy(request.params);
|
|
3554
|
+
break;
|
|
3394
3555
|
case "callTool":
|
|
3395
3556
|
result = await this.callTool(request.params);
|
|
3396
3557
|
break;
|
|
@@ -3447,7 +3608,8 @@ var SSEConnectionManager = class {
|
|
|
3447
3608
|
transport: s.transportType,
|
|
3448
3609
|
createdAt: s.createdAt,
|
|
3449
3610
|
updatedAt: s.updatedAt ?? s.createdAt,
|
|
3450
|
-
status: s.status ?? "pending"
|
|
3611
|
+
status: s.status ?? "pending",
|
|
3612
|
+
toolPolicy: s.toolPolicy
|
|
3451
3613
|
}))
|
|
3452
3614
|
};
|
|
3453
3615
|
}
|
|
@@ -3457,7 +3619,7 @@ var SSEConnectionManager = class {
|
|
|
3457
3619
|
async connect(params) {
|
|
3458
3620
|
const { serverName, serverUrl, callbackUrl, transportType } = params;
|
|
3459
3621
|
const headers = normalizeHeaders(params.headers);
|
|
3460
|
-
const serverId = params.serverId && params.serverId.length <= 12 ? params.serverId :
|
|
3622
|
+
const serverId = params.serverId && params.serverId.length <= 12 ? params.serverId : generateServerId();
|
|
3461
3623
|
const existingSessions = await sessions.list(this.userId);
|
|
3462
3624
|
const duplicate = existingSessions.find(
|
|
3463
3625
|
(s) => s.serverId === serverId || s.serverUrl === serverUrl
|
|
@@ -3495,7 +3657,7 @@ var SSEConnectionManager = class {
|
|
|
3495
3657
|
this.sendEvent(event);
|
|
3496
3658
|
});
|
|
3497
3659
|
await client.connect();
|
|
3498
|
-
await
|
|
3660
|
+
await this.listPolicyFilteredTools(sessionId);
|
|
3499
3661
|
return {
|
|
3500
3662
|
sessionId,
|
|
3501
3663
|
success: true
|
|
@@ -3566,22 +3728,98 @@ var SSEConnectionManager = class {
|
|
|
3566
3728
|
this.clients.set(sessionId, client);
|
|
3567
3729
|
return client;
|
|
3568
3730
|
}
|
|
3731
|
+
async listPolicyFilteredTools(sessionId) {
|
|
3732
|
+
const session = await sessions.get(this.userId, sessionId);
|
|
3733
|
+
if (!session) {
|
|
3734
|
+
throw new Error("Session not found");
|
|
3735
|
+
}
|
|
3736
|
+
const client = await this.getOrCreateClient(sessionId);
|
|
3737
|
+
const gateway = createToolPolicyGateway(this.userId, sessionId, client);
|
|
3738
|
+
const result = await gateway.listTools();
|
|
3739
|
+
this.emitConnectionEvent({
|
|
3740
|
+
type: "tools_discovered",
|
|
3741
|
+
sessionId,
|
|
3742
|
+
serverId: session.serverId ?? "unknown",
|
|
3743
|
+
toolCount: result.tools.length,
|
|
3744
|
+
tools: result.tools,
|
|
3745
|
+
timestamp: Date.now()
|
|
3746
|
+
});
|
|
3747
|
+
return { session, result };
|
|
3748
|
+
}
|
|
3569
3749
|
/**
|
|
3570
3750
|
* List tools from a session
|
|
3571
3751
|
*/
|
|
3572
3752
|
async listTools(params) {
|
|
3573
3753
|
const { sessionId } = params;
|
|
3574
|
-
const
|
|
3575
|
-
const result = await client.listTools();
|
|
3754
|
+
const { result } = await this.listPolicyFilteredTools(sessionId);
|
|
3576
3755
|
return { tools: result.tools };
|
|
3577
3756
|
}
|
|
3757
|
+
/**
|
|
3758
|
+
* Get all raw tools with effective access state for management UI.
|
|
3759
|
+
*/
|
|
3760
|
+
async getToolPolicy(params) {
|
|
3761
|
+
const { sessionId } = params;
|
|
3762
|
+
const session = await sessions.get(this.userId, sessionId);
|
|
3763
|
+
if (!session) {
|
|
3764
|
+
throw new Error("Session not found");
|
|
3765
|
+
}
|
|
3766
|
+
const client = await this.getOrCreateClient(sessionId);
|
|
3767
|
+
const allTools = await client.fetchTools();
|
|
3768
|
+
const toolPolicy = session.toolPolicy ?? {
|
|
3769
|
+
mode: "all",
|
|
3770
|
+
toolIds: [],
|
|
3771
|
+
updatedAt: session.updatedAt ?? session.createdAt
|
|
3772
|
+
};
|
|
3773
|
+
const serverId = session.serverId ?? "unknown";
|
|
3774
|
+
const tools = allTools.tools.map((tool) => ({
|
|
3775
|
+
...tool,
|
|
3776
|
+
toolId: createToolId(serverId, tool.name),
|
|
3777
|
+
allowed: isToolAllowed(toolPolicy, tool.name, session.serverId)
|
|
3778
|
+
}));
|
|
3779
|
+
return {
|
|
3780
|
+
toolPolicy,
|
|
3781
|
+
tools,
|
|
3782
|
+
toolCount: tools.length,
|
|
3783
|
+
allowedToolCount: tools.filter((tool) => tool.allowed).length
|
|
3784
|
+
};
|
|
3785
|
+
}
|
|
3786
|
+
/**
|
|
3787
|
+
* Update per-session tool access policy.
|
|
3788
|
+
*/
|
|
3789
|
+
async setToolPolicy(params) {
|
|
3790
|
+
const { sessionId } = params;
|
|
3791
|
+
const session = await sessions.get(this.userId, sessionId);
|
|
3792
|
+
if (!session) {
|
|
3793
|
+
throw new Error("Session not found");
|
|
3794
|
+
}
|
|
3795
|
+
const client = await this.getOrCreateClient(sessionId);
|
|
3796
|
+
const allTools = await client.fetchTools();
|
|
3797
|
+
const toolPolicy = normalizeToolPolicyForUpdate(params.toolPolicy);
|
|
3798
|
+
validateToolPolicyAgainstTools(toolPolicy, allTools.tools, session.serverId);
|
|
3799
|
+
await sessions.update(this.userId, sessionId, { toolPolicy });
|
|
3800
|
+
const filteredTools = createToolPolicyGateway(this.userId, sessionId, client).filterTools({ ...session, toolPolicy }, allTools.tools);
|
|
3801
|
+
this.emitConnectionEvent({
|
|
3802
|
+
type: "tools_discovered",
|
|
3803
|
+
sessionId,
|
|
3804
|
+
serverId: session.serverId ?? "unknown",
|
|
3805
|
+
toolCount: filteredTools.length,
|
|
3806
|
+
tools: filteredTools,
|
|
3807
|
+
timestamp: Date.now()
|
|
3808
|
+
});
|
|
3809
|
+
return {
|
|
3810
|
+
success: true,
|
|
3811
|
+
toolPolicy,
|
|
3812
|
+
tools: filteredTools,
|
|
3813
|
+
toolCount: filteredTools.length
|
|
3814
|
+
};
|
|
3815
|
+
}
|
|
3578
3816
|
/**
|
|
3579
3817
|
* Call a tool on the MCP server
|
|
3580
3818
|
*/
|
|
3581
3819
|
async callTool(params) {
|
|
3582
3820
|
const { sessionId, toolName, toolArgs } = params;
|
|
3583
3821
|
const client = await this.getOrCreateClient(sessionId);
|
|
3584
|
-
const result = await client.callTool(toolName, toolArgs);
|
|
3822
|
+
const result = await createToolPolicyGateway(this.userId, sessionId, client).callTool(toolName, toolArgs);
|
|
3585
3823
|
const meta = result._meta || {};
|
|
3586
3824
|
return {
|
|
3587
3825
|
...result,
|
|
@@ -3631,7 +3869,7 @@ var SSEConnectionManager = class {
|
|
|
3631
3869
|
client.onObservabilityEvent((event) => this.sendEvent(event));
|
|
3632
3870
|
await client.connect();
|
|
3633
3871
|
this.clients.set(sessionId, client);
|
|
3634
|
-
const tools = await
|
|
3872
|
+
const { result: tools } = await this.listPolicyFilteredTools(sessionId);
|
|
3635
3873
|
return { success: true, toolCount: tools.tools.length };
|
|
3636
3874
|
} catch (error) {
|
|
3637
3875
|
this.emitConnectionEvent({
|
|
@@ -3679,7 +3917,7 @@ var SSEConnectionManager = class {
|
|
|
3679
3917
|
client.onConnectionEvent((event) => this.emitConnectionEvent(event));
|
|
3680
3918
|
await client.finishAuth(code, oauthState);
|
|
3681
3919
|
this.clients.set(sessionId, client);
|
|
3682
|
-
const tools = await
|
|
3920
|
+
const { result: tools } = await this.listPolicyFilteredTools(sessionId);
|
|
3683
3921
|
return { success: true, toolCount: tools.tools.length };
|
|
3684
3922
|
} catch (error) {
|
|
3685
3923
|
this.emitConnectionEvent({
|
|
@@ -3978,6 +4216,12 @@ var SSEClient = class {
|
|
|
3978
4216
|
async disconnectFromServer(sessionId) {
|
|
3979
4217
|
return this.sendRequest("disconnect", { sessionId });
|
|
3980
4218
|
}
|
|
4219
|
+
async setToolPolicy(sessionId, toolPolicy) {
|
|
4220
|
+
return this.sendRequest("setToolPolicy", { sessionId, toolPolicy });
|
|
4221
|
+
}
|
|
4222
|
+
async getToolPolicy(sessionId) {
|
|
4223
|
+
return this.sendRequest("getToolPolicy", { sessionId });
|
|
4224
|
+
}
|
|
3981
4225
|
async listTools(sessionId) {
|
|
3982
4226
|
return this.sendRequest("listTools", { sessionId });
|
|
3983
4227
|
}
|