UAT: MCP tool handler signature mismatch causes TypeError when executed via ToolRunner #3708

Open
opened 2026-04-05 22:15:45 +00:00 by freemo · 0 comments
Owner

Metadata

  • Branch: fix/mcp-tool-handler-signature-mismatch
  • Commit Message: fix(mcp): align MCPToolAdapter handler signature with ToolRunner calling convention
  • Milestone: Backlog
  • Parent Epic: #397

Background and Context

In src/cleveragents/mcp/adapter.py, the MCPToolAdapter.register_tools() method creates tool handlers via _make_handler() using a **kwargs signature:

def handler(**kwargs: Any) -> dict[str, Any]:
    result = ar.invoke(tn, kwargs)
    ...

However, in src/cleveragents/tool/runner.py, the ToolRunner.execute() method calls the handler with a positional dict argument:

raw_output = spec.handler(inputs)

where inputs is a dict[str, Any] passed as a positional argument.

This calling convention mismatch means every MCP tool registered via MCPToolAdapter.register_tools() will raise a TypeError when executed through ToolRunner.execute(), making the entire MCP tool integration non-functional at runtime.

Current Behavior

When any MCP tool registered via MCPToolAdapter.register_tools() is executed through ToolRunner.execute(), a TypeError is raised:

TypeError: handler() takes 0 positional arguments but 1 was given

Steps to Reproduce:

  1. Create an MCPToolAdapter and connect it to an MCP server
  2. Call adapter.register_tools(registry, namespace="test")
  3. Create a ToolRunner with the registry
  4. Call runner.activate("test/some-tool") then runner.execute("test/some-tool", {"arg": "value"})
  5. Observe TypeError: handler() takes 0 positional arguments but 1 was given

Code Locations:

  • src/cleveragents/mcp/adapter.py lines ~580-590 (handler definition in _make_handler)
  • src/cleveragents/tool/runner.py line ~488 (raw_output = spec.handler(inputs))

Expected Behavior

MCP tools registered via MCPToolAdapter.register_tools() should execute successfully when invoked via ToolRunner.execute(). The handler should accept a positional dict[str, Any] argument matching the calling convention used by ToolRunner.

Acceptance Criteria

  • MCPToolAdapter._make_handler() produces handlers with signature (inputs: dict[str, Any]) -> dict[str, Any]
  • ToolRunner.execute() successfully invokes MCP-registered tools without TypeError
  • All existing non-MCP tool handlers continue to work correctly
  • Integration test covering MCPToolAdapterToolRunner round-trip passes
  • No regressions in existing tool runner tests

Subtasks

  • Update _make_handler() in src/cleveragents/mcp/adapter.py to use def handler(inputs: dict[str, Any]) -> dict[str, Any]: signature
  • Update the ar.invoke(tn, kwargs) call to ar.invoke(tn, inputs) accordingly
  • Audit any other handler factories in the MCP adapter for the same mismatch
  • Add or update unit tests for MCPToolAdapter._make_handler() to assert correct positional-dict calling convention
  • Add integration test: MCPToolAdapter.register_tools()ToolRunner.execute() round-trip

Definition of Done

  • All subtasks completed
  • A Git commit is created with the exact first line: fix(mcp): align MCPToolAdapter handler signature with ToolRunner calling convention
  • The commit is pushed to branch fix/mcp-tool-handler-signature-mismatch
  • A Pull Request has been submitted, reviewed, and merged
  • All nox stages pass
  • Coverage >= 97%

Backlog note: This issue was discovered during autonomous operation
on milestone v3.3.0. It does not block milestone completion and has been
placed in the backlog for human review and future milestone assignment.


Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/mcp-tool-handler-signature-mismatch` - **Commit Message**: `fix(mcp): align MCPToolAdapter handler signature with ToolRunner calling convention` - **Milestone**: Backlog - **Parent Epic**: #397 ## Background and Context In `src/cleveragents/mcp/adapter.py`, the `MCPToolAdapter.register_tools()` method creates tool handlers via `_make_handler()` using a `**kwargs` signature: ```python def handler(**kwargs: Any) -> dict[str, Any]: result = ar.invoke(tn, kwargs) ... ``` However, in `src/cleveragents/tool/runner.py`, the `ToolRunner.execute()` method calls the handler with a positional `dict` argument: ```python raw_output = spec.handler(inputs) ``` where `inputs` is a `dict[str, Any]` passed as a **positional argument**. This calling convention mismatch means every MCP tool registered via `MCPToolAdapter.register_tools()` will raise a `TypeError` when executed through `ToolRunner.execute()`, making the entire MCP tool integration non-functional at runtime. ## Current Behavior When any MCP tool registered via `MCPToolAdapter.register_tools()` is executed through `ToolRunner.execute()`, a `TypeError` is raised: ``` TypeError: handler() takes 0 positional arguments but 1 was given ``` **Steps to Reproduce**: 1. Create an `MCPToolAdapter` and connect it to an MCP server 2. Call `adapter.register_tools(registry, namespace="test")` 3. Create a `ToolRunner` with the registry 4. Call `runner.activate("test/some-tool")` then `runner.execute("test/some-tool", {"arg": "value"})` 5. Observe `TypeError: handler() takes 0 positional arguments but 1 was given` **Code Locations**: - `src/cleveragents/mcp/adapter.py` lines ~580-590 (handler definition in `_make_handler`) - `src/cleveragents/tool/runner.py` line ~488 (`raw_output = spec.handler(inputs)`) ## Expected Behavior MCP tools registered via `MCPToolAdapter.register_tools()` should execute successfully when invoked via `ToolRunner.execute()`. The handler should accept a positional `dict[str, Any]` argument matching the calling convention used by `ToolRunner`. ## Acceptance Criteria - [ ] `MCPToolAdapter._make_handler()` produces handlers with signature `(inputs: dict[str, Any]) -> dict[str, Any]` - [ ] `ToolRunner.execute()` successfully invokes MCP-registered tools without `TypeError` - [ ] All existing non-MCP tool handlers continue to work correctly - [ ] Integration test covering `MCPToolAdapter` → `ToolRunner` round-trip passes - [ ] No regressions in existing tool runner tests ## Subtasks - [ ] Update `_make_handler()` in `src/cleveragents/mcp/adapter.py` to use `def handler(inputs: dict[str, Any]) -> dict[str, Any]:` signature - [ ] Update the `ar.invoke(tn, kwargs)` call to `ar.invoke(tn, inputs)` accordingly - [ ] Audit any other handler factories in the MCP adapter for the same mismatch - [ ] Add or update unit tests for `MCPToolAdapter._make_handler()` to assert correct positional-dict calling convention - [ ] Add integration test: `MCPToolAdapter.register_tools()` → `ToolRunner.execute()` round-trip ## Definition of Done - [ ] All subtasks completed - [ ] A Git commit is created with the exact first line: `fix(mcp): align MCPToolAdapter handler signature with ToolRunner calling convention` - [ ] The commit is pushed to branch `fix/mcp-tool-handler-signature-mismatch` - [ ] A Pull Request has been submitted, reviewed, and merged - [ ] All nox stages pass - [ ] Coverage >= 97% > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.3.0. It does not block milestone completion and has been > placed in the backlog for human review and future milestone assignment. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#397 Epic: Server & Autonomy Infrastructure
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3708
No description provided.