@mcp-use/client 2.3.1-canary.0 → 2.3.1-canary.2
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/code-mode/connector.d.ts +1 -2
- package/dist/code-mode/connector.d.ts.map +1 -1
- package/dist/index-browser.js +83 -13
- package/dist/index-browser.js.map +1 -1
- package/dist/index.js +85 -25
- package/dist/index.js.map +1 -1
- package/dist/react/index.js +134 -17
- package/dist/react/index.js.map +1 -1
- package/dist/react/useMcp-helpers.d.ts +21 -0
- package/dist/react/useMcp-helpers.d.ts.map +1 -1
- package/dist/react/useMcp.d.ts.map +1 -1
- package/dist/transport/base.d.ts +16 -1
- package/dist/transport/base.d.ts.map +1 -1
- package/dist/transport/http.d.ts +1 -1
- package/dist/transport/http.d.ts.map +1 -1
- package/dist/transport/stdio.d.ts +1 -1
- package/dist/transport/stdio.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -645,6 +645,9 @@ var BaseConnector = class {
|
|
|
645
645
|
serverInfoCache = null;
|
|
646
646
|
authorizationCache;
|
|
647
647
|
connected = false;
|
|
648
|
+
connectPromise = null;
|
|
649
|
+
disconnectPromise = null;
|
|
650
|
+
disconnectGeneration = 0;
|
|
648
651
|
opts;
|
|
649
652
|
notificationHandlers = [];
|
|
650
653
|
rootsCache = [];
|
|
@@ -907,6 +910,54 @@ var BaseConnector = class {
|
|
|
907
910
|
"setupElicitationHandler: Elicitation handler registered successfully"
|
|
908
911
|
);
|
|
909
912
|
}
|
|
913
|
+
/**
|
|
914
|
+
* Establishes the transport connection and creates the SDK client.
|
|
915
|
+
*
|
|
916
|
+
* Coalesces concurrent connection attempts, synchronizes with ongoing
|
|
917
|
+
* disconnections, and guarantees that orphaned processes or transports
|
|
918
|
+
* are not leaked on failure or rapid disconnect.
|
|
919
|
+
*
|
|
920
|
+
* @returns A promise that resolves when the connector is connected.
|
|
921
|
+
*/
|
|
922
|
+
async connect() {
|
|
923
|
+
const generation = this.disconnectGeneration;
|
|
924
|
+
while (this.disconnectPromise) {
|
|
925
|
+
await this.disconnectPromise;
|
|
926
|
+
}
|
|
927
|
+
if (generation !== this.disconnectGeneration) {
|
|
928
|
+
throw new Error("Connection cancelled by disconnect");
|
|
929
|
+
}
|
|
930
|
+
if (this.connected) {
|
|
931
|
+
logger.debug("Already connected to MCP implementation");
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
if (this.connectPromise) {
|
|
935
|
+
return this.connectPromise;
|
|
936
|
+
}
|
|
937
|
+
const currentConnect = (async () => {
|
|
938
|
+
try {
|
|
939
|
+
await this.establishTransport();
|
|
940
|
+
if (generation !== this.disconnectGeneration) {
|
|
941
|
+
throw new Error("Connection cancelled by disconnect");
|
|
942
|
+
}
|
|
943
|
+
this.connected = true;
|
|
944
|
+
} catch (err) {
|
|
945
|
+
this.connected = false;
|
|
946
|
+
await this.cleanupResources();
|
|
947
|
+
throw err;
|
|
948
|
+
} finally {
|
|
949
|
+
this.connectPromise = null;
|
|
950
|
+
}
|
|
951
|
+
})();
|
|
952
|
+
this.connectPromise = currentConnect;
|
|
953
|
+
return this.connectPromise;
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Subclasses override this method to perform transport-specific connection logic.
|
|
957
|
+
* Default implementation is a no-op for backwards compatibility.
|
|
958
|
+
*/
|
|
959
|
+
async establishTransport() {
|
|
960
|
+
}
|
|
910
961
|
/**
|
|
911
962
|
* Run one logical MCP operation. HTTP connectors override this host seam to
|
|
912
963
|
* finish an SDK-started interactive OAuth flow and retry exactly once.
|
|
@@ -932,17 +983,42 @@ var BaseConnector = class {
|
|
|
932
983
|
/**
|
|
933
984
|
* Disconnects the SDK client and releases transport resources.
|
|
934
985
|
*
|
|
986
|
+
* Coalesces concurrent calls and coordinates with in-flight connections
|
|
987
|
+
* to ensure no child processes or transports are orphaned.
|
|
988
|
+
*
|
|
935
989
|
* @returns A promise that resolves after cleanup completes.
|
|
936
990
|
*/
|
|
937
991
|
async disconnect() {
|
|
938
|
-
|
|
992
|
+
this.disconnectGeneration++;
|
|
993
|
+
if (this.disconnectPromise) {
|
|
994
|
+
return this.disconnectPromise;
|
|
995
|
+
}
|
|
996
|
+
if (!this.connected && !this.connectPromise) {
|
|
939
997
|
logger.debug("Not connected to MCP implementation");
|
|
940
998
|
return;
|
|
941
999
|
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1000
|
+
const currentDisconnect = (async () => {
|
|
1001
|
+
let connectFailed = false;
|
|
1002
|
+
try {
|
|
1003
|
+
if (this.connectPromise) {
|
|
1004
|
+
try {
|
|
1005
|
+
await this.connectPromise;
|
|
1006
|
+
} catch {
|
|
1007
|
+
connectFailed = true;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
if (!connectFailed) {
|
|
1011
|
+
logger.debug("Disconnecting from MCP implementation");
|
|
1012
|
+
await this.cleanupResources();
|
|
1013
|
+
}
|
|
1014
|
+
this.connected = false;
|
|
1015
|
+
logger.debug("Disconnected from MCP implementation");
|
|
1016
|
+
} finally {
|
|
1017
|
+
this.disconnectPromise = null;
|
|
1018
|
+
}
|
|
1019
|
+
})();
|
|
1020
|
+
this.disconnectPromise = currentDisconnect;
|
|
1021
|
+
return this.disconnectPromise;
|
|
946
1022
|
}
|
|
947
1023
|
/** Whether an SDK client currently exists for this connector. */
|
|
948
1024
|
get isClientConnected() {
|
|
@@ -1639,11 +1715,7 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1639
1715
|
* @returns A promise that resolves after protocol negotiation completes.
|
|
1640
1716
|
* @throws An error with `code: 401` when authentication is required.
|
|
1641
1717
|
*/
|
|
1642
|
-
async
|
|
1643
|
-
if (this.connected) {
|
|
1644
|
-
logger.debug("Already connected to MCP implementation");
|
|
1645
|
-
return;
|
|
1646
|
-
}
|
|
1718
|
+
async establishTransport() {
|
|
1647
1719
|
const baseUrl = this.baseUrl;
|
|
1648
1720
|
logger.debug(`Connecting to MCP implementation via HTTP: ${baseUrl}`);
|
|
1649
1721
|
const oauthProvider = this.oauthProvider;
|
|
@@ -1662,7 +1734,6 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1662
1734
|
} catch (err) {
|
|
1663
1735
|
logger.debug("Streamable HTTP connect failed", err);
|
|
1664
1736
|
const { fallbackReason, is401Error, httpStatusCode } = this.classifyStreamableHttpFailure(err);
|
|
1665
|
-
await this.cleanupResources();
|
|
1666
1737
|
if (is401Error) {
|
|
1667
1738
|
logger.info("Authentication required");
|
|
1668
1739
|
const authError = new Error("Authentication required");
|
|
@@ -1836,7 +1907,6 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1836
1907
|
}
|
|
1837
1908
|
}
|
|
1838
1909
|
};
|
|
1839
|
-
this.connected = true;
|
|
1840
1910
|
this.transportType = "streamable-http";
|
|
1841
1911
|
logger.debug(
|
|
1842
1912
|
`Successfully connected to MCP implementation via streamable HTTP: ${baseUrl}`
|
|
@@ -1905,7 +1975,7 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1905
1975
|
};
|
|
1906
1976
|
|
|
1907
1977
|
// src/utils/version.ts
|
|
1908
|
-
var VERSION = "2.3.1-canary.
|
|
1978
|
+
var VERSION = "2.3.1-canary.2";
|
|
1909
1979
|
function getPackageVersion() {
|
|
1910
1980
|
return VERSION;
|
|
1911
1981
|
}
|
|
@@ -4725,6 +4795,26 @@ function assert(condition, message) {
|
|
|
4725
4795
|
throw new Error(message);
|
|
4726
4796
|
}
|
|
4727
4797
|
}
|
|
4798
|
+
function serializeClientIcons(icons) {
|
|
4799
|
+
if (icons === void 0) return "null";
|
|
4800
|
+
if (icons.length === 0) return "[]";
|
|
4801
|
+
return JSON.stringify(
|
|
4802
|
+
icons.map((icon) => [
|
|
4803
|
+
icon.src,
|
|
4804
|
+
icon.mimeType === void 0 ? null : icon.mimeType,
|
|
4805
|
+
icon.sizes === void 0 ? null : [...icon.sizes].sort()
|
|
4806
|
+
])
|
|
4807
|
+
);
|
|
4808
|
+
}
|
|
4809
|
+
function serializeProxyHeaders(headers, customHeaders) {
|
|
4810
|
+
if (headers === void 0 && customHeaders === void 0) return "";
|
|
4811
|
+
const serializeEntries = (record) => {
|
|
4812
|
+
if (record === void 0) return "null";
|
|
4813
|
+
const keys = Object.keys(record).sort();
|
|
4814
|
+
return JSON.stringify(keys.map((k) => [k, record[k]]));
|
|
4815
|
+
};
|
|
4816
|
+
return `${serializeEntries(headers)}|${serializeEntries(customHeaders)}`;
|
|
4817
|
+
}
|
|
4728
4818
|
async function loadServerIcon(params) {
|
|
4729
4819
|
try {
|
|
4730
4820
|
const iconUrl = params.serverInfo.icons?.[0]?.src;
|
|
@@ -5171,7 +5261,7 @@ function useMcp(options) {
|
|
|
5171
5261
|
storageKeyPrefix = "mcp:auth",
|
|
5172
5262
|
authProvider: providedAuthProvider,
|
|
5173
5263
|
headers: headersOption,
|
|
5174
|
-
proxyConfig,
|
|
5264
|
+
proxyConfig: rawProxyConfig,
|
|
5175
5265
|
oauthProxyUrl: oauthProxyUrlOption,
|
|
5176
5266
|
connectionMode,
|
|
5177
5267
|
autoProxyFallback = false,
|
|
@@ -5197,6 +5287,34 @@ function useMcp(options) {
|
|
|
5197
5287
|
onElicitation: onElicitationOption,
|
|
5198
5288
|
oauth: oauthOptions
|
|
5199
5289
|
} = options;
|
|
5290
|
+
const rawClientInfo = options.clientInfo;
|
|
5291
|
+
const clientInfoName = rawClientInfo?.name;
|
|
5292
|
+
const clientInfoTitle = rawClientInfo?.title;
|
|
5293
|
+
const clientInfoVersion = rawClientInfo?.version;
|
|
5294
|
+
const clientInfoDescription = rawClientInfo?.description;
|
|
5295
|
+
const clientInfoWebsiteUrl = rawClientInfo?.websiteUrl;
|
|
5296
|
+
const serializedClientIcons = serializeClientIcons(rawClientInfo?.icons);
|
|
5297
|
+
const clientInfo = useMemo(() => {
|
|
5298
|
+
if (!rawClientInfo) return void 0;
|
|
5299
|
+
return { ...rawClientInfo };
|
|
5300
|
+
}, [
|
|
5301
|
+
clientInfoName,
|
|
5302
|
+
clientInfoTitle,
|
|
5303
|
+
clientInfoVersion,
|
|
5304
|
+
clientInfoDescription,
|
|
5305
|
+
clientInfoWebsiteUrl,
|
|
5306
|
+
serializedClientIcons
|
|
5307
|
+
]);
|
|
5308
|
+
const rawProxyAddress = rawProxyConfig?.proxyAddress;
|
|
5309
|
+
const serializedProxyHeaders = serializeProxyHeaders(
|
|
5310
|
+
rawProxyConfig?.headers,
|
|
5311
|
+
rawProxyConfig?.customHeaders
|
|
5312
|
+
);
|
|
5313
|
+
const proxyConfig = useMemo(() => {
|
|
5314
|
+
if (!rawProxyConfig) return void 0;
|
|
5315
|
+
return { ...rawProxyConfig };
|
|
5316
|
+
}, [rawProxyAddress, serializedProxyHeaders]);
|
|
5317
|
+
const headers = headersOption ?? {};
|
|
5200
5318
|
const transportType = "http";
|
|
5201
5319
|
const requestedProxyAddress = proxyConfig?.proxyAddress;
|
|
5202
5320
|
const oauthClientId = oauthOptions?.clientId?.trim() || void 0;
|
|
@@ -5214,7 +5332,6 @@ function useMcp(options) {
|
|
|
5214
5332
|
}
|
|
5215
5333
|
return inst;
|
|
5216
5334
|
}, [url, logLevelOption]);
|
|
5217
|
-
const headers = headersOption ?? {};
|
|
5218
5335
|
const effectiveClientOptions = useMemo(
|
|
5219
5336
|
() => resolveClientOptions(clientOptions),
|
|
5220
5337
|
[clientOptions]
|
|
@@ -5237,8 +5354,8 @@ function useMcp(options) {
|
|
|
5237
5354
|
[]
|
|
5238
5355
|
);
|
|
5239
5356
|
const mergedClientInfo = useMemo(
|
|
5240
|
-
() =>
|
|
5241
|
-
[
|
|
5357
|
+
() => clientInfo ? { ...defaultClientInfo, ...clientInfo } : defaultClientInfo,
|
|
5358
|
+
[clientInfo, defaultClientInfo]
|
|
5242
5359
|
);
|
|
5243
5360
|
const derivedOAuthClientConfig = useMemo(
|
|
5244
5361
|
() => deriveOAuthClientConfigFromClientInfo(mergedClientInfo),
|