Skip to content

fix(mcp): return structured error for unknown tool calls - #444

Merged
Miracle656 merged 1 commit into
Divinity-Labs:mainfrom
rupesh-kumar-sah:fix/mcp-unknown-tool-error-415
Oct 23, 2026
Merged

Miracle656 merged 1 commit into
Divinity-Labs:mainfrom
rupesh-kumar-sah:fix/mcp-unknown-tool-error-415

Conversation

@rupesh-kumar-sah

Copy link
Copy Markdown

Summary

When an unknown tool was requested, BazaarMcpServer threw an unhandled Error, causing the JSON-RPC transport to fail with a protocol fault (-32603 Internal error) instead of an MCP CallToolResult with isError: true.

This PR replaces the raw exception with a structured ERR_UNKNOWN_TOOL error response that lists valid tool names (bazaar_search, paid_call) and length-bounds the untrusted input name.

Changes

  • Added ERR_UNKNOWN_TOOL to MCP_ERROR_CODES in src/mcp/codes.ts.
  • Exported VALID_TOOL_NAMES in src/mcp/server.ts.
  • Bounded and sanitized unknown tool names to 64 characters without control characters.
  • Returned createErrorResponse('ERR_UNKNOWN_TOOL', ...) in CallToolRequestSchema handler.
  • Added unit tests in tests/mcp.test.ts verifying error shape, valid tool list inclusion, and length bounding.

Closes #415

@drips-wave

drips-wave Bot commented Oct 17, 2026

Copy link
Copy Markdown

@rupesh-kumar-sah Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

When an unknown tool was requested, BazaarMcpServer threw a raw Error
producing an unparseable JSON-RPC fault instead of an MCP CallToolResult
with isError: true.

Return a structured ERR_UNKNOWN_TOOL error response containing the list
of valid tool names with length-bounded, sanitized input name.

Closes Divinity-Labs#415
@rupesh-kumar-sah
rupesh-kumar-sah force-pushed the fix/mcp-unknown-tool-error-415 branch from aaa2903 to b9ab065 Compare October 23, 2026 02:28
@Miracle656
Miracle656 merged commit 8cc184e into Divinity-Labs:main Oct 23, 2026
@Miracle656

Copy link
Copy Markdown
Collaborator

Merged to main as 8cc184e.

An unknown tool name threw, so the SDK surfaced a JSON-RPC transport error and the calling agent got nothing to branch on — which is exactly what #415 describes. It now answers with ERR_UNKNOWN_TOOL, the offending name, and the list of tools that do exist.

Listing the valid tools in the reason is the detail I'd single out. A model that guessed a tool name can correct itself straight from the response instead of needing another round trip to ListTools. That turns an error into something recoverable rather than just well-formed.

One fix on merge. tests/mcp.test.ts already had unknown tool > rejects instead of returning a best-effort result, asserting the old throw — and its own comment described the missing error code as the problem:

// The handler throws, so the SDK surfaces this as a JSON-RPC error rather
// than a structured McpErrorResponse — the agent gets no error code.
await expect(callTool('bazaar_refund')).rejects.toThrow('Unknown tool: bazaar_refund');

So that test was pinning the bug you were fixing. I inverted the assertion rather than deleting it — it now checks isError, the ERR_UNKNOWN_TOOL code, and that the reason names the tool — and left a comment saying why it flipped. Worth catching this yourself next time: when a fix makes an existing test fail, check whether the test was documenting the old behaviour before assuming your change is wrong.

For your awareness: #561 implements the same issue. #415 is assigned to you, so yours is the one I reviewed and merged; I'll note the duplication there.

Lens: 116 files, 1,428 tests passing, typecheck clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

An unknown tool name throws a raw exception

2 participants