mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-04-03 22:37:20 +02:00
🎯 fix: MCP Tool Misclassification from Action Delimiter Collision (#12512)
* fix: prevent MCP tools with `_action` in name from being misclassified as OpenAPI action tools
Add `isActionTool()` helper that checks for the `_action_` delimiter
while guarding against cross-delimiter collision with `_mcp_`. Replace
all `includes(actionDelimiter)` classification checks with the new
helper across backend and frontend.
* test: add coverage for MCP/action cross-delimiter collision
Verify that `isActionTool` correctly rejects MCP tool names containing
`_action` and that `loadAgentTools` does not filter them based on
`actionsEnabled`. Add ToolIcon and definitions test cases.
* fix: simplify isActionTool to handle all MCP name patterns
- Use `!toolName.includes('_mcp_')` instead of checking only after the
first `_action_` occurrence, which missed MCP tools with `_action_` in
the middle of their name (e.g. `get_action_data_mcp_myserver`).
- Reference `Constants.mcp_delimiter` value via a local const to avoid
circular import from config.ts, with a comment explaining why.
- Remove dead `actionDelimiter` import from definitions.ts.
- Replace double-filter with single-pass partition in loadToolsForExecution.
- Add test for mid-name `_action_` collision case.
* fix: narrow MCP exclusion to delimiter position in isActionTool
Only reject when `_mcp_` appears after `_action_` (the MCP suffix
position). `_mcp_` before `_action_` is part of the operationId and
is valid — e.g. `sync_mcp_state_action_api---example---com` is a
legitimate action tool whose operationId happens to contain `_mcp_`.
* fix: document positional _mcp_ guard and known RFC-invalid domain limitation
Expand JSDoc on isActionTool to explain the action/MCP format
disambiguation and the theoretical false negative for non-RFC-compliant
domains containing `_mcp_`. Add test documenting this known edge case.
This commit is contained in:
parent
611a1ef5dc
commit
275af48592
8 changed files with 139 additions and 11 deletions
|
|
@ -31,6 +31,7 @@ const {
|
|||
imageGenTools,
|
||||
EModelEndpoint,
|
||||
EToolResources,
|
||||
isActionTool,
|
||||
actionDelimiter,
|
||||
ImageVisionTool,
|
||||
openapiToFunction,
|
||||
|
|
@ -490,7 +491,7 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
|
|||
if (tool === Tools.web_search) {
|
||||
return checkCapability(AgentCapabilities.web_search);
|
||||
}
|
||||
if (tool.includes(actionDelimiter)) {
|
||||
if (isActionTool(tool)) {
|
||||
return actionsEnabled;
|
||||
}
|
||||
if (!areToolsEnabled) {
|
||||
|
|
@ -871,7 +872,7 @@ async function loadAgentTools({
|
|||
} else if (tool === Tools.web_search) {
|
||||
includesWebSearch = checkCapability(AgentCapabilities.web_search);
|
||||
return includesWebSearch;
|
||||
} else if (tool.includes(actionDelimiter)) {
|
||||
} else if (isActionTool(tool)) {
|
||||
return actionsEnabled;
|
||||
} else if (!areToolsEnabled) {
|
||||
return false;
|
||||
|
|
@ -978,7 +979,7 @@ async function loadAgentTools({
|
|||
|
||||
agentTools.push(...additionalTools);
|
||||
|
||||
const hasActionTools = _agentTools.some((t) => t.includes(actionDelimiter));
|
||||
const hasActionTools = _agentTools.some((t) => isActionTool(t));
|
||||
if (!hasActionTools) {
|
||||
return {
|
||||
toolRegistry,
|
||||
|
|
@ -1237,8 +1238,11 @@ async function loadToolsForExecution({
|
|||
? [...new Set([...requestedNonSpecialToolNames, ...ptcOrchestratedToolNames])]
|
||||
: requestedNonSpecialToolNames;
|
||||
|
||||
const actionToolNames = allToolNamesToLoad.filter((name) => name.includes(actionDelimiter));
|
||||
const regularToolNames = allToolNamesToLoad.filter((name) => !name.includes(actionDelimiter));
|
||||
const actionToolNames = [];
|
||||
const regularToolNames = [];
|
||||
for (const name of allToolNamesToLoad) {
|
||||
(isActionTool(name) ? actionToolNames : regularToolNames).push(name);
|
||||
}
|
||||
|
||||
if (regularToolNames.length > 0) {
|
||||
const includesWebSearch = regularToolNames.includes(Tools.web_search);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue