mcp-use 1.2.5-dev.5 → 1.3.0-canary.1
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-73SH52J2.js → chunk-6EHM3S3M.js} +191 -8
- package/dist/{chunk-37MPZ3D6.js → chunk-TIUSJAAE.js} +12 -0
- package/dist/{chunk-X2HJQBDI.js → chunk-VNEGDXZO.js} +26 -1
- package/dist/index.cjs +226 -6
- package/dist/index.js +3 -3
- package/dist/src/agents/index.cjs +189 -6
- package/dist/src/agents/index.js +1 -1
- package/dist/src/agents/mcp_agent.d.ts +90 -2
- package/dist/src/agents/mcp_agent.d.ts.map +1 -1
- package/dist/src/browser.cjs +201 -6
- package/dist/src/browser.js +2 -2
- package/dist/src/connectors/base.d.ts +11 -0
- package/dist/src/connectors/base.d.ts.map +1 -1
- package/dist/src/react/index.cjs +37 -0
- package/dist/src/react/index.js +2 -2
- package/dist/src/react/types.d.ts +7 -0
- package/dist/src/react/types.d.ts.map +1 -1
- package/dist/src/react/useMcp.d.ts.map +1 -1
- package/dist/src/server/index.cjs +108 -58
- package/dist/src/server/index.js +108 -58
- package/dist/src/server/mcp-server.d.ts +5 -0
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/package.json +41 -44
|
@@ -1319,11 +1319,11 @@ Raw error: ${result}`
|
|
|
1319
1319
|
|
|
1320
1320
|
// src/agents/mcp_agent.ts
|
|
1321
1321
|
import {
|
|
1322
|
+
AIMessage,
|
|
1322
1323
|
createAgent,
|
|
1324
|
+
HumanMessage,
|
|
1323
1325
|
modelCallLimitMiddleware,
|
|
1324
1326
|
SystemMessage as SystemMessage2,
|
|
1325
|
-
AIMessage,
|
|
1326
|
-
HumanMessage,
|
|
1327
1327
|
ToolMessage
|
|
1328
1328
|
} from "langchain";
|
|
1329
1329
|
import { zodToJsonSchema as zodToJsonSchema2 } from "zod-to-json-schema";
|
|
@@ -1880,6 +1880,185 @@ var MCPAgent = class {
|
|
|
1880
1880
|
return String(value);
|
|
1881
1881
|
}
|
|
1882
1882
|
}
|
|
1883
|
+
/**
|
|
1884
|
+
* Check if a message is AI/assistant-like regardless of whether it's a class instance.
|
|
1885
|
+
* Handles version mismatches, serialization boundaries, and different message formats.
|
|
1886
|
+
*
|
|
1887
|
+
* This method solves the issue where messages from LangChain agents may be plain JavaScript
|
|
1888
|
+
* objects (e.g., `{ type: 'ai', content: '...' }`) instead of AIMessage instances due to
|
|
1889
|
+
* serialization/deserialization across module boundaries or version mismatches.
|
|
1890
|
+
*
|
|
1891
|
+
* @example
|
|
1892
|
+
* // Real AIMessage instance (standard case)
|
|
1893
|
+
* _isAIMessageLike(new AIMessage("hello")) // => true
|
|
1894
|
+
*
|
|
1895
|
+
* @example
|
|
1896
|
+
* // Plain object after serialization (fixes issue #446)
|
|
1897
|
+
* _isAIMessageLike({ type: "ai", content: "hello" }) // => true
|
|
1898
|
+
*
|
|
1899
|
+
* @example
|
|
1900
|
+
* // OpenAI-style format with role
|
|
1901
|
+
* _isAIMessageLike({ role: "assistant", content: "hello" }) // => true
|
|
1902
|
+
*
|
|
1903
|
+
* @example
|
|
1904
|
+
* // Object with getType() method
|
|
1905
|
+
* _isAIMessageLike({ getType: () => "ai", content: "hello" }) // => true
|
|
1906
|
+
*
|
|
1907
|
+
* @param message - The message object to check
|
|
1908
|
+
* @returns true if the message represents an AI/assistant message
|
|
1909
|
+
*/
|
|
1910
|
+
_isAIMessageLike(message) {
|
|
1911
|
+
if (message instanceof AIMessage) {
|
|
1912
|
+
return true;
|
|
1913
|
+
}
|
|
1914
|
+
if (typeof message !== "object" || message === null) {
|
|
1915
|
+
return false;
|
|
1916
|
+
}
|
|
1917
|
+
const msg = message;
|
|
1918
|
+
if (typeof msg.getType === "function") {
|
|
1919
|
+
try {
|
|
1920
|
+
const type = msg.getType();
|
|
1921
|
+
if (type === "ai" || type === "assistant") {
|
|
1922
|
+
return true;
|
|
1923
|
+
}
|
|
1924
|
+
} catch (error) {
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
if (typeof msg._getType === "function") {
|
|
1928
|
+
try {
|
|
1929
|
+
const type = msg._getType();
|
|
1930
|
+
if (type === "ai" || type === "assistant") {
|
|
1931
|
+
return true;
|
|
1932
|
+
}
|
|
1933
|
+
} catch (error) {
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
if ("type" in msg) {
|
|
1937
|
+
return msg.type === "ai" || msg.type === "assistant";
|
|
1938
|
+
}
|
|
1939
|
+
if ("role" in msg) {
|
|
1940
|
+
return msg.role === "ai" || msg.role === "assistant";
|
|
1941
|
+
}
|
|
1942
|
+
return false;
|
|
1943
|
+
}
|
|
1944
|
+
/**
|
|
1945
|
+
* Check if a message has tool calls, handling both class instances and plain objects.
|
|
1946
|
+
* Safely checks for tool_calls array presence.
|
|
1947
|
+
*
|
|
1948
|
+
* @example
|
|
1949
|
+
* // AIMessage with tool calls
|
|
1950
|
+
* const msg = new AIMessage({ content: "", tool_calls: [{ name: "add", args: {} }] });
|
|
1951
|
+
* _messageHasToolCalls(msg) // => true
|
|
1952
|
+
*
|
|
1953
|
+
* @example
|
|
1954
|
+
* // Plain object with tool calls
|
|
1955
|
+
* _messageHasToolCalls({ type: "ai", tool_calls: [{ name: "add" }] }) // => true
|
|
1956
|
+
*
|
|
1957
|
+
* @example
|
|
1958
|
+
* // Message without tool calls
|
|
1959
|
+
* _messageHasToolCalls({ type: "ai", content: "hello" }) // => false
|
|
1960
|
+
*
|
|
1961
|
+
* @param message - The message object to check
|
|
1962
|
+
* @returns true if the message has non-empty tool_calls array
|
|
1963
|
+
*/
|
|
1964
|
+
_messageHasToolCalls(message) {
|
|
1965
|
+
if (typeof message === "object" && message !== null && "tool_calls" in message && Array.isArray(message.tool_calls)) {
|
|
1966
|
+
return message.tool_calls.length > 0;
|
|
1967
|
+
}
|
|
1968
|
+
return false;
|
|
1969
|
+
}
|
|
1970
|
+
/**
|
|
1971
|
+
* Check if a message is a HumanMessage-like object.
|
|
1972
|
+
* Handles both class instances and plain objects from serialization.
|
|
1973
|
+
*
|
|
1974
|
+
* @example
|
|
1975
|
+
* _isHumanMessageLike(new HumanMessage("hello")) // => true
|
|
1976
|
+
* _isHumanMessageLike({ type: "human", content: "hello" }) // => true
|
|
1977
|
+
*
|
|
1978
|
+
* @param message - The message object to check
|
|
1979
|
+
* @returns true if the message represents a human message
|
|
1980
|
+
*/
|
|
1981
|
+
_isHumanMessageLike(message) {
|
|
1982
|
+
if (message instanceof HumanMessage) {
|
|
1983
|
+
return true;
|
|
1984
|
+
}
|
|
1985
|
+
if (typeof message !== "object" || message === null) {
|
|
1986
|
+
return false;
|
|
1987
|
+
}
|
|
1988
|
+
const msg = message;
|
|
1989
|
+
if (typeof msg.getType === "function") {
|
|
1990
|
+
try {
|
|
1991
|
+
const type = msg.getType();
|
|
1992
|
+
if (type === "human" || type === "user") {
|
|
1993
|
+
return true;
|
|
1994
|
+
}
|
|
1995
|
+
} catch (error) {
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
if ("type" in msg && (msg.type === "human" || msg.type === "user")) {
|
|
1999
|
+
return true;
|
|
2000
|
+
}
|
|
2001
|
+
if ("role" in msg && (msg.role === "human" || msg.role === "user")) {
|
|
2002
|
+
return true;
|
|
2003
|
+
}
|
|
2004
|
+
return false;
|
|
2005
|
+
}
|
|
2006
|
+
/**
|
|
2007
|
+
* Check if a message is a ToolMessage-like object.
|
|
2008
|
+
* Handles both class instances and plain objects from serialization.
|
|
2009
|
+
*
|
|
2010
|
+
* @example
|
|
2011
|
+
* _isToolMessageLike(new ToolMessage({ content: "result", tool_call_id: "123" })) // => true
|
|
2012
|
+
* _isToolMessageLike({ type: "tool", content: "result" }) // => true
|
|
2013
|
+
*
|
|
2014
|
+
* @param message - The message object to check
|
|
2015
|
+
* @returns true if the message represents a tool message
|
|
2016
|
+
*/
|
|
2017
|
+
_isToolMessageLike(message) {
|
|
2018
|
+
if (message instanceof ToolMessage) {
|
|
2019
|
+
return true;
|
|
2020
|
+
}
|
|
2021
|
+
if (typeof message !== "object" || message === null) {
|
|
2022
|
+
return false;
|
|
2023
|
+
}
|
|
2024
|
+
const msg = message;
|
|
2025
|
+
if (typeof msg.getType === "function") {
|
|
2026
|
+
try {
|
|
2027
|
+
const type = msg.getType();
|
|
2028
|
+
if (type === "tool") {
|
|
2029
|
+
return true;
|
|
2030
|
+
}
|
|
2031
|
+
} catch (error) {
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
if ("type" in msg && msg.type === "tool") {
|
|
2035
|
+
return true;
|
|
2036
|
+
}
|
|
2037
|
+
return false;
|
|
2038
|
+
}
|
|
2039
|
+
/**
|
|
2040
|
+
* Extract content from a message, handling both AIMessage instances and plain objects.
|
|
2041
|
+
*
|
|
2042
|
+
* @example
|
|
2043
|
+
* // From AIMessage instance
|
|
2044
|
+
* _getMessageContent(new AIMessage("hello")) // => "hello"
|
|
2045
|
+
*
|
|
2046
|
+
* @example
|
|
2047
|
+
* // From plain object
|
|
2048
|
+
* _getMessageContent({ type: "ai", content: "hello" }) // => "hello"
|
|
2049
|
+
*
|
|
2050
|
+
* @param message - The message object to extract content from
|
|
2051
|
+
* @returns The content of the message, or undefined if not present
|
|
2052
|
+
*/
|
|
2053
|
+
_getMessageContent(message) {
|
|
2054
|
+
if (message instanceof AIMessage) {
|
|
2055
|
+
return message.content;
|
|
2056
|
+
}
|
|
2057
|
+
if (message && typeof message === "object" && "content" in message) {
|
|
2058
|
+
return message.content;
|
|
2059
|
+
}
|
|
2060
|
+
return void 0;
|
|
2061
|
+
}
|
|
1883
2062
|
async _consumeAndReturn(generator) {
|
|
1884
2063
|
while (true) {
|
|
1885
2064
|
const { done, value } = await generator.next();
|
|
@@ -1951,7 +2130,7 @@ var MCPAgent = class {
|
|
|
1951
2130
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
1952
2131
|
const langchainHistory = [];
|
|
1953
2132
|
for (const msg of historyToUse) {
|
|
1954
|
-
if (msg
|
|
2133
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg)) {
|
|
1955
2134
|
langchainHistory.push(msg);
|
|
1956
2135
|
}
|
|
1957
2136
|
}
|
|
@@ -2020,7 +2199,7 @@ var MCPAgent = class {
|
|
|
2020
2199
|
};
|
|
2021
2200
|
}
|
|
2022
2201
|
}
|
|
2023
|
-
if (message
|
|
2202
|
+
if (this._isToolMessageLike(message)) {
|
|
2024
2203
|
const observation = message.content;
|
|
2025
2204
|
let observationStr = String(observation);
|
|
2026
2205
|
if (observationStr.length > 100) {
|
|
@@ -2055,8 +2234,10 @@ var MCPAgent = class {
|
|
|
2055
2234
|
}
|
|
2056
2235
|
}
|
|
2057
2236
|
}
|
|
2058
|
-
if (message
|
|
2059
|
-
finalOutput = this._normalizeOutput(
|
|
2237
|
+
if (this._isAIMessageLike(message) && !this._messageHasToolCalls(message)) {
|
|
2238
|
+
finalOutput = this._normalizeOutput(
|
|
2239
|
+
this._getMessageContent(message)
|
|
2240
|
+
);
|
|
2060
2241
|
logger.info("\u2705 Agent finished with output");
|
|
2061
2242
|
}
|
|
2062
2243
|
}
|
|
@@ -2239,10 +2420,12 @@ var MCPAgent = class {
|
|
|
2239
2420
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
2240
2421
|
const langchainHistory = [];
|
|
2241
2422
|
for (const msg of historyToUse) {
|
|
2242
|
-
if (msg
|
|
2423
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg) || this._isToolMessageLike(msg)) {
|
|
2243
2424
|
langchainHistory.push(msg);
|
|
2244
2425
|
} else {
|
|
2245
|
-
logger.info(
|
|
2426
|
+
logger.info(
|
|
2427
|
+
`\u26A0\uFE0F Skipped message of type: ${msg.constructor?.name || typeof msg}`
|
|
2428
|
+
);
|
|
2246
2429
|
}
|
|
2247
2430
|
}
|
|
2248
2431
|
const inputs = [
|
|
@@ -42,6 +42,7 @@ var BaseConnector = class {
|
|
|
42
42
|
connectionManager = null;
|
|
43
43
|
toolsCache = null;
|
|
44
44
|
capabilitiesCache = null;
|
|
45
|
+
serverInfoCache = null;
|
|
45
46
|
connected = false;
|
|
46
47
|
opts;
|
|
47
48
|
constructor(opts = {}) {
|
|
@@ -76,6 +77,8 @@ var BaseConnector = class {
|
|
|
76
77
|
logger.debug("Caching server capabilities & tools");
|
|
77
78
|
const capabilities = this.client.getServerCapabilities();
|
|
78
79
|
this.capabilitiesCache = capabilities;
|
|
80
|
+
const serverInfo = this.client.getServerVersion();
|
|
81
|
+
this.serverInfoCache = serverInfo || null;
|
|
79
82
|
const listToolsRes = await this.client.listTools(
|
|
80
83
|
void 0,
|
|
81
84
|
defaultRequestOptions
|
|
@@ -83,6 +86,7 @@ var BaseConnector = class {
|
|
|
83
86
|
this.toolsCache = listToolsRes.tools ?? [];
|
|
84
87
|
logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
|
|
85
88
|
logger.debug("Server capabilities:", capabilities);
|
|
89
|
+
logger.debug("Server info:", serverInfo);
|
|
86
90
|
return capabilities;
|
|
87
91
|
}
|
|
88
92
|
/** Lazily expose the cached tools list. */
|
|
@@ -92,6 +96,14 @@ var BaseConnector = class {
|
|
|
92
96
|
}
|
|
93
97
|
return this.toolsCache;
|
|
94
98
|
}
|
|
99
|
+
/** Expose cached server capabilities. */
|
|
100
|
+
get serverCapabilities() {
|
|
101
|
+
return this.capabilitiesCache;
|
|
102
|
+
}
|
|
103
|
+
/** Expose cached server info. */
|
|
104
|
+
get serverInfo() {
|
|
105
|
+
return this.serverInfoCache;
|
|
106
|
+
}
|
|
95
107
|
/** Call a tool on the server. */
|
|
96
108
|
async callTool(name, args, options) {
|
|
97
109
|
if (!this.client) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BrowserMCPClient,
|
|
3
3
|
BrowserOAuthClientProvider
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-TIUSJAAE.js";
|
|
5
5
|
import {
|
|
6
6
|
__name
|
|
7
7
|
} from "./chunk-3GQAWCBQ.js";
|
|
@@ -50,6 +50,8 @@ function useMcp(options) {
|
|
|
50
50
|
const [resources, setResources] = useState([]);
|
|
51
51
|
const [resourceTemplates, setResourceTemplates] = useState([]);
|
|
52
52
|
const [prompts, setPrompts] = useState([]);
|
|
53
|
+
const [serverInfo, setServerInfo] = useState();
|
|
54
|
+
const [capabilities, setCapabilities] = useState();
|
|
53
55
|
const [error, setError] = useState(void 0);
|
|
54
56
|
const [log, setLog] = useState([]);
|
|
55
57
|
const [authUrl, setAuthUrl] = useState(void 0);
|
|
@@ -198,6 +200,17 @@ function useMcp(options) {
|
|
|
198
200
|
const session = await clientRef.current.createSession(serverName);
|
|
199
201
|
await session.initialize();
|
|
200
202
|
addLog("info", "\u2705 Successfully connected to MCP server");
|
|
203
|
+
addLog("info", "Server info:", session.connector.serverInfo);
|
|
204
|
+
addLog(
|
|
205
|
+
"info",
|
|
206
|
+
"Server capabilities:",
|
|
207
|
+
session.connector.serverCapabilities
|
|
208
|
+
);
|
|
209
|
+
console.log("[useMcp] Server info:", session.connector.serverInfo);
|
|
210
|
+
console.log(
|
|
211
|
+
"[useMcp] Server capabilities:",
|
|
212
|
+
session.connector.serverCapabilities
|
|
213
|
+
);
|
|
201
214
|
setState("ready");
|
|
202
215
|
successfulTransportRef.current = transportTypeParam;
|
|
203
216
|
setTools(session.connector.tools || []);
|
|
@@ -205,6 +218,16 @@ function useMcp(options) {
|
|
|
205
218
|
setResources(resourcesResult.resources || []);
|
|
206
219
|
const promptsResult = await session.connector.listPrompts();
|
|
207
220
|
setPrompts(promptsResult.prompts || []);
|
|
221
|
+
const serverInfo2 = session.connector.serverInfo;
|
|
222
|
+
const capabilities2 = session.connector.serverCapabilities;
|
|
223
|
+
if (serverInfo2) {
|
|
224
|
+
console.log("[useMcp] Server info:", serverInfo2);
|
|
225
|
+
setServerInfo(serverInfo2);
|
|
226
|
+
}
|
|
227
|
+
if (capabilities2) {
|
|
228
|
+
console.log("[useMcp] Server capabilities:", capabilities2);
|
|
229
|
+
setCapabilities(capabilities2);
|
|
230
|
+
}
|
|
208
231
|
return "success";
|
|
209
232
|
} catch (err) {
|
|
210
233
|
const errorMessage = err?.message || String(err);
|
|
@@ -567,6 +590,8 @@ function useMcp(options) {
|
|
|
567
590
|
resources,
|
|
568
591
|
resourceTemplates,
|
|
569
592
|
prompts,
|
|
593
|
+
serverInfo,
|
|
594
|
+
capabilities,
|
|
570
595
|
error,
|
|
571
596
|
log,
|
|
572
597
|
authUrl,
|
package/dist/index.cjs
CHANGED
|
@@ -2488,6 +2488,185 @@ var MCPAgent = class {
|
|
|
2488
2488
|
return String(value);
|
|
2489
2489
|
}
|
|
2490
2490
|
}
|
|
2491
|
+
/**
|
|
2492
|
+
* Check if a message is AI/assistant-like regardless of whether it's a class instance.
|
|
2493
|
+
* Handles version mismatches, serialization boundaries, and different message formats.
|
|
2494
|
+
*
|
|
2495
|
+
* This method solves the issue where messages from LangChain agents may be plain JavaScript
|
|
2496
|
+
* objects (e.g., `{ type: 'ai', content: '...' }`) instead of AIMessage instances due to
|
|
2497
|
+
* serialization/deserialization across module boundaries or version mismatches.
|
|
2498
|
+
*
|
|
2499
|
+
* @example
|
|
2500
|
+
* // Real AIMessage instance (standard case)
|
|
2501
|
+
* _isAIMessageLike(new AIMessage("hello")) // => true
|
|
2502
|
+
*
|
|
2503
|
+
* @example
|
|
2504
|
+
* // Plain object after serialization (fixes issue #446)
|
|
2505
|
+
* _isAIMessageLike({ type: "ai", content: "hello" }) // => true
|
|
2506
|
+
*
|
|
2507
|
+
* @example
|
|
2508
|
+
* // OpenAI-style format with role
|
|
2509
|
+
* _isAIMessageLike({ role: "assistant", content: "hello" }) // => true
|
|
2510
|
+
*
|
|
2511
|
+
* @example
|
|
2512
|
+
* // Object with getType() method
|
|
2513
|
+
* _isAIMessageLike({ getType: () => "ai", content: "hello" }) // => true
|
|
2514
|
+
*
|
|
2515
|
+
* @param message - The message object to check
|
|
2516
|
+
* @returns true if the message represents an AI/assistant message
|
|
2517
|
+
*/
|
|
2518
|
+
_isAIMessageLike(message) {
|
|
2519
|
+
if (message instanceof import_langchain2.AIMessage) {
|
|
2520
|
+
return true;
|
|
2521
|
+
}
|
|
2522
|
+
if (typeof message !== "object" || message === null) {
|
|
2523
|
+
return false;
|
|
2524
|
+
}
|
|
2525
|
+
const msg = message;
|
|
2526
|
+
if (typeof msg.getType === "function") {
|
|
2527
|
+
try {
|
|
2528
|
+
const type = msg.getType();
|
|
2529
|
+
if (type === "ai" || type === "assistant") {
|
|
2530
|
+
return true;
|
|
2531
|
+
}
|
|
2532
|
+
} catch (error) {
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
if (typeof msg._getType === "function") {
|
|
2536
|
+
try {
|
|
2537
|
+
const type = msg._getType();
|
|
2538
|
+
if (type === "ai" || type === "assistant") {
|
|
2539
|
+
return true;
|
|
2540
|
+
}
|
|
2541
|
+
} catch (error) {
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
if ("type" in msg) {
|
|
2545
|
+
return msg.type === "ai" || msg.type === "assistant";
|
|
2546
|
+
}
|
|
2547
|
+
if ("role" in msg) {
|
|
2548
|
+
return msg.role === "ai" || msg.role === "assistant";
|
|
2549
|
+
}
|
|
2550
|
+
return false;
|
|
2551
|
+
}
|
|
2552
|
+
/**
|
|
2553
|
+
* Check if a message has tool calls, handling both class instances and plain objects.
|
|
2554
|
+
* Safely checks for tool_calls array presence.
|
|
2555
|
+
*
|
|
2556
|
+
* @example
|
|
2557
|
+
* // AIMessage with tool calls
|
|
2558
|
+
* const msg = new AIMessage({ content: "", tool_calls: [{ name: "add", args: {} }] });
|
|
2559
|
+
* _messageHasToolCalls(msg) // => true
|
|
2560
|
+
*
|
|
2561
|
+
* @example
|
|
2562
|
+
* // Plain object with tool calls
|
|
2563
|
+
* _messageHasToolCalls({ type: "ai", tool_calls: [{ name: "add" }] }) // => true
|
|
2564
|
+
*
|
|
2565
|
+
* @example
|
|
2566
|
+
* // Message without tool calls
|
|
2567
|
+
* _messageHasToolCalls({ type: "ai", content: "hello" }) // => false
|
|
2568
|
+
*
|
|
2569
|
+
* @param message - The message object to check
|
|
2570
|
+
* @returns true if the message has non-empty tool_calls array
|
|
2571
|
+
*/
|
|
2572
|
+
_messageHasToolCalls(message) {
|
|
2573
|
+
if (typeof message === "object" && message !== null && "tool_calls" in message && Array.isArray(message.tool_calls)) {
|
|
2574
|
+
return message.tool_calls.length > 0;
|
|
2575
|
+
}
|
|
2576
|
+
return false;
|
|
2577
|
+
}
|
|
2578
|
+
/**
|
|
2579
|
+
* Check if a message is a HumanMessage-like object.
|
|
2580
|
+
* Handles both class instances and plain objects from serialization.
|
|
2581
|
+
*
|
|
2582
|
+
* @example
|
|
2583
|
+
* _isHumanMessageLike(new HumanMessage("hello")) // => true
|
|
2584
|
+
* _isHumanMessageLike({ type: "human", content: "hello" }) // => true
|
|
2585
|
+
*
|
|
2586
|
+
* @param message - The message object to check
|
|
2587
|
+
* @returns true if the message represents a human message
|
|
2588
|
+
*/
|
|
2589
|
+
_isHumanMessageLike(message) {
|
|
2590
|
+
if (message instanceof import_langchain2.HumanMessage) {
|
|
2591
|
+
return true;
|
|
2592
|
+
}
|
|
2593
|
+
if (typeof message !== "object" || message === null) {
|
|
2594
|
+
return false;
|
|
2595
|
+
}
|
|
2596
|
+
const msg = message;
|
|
2597
|
+
if (typeof msg.getType === "function") {
|
|
2598
|
+
try {
|
|
2599
|
+
const type = msg.getType();
|
|
2600
|
+
if (type === "human" || type === "user") {
|
|
2601
|
+
return true;
|
|
2602
|
+
}
|
|
2603
|
+
} catch (error) {
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
if ("type" in msg && (msg.type === "human" || msg.type === "user")) {
|
|
2607
|
+
return true;
|
|
2608
|
+
}
|
|
2609
|
+
if ("role" in msg && (msg.role === "human" || msg.role === "user")) {
|
|
2610
|
+
return true;
|
|
2611
|
+
}
|
|
2612
|
+
return false;
|
|
2613
|
+
}
|
|
2614
|
+
/**
|
|
2615
|
+
* Check if a message is a ToolMessage-like object.
|
|
2616
|
+
* Handles both class instances and plain objects from serialization.
|
|
2617
|
+
*
|
|
2618
|
+
* @example
|
|
2619
|
+
* _isToolMessageLike(new ToolMessage({ content: "result", tool_call_id: "123" })) // => true
|
|
2620
|
+
* _isToolMessageLike({ type: "tool", content: "result" }) // => true
|
|
2621
|
+
*
|
|
2622
|
+
* @param message - The message object to check
|
|
2623
|
+
* @returns true if the message represents a tool message
|
|
2624
|
+
*/
|
|
2625
|
+
_isToolMessageLike(message) {
|
|
2626
|
+
if (message instanceof import_langchain2.ToolMessage) {
|
|
2627
|
+
return true;
|
|
2628
|
+
}
|
|
2629
|
+
if (typeof message !== "object" || message === null) {
|
|
2630
|
+
return false;
|
|
2631
|
+
}
|
|
2632
|
+
const msg = message;
|
|
2633
|
+
if (typeof msg.getType === "function") {
|
|
2634
|
+
try {
|
|
2635
|
+
const type = msg.getType();
|
|
2636
|
+
if (type === "tool") {
|
|
2637
|
+
return true;
|
|
2638
|
+
}
|
|
2639
|
+
} catch (error) {
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
if ("type" in msg && msg.type === "tool") {
|
|
2643
|
+
return true;
|
|
2644
|
+
}
|
|
2645
|
+
return false;
|
|
2646
|
+
}
|
|
2647
|
+
/**
|
|
2648
|
+
* Extract content from a message, handling both AIMessage instances and plain objects.
|
|
2649
|
+
*
|
|
2650
|
+
* @example
|
|
2651
|
+
* // From AIMessage instance
|
|
2652
|
+
* _getMessageContent(new AIMessage("hello")) // => "hello"
|
|
2653
|
+
*
|
|
2654
|
+
* @example
|
|
2655
|
+
* // From plain object
|
|
2656
|
+
* _getMessageContent({ type: "ai", content: "hello" }) // => "hello"
|
|
2657
|
+
*
|
|
2658
|
+
* @param message - The message object to extract content from
|
|
2659
|
+
* @returns The content of the message, or undefined if not present
|
|
2660
|
+
*/
|
|
2661
|
+
_getMessageContent(message) {
|
|
2662
|
+
if (message instanceof import_langchain2.AIMessage) {
|
|
2663
|
+
return message.content;
|
|
2664
|
+
}
|
|
2665
|
+
if (message && typeof message === "object" && "content" in message) {
|
|
2666
|
+
return message.content;
|
|
2667
|
+
}
|
|
2668
|
+
return void 0;
|
|
2669
|
+
}
|
|
2491
2670
|
async _consumeAndReturn(generator) {
|
|
2492
2671
|
while (true) {
|
|
2493
2672
|
const { done, value } = await generator.next();
|
|
@@ -2559,7 +2738,7 @@ var MCPAgent = class {
|
|
|
2559
2738
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
2560
2739
|
const langchainHistory = [];
|
|
2561
2740
|
for (const msg of historyToUse) {
|
|
2562
|
-
if (msg
|
|
2741
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg)) {
|
|
2563
2742
|
langchainHistory.push(msg);
|
|
2564
2743
|
}
|
|
2565
2744
|
}
|
|
@@ -2628,7 +2807,7 @@ var MCPAgent = class {
|
|
|
2628
2807
|
};
|
|
2629
2808
|
}
|
|
2630
2809
|
}
|
|
2631
|
-
if (
|
|
2810
|
+
if (this._isToolMessageLike(message)) {
|
|
2632
2811
|
const observation = message.content;
|
|
2633
2812
|
let observationStr = String(observation);
|
|
2634
2813
|
if (observationStr.length > 100) {
|
|
@@ -2663,8 +2842,10 @@ var MCPAgent = class {
|
|
|
2663
2842
|
}
|
|
2664
2843
|
}
|
|
2665
2844
|
}
|
|
2666
|
-
if (
|
|
2667
|
-
finalOutput = this._normalizeOutput(
|
|
2845
|
+
if (this._isAIMessageLike(message) && !this._messageHasToolCalls(message)) {
|
|
2846
|
+
finalOutput = this._normalizeOutput(
|
|
2847
|
+
this._getMessageContent(message)
|
|
2848
|
+
);
|
|
2668
2849
|
logger.info("\u2705 Agent finished with output");
|
|
2669
2850
|
}
|
|
2670
2851
|
}
|
|
@@ -2847,10 +3028,12 @@ var MCPAgent = class {
|
|
|
2847
3028
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
2848
3029
|
const langchainHistory = [];
|
|
2849
3030
|
for (const msg of historyToUse) {
|
|
2850
|
-
if (msg
|
|
3031
|
+
if (this._isHumanMessageLike(msg) || this._isAIMessageLike(msg) || this._isToolMessageLike(msg)) {
|
|
2851
3032
|
langchainHistory.push(msg);
|
|
2852
3033
|
} else {
|
|
2853
|
-
logger.info(
|
|
3034
|
+
logger.info(
|
|
3035
|
+
`\u26A0\uFE0F Skipped message of type: ${msg.constructor?.name || typeof msg}`
|
|
3036
|
+
);
|
|
2854
3037
|
}
|
|
2855
3038
|
}
|
|
2856
3039
|
const inputs = [
|
|
@@ -3593,6 +3776,7 @@ var BaseConnector = class {
|
|
|
3593
3776
|
connectionManager = null;
|
|
3594
3777
|
toolsCache = null;
|
|
3595
3778
|
capabilitiesCache = null;
|
|
3779
|
+
serverInfoCache = null;
|
|
3596
3780
|
connected = false;
|
|
3597
3781
|
opts;
|
|
3598
3782
|
constructor(opts = {}) {
|
|
@@ -3627,6 +3811,8 @@ var BaseConnector = class {
|
|
|
3627
3811
|
logger.debug("Caching server capabilities & tools");
|
|
3628
3812
|
const capabilities = this.client.getServerCapabilities();
|
|
3629
3813
|
this.capabilitiesCache = capabilities;
|
|
3814
|
+
const serverInfo = this.client.getServerVersion();
|
|
3815
|
+
this.serverInfoCache = serverInfo || null;
|
|
3630
3816
|
const listToolsRes = await this.client.listTools(
|
|
3631
3817
|
void 0,
|
|
3632
3818
|
defaultRequestOptions
|
|
@@ -3634,6 +3820,7 @@ var BaseConnector = class {
|
|
|
3634
3820
|
this.toolsCache = listToolsRes.tools ?? [];
|
|
3635
3821
|
logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
|
|
3636
3822
|
logger.debug("Server capabilities:", capabilities);
|
|
3823
|
+
logger.debug("Server info:", serverInfo);
|
|
3637
3824
|
return capabilities;
|
|
3638
3825
|
}
|
|
3639
3826
|
/** Lazily expose the cached tools list. */
|
|
@@ -3643,6 +3830,14 @@ var BaseConnector = class {
|
|
|
3643
3830
|
}
|
|
3644
3831
|
return this.toolsCache;
|
|
3645
3832
|
}
|
|
3833
|
+
/** Expose cached server capabilities. */
|
|
3834
|
+
get serverCapabilities() {
|
|
3835
|
+
return this.capabilitiesCache;
|
|
3836
|
+
}
|
|
3837
|
+
/** Expose cached server info. */
|
|
3838
|
+
get serverInfo() {
|
|
3839
|
+
return this.serverInfoCache;
|
|
3840
|
+
}
|
|
3646
3841
|
/** Call a tool on the server. */
|
|
3647
3842
|
async callTool(name, args, options) {
|
|
3648
3843
|
if (!this.client) {
|
|
@@ -5330,6 +5525,8 @@ function useMcp(options) {
|
|
|
5330
5525
|
const [resources, setResources] = (0, import_react.useState)([]);
|
|
5331
5526
|
const [resourceTemplates, setResourceTemplates] = (0, import_react.useState)([]);
|
|
5332
5527
|
const [prompts, setPrompts] = (0, import_react.useState)([]);
|
|
5528
|
+
const [serverInfo, setServerInfo] = (0, import_react.useState)();
|
|
5529
|
+
const [capabilities, setCapabilities] = (0, import_react.useState)();
|
|
5333
5530
|
const [error, setError] = (0, import_react.useState)(void 0);
|
|
5334
5531
|
const [log, setLog] = (0, import_react.useState)([]);
|
|
5335
5532
|
const [authUrl, setAuthUrl] = (0, import_react.useState)(void 0);
|
|
@@ -5478,6 +5675,17 @@ function useMcp(options) {
|
|
|
5478
5675
|
const session = await clientRef.current.createSession(serverName);
|
|
5479
5676
|
await session.initialize();
|
|
5480
5677
|
addLog("info", "\u2705 Successfully connected to MCP server");
|
|
5678
|
+
addLog("info", "Server info:", session.connector.serverInfo);
|
|
5679
|
+
addLog(
|
|
5680
|
+
"info",
|
|
5681
|
+
"Server capabilities:",
|
|
5682
|
+
session.connector.serverCapabilities
|
|
5683
|
+
);
|
|
5684
|
+
console.log("[useMcp] Server info:", session.connector.serverInfo);
|
|
5685
|
+
console.log(
|
|
5686
|
+
"[useMcp] Server capabilities:",
|
|
5687
|
+
session.connector.serverCapabilities
|
|
5688
|
+
);
|
|
5481
5689
|
setState("ready");
|
|
5482
5690
|
successfulTransportRef.current = transportTypeParam;
|
|
5483
5691
|
setTools(session.connector.tools || []);
|
|
@@ -5485,6 +5693,16 @@ function useMcp(options) {
|
|
|
5485
5693
|
setResources(resourcesResult.resources || []);
|
|
5486
5694
|
const promptsResult = await session.connector.listPrompts();
|
|
5487
5695
|
setPrompts(promptsResult.prompts || []);
|
|
5696
|
+
const serverInfo2 = session.connector.serverInfo;
|
|
5697
|
+
const capabilities2 = session.connector.serverCapabilities;
|
|
5698
|
+
if (serverInfo2) {
|
|
5699
|
+
console.log("[useMcp] Server info:", serverInfo2);
|
|
5700
|
+
setServerInfo(serverInfo2);
|
|
5701
|
+
}
|
|
5702
|
+
if (capabilities2) {
|
|
5703
|
+
console.log("[useMcp] Server capabilities:", capabilities2);
|
|
5704
|
+
setCapabilities(capabilities2);
|
|
5705
|
+
}
|
|
5488
5706
|
return "success";
|
|
5489
5707
|
} catch (err) {
|
|
5490
5708
|
const errorMessage = err?.message || String(err);
|
|
@@ -5847,6 +6065,8 @@ function useMcp(options) {
|
|
|
5847
6065
|
resources,
|
|
5848
6066
|
resourceTemplates,
|
|
5849
6067
|
prompts,
|
|
6068
|
+
serverInfo,
|
|
6069
|
+
capabilities,
|
|
5850
6070
|
error,
|
|
5851
6071
|
log,
|
|
5852
6072
|
authUrl,
|
package/dist/index.js
CHANGED
|
@@ -17,14 +17,14 @@ import {
|
|
|
17
17
|
ServerManager,
|
|
18
18
|
Telemetry,
|
|
19
19
|
setTelemetrySource
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-6EHM3S3M.js";
|
|
21
21
|
import {
|
|
22
22
|
useMcp,
|
|
23
23
|
useWidget,
|
|
24
24
|
useWidgetProps,
|
|
25
25
|
useWidgetState,
|
|
26
26
|
useWidgetTheme
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-VNEGDXZO.js";
|
|
28
28
|
import {
|
|
29
29
|
BaseConnector,
|
|
30
30
|
BaseMCPClient,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
MCPSession,
|
|
35
35
|
WebSocketConnector,
|
|
36
36
|
onMcpAuthorization
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-TIUSJAAE.js";
|
|
38
38
|
import "./chunk-YURRUCIM.js";
|
|
39
39
|
import {
|
|
40
40
|
Logger,
|