fix(mcp): reject tools/call requests with non-object arguments#99180
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 7, 2026, 6:23 AM ET / 10:23 UTC. Summary PR surface: Source +5, Tests +67. Total +72 across 2 files. Reproducibility: yes. at source level: current main casts Review metrics: 1 noteworthy metric.
Stored data model Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land the narrow handler validation and regression coverage once a Gateway/MCP owner explicitly accepts the stricter malformed-client boundary. Do we have a high-confidence way to reproduce the issue? Yes at source level: current main casts Is this the best way to solve the issue? Yes, conditional on maintainer acceptance of the compatibility break: validating at the raw HTTP MCP handler is narrower than changing stdio handling or adding broad per-tool schema validation for this boundary. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 9fb24032215a. Label changesLabel justifications:
Evidence reviewedPR surface: Source +5, Tests +67. Total +72 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (7 earlier review cycles)
|
|
Updated the PR body to remove the leading BOM and added the requested loopback behavior proof: malformed The Real behavior proof check is now passing. @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Strengthened the proof without expanding the production scope. The handler change is unchanged and remains limited to the Gateway HTTP Focused validation: @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Strengthened the PR proof without changing code: added the SDK argument-contract rationale, sibling stdio-surface comparison, accepted/rejected argument matrix, and current proof/check status. The PR body is now UTF-8 without BOM.\n\n@clawsweeper re-review |
|
Added a small test-only proof update on top of the latest PR head. What changed:
This completes the proof triangle: present non-object values are rejected before side effects, omitted @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
All checks are green on the latest pushed head (8073af6). The branch was synced with upstream/main; the current BEHIND state is from newer unrelated upstream churn in QA/GitHub Copilot files and does not touch this MCP gateway change. @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
2652005 to
412ef8c
Compare
Co-authored-by: VectorPeak <[email protected]>
412ef8c to
705e63a
Compare
|
Land-ready maintainer verification:
No unresolved review threads or known proof gaps remain. |
|
Merged via squash.
|
Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
What Problem This Solves
The raw Gateway MCP loopback handler accepted any JSON value in
tools/call.params.argumentsand cast it to an object record. Malformednull, array, or primitive arguments could therefore reach before-tool hooks and tool implementations even though MCP defines this field as an optional object map.Why This Change Was Made
The loopback handler now rejects a present non-object
argumentsvalue with JSON-RPC-32602before hooks, capture preparation, or tool execution. Omitted arguments still become{}, and valid object arguments pass through unchanged.This is deliberately limited to the raw loopback HTTP boundary. The sibling stdio MCP server already registers
CallToolRequestSchemafrom the SDK and receives the same validation there. Applying full per-tool schema validation or parsing every loopback request through the SDK would broaden behavior beyond this malformed envelope.User Impact
Valid MCP clients are unchanged. Clients sending malformed primitive,
null, or array tool arguments now receiveInvalid params: tools/call arguments must be an objectinstead of passing the wrong runtime shape into OpenClaw tools.Evidence
@modelcontextprotocol/sdk1.29.0 definesCallToolRequestParamsSchema.argumentsasz.record(z.string(), z.unknown()).optional()indist/esm/types.js;src/mcp/tools-stdio-server.tsuses that request schema.run_2be60da5f513combined the regression test with current-mainsrc/gateway/mcp-http.handlers.tsand reproduced the malformed-arguments failure.run_6273eafe9b17, provideraws, leasecbx_e322edfdf5fc:pnpm test src/gateway/mcp-http.test.tspassed 272/272 tests across four Gateway projects before the test-only mock typing correction.28858393759passed on705e63af0e793e46db0467031e1f405db93568a9, includingcheck-test-typesand every selected test shard. A repeat sanitized AWS attempt (run_1fa1a1d425db) could not install dependencies because AWS fell the requested beast lease back to at3.smalland the install was OOM-killed.null, array, and string inputs return-32602with zero hook/tool calls; omitted arguments reach both as{}; the existing object execution test now verifies a non-empty argument object reaches the hook and executor unchanged.mainas one commit, preserving contributor credit withCo-authored-by: VectorPeak.git diff --checkpassed.705e63af0e793e46db0467031e1f405db93568a9was clean with 0.92 confidence.