Add a code review step which uses a short-lived provider token (#7932)

This commit is contained in:
Jack Amadeo
2026-03-24 08:57:40 -04:00
committed by GitHub
parent ce160b183d
commit 928f4ac46a
11 changed files with 1165 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = ["mcp"]
# ///
"""MCP server for collecting PR review comments and conclusion."""
import json
import os
from pathlib import Path
from mcp.server.fastmcp import FastMCP
server = FastMCP("pr-review")
output_dir = Path(os.environ.get("REVIEW_OUTPUT_DIR", "/tmp"))
def _append_comment(comment: dict) -> int:
"""Append a comment to the comments file and return the new total."""
comments_file = output_dir / "comments.json"
comments = json.loads(comments_file.read_text()) if comments_file.exists() else []
comments.append(comment)
comments_file.write_text(json.dumps(comments, indent=2))
return len(comments)
@server.tool()
def add_comment(
path: str,
line: int,
body: str,
suggestion: str | None = None,
side: str = "RIGHT",
start_line: int | None = None,
) -> str:
"""Add a review comment on a specific line in the PR diff.
Args:
path: The relative file path in the repository (e.g. "src/main.rs").
line: The line number in the file that the comment applies to.
For added or modified lines, use the line number in the new version of the file (side=RIGHT).
For deleted lines, use the line number in the old version of the file (side=LEFT).
body: The review comment text (Markdown supported).
suggestion: Optional replacement code for the line(s). When provided, GitHub renders an
"Apply suggestion" button the author can click. The suggestion replaces the
entire line (or range if start_line is set).
side: Which version of the file the line number refers to.
"RIGHT" for the new/modified version (default), "LEFT" for the old/deleted version.
start_line: For multi-line comments, the first line of the range. When set, `line` is the last line.
"""
if suggestion is not None:
body = (
f"{body}\n\n```suggestion\n{suggestion}\n```"
if body
else f"```suggestion\n{suggestion}\n```"
)
comment = {"path": path, "line": line, "side": side, "body": body}
if start_line is not None:
comment["start_line"] = start_line
comment["start_side"] = side
total = _append_comment(comment)
return f"Comment added on {path}:{line} ({total} total)."
@server.tool()
def finish_review(body: str = "") -> str:
"""Finish the review.
Args:
body: Optional top-level review body (Markdown supported). Only include if it
contains information not already covered by inline comments. Most reviews
should leave this empty.
"""
conclusion = {"body": body, "event": "COMMENT"}
conclusion_file = output_dir / "conclusion.json"
conclusion_file.write_text(json.dumps(conclusion, indent=2))
return "Review finished."
if __name__ == "__main__":
server.run(transport="stdio")