Skip to content

fix: handle MCP tool arguments named kind#3803

Draft
rajshah4 wants to merge 1 commit into
mainfrom
codex/mcp-kind-schema-collision
Draft

fix: handle MCP tool arguments named kind#3803
rajshah4 wants to merge 1 commit into
mainfrom
codex/mcp-kind-schema-collision

Conversation

@rajshah4

@rajshah4 rajshah4 commented Jun 19, 2026

Copy link
Copy Markdown
Member

Summary

Fix MCP tool schema handling when a server exposes a valid tool argument named kind.

OpenHands uses kind internally as a discriminator on schema/action models. MCP tool servers can also define kind as a normal input argument in their JSON Schema, for example as a symbol-kind or node-kind filter. Before this change, that collision could break dynamic MCP action model creation or cause the external kind argument to be stripped during argument sanitization.

What changed

  • Alias MCP input fields that collide with OpenHands discriminator field names.
  • Preserve the original external MCP argument name when validating and dumping tool arguments.
  • Continue stripping OpenHands' internal computed kind when the MCP schema did not define it.
  • Add a regression test for a GitNexus-style code-intelligence tool schema with a kind argument.

Why

MCP tool input schemas define arbitrary object properties, and tools/call sends arbitrary argument keys. A tool argument named kind is therefore valid MCP. The client-side OpenHands schema adapter should tolerate that external schema shape without exposing or losing OpenHands' own discriminator.

This is related to prior MCP schema compatibility work such as #1509 and the DiscriminatedUnionMixin changes in #1555, but fixes a separate collision between external MCP arguments and OpenHands' internal discriminator field.

Tests

uv run pytest tests/sdk/mcp/test_mcp_tool_validation.py tests/sdk/mcp/test_mcp_tool_serialization.py tests/sdk/tool/test_client_tool.py::test_executor_returns_acknowledgment -q

Result: 9 passed.


Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.13-nodejs22-slim Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:93e813f-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-93e813f-python \
  ghcr.io/openhands/agent-server:93e813f-python

All tags pushed for this build

ghcr.io/openhands/agent-server:93e813f-golang-amd64
ghcr.io/openhands/agent-server:93e813f623d46b11889b6e844638ed35c38ace43-golang-amd64
ghcr.io/openhands/agent-server:codex-mcp-kind-schema-collision-golang-amd64
ghcr.io/openhands/agent-server:93e813f-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:93e813f-golang-arm64
ghcr.io/openhands/agent-server:93e813f623d46b11889b6e844638ed35c38ace43-golang-arm64
ghcr.io/openhands/agent-server:codex-mcp-kind-schema-collision-golang-arm64
ghcr.io/openhands/agent-server:93e813f-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:93e813f-java-amd64
ghcr.io/openhands/agent-server:93e813f623d46b11889b6e844638ed35c38ace43-java-amd64
ghcr.io/openhands/agent-server:codex-mcp-kind-schema-collision-java-amd64
ghcr.io/openhands/agent-server:93e813f-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:93e813f-java-arm64
ghcr.io/openhands/agent-server:93e813f623d46b11889b6e844638ed35c38ace43-java-arm64
ghcr.io/openhands/agent-server:codex-mcp-kind-schema-collision-java-arm64
ghcr.io/openhands/agent-server:93e813f-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:93e813f-python-amd64
ghcr.io/openhands/agent-server:93e813f623d46b11889b6e844638ed35c38ace43-python-amd64
ghcr.io/openhands/agent-server:codex-mcp-kind-schema-collision-python-amd64
ghcr.io/openhands/agent-server:93e813f-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-amd64
ghcr.io/openhands/agent-server:93e813f-python-arm64
ghcr.io/openhands/agent-server:93e813f623d46b11889b6e844638ed35c38ace43-python-arm64
ghcr.io/openhands/agent-server:codex-mcp-kind-schema-collision-python-arm64
ghcr.io/openhands/agent-server:93e813f-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-arm64
ghcr.io/openhands/agent-server:93e813f-golang
ghcr.io/openhands/agent-server:93e813f623d46b11889b6e844638ed35c38ace43-golang
ghcr.io/openhands/agent-server:codex-mcp-kind-schema-collision-golang
ghcr.io/openhands/agent-server:93e813f-golang_tag_1.21-bookworm
ghcr.io/openhands/agent-server:93e813f-java
ghcr.io/openhands/agent-server:93e813f623d46b11889b6e844638ed35c38ace43-java
ghcr.io/openhands/agent-server:codex-mcp-kind-schema-collision-java
ghcr.io/openhands/agent-server:93e813f-eclipse-temurin_tag_17-jdk
ghcr.io/openhands/agent-server:93e813f-python
ghcr.io/openhands/agent-server:93e813f623d46b11889b6e844638ed35c38ace43-python
ghcr.io/openhands/agent-server:codex-mcp-kind-schema-collision-python
ghcr.io/openhands/agent-server:93e813f-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim

About Multi-Architecture Support

  • Each variant tag (e.g., 93e813f-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., 93e813f-python-amd64) are also available if needed

@github-actions

Copy link
Copy Markdown
Contributor

Python API breakage checks — ✅ PASSED

Result:PASSED

Action log

@github-actions

Copy link
Copy Markdown
Contributor

REST API breakage checks (OpenAPI) — ✅ PASSED

Result:PASSED

Action log

@github-actions

Copy link
Copy Markdown
Contributor

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-sdk/openhands/sdk/mcp
   tool.py1271687%71, 85–88, 225, 232, 234–236, 306–307, 312, 320, 348, 378
openhands-sdk/openhands/sdk/tool
   schema.py163696%209, 248–249, 374–375, 382
openhands-sdk/openhands/sdk/utils
   models.py1623180%42–43, 78, 80, 88–92, 178, 225–227, 230, 233, 237, 247, 285, 293, 296–297, 300, 351–352, 354–356, 358, 362, 364, 368
TOTAL32448899672% 

@rajshah4

Copy link
Copy Markdown
Member Author

Keeping this as draft for maintainer feedback because it touches the shared discriminator path. The regression is MCP-specific: valid tool schemas can define an argument named kind, which currently collides with OpenHands' internal kind discriminator. Happy to narrow this further if you prefer the fix to live entirely in MCP schema import/sanitization.

@rajshah4 rajshah4 added bug Something isn't working mcp sdk labels Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working mcp sdk

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant