Skip to content

Reject unexpected MCP read tool arguments#899

Open
xiefuzheng713-alt wants to merge 1 commit into
ramimbo:mainfrom
xiefuzheng713-alt:codex/mcp-read-tool-args-844
Open

Reject unexpected MCP read tool arguments#899
xiefuzheng713-alt wants to merge 1 commit into
ramimbo:mainfrom
xiefuzheng713-alt:codex/mcp-read-tool-args-844

Conversation

@xiefuzheng713-alt
Copy link
Copy Markdown

@xiefuzheng713-alt xiefuzheng713-alt commented Jun 4, 2026

Bounty #844

Summary

  • reject undeclared arguments for read-only MCP selector tools: get_bounty, list_bounty_attempts, get_balance, get_wallet, get_ledger_entry, and get_proof;
  • prevent typoed agent fields like { acount: ... } or { seq: 2 } from being silently ignored while the tool succeeds;
  • keep valid calls and existing response shapes unchanged.

Duplicate / Scope Check

Validation

  • uv run --python 3.12 --extra dev python -m pytest tests/test_mcp_tools.py tests/test_api_mcp.py::test_mcp_read_tools_reject_unexpected_arguments -q -> 19 passed, 1 existing warning.
  • uv run --python 3.12 --extra dev python -m pytest tests/test_api_mcp.py tests/test_mcp_tools.py -q -> 124 passed, 1 existing warning.
  • uv run --python 3.12 --extra dev ruff check app/mcp_tools.py tests/test_api_mcp.py tests/test_mcp_tools.py -> passed.
  • uv run --python 3.12 --extra dev ruff format --check app/mcp_tools.py tests/test_api_mcp.py tests/test_mcp_tools.py -> 3 files already formatted.
  • uv run --python 3.12 --extra dev mypy app/mcp_tools.py app/mcp.py -> success.
  • uv run --python 3.12 --extra dev python scripts/docs_smoke.py -> docs smoke ok.
  • git diff --check origin/main...HEAD -> clean.
  • git merge-tree --write-tree origin/main HEAD -> clean tree abda6f4c7b8cc6d19c1ef4bc0fd2711b121cfce1.

Summary by CodeRabbit

  • Bug Fixes
    • MCP tool calls (get_bounty, list_bounty_attempts, get_balance, get_wallet, get_ledger_entry, get_proof) now validate input arguments and reject unexpected fields with clear error messages.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 64c45930-08b4-4c60-997d-4a648c017cda

📥 Commits

Reviewing files that changed from the base of the PR and between d4d0e48 and 3672fce.

📒 Files selected for processing (3)
  • app/mcp_tools.py
  • tests/test_api_mcp.py
  • tests/test_mcp_tools.py

📝 Walkthrough

Walkthrough

This PR adds input validation to MCP read tools by introducing a reject_unexpected_args helper that rejects any argument keys not in a tool-specific allowed set. The validation is applied to six tools and covered by unit and integration tests.

Changes

MCP Tool Argument Validation

Layer / File(s) Summary
Validation helper and tool integration
app/mcp_tools.py
reject_unexpected_args(allowed) helper validates argument keys against an allowed set and raises ValueError on unexpected keys. Applied to get_bounty, list_bounty_attempts, get_balance, get_wallet, get_ledger_entry, and get_proof tool branches, each specifying its own allowed argument set.
Unit test validation
tests/test_mcp_tools.py
Parametrized test calls call_mcp_tool with multiple read tools and unexpected argument keys, asserting ValueError with unexpected argument: ... message.
HTTP integration tests
tests/test_api_mcp.py
Parametrized test calls /mcp endpoint with unexpected argument payloads for read tools, asserting JSON-RPC response contains invalid tool arguments error code.

Possibly Related Issues

  • ramimbo/mergework#794: Addresses MCP schema and runtime argument validation conformance by enforcing rejection of undeclared tool arguments at runtime.

Possibly Related PRs

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Bounty Pr Focus ⚠️ Warning PR diff matches stated scope and includes proper test coverage for all 6 read tools, but commit message lacks required Bounty #844 or Refs #844 reference per PR template. Add Bounty #844 or Refs #844 reference to commit message or PR description to document the tracking issue.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title directly names the changed surface—rejecting unexpected MCP read tool arguments—and matches the core change in the changeset.
Description check ✅ Passed Description includes summary, scope/duplicate checks, and comprehensive validation results, though Evidence section headings differ from template structure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Mergework Public Artifact Hygiene ✅ Passed PR contains only code changes for MCP tool argument validation. No README, docs, or public changes. No problematic investment, price, cash-out, payout, or security claims.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@mauricemohr88-debug mauricemohr88-debug left a comment

Choose a reason for hiding this comment

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

Current-head review for #838 on 3672fce64c17284b941dcbeac5ad6578a5ea54a9.

Evidence checked:

  • Inspected app/mcp_tools.py; the new reject_unexpected_args guard is applied to the read-only selector tools get_bounty, list_bounty_attempts, get_balance, get_wallet, get_ledger_entry, and get_proof.
  • Verified valid current-main selectors remain in the allowed sets, while typoed extra fields fail before a tool can succeed with misleading ignored input.
  • Inspected tests/test_api_mcp.py and tests/test_mcp_tools.py; coverage exercises unexpected arguments through both the MCP HTTP layer and the direct tool dispatcher.
  • Confirmed GitHub reports PR #899 open, current head 3672fce64c17284b941dcbeac5ad6578a5ea54a9, merge state clean, and both visible checks successful.
  • Ran uv run --python 3.12 --extra dev python -m pytest tests/test_mcp_tools.py tests/test_api_mcp.py::test_mcp_read_tools_reject_unexpected_arguments -q: 19 passed, 1 existing Starlette warning.
  • Ran uv run --python 3.12 --extra dev python -m pytest tests/test_api_mcp.py tests/test_mcp_tools.py -q: 124 passed, 1 existing warning.
  • Ran uv run --python 3.12 --extra dev ruff check app/mcp_tools.py tests/test_api_mcp.py tests/test_mcp_tools.py: passed.
  • Ran uv run --python 3.12 --extra dev ruff format --check app/mcp_tools.py tests/test_api_mcp.py tests/test_mcp_tools.py: 3 files already formatted.
  • Ran uv run --python 3.12 --extra dev mypy app/mcp_tools.py app/mcp.py: success.
  • Ran uv run --python 3.12 --extra dev python scripts/docs_smoke.py: docs smoke ok.
  • Ran git diff --check origin/main...HEAD and git merge-tree --write-tree origin/main HEAD: clean.

One queue-integration note: this is clean against current origin/main, but it overlaps PR #893 in app/mcp_tools.py. git merge-tree origin/main origin/pr/893 origin/pr/899 reports conflicts around the helper definitions plus the get_ledger_entry and get_proof selector handling. If #893 lands first, this PR should keep its new proof_hash and ledger_sequence aliases in the allowed argument sets instead of reverting those alias paths back to only hash and sequence.

I do not see a current-main blocker. The runtime guard is useful and test-backed; the only caution is the explicit rebase/merge coordination with #893 before final landing order.

Copy link
Copy Markdown
Contributor

@MolhamHamwi MolhamHamwi left a comment

Choose a reason for hiding this comment

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

Reviewed current head 3672fce64c17284b941dcbeac5ad6578a5ea54a9 for the MCP read-tool argument guard.

Evidence checked:

  • app/mcp_tools.py: the new reject_unexpected_args() helper is called before read-tool-specific parsing for get_bounty, list_bounty_attempts, get_balance, get_wallet, get_ledger_entry, and get_proof. That ordering is important because typo/unknown keys now fail deterministically instead of being silently ignored while another selector is accepted.
  • tests/test_mcp_tools.py: direct call_mcp_tool() coverage confirms each read tool raises the exact unexpected argument name, including typo-like cases such as acount.
  • tests/test_api_mcp.py: JSON-RPC coverage confirms the same failures are surfaced as -32602 invalid tool arguments without leaking internal validation text.
  • CI is green on the PR, and local focused verification passed with:
    uv run pytest tests/test_mcp_tools.py::test_call_mcp_tool_rejects_unexpected_read_tool_arguments tests/test_api_mcp.py::test_mcp_read_tools_reject_unexpected_arguments -q
    Result: 12 passed, 1 warning.

I do not see a blocker. The scope is focused on read tools only and does not change write-tool argument compatibility.

Disclosure: This review is submitted for the MRWK review bounty.

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