Browse by type
gh-pr-review is a GitHub CLI extension that finally brings inline PR review comments to the terminal.
GitHub’s built-in gh tool does not show inline comments or review threads — but this extension does.
With gh-pr-review, you can:
Designed for developers, DevOps teams, and AI systems that need full pull request review context, not just top-level comments.
Blog post: gh-pr-review: LLM-friendly PR review workflows in your CLI — explains the motivation, design principles, and CLI + JSON output examples.
The quickest path from opening a pending review to resolving threads:
sh
gh extension install agynio/gh-pr-review
# Update an existing installation
gh extension upgrade agynio/gh-pr-review
id (GraphQL
node).```sh gh pr-review review --start -R owner/repo 42
{ "id": "PRR_kwDOAAABbcdEFG12", "state": "PENDING" } ```
Pending reviews omit submitted_at; the field appears after submission.
review --add-comment command fails fast if you supply a numeric ID instead
of the required PRR_… GraphQL identifier.```sh gh pr-review review --add-comment \ --review-id PRR_kwDOAAABbcdEFG12 \ --path internal/service.go \ --line 42 \ --body "nit: use helper" \ -R owner/repo 42
{ "id": "PRRT_kwDOAAABbcdEFG12", "path": "internal/service.go", "is_outdated": false, "line": 42 } ```
review view surfaces pending
review summaries, thread state, and inline comment metadata. Thread IDs are
always included; enable --include-comment-node-id when you also need the
individual comment node identifiers.```sh gh pr-review review view --reviewer octocat -R owner/repo 42
{ "reviews": [ { "id": "PRR_kwDOAAABbcdEFG12", "state": "COMMENTED", "comments": [ { "thread_id": "PRRT_kwDOAAABbcdEFG12", "path": "internal/service.go", "body": "nit: prefer helper", "is_resolved": false, "is_outdated": false, "thread": [] } ] } ] } ```
Use the thread_id values with comments reply to continue discussions. If
you are replying inside your own pending review, pass the associated
PRR_… identifier with --review-id.
sh
gh pr-review comments reply \
--thread-id PRRT_kwDOAAABbcdEFG12 \
--body "Follow-up addressed in commit abc123" \
-R owner/repo 42
PRR_…
identifier when finalizing. Successful submissions emit a status-only
payload. GraphQL-level errors are returned as structured JSON for
troubleshooting.```sh gh pr-review review --submit \ --review-id PRR_kwDOAAABbcdEFG12 \ --event REQUEST_CHANGES \ --body "Please add tests" \ -R owner/repo 42
{ "status": "Review submitted successfully" } ```
On GraphQL errors, the command exits non-zero after emitting:
json
{
"status": "Review submission failed",
"errors": [
{ "message": "mutation failed", "path": ["mutation", "submitPullRequestReview"] }
]
}
[]
when no threads match.```sh gh pr-review threads list --unresolved --mine -R owner/repo 42
[ { "threadId": "R_ywDoABC123", "isResolved": false, "path": "internal/service.go", "line": 42, "isOutdated": false } ] ```
```sh gh pr-review threads resolve --thread-id R_ywDoABC123 -R owner/repo 42
{ "thread_node_id": "R_ywDoABC123", "is_resolved": true } ```
gh pr-review review view emits a GraphQL-only snapshot of pull request
discussion. The response groups reviews → parent inline comments → thread
replies, omitting optional fields entirely instead of returning null.
Run it with either a combined selector or explicit flags:
gh pr-review review view -R owner/repo --pr 3
Install or upgrade to v1.6.0 or newer (GraphQL-only thread resolution and minimal comment replies):
gh extension install agynio/gh-pr-review
# Update an existing installation
gh extension upgrade agynio/gh-pr-review
created_at ascending.author_login only—no user objects or html_url fields.body, submitted_at, line, thread) are omitted when
empty; empty reply lists render as "thread": [].| Flag | Purpose |
|---|---|
--reviewer <login> |
Only include reviews authored by <login> (case-insensitive). |
--states <list> |
Comma-separated review states (APPROVED, CHANGES_REQUESTED, COMMENTED, DISMISSED). |
--unresolved |
Keep only unresolved threads. |
--not_outdated |
Exclude threads marked as outdated. |
--tail <n> |
Retain only the last n replies per thread (0 = all). The parent inline comment is always kept; only replies are trimmed. |
--include-comment-node-id |
Add GraphQL comment node identifiers to parent comments and replies. |
# Default: return all reviews, states, threads
gh pr-review review view -R owner/repo --pr 3
# Unresolved threads only
gh pr-review review view -R owner/repo --pr 3 --unresolved
# Focus changes requested from a single reviewer; keep only latest reply per thread
gh pr-review review view -R owner/repo --pr 3 --reviewer alice --states CHANGES_REQUESTED --tail 1
# Drop outdated threads and include comment node IDs
gh pr-review review view -R owner/repo --pr 3 --not_outdated --include-comment-node-id
{
"reviews": [
{
"id": "PRR_…",
"state": "APPROVED|CHANGES_REQUESTED|COMMENTED|DISMISSED",
"author_login": "…",
"body": "…", // omitted if empty
"submitted_at": "…", // omitted if absent
"comments": [ // omitted if none
{
"thread_id": "PRRT_…",
"comment_node_id": "PRRC_…", // omitted unless requested
"path": "…",
"line": 21, // omitted if null
"author_login": "…",
"body": "…",
"created_at": "…",
"is_resolved": true,
"is_outdated": false,
"thread": [ // replies only; sorted asc; tail applies
{
"comment_node_id": "PRRC_…", // omitted unless requested
"author_login": "…",
"body": "…",
"created_at": "…"
}
]
}
]
}
]
}
Use the thread_id values surfaced in the report when replying. Provide
--review-id alongside --thread-id when continuing a pending review you own.
gh pr-review comments reply -R owner/repo --pr 3 \
--thread-id PRRT_kwDOAAABbcdEFG12 \
--body "Follow-up addressed in commit abc123"
gh pr-review comments reply -R owner/repo --pr 3 \
--thread-id PRRT_kwDOAAABbcdEFG12 \
--review-id PRR_kwDOAAABbcdEFG12 \
--body "Reply from pending review"
Each command binds to a single GitHub backend—there are no runtime fallbacks.
| Command | Backend | Notes |
|---|---|---|
review --start |
GraphQL | Opens a pending review via addPullRequestReview. |
review --add-comment |
GraphQL | Requires a PRR_… review node ID. |
review view |
GraphQL | Aggregates reviews, inline comments, and replies (used for thread IDs). |
review --submit |
GraphQL | Finalizes a pending review via submitPullRequestReview using the PRR_… review node ID (executed through the internal gh api graphql wrapper). |
comments reply |
GraphQL | Replies via addPullRequestReviewThreadReply; supply --review-id when responding from a pending review. |
threads list |
GraphQL | Enumerates review threads for the pull request. |
threads resolve / unresolve |
GraphQL | Mutates thread resolution via resolveReviewThread / unresolveReviewThread; supply GraphQL thread node IDs (PRRT_…). |
gh-pr-review is designed to give LLMs and agents the exact PR review context they need — without the noisy, multi-step GitHub API workflow.
Replaces multi-call API chains with one command
Instead of calling list reviews → list thread comments → list comments,
a single gh pr-review review view command returns the entire, assembled review structure.
Deterministic, stable output
Consistent formatting, stable ordering, and predictable field names make parsing reliable for agents.
Compact, meaningful JSON
Only essential fields are returned. Low-signal metadata (URLs, hashes, unused fields) is stripped out to reduce token usage.
Pre-joined review threads
Threads come fully reconstructed with inline context — no need for agents to merge comments manually.
Server-side filters for token efficiency
Options like --unresolved and --tail help reduce payload size and keep inputs affordable for LLMs.
“A good tool definition should define a clear, narrow purpose, return exactly the meaningful context the agent needs, and avoid burdening the model with low-signal intermediate results.”
Run the test suite and linters locally with cgo disabled (matching the release build):
CGO_ENABLED=0 go test ./...
CGO_ENABLED=0 golangci-lint run
Releases are built using the
cli/gh-extension-precompile
workflow to publish binaries for macOS, Linux, and Windows.
$ claude mcp add gh-pr-review \
-- python -m otcore.mcp_server <graph>