Skip to content

Comments

fix: update MergeAgentHandlerTool to rightly handle MCP protocol#4255

Open
mplacona wants to merge 11 commits intocrewAIInc:mainfrom
mplacona:main
Open

fix: update MergeAgentHandlerTool to rightly handle MCP protocol#4255
mplacona wants to merge 11 commits intocrewAIInc:mainfrom
mplacona:main

Conversation

@mplacona
Copy link

@mplacona mplacona commented Jan 20, 2026

Disclosure: I worked with Merge on getting this PR together

Problem

The MergeAgentHandlerTool was not correctly handling the Agent Handler MCP protocol's parameter format:

  1. Agent Handler wraps all parameters in an input object
  2. MCP protocol uses inputSchema instead of parameters for tool schemas
  3. Schema parsing didn't handle anyOf nullable type definitions
  4. Pydantic schema exposed the wrapper object instead of actual parameters

This caused tools to fail when called by CrewAI agents.

Solution

Parameter Wrapping

  • Wrap all arguments in an {"input": kwargs} structure before sending to Agent Handler
  • Add backwards compatibility to detect pre-wrapped input and pass through as-is

Schema Parsing

  • Updated to parse inputSchema from MCP responses (not parameters)
  • Automatically unwrap the input object to expose actual tool parameters in Pydantic schema
  • This ensures CrewAI agents see the real parameters (e.g., title, description) instead of just input

Nullable Type Support

  • Added support for anyOf type definitions commonly used for nullable fields
  • Properly marks nullable fields as optional with None default values
  • Correctly infers the primary type from anyOf definitions

Debugging Improvements

  • Added debug logging when inputSchema is missing from responses
  • Better error messages for schema parsing failures

Testing

  • Updated all test mocks to use inputSchema format matching real MCP responses
  • Added tests for schema parsing from inputSchema
  • Added tests for anyOf nullable type handling
  • Added tests for backwards compatibility with pre-wrapped input
  • Verified all tests pass with new parameter wrapping logic

Impact

  • Tools now work correctly with Agent Handler MCP protocol
  • Pydantic schemas correctly represent actual tool parameters
  • CrewAI agents can properly invoke Agent Handler tools
  • Backwards compatible with any existing code that pre-wraps parameters

Note

Medium Risk
Changes affect how all Agent Handler tool calls are serialized and how Pydantic argument schemas are inferred, which can break integrations if assumptions differ from real MCP responses. Coverage is strong, but runtime behavior depends on external schema variations.

Overview
Fixes MergeAgentHandlerTool to match Agent Handler’s MCP protocol by wrapping tool call arguments under input (with pass-through support for legacy pre-wrapped calls) and by parsing tool schemas from inputSchema instead of parameters.

Schema generation now unwraps the top-level input object so args_schema exposes real tool parameters, and adds handling for nullable JSON Schema definitions via anyOf (including keeping required-but-nullable fields required). Tests were updated to use inputSchema, assert input-wrapped requests, and add coverage for nullable/required/optional schema edge cases and backwards-compat behavior.

Written by Cursor Bugbot for commit ab16c4b. This will update automatically on new commits. Configure here.

…l correctly

## Problem
The MergeAgentHandlerTool was not correctly handling the Agent Handler MCP protocol's parameter format:
1. Agent Handler wraps all parameters in an `input` object
2. MCP protocol uses `inputSchema` instead of `parameters` for tool schemas
3. Schema parsing didn't handle `anyOf` nullable type definitions
4. Pydantic schema exposed the wrapper object instead of actual parameters

This caused tools to fail when called by CrewAI agents.

## Solution

### Parameter Wrapping
- Wrap all arguments in an `{"input": kwargs}` structure before sending to Agent Handler
- Add backwards compatibility to detect pre-wrapped input and pass through as-is

### Schema Parsing
- Updated to parse `inputSchema` from MCP responses (not `parameters`)
- Automatically unwrap the `input` object to expose actual tool parameters in Pydantic schema
- This ensures CrewAI agents see the real parameters (e.g., `title`, `description`) instead of just `input`

### Nullable Type Support
- Added support for `anyOf` type definitions commonly used for nullable fields
- Properly marks nullable fields as optional with `None` default values
- Correctly infers the primary type from `anyOf` definitions

### Debugging Improvements
- Added debug logging when `inputSchema` is missing from responses
- Better error messages for schema parsing failures

## Testing
- Updated all test mocks to use `inputSchema` format matching real MCP responses
- Added tests for schema parsing from `inputSchema`
- Added tests for `anyOf` nullable type handling
- Added tests for backwards compatibility with pre-wrapped input
- Verified all tests pass with new parameter wrapping logic

## Impact
- Tools now work correctly with Agent Handler MCP protocol
- Pydantic schemas correctly represent actual tool parameters
- CrewAI agents can properly invoke Agent Handler tools
- Backwards compatible with any existing code that pre-wraps parameters
Copy link
Contributor

@gilfeig gilfeig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

cursor[bot]

This comment was marked as outdated.

Separate nullable type annotation from optional default value in
schema parsing. Previously, required nullable fields were incorrectly
given a None default, allowing callers to omit them. This caused API
errors when backends distinguish between missing fields and explicit
null values.

Changes:
- Split nullable (type accepts None) from optional (has default)
- Required nullable fields now require explicit value (can be None)
- Improve input parameter wrapping check with isinstance guard
- Add comprehensive tests for all field type combinations

All 27 tests pass, confirming fix works without breaking existing
functionality.
@mplacona
Copy link
Author

mplacona commented Feb 3, 2026

@lorenzejay could you please help me get this past the finish line? Thanks

@lorenzejay
Copy link
Collaborator

any chance you can send a loom video of this working or help me build a way to test this out?

"name": "linear__create_issue",
"description": "Creates a new issue in Linear",
"parameters": {
"inputSchema": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

function calling expects paramters. Why are we changing this to inputScheme?

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

elif json_type == "array":
field_type = list[Any]
elif json_type == "object":
field_type = dict[str, Any]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated JSON-to-Python type mapping logic blocks

Low Severity

The JSON schema type-to-Python type mapping logic (mapping "string"str, "integer"int, etc.) is fully duplicated: once inside the anyOf branch and once in the else branch. Extracting this into a small helper function or dict lookup would reduce the maintenance burden and ensure any future type mapping changes are applied consistently in both paths.

Fix in Cursor Fix in Web

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.

3 participants