Skip to content

Extract MCP transport handler#329

Merged
ramimbo merged 1 commit into
ramimbo:mainfrom
shootingallday:shootingallday/code-health-320
May 25, 2026
Merged

Extract MCP transport handler#329
ramimbo merged 1 commit into
ramimbo:mainfrom
shootingallday:shootingallday/code-health-320

Conversation

@shootingallday
Copy link
Copy Markdown
Contributor

@shootingallday shootingallday commented May 25, 2026

Refs #320

Summary

  • Extract the /mcp JSON-RPC transport handling from app/main.py into app/mcp.py.
  • Keep tool dispatch behavior delegated to the existing _call_mcp_tool() implementation, so public MCP behavior stays unchanged.
  • Centralize MCP tool metadata, request validation, error shaping, and structured-content response shaping behind handle_mcp_request().

Complexity reduced

app/main.py no longer carries the MCP transport parser and response boilerplate inline with route/page/admin wiring. The MCP boundary is now easier to review independently: app/mcp.py owns protocol-level JSON-RPC handling, while app/main.py only wires the route to the existing business dispatch function.

Evidence

  • uv run --extra dev python -m pytest tests/test_api_mcp.py -q -> 68 passed.
  • uv run --extra dev ruff check app/main.py app/mcp.py tests/test_api_mcp.py -> passed.
  • uv run --extra dev ruff format --check app/main.py app/mcp.py tests/test_api_mcp.py -> passed.
  • uv run --extra dev python -m mypy app/main.py app/mcp.py -> success.
  • git diff --check -> clean.

Safety

  • No MCP tool semantics, ledger behavior, wallet behavior, webhook behavior, admin behavior, payouts, or public pages are intentionally changed.
  • No secrets, wallet private keys, payout credentials, private vulnerability details, deployment values, or MRWK price claims are included.

Summary by CodeRabbit

  • Refactor

    • Improved code organization by restructuring how Model Context Protocol (MCP) requests are processed internally for better maintainability.
  • Improvements

    • Enhanced error detection and validation for tool operations.
    • Better error reporting and response formatting for MCP tool requests.
    • Improved handling of various failure scenarios in tool execution.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 79f28bf7-eb9e-4ecc-8731-3bff9af95012

📥 Commits

Reviewing files that changed from the base of the PR and between 55608e3 and 7cba74e.

📒 Files selected for processing (2)
  • app/main.py
  • app/mcp.py

📝 Walkthrough

Walkthrough

The PR extracts JSON-RPC request handling logic from the /mcp POST endpoint in main.py into a new app/mcp.py module, centralizing tool catalog definition, request parsing, parameter validation, tool invocation, exception mapping, and response formatting into a reusable handle_mcp_request handler that accepts an injected tool execution callback.

Changes

MCP Handler Module Extraction

Layer / File(s) Summary
MCP tools catalog and handler contract
app/mcp.py
Defines MCPToolHandler type alias for tool execution callbacks and MCP_TOOLS list with metadata for tools/list responses.
JSON-RPC response handling and request dispatcher
app/mcp.py
Implements helper functions to construct JSON-RPC error objects and format tool results (dict as structured content, non-dict as text), then implements handle_mcp_request to parse the JSON-RPC body, route tools/list vs. tools/call, validate params, params.arguments, and tool name type, invoke the injected call_tool callback, catch KeyError, TypeError, ValueError, LedgerError, and HTTPException as invalid argument errors, and return structured JSON-RPC responses.
Endpoint delegation to centralized handler
app/main.py
Imports handle_mcp_request and updates the /mcp endpoint to delegate request handling instead of executing inline parsing and tool dispatch logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • ramimbo/mergework#239: Modifies get_wallet normalization in _call_mcp_tool to raise HTTPException, which is now caught and mapped to JSON-RPC "invalid arguments" error by the new centralized handler.

Suggested reviewers

  • Karry2019web
  • weilixiong
  • TateLyman
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: extracting MCP transport handler logic from main.py into a new dedicated module, which is clear and specific.
Description check ✅ Passed The description includes summary, evidence of testing (pytest, ruff, mypy), safety notes, and related issue reference (#320), covering all critical template sections comprehensively.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Copy link
Copy Markdown
Contributor

@ayskobtw-lil ayskobtw-lil left a comment

Choose a reason for hiding this comment

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

No blockers from my review on current head 7cba74e30fe03446f1be6e56eef4df2782650a80.

Evidence checked:

  • Inspected app/mcp.py and the delegated /mcp route in app/main.py.
  • Compared the extracted tools/list, tools/call, malformed request, parse-error, invalid params, invalid tool-arguments, structuredContent, and text-result paths against the previous inline implementation.
  • Verified _call_mcp_tool() remains the business dispatch boundary and the new handler only owns JSON-RPC transport/error shaping.
  • Confirmed CodeRabbit reports no actionable comments and hosted CI is green.

Validation run locally:

  • python -m pytest tests/test_api_mcp.py -q -> 68 passed.
  • python -m ruff check app/main.py app/mcp.py tests/test_api_mcp.py -> passed.
  • python -m ruff format --check app/main.py app/mcp.py tests/test_api_mcp.py -> passed.
  • python -m mypy app/main.py app/mcp.py -> success.
  • git diff --check origin/main...HEAD -> clean.

Residual risk is limited to future drift between MCP_TOOLS metadata and _call_mcp_tool() behavior, but this PR preserves the current advertised tool set and response shape.

@ramimbo ramimbo merged commit cd9cfae into ramimbo:main May 25, 2026
2 checks passed
@ramimbo ramimbo added mrwk:accepted Maintainer accepted for payout mrwk:paid Ledger payment recorded labels May 25, 2026
Copy link
Copy Markdown
Contributor

@artylobos artylobos left a comment

Choose a reason for hiding this comment

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

Reviewed the MCP transport extraction in PR #329.

Evidence checked:

  • Inspected app/mcp.py and the delegated /mcp route in app/main.py, and compared the extracted handler against the prior inline JSON-RPC handling from origin/main.
  • Verified parse-error, non-object request, unknown method, invalid params/arguments, missing tool name, invalid tool argument, tools/list, string tool result, and dict structuredContent behavior are still covered by the MCP tests.
  • Confirmed app/main.py now only wires the route to _call_mcp_tool, while protocol-level request validation and result shaping live in app/mcp.py.

Validation run locally on the PR head:

  • git diff --check origin/main...HEAD -> clean.
  • uv run --extra dev python -m pytest tests/test_api_mcp.py -q -> 68 passed.
  • uv run --extra dev ruff check app/main.py app/mcp.py tests/test_api_mcp.py -> passed.
  • uv run --extra dev ruff format --check app/main.py app/mcp.py tests/test_api_mcp.py -> 3 files already formatted.
  • uv run --extra dev python -m mypy app/main.py app/mcp.py -> success.

No blockers found. Residual risk is limited to the tool catalog now being a module-level mutable list, but this is equivalent for the current tools/list response path and not a merge blocker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mrwk:accepted Maintainer accepted for payout mrwk:paid Ledger payment recorded

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants