fix(mcp): register CallToolRequest handler explicitly + populate _tool_cache #22

Merged
kaykayyali merged 1 commits from fix/mcp-call-tool-dispatch into main 2026-06-26 14:23:43 +00:00
Owner

Summary

  • Wire CallToolRequest handler through the same internal mcp.request_handlers[] API as ListToolsRequest (was relying on @mcp.call_tool() decorator that doesn't work on Server subclass).
  • Populate mcp._tool_cache so the SDK's input-validation pipeline works (was logging 'Tool X not listed, no validation will be performed' silently).

Why

The MCP server's tools/call JSON-RPC method returned no response because CallToolRequest was never registered. The tools/list path worked (was manually wired), but every tool call was a silent no-op. Without this, MCP-driven cycles / kanban workers can't drive the orchestrator.

Validation

  • 9 new tests in tests/contract/test_mcp_call_dispatch.py (475 lines).
  • 23 MCP-related tests total, 54 contract+unit tests pass.
  • mypy clean.
  • End-to-end stdio round-trip: spawn damascus mcp-serve, run initialize/initialized/tools-call, assert valid JSON-RPC response.
## Summary - Wire `CallToolRequest` handler through the same internal `mcp.request_handlers[]` API as `ListToolsRequest` (was relying on `@mcp.call_tool()` decorator that doesn't work on `Server` subclass). - Populate `mcp._tool_cache` so the SDK's input-validation pipeline works (was logging 'Tool X not listed, no validation will be performed' silently). ## Why The MCP server's `tools/call` JSON-RPC method returned no response because `CallToolRequest` was never registered. The `tools/list` path worked (was manually wired), but every tool call was a silent no-op. Without this, MCP-driven cycles / kanban workers can't drive the orchestrator. ## Validation - 9 new tests in `tests/contract/test_mcp_call_dispatch.py` (475 lines). - 23 MCP-related tests total, 54 contract+unit tests pass. - mypy clean. - End-to-end stdio round-trip: spawn `damascus mcp-serve`, run `initialize/initialized/tools-call`, assert valid JSON-RPC response.
kaykayyali added 1 commit 2026-06-26 14:23:38 +00:00
fix(mcp): register CallToolRequest handler explicitly + populate _tool_cache
Some checks failed
test / contract-and-unit (pull_request) Failing after 14s
3ee735d248
Refactor the MCP server's handler wiring so both ListToolsRequest and
CallToolRequest handlers are registered through the same internal
mcp.request_handlers[...] = ... API the SDK's decorators use.
This makes the dispatch table visible in one place instead of being
split between explicit registration and the @mcp.call_tool() decorator.

While verifying the wiring end-to-end I also discovered a real bug:
the SDK's _get_cached_tool_definition() returns None for every tool
because the manual _list_tools_handler never populated mcp._tool_cache
(the SDK's own @mcp.list_tools() decorator does this transparently).
That made the SDK log 'Tool X not listed, no validation will be
performed' on every tools/call. Pydantic validation in _dispatch
still caught bad args, so the bug was silent — but fixing it removes
the warning and makes the SDK's input-validation pipeline work as
designed.

The new _call_tool_handler also wraps the result in a proper
ServerResult(CallToolResult(...)) envelope and converts dispatch
exceptions into isError=True results, matching the shape the SDK's
@server.call_tool() decorator produces.

Tests:
- New file tests/contract/test_mcp_call_dispatch.py covers:
  - handler-registration structural assertion
  - list_items and system_status dispatch + response shape
  - unknown-tool error result
  - validation error result (priority_min=-1, bounds invariant)
  - list-tools regression (7 tools, inputSchema drift guard)
  - end-to-end stdio round-trip (spawn damascus mcp-serve, run
    initialize/initialized/tools-call, assert valid JSON-RPC response)
- 9 new tests, 23 MCP-related tests total, 54 contract+unit tests
  pass; mypy clean.
kaykayyali merged commit 33e953d505 into main 2026-06-26 14:23:43 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kaykayyali/damascus-orchestrator#22