Diagnose Failed or Wrong MCP Tool Calls
Classify the failure before changing code: no tool call means discovery trouble, a rejected call points to credentials, limits, or protocol handling, and a plausible but wrong answer often means truncation. Reproduce the same request through REST, expose response headers, and keep the request ID that ties the failure to one vendor-side call.
Start by locating the failure layer
Do not debug an MCP tool call as one continuous event. Separate it into three layers first:
- The client never called the tool.
- The client called it, but the MCP server rejected the call.
- The server reached the underlying API, returned data, and the model then misread an incomplete or misleading result.
Those layers can produce similar chat output, but they require different fixes. Changing credentials cannot repair a tool the model never selected. Renaming a tool cannot repair a rejected credential. Repeating a request cannot restore JSON that the client already truncated.
Treat the model’s final prose as a symptom, not a trace. You need the client transcript, server record, or tool result showing whether a call occurred and what came back. If that evidence is missing, establish MCP server observability before changing the tool.
Use the MCP specification, accessed 2026-08-26, to identify the protocol boundary. Then use the vendor’s REST API to test everything behind that boundary. This distinction keeps a protocol failure, a tool execution failure, and a bad interpretation from being folded into one generic MCP problem.
Cycle 1: the tool was never called
Symptom
The assistant answers from its own context, says it cannot complete the task, or calls a neighbouring tool. There is no record of the intended tool call in the client transcript or server logs.
This is not a failed API request. No request reached the server.
Likely cause
A tool that was never called is usually a tool the model could not distinguish from a neighbour. That is a naming and description problem rather than a capability problem.
Two tools can expose different operations while still looking interchangeable to the model. A name that identifies only the resource, or a description that says only that the tool manages assets, does not state the condition under which one tool should be chosen instead of another. Adding more capability behind the same ambiguous description does not improve selection.
Check
Open the client trace for the failed turn and answer these in order:
- Was any tool call emitted?
- If so, which tool name was selected?
- What names and descriptions for the intended tool and its nearest neighbours were visible to the model on that turn?
- Does each description state a different operation, expected input, and returned result?
- Could a reader choose the intended tool from those descriptions without knowing the server implementation?
Test the distinction directly with prompts that differ by one condition. If the same tool is selected for both, or selection varies without a change in the requested operation, the descriptions are not separating the cases.
Do not begin by inspecting API credentials, request parameters, rate limits, or vendor status. None of those can affect a request that the client never made.
Fix
Rename or rewrite the tools so each one states its job and boundary. Put the differentiating condition in the description: what operation it performs, what identifiers it expects, what it returns, and when a neighbouring tool is the wrong choice.
Then repeat the original prompt and inspect the trace again. The fix is demonstrated only when the intended call appears. A better final answer without a call does not prove tool selection was repaired.
Cycle 2: the server rejected the call
Symptom
The client trace contains the intended tool call, but the result is an error rather than vendor data. The error may be too generic to tell you whether the credential, MCP server, or underlying API rejected the request.
Likely cause
Authentication failures surface as generic errors on some servers. A message that appears to blame tool execution therefore does not establish that the MCP server itself is faulty.
The decisive boundary test is the underlying REST API. Reproduce the request there with the same parameters before changing anything. If it fails there too, the MCP layer was never involved in the failure.
For Cloudinary operations, use the Admin API reference and request documentation, checked 2026-08-18, to construct that comparison. The point is not to create a simpler or approximate request. It is to send the same operation, identifiers, and parameter values with the credential that the MCP server was expected to use.
Check
Preserve the failed tool input, then make the equivalent REST request without first renaming fields, dropping optional values, changing the target product environment, or substituting credentials.
Classify the result:
- If REST rejects the same credential or parameters, the failure is below the MCP server. The tool call did not create it.
- If REST succeeds with the same values while the tool call is rejected, the difference is in the MCP path: the server’s credential, parameter mapping, or protocol handling.
- If you cannot reproduce the same request, you do not yet have enough evidence to assign the failure to either layer.
Keep protocol errors separate from tool failures. The practical distinction is whether the MCP exchange itself failed or the called operation returned an error. Use the site’s guide to distinguishing JSON-RPC errors from MCP tool failures when the client presents both as a single error message.
Fix
When REST fails, repair the credential or request at the API layer and rerun the REST request first. Return to the MCP call only after the same REST operation succeeds.
When REST succeeds but the MCP call fails, compare the accepted REST parameters with the tool input and the server’s mapping. Correct the mapping or server-side credential, then run the unchanged test case again. Keeping the test case fixed matters: if you change both the request and the server, a successful retry cannot tell you which change repaired the fault.
Do not treat a generic authentication error as proof of an MCP server outage. The same-parameter REST reproduction is the check that decides whether the server belongs in the investigation.
Cycle 3: identical calls fail intermittently
Symptom
A call succeeds in one agent run and fails in another even though the visible parameters appear unchanged. Manual testing may pass while a longer multi-step run produces scattered failures.
Likely cause
Rate limiting under agent workloads looks intermittent because the burst pattern is uneven. An agent may place several calls close together and then remain quiet while it interprets results or chooses another step. The resulting failures do not form a steady pattern, so they can be mistaken for malformed inputs.
A successful retry also does not prove that the earlier payload was invalid. The remaining allowance may simply have changed between attempts.
Check
Inspect the remaining rate-limit allowance at the failed call, not only during a later manual retry. Correlate it with the sequence of calls in the same agent run.
Ask:
- How many calls reached the API immediately before the failure?
- Was the remaining allowance present in the tool result or retained server record?
- Does failure coincide with low or exhausted allowance while the same parameters succeed when allowance is available?
- Does the same request still fail through REST when allowance is available?
If the tool result hides the relevant response headers, fix that visibility before labelling the request malformed. The implementation pattern is covered in surfacing rate-limit and request-ID headers.
Fix
Reduce the burst presented to the API, then repeat the same request while recording the remaining allowance for every call. The exact scheduling policy depends on the client and server, but the acceptance condition is concrete: the unchanged request succeeds when allowance remains and fails as that allowance is exhausted.
Do not rewrite valid parameters merely because a burst-triggered failure is intermittent. First show that the request fails while allowance remains. Without that check, changing the payload treats timing evidence as a schema problem.
Cycle 4: the call succeeds but the answer is wrong
Symptom
The tool reports success and the assistant gives a confident answer, but records are missing, a list ends unexpectedly, or a conclusion is unsupported by the complete API response.
There may be no parse error. That absence is part of the danger: the result looks usable enough for the model to continue.
Likely cause
A result larger than the client’s tolerance is truncated rather than rejected. A truncated JSON payload read as complete is the failure mode that produces confident wrong answers.
The API and server may both have completed their work correctly. The loss can occur when the client accepts only part of the tool result. The model then reasons over the part it received and has no reliable basis for inferring which records or fields were omitted.
This is different from a rejected large request. The symptom is apparent success followed by an incorrect interpretation, not an explicit size error.
Check
Reproduce the operation through REST with the same parameters and retain the complete response. Compare that response with the exact tool result supplied to the model.
Check measurable boundaries rather than reading only the first few records:
- Compare the response lengths.
- Compare the final record or final field visible in each response.
- Check whether the tool result ends where the REST result ends.
- Check whether the received JSON is structurally complete before treating it as a complete dataset.
- If the response supplies its own record count or continuation information, compare that with what the client retained.
If REST contains data absent from the successful tool result, the request was not wrong and the model did not receive the full answer. Investigate the result boundary using the guide to MCP tool results that overflow client context.
Fix
Make the returned result smaller using the operation’s existing filters, field selection, limits, or pagination where those controls are available. If one complete response still exceeds the client’s tolerance, split the work into bounded requests whose results can each be verified as complete.
After changing the request shape, compare every bounded tool result with its REST equivalent. Do not accept fluent output as the test. The test is that the tool result reaches the same boundary as the corresponding REST response and remains complete before the model interprets it.
Never ask the model to compensate for an unknown missing tail. Once truncation is possible, claims about totals, absence, ordering, or the last matching record are unverified until the complete response is available.
Cycle 5: the vendor cannot identify the failed call
Symptom
You can describe the operation and approximate time, but a support ticket can identify only a category of failures. The tool result contains data or a generic error without the vendor’s request ID.
Likely cause
The API response headers were not embedded in the tool result or retained elsewhere. Without the request ID, the visible error cannot be tied to the vendor’s record of one specific call.
For the Cloudinary MCP servers covered by the Cloudinary MCP server documentation, checked 2026-08-18, enabling embedded response headers puts the request ID in the tool result. That ID is the only thing that turns a vendor support ticket from a report about a category into a report about a specific call.
The same visibility also supports the rate-limit check in the previous cycle. A later test is not a substitute because it produces a different request ID and may occur under a different remaining allowance.
Check
Inspect the exact failed tool result. Confirm whether it contains the response headers and a request ID. Do not assume the server recorded an identifier that the client can recover later.
Then inspect a controlled call with embedded response headers enabled. Verify that its request ID appears in the tool result visible to the client. If it does not, the observability path is still incomplete even if the operation itself succeeds.
For an intermittent failure, capture the identifier from the failing call. An ID from a successful reproduction identifies the reproduction, not the original failure.
Fix
Enable embedded response headers and preserve the resulting request ID with the failed tool input and result. Include that exact identifier when escalating the call to the vendor.
Keep header embedding enabled while diagnosing authentication and rate-limit failures. It does not replace the REST reproduction: REST decides whether the MCP layer was involved, while the request ID lets the vendor locate the particular API call.
A fixed-order diagnostic run
Use the same order every time so one layer’s evidence is not mistaken for another’s:
- Inspect the client trace. If the tool was never called, fix its name and description, then prove selection with the same prompt.
- If it was called and rejected, repeat the exact parameters through REST before changing anything.
- If REST also fails, repair the API credential or request. The MCP layer was not involved.
- If failures vary between otherwise identical calls, record the remaining allowance at each call and test for the uneven burst pattern.
- If the call succeeds but the answer is wrong, compare the complete REST response with the exact tool result for truncation.
- Enable embedded response headers and retain the failed call’s request ID before escalation.
This order produces a defensible diagnosis: evidence that a call happened, evidence about which boundary rejected it, evidence that the returned payload was complete, and an identifier for the exact vendor-side request.
Sources
- MCP specificationmodelcontextprotocol.io
- Admin API reference and request documentationcloudinary.com
- Cloudinary MCP server documentationcloudinary.com
See also
List an MCP server's resources, select the URI that belongs in context, read it, and handle text or binary content by MIME type.
What the Environment Config MCP server changes, why shared presets and transformations have broad reach, and what reviewers need to record.
When a marketplace plugin is the right way to install MCP servers and skills, when a hand-written config entry is, and why most teams end up with both.
How MCP 2026-07-28 removes handshake and session state, makes requests self-describing, and keeps application state explicit.