danny-avila/LibreChat · error · Error
[MCP][${serverName}][${toolName}] tool call failed${error?.m
Error message
[MCP][${serverName}][${toolName}] tool call failed${error?.message ? `: ${error?.message}` : '.'} What it means
The MCP tool _call catch-all (MCP.js:1153) rethrows with this message when the caught error is neither an OAuth-class error nor recoverable — it appends the upstream error.message if present. It is the generic surface for any MCP tool call failure: transport errors, server-side execution failures, malformed tool arguments, timeouts, aborts.
Source
Thrown at api/server/services/MCP.js:1153
error.message === 'OAuth flow initiated - return early' ||
error.message === 'Pending OAuth flow reused - return early';
if (isOAuthError) {
if (
capturedServerConfig &&
!requiresOAuthMachinery(capturedServerConfig) &&
!isOAuthFlowSignal
) {
throw new Error(
`[MCP][${serverName}][${toolName}] upstream authentication failed; MCP OAuth is not configured for this server.`,
);
}
throw new Error(
`[MCP][${serverName}][${toolName}] OAuth authentication required. Please check the server logs for the authentication URL.`,
);
}
throw new Error(
`[MCP][${serverName}][${toolName}] tool call failed${error?.message ? `: ${error?.message}` : '.'}`,
);
}
};
const toolInstance = tool(_call, {
schema,
name: normalizedToolKey,
description: description || '',
responseFormat: AgentConstants.CONTENT_AND_ARTIFACT,
});
toolInstance.mcp = true;
toolInstance.mcpRawServerName = serverName;
// Ephemeral request-scoped servers (runtime body placeholders) tear their
// connection down at request end, so they must never be backgrounded. A
// missing/stale config means the server's lifetime is unknowable, so fail
// closed (foreground) rather than risk a detached call against a torn-down
// connection.View on GitHub (pinned to 5ff282f900)
Solutions
- Read the appended error.message — it is the upstream's own failure reason and is the primary diagnostic.
- If transient (timeout/reset), retry the call; if the server is remote, check connectivity.
- Validate the tool arguments against the server's current schema; update the call if the server changed.
- If an AbortSignal is being passed, ensure it is not being cancelled prematurely upstream.
Defensive patterns
Strategy: try-catch
Validate before calling
function assertToolArgs(schema, args) {
for (const [k, t] of Object.entries(schema)) {
if (typeof args?.[k] !== t) throw new Error(`arg ${k} expected ${t}`);
}
} Try / catch
try {
return await callMcpTool(...);
} catch (e) {
if (/timeout|reset|ECONNRESET|429|503/.test(e.message)) { await backoff(); return retry(); }
throw e;
} Prevention
- Validate tool arguments against the server's current schema before calling.
- Pass a realistic AbortSignal timeout rather than letting requests hang.
- Log the appended upstream error.message for every MCP tool failure.
When it happens
Trigger: mcpManager.callTool rejects for any non-auth reason: the MCP server returned a non-401 error, the SSE/stdio transport died, the tool arguments failed server-side validation, an AbortSignal fired, or the server threw during execution.
Common situations: Network outage to a remote MCP server. A tool whose arguments changed upstream. Long-running tool hit the request timeout. Server restarted mid-call. Schema mismatch after an MCP server upgrade.
Related errors
- Graph token acquisition failed: ${error.message}
- Forbidden: Insufficient MCP server permissions
- [MCP][${serverName}][${toolName}] upstream authentication fa
- [MCP][${serverName}][${toolName}] OAuth authentication requi
- invalid_action_error
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/9d5be58192613616.
Report an issue: GitHub.