mcp-use 1.5.0 → 1.5.1-canary.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/.tsbuildinfo +1 -1
- package/dist/{chunk-WERYJ6PF.js → chunk-2AOGMX4T.js} +1 -1
- package/dist/{chunk-DSBKVAWD.js → chunk-2JBWOW4S.js} +152 -0
- package/dist/{chunk-UT7O4SIJ.js → chunk-BWOTID2D.js} +209 -75
- package/dist/{chunk-GPAOZN2F.js → chunk-QRABML5H.js} +15 -3
- package/dist/index.cjs +395 -84
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -10
- package/dist/src/agents/index.cjs +1 -0
- package/dist/src/agents/index.js +2 -2
- package/dist/src/browser.cjs +351 -72
- package/dist/src/browser.d.ts +2 -0
- package/dist/src/browser.d.ts.map +1 -1
- package/dist/src/browser.js +2 -2
- package/dist/src/client/browser.d.ts.map +1 -1
- package/dist/src/client/prompts.cjs +3 -0
- package/dist/src/client/prompts.js +2 -2
- package/dist/src/client.d.ts +8 -0
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/config.d.ts +2 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/connectors/base.d.ts +79 -1
- package/dist/src/connectors/base.d.ts.map +1 -1
- package/dist/src/connectors/http.d.ts +1 -0
- package/dist/src/connectors/http.d.ts.map +1 -1
- package/dist/src/connectors/stdio.d.ts.map +1 -1
- package/dist/src/connectors/websocket.d.ts +6 -0
- package/dist/src/connectors/websocket.d.ts.map +1 -1
- package/dist/src/react/index.cjs +365 -73
- package/dist/src/react/index.d.ts +1 -0
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/react/index.js +3 -3
- package/dist/src/react/types.d.ts +9 -1
- package/dist/src/react/types.d.ts.map +1 -1
- package/dist/src/react/useMcp.d.ts.map +1 -1
- package/dist/src/server/adapters/mcp-ui-adapter.d.ts +1 -0
- package/dist/src/server/adapters/mcp-ui-adapter.d.ts.map +1 -1
- package/dist/src/server/index.cjs +605 -168
- package/dist/src/server/index.js +605 -168
- package/dist/src/server/mcp-server.d.ts +201 -10
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/dist/src/server/types/common.d.ts +28 -0
- package/dist/src/server/types/common.d.ts.map +1 -1
- package/dist/src/session.d.ts +40 -1
- package/dist/src/session.d.ts.map +1 -1
- package/package.json +10 -4
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
import {
|
|
23
23
|
CodeModeConnector,
|
|
24
24
|
PROMPTS
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-2AOGMX4T.js";
|
|
26
26
|
import {
|
|
27
27
|
ErrorBoundary,
|
|
28
28
|
Image,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
useWidgetProps,
|
|
35
35
|
useWidgetState,
|
|
36
36
|
useWidgetTheme
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-QRABML5H.js";
|
|
38
38
|
import {
|
|
39
39
|
BaseMCPClient,
|
|
40
40
|
BrowserOAuthClientProvider,
|
|
@@ -43,10 +43,10 @@ import {
|
|
|
43
43
|
MCPSession,
|
|
44
44
|
WebSocketConnector,
|
|
45
45
|
onMcpAuthorization
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-BWOTID2D.js";
|
|
47
47
|
import {
|
|
48
48
|
BaseConnector
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-2JBWOW4S.js";
|
|
50
50
|
import "./chunk-YURRUCIM.js";
|
|
51
51
|
import {
|
|
52
52
|
Logger,
|
|
@@ -808,9 +808,22 @@ var StdioConnector = class extends BaseConnector {
|
|
|
808
808
|
this.errlog
|
|
809
809
|
);
|
|
810
810
|
const transport = await this.connectionManager.start();
|
|
811
|
-
|
|
811
|
+
const clientOptions = {
|
|
812
|
+
...this.opts.clientOptions || {},
|
|
813
|
+
capabilities: {
|
|
814
|
+
...this.opts.clientOptions?.capabilities || {},
|
|
815
|
+
roots: { listChanged: true },
|
|
816
|
+
// Always advertise roots capability
|
|
817
|
+
// Add sampling capability if callback is provided
|
|
818
|
+
...this.opts.samplingCallback ? { sampling: {} } : {}
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
this.client = new Client(this.clientInfo, clientOptions);
|
|
812
822
|
await this.client.connect(transport);
|
|
813
823
|
this.connected = true;
|
|
824
|
+
this.setupNotificationHandler();
|
|
825
|
+
this.setupRootsHandler();
|
|
826
|
+
this.setupSamplingHandler();
|
|
814
827
|
logger.debug(
|
|
815
828
|
`Successfully connected to MCP implementation: ${this.command}`
|
|
816
829
|
);
|
|
@@ -834,12 +847,13 @@ function loadConfigFile(filepath) {
|
|
|
834
847
|
return JSON.parse(raw);
|
|
835
848
|
}
|
|
836
849
|
__name(loadConfigFile, "loadConfigFile");
|
|
837
|
-
function createConnectorFromConfig(serverConfig) {
|
|
850
|
+
function createConnectorFromConfig(serverConfig, connectorOptions) {
|
|
838
851
|
if ("command" in serverConfig && "args" in serverConfig) {
|
|
839
852
|
return new StdioConnector({
|
|
840
853
|
command: serverConfig.command,
|
|
841
854
|
args: serverConfig.args,
|
|
842
|
-
env: serverConfig.env
|
|
855
|
+
env: serverConfig.env,
|
|
856
|
+
...connectorOptions
|
|
843
857
|
});
|
|
844
858
|
}
|
|
845
859
|
if ("url" in serverConfig) {
|
|
@@ -848,13 +862,15 @@ function createConnectorFromConfig(serverConfig) {
|
|
|
848
862
|
headers: serverConfig.headers,
|
|
849
863
|
authToken: serverConfig.auth_token || serverConfig.authToken,
|
|
850
864
|
// Only force SSE if explicitly requested
|
|
851
|
-
preferSse: serverConfig.preferSse || transport === "sse"
|
|
865
|
+
preferSse: serverConfig.preferSse || transport === "sse",
|
|
866
|
+
...connectorOptions
|
|
852
867
|
});
|
|
853
868
|
}
|
|
854
869
|
if ("ws_url" in serverConfig) {
|
|
855
870
|
return new WebSocketConnector(serverConfig.ws_url, {
|
|
856
871
|
headers: serverConfig.headers,
|
|
857
|
-
authToken: serverConfig.auth_token
|
|
872
|
+
authToken: serverConfig.auth_token,
|
|
873
|
+
...connectorOptions
|
|
858
874
|
});
|
|
859
875
|
}
|
|
860
876
|
throw new Error("Cannot determine connector type from config");
|
|
@@ -871,6 +887,7 @@ var MCPClient = class _MCPClient extends BaseMCPClient {
|
|
|
871
887
|
_customCodeExecutor = null;
|
|
872
888
|
_codeExecutorConfig = "vm";
|
|
873
889
|
_executorOptions;
|
|
890
|
+
_samplingCallback;
|
|
874
891
|
constructor(config, options) {
|
|
875
892
|
if (config) {
|
|
876
893
|
if (typeof config === "string") {
|
|
@@ -896,6 +913,7 @@ var MCPClient = class _MCPClient extends BaseMCPClient {
|
|
|
896
913
|
this.codeMode = codeModeEnabled;
|
|
897
914
|
this._codeExecutorConfig = executorConfig;
|
|
898
915
|
this._executorOptions = executorOptions;
|
|
916
|
+
this._samplingCallback = options?.samplingCallback;
|
|
899
917
|
if (this.codeMode) {
|
|
900
918
|
this._setupCodeModeConnector();
|
|
901
919
|
}
|
|
@@ -921,7 +939,9 @@ var MCPClient = class _MCPClient extends BaseMCPClient {
|
|
|
921
939
|
* Supports all connector types including StdioConnector
|
|
922
940
|
*/
|
|
923
941
|
createConnectorFromConfig(serverConfig) {
|
|
924
|
-
return createConnectorFromConfig(serverConfig
|
|
942
|
+
return createConnectorFromConfig(serverConfig, {
|
|
943
|
+
samplingCallback: this._samplingCallback
|
|
944
|
+
});
|
|
925
945
|
}
|
|
926
946
|
_setupCodeModeConnector() {
|
|
927
947
|
logger.debug("Code mode connector initialized as internal meta server");
|
package/dist/src/agents/index.js
CHANGED
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
} from "../../chunk-MCF5P6GJ.js";
|
|
8
8
|
import {
|
|
9
9
|
PROMPTS
|
|
10
|
-
} from "../../chunk-
|
|
11
|
-
import "../../chunk-
|
|
10
|
+
} from "../../chunk-2AOGMX4T.js";
|
|
11
|
+
import "../../chunk-2JBWOW4S.js";
|
|
12
12
|
import "../../chunk-YURRUCIM.js";
|
|
13
13
|
import "../../chunk-34R6SIER.js";
|
|
14
14
|
import "../../chunk-3GQAWCBQ.js";
|
package/dist/src/browser.cjs
CHANGED
|
@@ -1009,7 +1009,7 @@ module.exports = __toCommonJS(browser_exports);
|
|
|
1009
1009
|
|
|
1010
1010
|
// src/connectors/http.ts
|
|
1011
1011
|
var import_client = require("@modelcontextprotocol/sdk/client/index.js");
|
|
1012
|
-
var
|
|
1012
|
+
var import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
1013
1013
|
init_logging();
|
|
1014
1014
|
|
|
1015
1015
|
// src/task_managers/sse.ts
|
|
@@ -1177,73 +1177,170 @@ var SseConnectionManager = class extends ConnectionManager {
|
|
|
1177
1177
|
}
|
|
1178
1178
|
};
|
|
1179
1179
|
|
|
1180
|
-
// src/
|
|
1181
|
-
var
|
|
1180
|
+
// src/connectors/base.ts
|
|
1181
|
+
var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
1182
1182
|
init_logging();
|
|
1183
|
-
var
|
|
1183
|
+
var BaseConnector = class {
|
|
1184
1184
|
static {
|
|
1185
|
-
__name(this, "
|
|
1185
|
+
__name(this, "BaseConnector");
|
|
1186
1186
|
}
|
|
1187
|
-
|
|
1187
|
+
client = null;
|
|
1188
|
+
connectionManager = null;
|
|
1189
|
+
toolsCache = null;
|
|
1190
|
+
capabilitiesCache = null;
|
|
1191
|
+
serverInfoCache = null;
|
|
1192
|
+
connected = false;
|
|
1188
1193
|
opts;
|
|
1189
|
-
|
|
1194
|
+
notificationHandlers = [];
|
|
1195
|
+
rootsCache = [];
|
|
1196
|
+
constructor(opts = {}) {
|
|
1197
|
+
this.opts = opts;
|
|
1198
|
+
if (opts.roots) {
|
|
1199
|
+
this.rootsCache = [...opts.roots];
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1190
1202
|
/**
|
|
1191
|
-
*
|
|
1203
|
+
* Register a handler for server notifications
|
|
1192
1204
|
*
|
|
1193
|
-
* @param
|
|
1194
|
-
*
|
|
1205
|
+
* @param handler - Function to call when a notification is received
|
|
1206
|
+
*
|
|
1207
|
+
* @example
|
|
1208
|
+
* ```typescript
|
|
1209
|
+
* connector.onNotification((notification) => {
|
|
1210
|
+
* console.log(`Received: ${notification.method}`, notification.params);
|
|
1211
|
+
* });
|
|
1212
|
+
* ```
|
|
1195
1213
|
*/
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
this.
|
|
1199
|
-
|
|
1214
|
+
onNotification(handler) {
|
|
1215
|
+
this.notificationHandlers.push(handler);
|
|
1216
|
+
if (this.client) {
|
|
1217
|
+
this.setupNotificationHandler();
|
|
1218
|
+
}
|
|
1200
1219
|
}
|
|
1201
1220
|
/**
|
|
1202
|
-
*
|
|
1203
|
-
*
|
|
1221
|
+
* Internal: wire notification handlers to the SDK client
|
|
1222
|
+
* Includes automatic handling for list_changed notifications per MCP spec
|
|
1204
1223
|
*/
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1224
|
+
setupNotificationHandler() {
|
|
1225
|
+
if (!this.client) return;
|
|
1226
|
+
this.client.fallbackNotificationHandler = async (notification) => {
|
|
1227
|
+
switch (notification.method) {
|
|
1228
|
+
case "notifications/tools/list_changed":
|
|
1229
|
+
await this.refreshToolsCache();
|
|
1230
|
+
break;
|
|
1231
|
+
case "notifications/resources/list_changed":
|
|
1232
|
+
await this.onResourcesListChanged();
|
|
1233
|
+
break;
|
|
1234
|
+
case "notifications/prompts/list_changed":
|
|
1235
|
+
await this.onPromptsListChanged();
|
|
1236
|
+
break;
|
|
1237
|
+
default:
|
|
1238
|
+
break;
|
|
1239
|
+
}
|
|
1240
|
+
for (const handler of this.notificationHandlers) {
|
|
1241
|
+
try {
|
|
1242
|
+
await handler(notification);
|
|
1243
|
+
} catch (err) {
|
|
1244
|
+
logger.error("Error in notification handler:", err);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1209
1248
|
}
|
|
1210
1249
|
/**
|
|
1211
|
-
*
|
|
1250
|
+
* Auto-refresh tools cache when server sends tools/list_changed notification
|
|
1212
1251
|
*/
|
|
1213
|
-
async
|
|
1214
|
-
if (this.
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1252
|
+
async refreshToolsCache() {
|
|
1253
|
+
if (!this.client) return;
|
|
1254
|
+
try {
|
|
1255
|
+
logger.debug(
|
|
1256
|
+
"[Auto] Refreshing tools cache due to list_changed notification"
|
|
1257
|
+
);
|
|
1258
|
+
const result = await this.client.listTools();
|
|
1259
|
+
this.toolsCache = result.tools ?? [];
|
|
1260
|
+
logger.debug(
|
|
1261
|
+
`[Auto] Refreshed tools cache: ${this.toolsCache.length} tools`
|
|
1262
|
+
);
|
|
1263
|
+
} catch (err) {
|
|
1264
|
+
logger.warn("[Auto] Failed to refresh tools cache:", err);
|
|
1222
1265
|
}
|
|
1223
1266
|
}
|
|
1224
1267
|
/**
|
|
1225
|
-
*
|
|
1268
|
+
* Called when server sends resources/list_changed notification
|
|
1269
|
+
* Resources aren't cached by default, but we log for user awareness
|
|
1226
1270
|
*/
|
|
1227
|
-
|
|
1228
|
-
|
|
1271
|
+
async onResourcesListChanged() {
|
|
1272
|
+
logger.debug(
|
|
1273
|
+
"[Auto] Resources list changed - clients should re-fetch if needed"
|
|
1274
|
+
);
|
|
1229
1275
|
}
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1276
|
+
/**
|
|
1277
|
+
* Called when server sends prompts/list_changed notification
|
|
1278
|
+
* Prompts aren't cached by default, but we log for user awareness
|
|
1279
|
+
*/
|
|
1280
|
+
async onPromptsListChanged() {
|
|
1281
|
+
logger.debug(
|
|
1282
|
+
"[Auto] Prompts list changed - clients should re-fetch if needed"
|
|
1283
|
+
);
|
|
1237
1284
|
}
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1285
|
+
/**
|
|
1286
|
+
* Set roots and notify the server.
|
|
1287
|
+
* Roots represent directories or files that the client has access to.
|
|
1288
|
+
*
|
|
1289
|
+
* @param roots - Array of Root objects with `uri` (must start with "file://") and optional `name`
|
|
1290
|
+
*
|
|
1291
|
+
* @example
|
|
1292
|
+
* ```typescript
|
|
1293
|
+
* await connector.setRoots([
|
|
1294
|
+
* { uri: "file:///home/user/project", name: "My Project" },
|
|
1295
|
+
* { uri: "file:///home/user/data" }
|
|
1296
|
+
* ]);
|
|
1297
|
+
* ```
|
|
1298
|
+
*/
|
|
1299
|
+
async setRoots(roots) {
|
|
1300
|
+
this.rootsCache = [...roots];
|
|
1301
|
+
if (this.client) {
|
|
1302
|
+
logger.debug(
|
|
1303
|
+
`Sending roots/list_changed notification with ${roots.length} root(s)`
|
|
1304
|
+
);
|
|
1305
|
+
await this.client.sendRootsListChanged();
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
/**
|
|
1309
|
+
* Get the current roots.
|
|
1310
|
+
*/
|
|
1311
|
+
getRoots() {
|
|
1312
|
+
return [...this.rootsCache];
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* Internal: set up roots/list request handler.
|
|
1316
|
+
* This is called after the client connects to register the handler for server requests.
|
|
1317
|
+
*/
|
|
1318
|
+
setupRootsHandler() {
|
|
1319
|
+
if (!this.client) return;
|
|
1320
|
+
this.client.setRequestHandler(
|
|
1321
|
+
import_types.ListRootsRequestSchema,
|
|
1322
|
+
async (_request, _extra) => {
|
|
1323
|
+
logger.debug(
|
|
1324
|
+
`Server requested roots list, returning ${this.rootsCache.length} root(s)`
|
|
1325
|
+
);
|
|
1326
|
+
return { roots: this.rootsCache };
|
|
1327
|
+
}
|
|
1328
|
+
);
|
|
1329
|
+
}
|
|
1330
|
+
/**
|
|
1331
|
+
* Internal: set up sampling/createMessage request handler.
|
|
1332
|
+
* This is called after the client connects to register the handler for sampling requests.
|
|
1333
|
+
*/
|
|
1334
|
+
setupSamplingHandler() {
|
|
1335
|
+
if (!this.client) return;
|
|
1336
|
+
if (!this.opts.samplingCallback) return;
|
|
1337
|
+
this.client.setRequestHandler(
|
|
1338
|
+
import_types.CreateMessageRequestSchema,
|
|
1339
|
+
async (request, _extra) => {
|
|
1340
|
+
logger.debug("Server requested sampling, forwarding to callback");
|
|
1341
|
+
return await this.opts.samplingCallback(request.params);
|
|
1342
|
+
}
|
|
1343
|
+
);
|
|
1247
1344
|
}
|
|
1248
1345
|
/** Disconnect and release resources. */
|
|
1249
1346
|
async disconnect() {
|
|
@@ -1495,6 +1592,7 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1495
1592
|
clientInfo;
|
|
1496
1593
|
preferSse;
|
|
1497
1594
|
transportType = null;
|
|
1595
|
+
streamableTransport = null;
|
|
1498
1596
|
constructor(baseUrl, opts = {}) {
|
|
1499
1597
|
super(opts);
|
|
1500
1598
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
@@ -1530,7 +1628,7 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1530
1628
|
} catch (err) {
|
|
1531
1629
|
let fallbackReason = "Unknown error";
|
|
1532
1630
|
let is401Error = false;
|
|
1533
|
-
if (err instanceof
|
|
1631
|
+
if (err instanceof import_streamableHttp.StreamableHTTPError) {
|
|
1534
1632
|
is401Error = err.code === 401;
|
|
1535
1633
|
if (err.code === 400 && err.message.includes("Missing session ID")) {
|
|
1536
1634
|
fallbackReason = "Server requires session ID (FastMCP compatibility) - using SSE transport";
|
|
@@ -1586,34 +1684,67 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1586
1684
|
}
|
|
1587
1685
|
async connectWithStreamableHttp(baseUrl) {
|
|
1588
1686
|
try {
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1687
|
+
const streamableTransport = new import_streamableHttp.StreamableHTTPClientTransport(
|
|
1688
|
+
new URL(baseUrl),
|
|
1689
|
+
{
|
|
1690
|
+
authProvider: this.opts.authProvider,
|
|
1691
|
+
// ← Pass OAuth provider to SDK
|
|
1692
|
+
requestInit: {
|
|
1693
|
+
headers: this.headers
|
|
1694
|
+
},
|
|
1695
|
+
// Pass through reconnection options
|
|
1696
|
+
reconnectionOptions: {
|
|
1697
|
+
maxReconnectionDelay: 3e4,
|
|
1698
|
+
initialReconnectionDelay: 1e3,
|
|
1699
|
+
reconnectionDelayGrowFactor: 1.5,
|
|
1700
|
+
maxRetries: 2
|
|
1701
|
+
}
|
|
1702
|
+
// Don't pass sessionId - let the SDK generate it automatically during connect()
|
|
1601
1703
|
}
|
|
1602
|
-
|
|
1603
|
-
let transport =
|
|
1704
|
+
);
|
|
1705
|
+
let transport = streamableTransport;
|
|
1604
1706
|
if (this.opts.wrapTransport) {
|
|
1605
1707
|
const serverId = this.baseUrl;
|
|
1606
|
-
transport = this.opts.wrapTransport(
|
|
1708
|
+
transport = this.opts.wrapTransport(
|
|
1709
|
+
transport,
|
|
1710
|
+
serverId
|
|
1711
|
+
);
|
|
1607
1712
|
}
|
|
1608
|
-
|
|
1713
|
+
const clientOptions = {
|
|
1714
|
+
...this.opts.clientOptions || {},
|
|
1715
|
+
capabilities: {
|
|
1716
|
+
...this.opts.clientOptions?.capabilities || {},
|
|
1717
|
+
roots: { listChanged: true },
|
|
1718
|
+
// Always advertise roots capability
|
|
1719
|
+
// Add sampling capability if callback is provided
|
|
1720
|
+
...this.opts.samplingCallback ? { sampling: {} } : {}
|
|
1721
|
+
}
|
|
1722
|
+
};
|
|
1723
|
+
logger.debug(
|
|
1724
|
+
`Creating Client with capabilities:`,
|
|
1725
|
+
JSON.stringify(clientOptions.capabilities, null, 2)
|
|
1726
|
+
);
|
|
1727
|
+
this.client = new import_client.Client(this.clientInfo, clientOptions);
|
|
1728
|
+
this.setupRootsHandler();
|
|
1729
|
+
logger.debug("Roots handler registered before connect");
|
|
1609
1730
|
try {
|
|
1610
|
-
await this.client.connect(transport
|
|
1731
|
+
await this.client.connect(transport, {
|
|
1732
|
+
timeout: Math.min(this.timeout, 3e3)
|
|
1733
|
+
});
|
|
1734
|
+
const sessionId = streamableTransport.sessionId;
|
|
1735
|
+
if (sessionId) {
|
|
1736
|
+
logger.debug(`Session ID obtained: ${sessionId}`);
|
|
1737
|
+
} else {
|
|
1738
|
+
logger.warn(
|
|
1739
|
+
"Session ID not available after connect - this may cause issues with SSE stream"
|
|
1740
|
+
);
|
|
1741
|
+
}
|
|
1611
1742
|
} catch (connectErr) {
|
|
1612
1743
|
if (connectErr instanceof Error) {
|
|
1613
1744
|
const errMsg = connectErr.message || connectErr.toString();
|
|
1614
|
-
if (errMsg.includes("Missing session ID") || errMsg.includes("Bad Request: Missing session ID")) {
|
|
1745
|
+
if (errMsg.includes("Missing session ID") || errMsg.includes("Bad Request: Missing session ID") || errMsg.includes("Mcp-Session-Id header is required")) {
|
|
1615
1746
|
const wrappedError = new Error(
|
|
1616
|
-
`
|
|
1747
|
+
`Session ID error: ${errMsg}. The SDK should automatically extract session ID from initialize response.`
|
|
1617
1748
|
);
|
|
1618
1749
|
wrappedError.cause = connectErr;
|
|
1619
1750
|
throw wrappedError;
|
|
@@ -1621,8 +1752,24 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1621
1752
|
}
|
|
1622
1753
|
throw connectErr;
|
|
1623
1754
|
}
|
|
1755
|
+
this.streamableTransport = streamableTransport;
|
|
1756
|
+
this.connectionManager = {
|
|
1757
|
+
stop: /* @__PURE__ */ __name(async () => {
|
|
1758
|
+
if (this.streamableTransport) {
|
|
1759
|
+
try {
|
|
1760
|
+
await this.streamableTransport.close();
|
|
1761
|
+
} catch (e) {
|
|
1762
|
+
logger.warn(`Error closing Streamable HTTP transport: ${e}`);
|
|
1763
|
+
} finally {
|
|
1764
|
+
this.streamableTransport = null;
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
}, "stop")
|
|
1768
|
+
};
|
|
1624
1769
|
this.connected = true;
|
|
1625
1770
|
this.transportType = "streamable-http";
|
|
1771
|
+
this.setupNotificationHandler();
|
|
1772
|
+
this.setupSamplingHandler();
|
|
1626
1773
|
logger.debug(
|
|
1627
1774
|
`Successfully connected to MCP implementation via streamable HTTP: ${baseUrl}`
|
|
1628
1775
|
);
|
|
@@ -1643,10 +1790,28 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1643
1790
|
const serverId = this.baseUrl;
|
|
1644
1791
|
transport = this.opts.wrapTransport(transport, serverId);
|
|
1645
1792
|
}
|
|
1646
|
-
|
|
1793
|
+
const clientOptions = {
|
|
1794
|
+
...this.opts.clientOptions || {},
|
|
1795
|
+
capabilities: {
|
|
1796
|
+
...this.opts.clientOptions?.capabilities || {},
|
|
1797
|
+
roots: { listChanged: true },
|
|
1798
|
+
// Always advertise roots capability
|
|
1799
|
+
// Add sampling capability if callback is provided
|
|
1800
|
+
...this.opts.samplingCallback ? { sampling: {} } : {}
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1803
|
+
logger.debug(
|
|
1804
|
+
`Creating Client with capabilities (SSE):`,
|
|
1805
|
+
JSON.stringify(clientOptions.capabilities, null, 2)
|
|
1806
|
+
);
|
|
1807
|
+
this.client = new import_client.Client(this.clientInfo, clientOptions);
|
|
1808
|
+
this.setupRootsHandler();
|
|
1809
|
+
logger.debug("Roots handler registered before connect (SSE)");
|
|
1647
1810
|
await this.client.connect(transport);
|
|
1648
1811
|
this.connected = true;
|
|
1649
1812
|
this.transportType = "sse";
|
|
1813
|
+
this.setupNotificationHandler();
|
|
1814
|
+
this.setupSamplingHandler();
|
|
1650
1815
|
logger.debug(
|
|
1651
1816
|
`Successfully connected to MCP implementation via HTTP/SSE: ${baseUrl}`
|
|
1652
1817
|
);
|
|
@@ -1822,6 +1987,9 @@ var WebSocketConnector = class extends BaseConnector {
|
|
|
1822
1987
|
this.pending.delete(id);
|
|
1823
1988
|
if ("result" in data) resolve(data.result);
|
|
1824
1989
|
else if ("error" in data) reject(data.error);
|
|
1990
|
+
} else if (data.method && !data.id) {
|
|
1991
|
+
logger.debug("Received notification", data.method, data.params);
|
|
1992
|
+
this.handleNotification(data);
|
|
1825
1993
|
} else {
|
|
1826
1994
|
logger.debug("Received unsolicited message", data);
|
|
1827
1995
|
}
|
|
@@ -1852,6 +2020,49 @@ var WebSocketConnector = class extends BaseConnector {
|
|
|
1852
2020
|
for (const { reject } of this.pending.values()) reject(err);
|
|
1853
2021
|
this.pending.clear();
|
|
1854
2022
|
}
|
|
2023
|
+
async handleNotification(data) {
|
|
2024
|
+
switch (data.method) {
|
|
2025
|
+
case "notifications/tools/list_changed":
|
|
2026
|
+
await this.refreshToolsCache();
|
|
2027
|
+
break;
|
|
2028
|
+
case "notifications/resources/list_changed":
|
|
2029
|
+
await this.onResourcesListChanged();
|
|
2030
|
+
break;
|
|
2031
|
+
case "notifications/prompts/list_changed":
|
|
2032
|
+
await this.onPromptsListChanged();
|
|
2033
|
+
break;
|
|
2034
|
+
default:
|
|
2035
|
+
break;
|
|
2036
|
+
}
|
|
2037
|
+
for (const handler of this.notificationHandlers) {
|
|
2038
|
+
try {
|
|
2039
|
+
await handler({
|
|
2040
|
+
method: data.method,
|
|
2041
|
+
params: data.params
|
|
2042
|
+
});
|
|
2043
|
+
} catch (err) {
|
|
2044
|
+
logger.error("Error in notification handler:", err);
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
/**
|
|
2049
|
+
* Auto-refresh tools cache when server sends tools/list_changed notification
|
|
2050
|
+
* Override to use WebSocket-specific listTools method
|
|
2051
|
+
*/
|
|
2052
|
+
async refreshToolsCache() {
|
|
2053
|
+
try {
|
|
2054
|
+
logger.debug(
|
|
2055
|
+
"[Auto] Refreshing tools cache due to list_changed notification"
|
|
2056
|
+
);
|
|
2057
|
+
const tools = await this.listTools();
|
|
2058
|
+
this.toolsCache = tools.map((t) => t);
|
|
2059
|
+
logger.debug(
|
|
2060
|
+
`[Auto] Refreshed tools cache: ${this.toolsCache.length} tools`
|
|
2061
|
+
);
|
|
2062
|
+
} catch (err) {
|
|
2063
|
+
logger.warn("[Auto] Failed to refresh tools cache:", err);
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
1855
2066
|
async initialize() {
|
|
1856
2067
|
logger.debug("Initializing MCP session over WebSocket");
|
|
1857
2068
|
const result = await this.sendRequest("initialize");
|
|
@@ -1931,6 +2142,51 @@ var MCPSession = class {
|
|
|
1931
2142
|
get isConnected() {
|
|
1932
2143
|
return this.connector && this.connector.isClientConnected;
|
|
1933
2144
|
}
|
|
2145
|
+
/**
|
|
2146
|
+
* Register an event handler for session events
|
|
2147
|
+
*
|
|
2148
|
+
* @param event - The event type to listen for
|
|
2149
|
+
* @param handler - The handler function to call when the event occurs
|
|
2150
|
+
*
|
|
2151
|
+
* @example
|
|
2152
|
+
* ```typescript
|
|
2153
|
+
* session.on("notification", async (notification) => {
|
|
2154
|
+
* console.log(`Received: ${notification.method}`, notification.params);
|
|
2155
|
+
*
|
|
2156
|
+
* if (notification.method === "notifications/tools/list_changed") {
|
|
2157
|
+
* // Refresh tools list
|
|
2158
|
+
* }
|
|
2159
|
+
* });
|
|
2160
|
+
* ```
|
|
2161
|
+
*/
|
|
2162
|
+
on(event, handler) {
|
|
2163
|
+
if (event === "notification") {
|
|
2164
|
+
this.connector.onNotification(handler);
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
/**
|
|
2168
|
+
* Set roots and notify the server.
|
|
2169
|
+
* Roots represent directories or files that the client has access to.
|
|
2170
|
+
*
|
|
2171
|
+
* @param roots - Array of Root objects with `uri` (must start with "file://") and optional `name`
|
|
2172
|
+
*
|
|
2173
|
+
* @example
|
|
2174
|
+
* ```typescript
|
|
2175
|
+
* await session.setRoots([
|
|
2176
|
+
* { uri: "file:///home/user/project", name: "My Project" },
|
|
2177
|
+
* { uri: "file:///home/user/data" }
|
|
2178
|
+
* ]);
|
|
2179
|
+
* ```
|
|
2180
|
+
*/
|
|
2181
|
+
async setRoots(roots) {
|
|
2182
|
+
return this.connector.setRoots(roots);
|
|
2183
|
+
}
|
|
2184
|
+
/**
|
|
2185
|
+
* Get the current roots.
|
|
2186
|
+
*/
|
|
2187
|
+
getRoots() {
|
|
2188
|
+
return this.connector.getRoots();
|
|
2189
|
+
}
|
|
1934
2190
|
};
|
|
1935
2191
|
|
|
1936
2192
|
// src/client/base.ts
|
|
@@ -2066,7 +2322,16 @@ var BrowserMCPClient = class _BrowserMCPClient extends BaseMCPClient {
|
|
|
2066
2322
|
* Supports HTTP and WebSocket connectors only
|
|
2067
2323
|
*/
|
|
2068
2324
|
createConnectorFromConfig(serverConfig) {
|
|
2069
|
-
const {
|
|
2325
|
+
const {
|
|
2326
|
+
url,
|
|
2327
|
+
transport,
|
|
2328
|
+
headers,
|
|
2329
|
+
authToken,
|
|
2330
|
+
authProvider,
|
|
2331
|
+
wrapTransport,
|
|
2332
|
+
clientOptions,
|
|
2333
|
+
samplingCallback
|
|
2334
|
+
} = serverConfig;
|
|
2070
2335
|
if (!url) {
|
|
2071
2336
|
throw new Error("Server URL is required");
|
|
2072
2337
|
}
|
|
@@ -2075,9 +2340,23 @@ var BrowserMCPClient = class _BrowserMCPClient extends BaseMCPClient {
|
|
|
2075
2340
|
authToken,
|
|
2076
2341
|
authProvider,
|
|
2077
2342
|
// ← Pass OAuth provider to connector
|
|
2078
|
-
wrapTransport
|
|
2343
|
+
wrapTransport,
|
|
2079
2344
|
// ← Pass transport wrapper if provided
|
|
2345
|
+
clientOptions,
|
|
2346
|
+
// ← Pass client options (capabilities, etc.) to connector
|
|
2347
|
+
samplingCallback
|
|
2348
|
+
// ← Pass sampling callback to connector
|
|
2080
2349
|
};
|
|
2350
|
+
if (clientOptions) {
|
|
2351
|
+
console.log(
|
|
2352
|
+
"[BrowserMCPClient] Passing clientOptions to connector:",
|
|
2353
|
+
JSON.stringify(clientOptions, null, 2)
|
|
2354
|
+
);
|
|
2355
|
+
} else {
|
|
2356
|
+
console.warn(
|
|
2357
|
+
"[BrowserMCPClient] No clientOptions provided to connector!"
|
|
2358
|
+
);
|
|
2359
|
+
}
|
|
2081
2360
|
if (transport === "websocket" || url.startsWith("ws://") || url.startsWith("wss://")) {
|
|
2082
2361
|
return new WebSocketConnector(url, connectorOptions);
|
|
2083
2362
|
} else if (transport === "http" || url.startsWith("http://") || url.startsWith("https://")) {
|
package/dist/src/browser.d.ts
CHANGED
|
@@ -6,9 +6,11 @@ export { MCPAgent } from "./agents/mcp_agent.js";
|
|
|
6
6
|
export { RemoteAgent } from "./agents/remote.js";
|
|
7
7
|
export { BaseAdapter, LangChainAdapter } from "./adapters/index.js";
|
|
8
8
|
export { BaseConnector } from "./connectors/base.js";
|
|
9
|
+
export type { NotificationHandler } from "./connectors/base.js";
|
|
9
10
|
export { HttpConnector } from "./connectors/http.js";
|
|
10
11
|
export { WebSocketConnector } from "./connectors/websocket.js";
|
|
11
12
|
export { MCPSession } from "./session.js";
|
|
13
|
+
export type { Notification, Root } from "./session.js";
|
|
12
14
|
export { BrowserOAuthClientProvider } from "./auth/browser-provider.js";
|
|
13
15
|
export { onMcpAuthorization } from "./auth/callback.js";
|
|
14
16
|
export type { StoredState } from "./auth/types.js";
|