feat(cursor-review): collect structured output through MCP tools#33
feat(cursor-review): collect structured output through MCP tools#33huntcsg wants to merge 4 commits into
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 47 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (11)
📝 WalkthroughWalkthroughThe Cursor Review pipeline replaces raw JSON extraction with a stdio MCP server that validates and atomically persists panel and judge findings. Prompts, workflows, status handling, documentation, and tests now use the structured-output lifecycle. ChangesCursor Review MCP pipeline
Sequence Diagram(s)sequenceDiagram
participant PanelAgent
participant ReviewerMCP
participant PanelJSON
participant JudgeAgent
participant JudgeMCP
PanelAgent->>ReviewerMCP: Record findings and finish
ReviewerMCP->>PanelJSON: Persist structured panel record
JudgeAgent->>JudgeMCP: Submit final findings
JudgeMCP->>PanelJSON: Persist structured judge record
JudgeMCP-->>JudgeAgent: Return tool result
Suggested reviewers: 🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
eb033f3 to
4fcfbbe
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/cursor-review/review-output-mcp.py:
- Line 228: Update the call_tool invocation in the tool-processing flow to pass
params.get("arguments") unchanged, removing the `or {}` fallback. Preserve
malformed falsy values such as lists, booleans, and strings so downstream
validation can reject them, while retaining the existing default behavior for
truly absent arguments if supported by call_tool.
In @.github/cursor-review/tests/test_review_output_mcp.py:
- Around line 111-119: Update test_invalid_tool_input_does_not_replace_output to
snapshot the initialized record before submission, then send a findings list
containing both valid and invalid entries. Keep the existing error assertions
and additionally fetch or inspect the persisted record afterward, asserting it
exactly matches the initial snapshot.
In @.github/workflows/cursor-review.yml:
- Around line 369-374: Replace the PR-controlled .cursor entry with a fresh
workflow-owned directory before writing trusted configuration: at
.github/workflows/cursor-review.yml lines 369-374, remove the existing .cursor
path and recreate it before the first configuration step; apply the same
replacement at lines 514-519 before configuring judge output. Do not rely only
on symlink detection, since the entry may be a file or other conflicting path.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0b3f97d5-a351-4f7b-998f-cb2ed070dc6d
📒 Files selected for processing (11)
.github/cursor-review/README.md.github/cursor-review/extract-findings.py.github/cursor-review/post-review.py.github/cursor-review/prompt-adversarial.md.github/cursor-review/prompt-edge-case.md.github/cursor-review/prompt-judge.md.github/cursor-review/review-output-mcp.py.github/cursor-review/tests/test_extract_findings.py.github/cursor-review/tests/test_review_output_mcp.py.github/workflows/cursor-review.yml.github/workflows/test-cursor-review-scripts.yml
💤 Files with no reviewable changes (2)
- .github/cursor-review/tests/test_extract_findings.py
- .github/cursor-review/extract-findings.py
4fcfbbe to
1c35b8f
Compare
End-to-end exampleThe structured-output workflow was exercised against a deliberately defective, plausible change in Comfy-Org/cloud#5197.
The fixture PR is test-only and intentionally retains the reported defects so the posted inline findings remain inspectable. |
71184ae to
0ba5196
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/cursor-review/review-output-mcp.py:
- Around line 63-68: Update read_record to validate that the value returned by
json.load is a dictionary before returning it; for any valid non-object JSON
payload, fall back to initial_record(args). Preserve the existing fallback for
OSError and JSONDecodeError so call_tool always receives a record supporting
get().
- Around line 206-254: Broaden exception handling in handle’s tools/call branch
to catch OSError from call_tool and return the same clean JSON-RPC isError
response with the error text. Also update serve’s per-line processing to handle
OSError from request handling so filesystem failures do not terminate the
session, while preserving the existing parse-error response behavior.
In @.github/workflows/cursor-review.yml:
- Around line 763-780: Update the judge cursor-agent invocation in the
structured final review section to capture its exit status in a variable,
matching the reviewer job’s Run cursor review pattern, while still allowing the
workflow to continue. Log the captured exit code alongside the existing raw
output and stderr so process failures are distinguishable from valid judge
responses.
- Around line 711-728: Update the panel aggregation logic around the present
set-comprehension and panel artifact loading so non-dict JSON entries are
ignored or converted into the existing per-cell error representation instead of
calling cell.get on them. Preserve valid model/review_type detection and ensure
malformed artifacts cannot abort the “Aggregate panel findings” step.
In @.github/workflows/test-cursor-review-scripts.yml:
- Around line 3-6: Restore the workflow header comment in the test workflow so
it documents the required inputs, secrets, triggers, and a caller-pattern
example, while retaining the existing test-purpose context. Keep the
documentation aligned with the reusable workflow’s actual invocation contract.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5453e9c8-386f-48d8-b8d5-4f9f18d90fde
📒 Files selected for processing (11)
.github/cursor-review/README.md.github/cursor-review/extract-findings.py.github/cursor-review/post-review.py.github/cursor-review/prompt-adversarial.md.github/cursor-review/prompt-edge-case.md.github/cursor-review/prompt-judge.md.github/cursor-review/review-output-mcp.py.github/cursor-review/tests/test_extract_findings.py.github/cursor-review/tests/test_review_output_mcp.py.github/workflows/cursor-review.yml.github/workflows/test-cursor-review-scripts.yml
💤 Files with no reviewable changes (2)
- .github/cursor-review/extract-findings.py
- .github/cursor-review/tests/test_extract_findings.py
Amp-Thread-ID: https://ampcode.com/threads/T-019f7201-5122-7674-9389-5610ebeb5d9d Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019f7201-5122-7674-9389-5610ebeb5d9d Co-authored-by: Amp <amp@ampcode.com>
0ba5196 to
364e9a3
Compare
Summary
Replace Cursor Review's free-form JSON response contract with a small, dependency-free stdio MCP server that gives reviewers and the judge typed output tools.
cursor_review_record_findingonce per issue andcursor_review_finishexactly oncecursor_review_submit_finalexactly once with the adjudicated findingsStrategy
The workflow writes a trusted project-scoped
.cursor/mcp.jsonthat startsreview-output-mcp.pyin reviewer or judge mode. It also writes an exact.cursor/cli.jsonallowlist for only the output tools needed by that role, avoiding broad--forcepermissions.The MCP server owns the result contract:
The consolidate job continues to consume the existing normalized findings shape, so posting and blocking-gate behavior remain compatible.
Why this should be more reliable
The previous path depended on probabilistic formatting compliance: each model had to place valid JSON in free-form stdout, after which the workflow searched prose and Markdown fences, coerced common wrapper objects, and retried the judge when parsing still failed. That history already includes multiple hardening changes for prose-wrapped, malformed, or otherwise unparseable responses.
This change moves correctness to a typed protocol boundary:
MCP or agent execution can still fail, but those failures now remain explicit operational errors. They are no longer ambiguous parsing failures and cannot silently become an empty successful review. In short, the result path changes from heuristic extraction of model-authored text to deterministic validation and persistence of tool arguments.
Security and compatibility
.cursordirectory and atomically replaces config filespost-review.pycontractsVerification
python3 -m unittest discover -s .github/cursor-review/tests -p 'test_*.py' -v— 11 tests passgit diff --checkpasses