different-ai/openwork · error · ProbeFailure
MCP_TOOL_EXECUTION
MCP_TOOL_EXECUTION
Error message
No suitable tool was available for the requested probe
What it means
When the probe should execute a tool call, it auto-selects the first discovered tool of the required kind: a mutation tool for commit-then-disconnect faults, otherwise a read tool. If the discovered catalog contains no tool of that kind, the probe throws MCP_TOOL_EXECUTION / mcp_tool.
Source
Thrown at packages/enterprise-mcp-mock-server/src/testing/probe.ts:870
if (missing.length > 0 || unexpected.length > 0) {
throw new ProbeFailure(
"MCP_TOOL_DISCOVERY",
"profile_fixture_mismatch",
`Catalog does not match pinned profile fixture ${profile.fixtureVersion}`,
)
}
}
recordPassed(phases, "MCP_TOOL_DISCOVERY", startedAt, `Retrieved ${toolNames.size} unique tools with bounded pagination`)
const fault = activeFault
const shouldCall = options.callTool !== undefined || mode === "safe-read" || fault?.phase === "PROVIDER_AUTHORIZATION" || fault?.phase === "PROVIDER_EXECUTION"
if (shouldCall) {
const selected = options.callTool
? { name: options.callTool.name, arguments: options.callTool.arguments }
: (() => {
const mutationRequired = fault?.effect === "commit-then-disconnect"
const tool = discoveredTools.find((candidate) => candidate.kind === (mutationRequired ? "mutation" : "read"))
if (!tool) throw new ProbeFailure("MCP_TOOL_EXECUTION", "mcp_tool", "No suitable tool was available for the requested probe")
return { name: tool.name, arguments: defaultArguments(tool.inputSchema) }
})()
const selectedTool = profile.tools.find((tool) => tool.name === selected.name)
if (mode === "safe-read" && selectedTool?.kind !== "read") {
throw new ProbeFailure("CONFIGURATION", "configuration", "safe-read mode accepts only a declared read-only tool")
}
startedAt = Date.now()
let toolResponse: Response
try {
toolResponse = await fetchStep(mcpUrl, {
method: "POST",
headers: sessionHeaders,
body: JSON.stringify({ jsonrpc: "2.0", id: 100, method: "tools/call", params: selected }),
}, "MCP_TOOL_EXECUTION", overallDeadline)
} catch {
throw new ProbeFailure(
selectedTool?.kind === "mutation" ? "PROVIDER_EXECUTION" : "MCP_TOOL_EXECUTION",
selectedTool?.kind === "mutation" ? "mutation_indeterminate" : "mcp_tool",View on GitHub (pinned to 2b7df46e8a)
Solutions
- Add a tool of the required kind (mutation for commit-then-disconnect, otherwise read) to the profile fixture.
- Pass options.callTool explicitly with a name and arguments matching a registered tool.
- Fix earlier discovery failures (invalid schemas) so tools actually land in discoveredTools.
- Verify the server's advertised tool kinds match the fixture kinds.
Example fix
// before: read-only profile used with a commit-then-disconnect fault
const profile = { tools: [{ name: "get_docs", kind: "read" }] };
// after: include a mutation tool
const profile = { tools: [{ name: "get_docs", kind: "read" }, { name: "create_doc", kind: "mutation" }] }; Defensive patterns
Strategy: validation
Validate before calling
const mutationRequired = fault?.effect === "commit-then-disconnect";
const kindNeeded = mutationRequired ? "mutation" : "read";
if (!options.callTool && !profile.tools.some((t) => t.kind === kindNeeded)) {
throw new Error(`Profile lacks a '${kindNeeded}' tool required by this probe mode`);
} Try / catch
try {
await probeEnterpriseMcpMockServer(options);
} catch (e) {
if (e instanceof ProbeFailure && e.code === "MCP_TOOL_EXECUTION" && e.reason === "mcp_tool") {
// add the required tool kind to the fixture or pass options.callTool
} else throw e;
} Prevention
- Ensure every fixture includes at least one read and one mutation tool.
- Pass options.callTool explicitly when a specific tool is required.
- Fix discovery failures first — tools rejected for schema never reach discoveredTools.
When it happens
Trigger: probeEnterpriseMcpMockServer with shouldCall true, no options.callTool override, and discoveredTools contains no candidate whose kind matches the requested ("mutation" for commit-then-disconnect faults, otherwise "read").
Common situations: Profile only defines read tools while the fault scenario needs a mutation tool; all tools failed schema validation earlier so discoveredTools is empty; custom callTool name not present in the profile.
Related errors
- MCP_TOOL_REPORTED_ERROR
- Failed to run MCP tool (${response.status}).
- MCP_PROVIDER_INVALID_PARAMS|MCP_PROVIDER_HTTP_403|MCP_PROVIDER_HTTP_429
- ${result.message}
- ${toolResultError(result)}
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/77c3988f714689bf.
Report an issue: GitHub.