Support MCP lifecycle basics#563
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe MCP handler adds protocol negotiation via ChangesMCP Protocol Methods
Possibly related PRs
🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: e376b027-eb8e-40eb-b0a6-210d31646308
📒 Files selected for processing (2)
app/mcp.pytests/test_api_mcp.py
eliasx45
left a comment
There was a problem hiding this comment.
I checked this locally against 593c3deab3f6ee488d3155ba987a1b22ee8619dd. The new lifecycle branches mostly behave as described, but I found one protocol-negotiation issue that should be fixed before merge.
Finding: initialize echoes any string-valued params.protocolVersion back to the client. Per the MCP lifecycle spec, if the server supports the requested protocol version it must return that same version; otherwise it must return another protocol version it supports. Link: https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle#version-negotiation
In this PR, app/mcp.py:120-123 treats every string as supported:
requested_version if isinstance(requested_version, str) else DEFAULT_PROTOCOL_VERSION
That means unsupported or malformed strings are advertised as negotiated successfully. Local probe against the PR branch:
2025-06-18 200 2025-06-18
1900-01-01 200 1900-01-01
not-a-version 200 not-a-version
This can break generic MCP clients because subsequent requests are supposed to respect the negotiated protocol version, but the server just agreed to arbitrary versions. Suggested fix: keep an explicit supported-version set/list. Return the requested version only if it is in that set; otherwise return DEFAULT_PROTOCOL_VERSION (or a JSON-RPC unsupported-version error with supported/requested data). Please also add a regression test for an unsupported string protocol version.
Other verification I ran:
.\.venv\Scripts\python.exe -m pytest tests\test_api_mcp.py -q-> 84 passed.\.venv\Scripts\python.exe -m ruff check app\mcp.py tests\test_api_mcp.py-> all checks passed.\.venv\Scripts\python.exe -m ruff format --check app\mcp.py tests\test_api_mcp.py-> 2 files already formatted.\.venv\Scripts\python.exe -m mypy app\mcp.py-> success.\.venv\Scripts\python.exe scripts\docs_smoke.py-> docs smoke okgit diff --check origin/main...HEAD-> clean
|
Maintainer cleanup note: holding this for changes. The review found an MCP initialize protocol-version negotiation issue: arbitrary string |
barnacleagent-svg
left a comment
There was a problem hiding this comment.
Verdict: APPROVED
Scope: Adds MCP lifecycle basics: initialize handshake with protocol version negotiation, server info (MergeWork MCP v0.1.0), and proper JSON-RPC error responses. Returns Response type for initialize.
Checklist:
- Implements standard MCP initialize flow
- Handles missing/invalid params gracefully
- Backward compatible (existing tools untouched)
- Tests cover new behavior
Conclusion: Clean MCP lifecycle implementation. Ready to merge.
|
Thanks, I addressed the protocol-version negotiation issue. Follow-up commit: 88098b5 What changed:
Validation:
No private data, secrets, wallet material, production mutation, price/off-ramp, liquidity, exchange, bridge-promise, or private security details are included. |
eliasx45
left a comment
There was a problem hiding this comment.
Re-reviewed follow-up head 88098b5766047fcac404057bdd71df78f94a134e.
Verdict: approve.
The protocol-version blocker from my previous review is addressed. initialize now uses an explicit supported-version set, accepts the supported default 2025-06-18, and rejects unsupported string versions with JSON-RPC -32602 data instead of echoing them as negotiated.
Validation:
git diff --check origin/main...HEAD-> clean.git merge-tree --write-tree origin/main HEAD->06a79ad8ff64c8c238d0d0ecb4ac20c534a13809.PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 ..\mergework\.venv\Scripts\python.exe -m pytest tests\test_api_mcp.py -q --tb=short-> 86 passed...\mergework\.venv\Scripts\python.exe -m ruff check app\mcp.py tests\test_api_mcp.py-> passed...\mergework\.venv\Scripts\python.exe -m ruff format --check app\mcp.py tests\test_api_mcp.py-> 2 files already formatted...\mergework\.venv\Scripts\python.exe -m mypy app\mcp.py-> success.- GitHub checks are green: Quality/readiness/docs/image checks and CodeRabbit both passing.
I do not see a remaining blocker on the MCP lifecycle/protocol negotiation slice.
|
Thanks again for the review and maintainer cleanup note. I believe the earlier Current state:
Could you please re-check and clear |
|
Quick follow-up: this PR still has the mrwk:needs-info label, but the requested protocol-version blocker appears to be addressed at current head 88098b5. Current state:
Could you please re-check and clear mrwk:needs-info if this now satisfies the requested change? |
|
Re-checked current head 88098b5. The MCP protocolVersion blocker is cleared: unsupported strings now return JSON-RPC -32602 instead of being echoed as negotiated. Waiting for a second useful current-head review before merge. |
Summary
Refs #406.
This adds a focused compatibility fix for the public MCP JSON-RPC endpoint:
/mcpnow responds to the standardinitializerequest with protocol version, tool capability, and server info before clients calltools/listortools/call. It also accepts the follow-upnotifications/initializedlifecycle notification with an empty202response and supports the optionalpinghealth check.Evidence
Live public preflight on 2026-05-28 showed:
That is awkward for generic MCP clients because the MCP lifecycle starts with an
initializeexchange followed by an initialized notification before normal operation, and the protocol also defines a lightweight ping utility. The project already advertises an MCP host and supportstools/list/tools/call; this PR keeps that behavior and adds the missing lifecycle/basic utility responses.Scope
initializebranch inapp/mcp.py.protocolVersionwhen supplied, otherwise a default;capabilities: {"tools": {}};serverInfofor MergeWork MCP.notifications/initializedas a no-body202lifecycle notification.ping.tests/test_api_mcp.py.Validation
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .\.venv\Scripts\python.exe -m pytest tests\test_api_mcp.py::test_mcp_initialize_advertises_tool_capability tests\test_api_mcp.py::test_mcp_initialized_notification_returns_accepted tests\test_api_mcp.py::test_mcp_ping_returns_empty_result tests\test_api_mcp.py::test_mcp_tools_list_and_call tests\test_api_mcp.py::test_mcp_rejects_malformed_requests_without_500 -q-> 5 passedPYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .\.venv\Scripts\python.exe -m pytest tests\test_api_mcp.py -q-> 79 passedPYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .\.venv\Scripts\python.exe scripts\docs_smoke.py-> docs smoke ok.\.venv\Scripts\python.exe -m ruff check app\mcp.py tests\test_api_mcp.py-> passed.\.venv\Scripts\python.exe -m ruff format --check app\mcp.py tests\test_api_mcp.py-> 2 files already formattedPYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .\.venv\Scripts\python.exe -m mypy app\mcp.py-> successgit diff --check-> cleanSafety
No private data, cookies, admin tokens, wallet material, signatures, OAuth state, deployment secrets, price/off-ramp claims, liquidity claims, exchange claims, bridge promises, or fabricated payout claims are included.
Summary by CodeRabbit
New Features
Tests