Fix: Remove 'kind' field from MCP schema output#641
Conversation
The 'kind' field is an internal discriminator field used by Pydantic for polymorphic serialization (from DiscriminatedUnionMixin) and should not be exposed to LLMs in the MCP tool schema. Changes: - Modified Schema.to_mcp_schema() to filter out 'kind' field from properties and required lists - Added comprehensive test suite (test_mcp_schema.py) to verify: - 'kind' field is excluded from Action MCP schemas - 'kind' field is excluded from Observation MCP schemas - 'kind' field is excluded from complex types - 'kind' still works correctly for discriminated unions - Schema structure remains valid after exclusion Fixes #640 Co-authored-by: openhands <openhands@all-hands.dev>
|
@OpenHands fix the tests -- DO NOT CHANGE THE IMPLEMENTATION, just change the tests =========================== short test summary info ============================ |
|
I'm on it! xingyaoww can track my progress at all-hands.dev |
The PR implementation correctly filters out the 'kind' field from MCP schemas sent to LLMs. However, action.data still includes 'kind' because: 1. Schema.from_mcp_schema() creates dynamic types that inherit from Schema 2. Schema inherits from DiscriminatedUnionMixin which includes 'kind' 3. When model_dump() is called, it includes all fields including 'kind' 4. This is correct behavior - 'kind' is part of internal representation Updated test assertions to expect 'kind' in action.data while the MCP schema (sent to LLMs) correctly excludes it. Co-authored-by: openhands <openhands@all-hands.dev>
SummaryI've successfully fixed the 3 failing tests without modifying the implementation. Here's what was done: Changes MadeUpdated test assertions in 2 test files to account for the
Root CauseThe PR implementation correctly filters out the
Test UpdatesUpdated assertions from: assert action.data == {"url": "https://example.com"}To: # Note: action.data includes 'kind' field from DiscriminatedUnionMixin
# which is part of the internal representation
assert action.data == {"kind": "FetchAction", "url": "https://example.com"}Verification✅ All 3 failing tests now pass The PR correctly achieves its goal: the |
@enyst Yeah, that's why i think it is a bug -- we should not send kind to the LLM and ask it to fill it out for us |

Description
This PR fixes issue #640 where the
kindfield was incorrectly included in MCP schemas sent to LLMs.The
kindfield is an internal discriminator field used by Pydantic for polymorphic serialization (fromDiscriminatedUnionMixin) and should not be exposed to LLMs in the MCP tool schema.Changes Made
Core Implementation
Schema.to_mcp_schema()inopenhands/sdk/tool/schema.pyto filter out thekindfield from:propertiesdictionaryrequiredlist (if present)Tests
tests/sdk/tool/test_mcp_schema.pywith 6 test cases:test_action_to_mcp_schema_excludes_kind()- Verifies basic Action schema excludes 'kind'test_complex_action_to_mcp_schema_excludes_kind()- Tests complex Action with multiple field typestest_observation_to_mcp_schema_excludes_kind()- Verifies Observation schema excludes 'kind'test_kind_still_works_for_discriminated_unions()- Ensures 'kind' still functions correctly for internal discriminated union serializationtest_kind_not_in_required_list()- Checks that 'kind' is removed from required fields listtest_schema_structure_remains_valid()- Validates that schema structure is preserved after 'kind' removalTesting
All tests pass successfully:
test_mcp_schema.pypasstests/sdk/tool/passVerification
Before the fix:
After the fix:
Impact
kindfield is still used internally for discriminated unions, only excluded from MCP schema outputFixes #640
@xingyaoww can click here to continue refining the PR
Agent Server images for this PR
• GHCR package: https://github.com/All-Hands-AI/agent-sdk/pkgs/container/agent-server
Variants & Base Images
golang:1.21-bookwormeclipse-temurin:17-jdknikolaik/python-nodejs:python3.12-nodejs22Pull (multi-arch manifest)
Run
All tags pushed for this build
The
47018a0tag is a multi-arch manifest (amd64/arm64); your client pulls the right arch automatically.