fix: Fix PR review tools (except create_pull_request_review which works already) when authenticated with a GitHub App installation token (S2S) - #3353
Conversation
This comment has been minimized.
This comment has been minimized.
484f1a1 to
6a6bc47
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The REST error path can leak response bodies and eventually exhaust connections.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Enables pending pull-request review operations for GitHub App installation tokens by using REST review lookup with existing GraphQL mutations.
Changes:
- Finds pending reviews through paginated REST requests.
- Applies the lookup to consolidated and granular tools.
- Adds pagination and failure-path tests.
| File | Description |
|---|---|
pkg/github/pullrequests.go |
Adds REST pending-review lookup. |
pkg/github/pullrequests_test.go |
Tests lookup, pagination, and errors. |
pkg/github/pullrequests_granular.go |
Integrates REST lookup into granular tools. |
pkg/github/granular_tools_test.go |
Updates granular comment test setup. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
create_pull_request_review which works already) when authenticated with a GitHub App installation token (S2S)
Use the REST reviews endpoint to locate the caller-visible pending review and retain GraphQL for comment, submit, and delete mutations. This supports GitHub App installation tokens, for which viewerLatestReview excludes pending reviews. Add pagination coverage and update both consolidated and granular review tools without changing their schemas. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f5bfbcc5-06e4-4487-910f-6a2ca7b5bd7b
6a6bc47 to
a7d2b3b
Compare
|
I looked into the possibility of fixing this in the GitHub API, but it looks like the complexity would be high. In the API, The implementation here, leaning on REST, feels like the practical solution. |
|
After more digging into the monolith code and what's going on here, I don't think this is the right approach. I'll think on it some more. |
|
Пиши мне в телефон телеграмм вапсап |
|
copilot/bot-pending-pr-reviews |

Summary
Creating a pending PR review (
create_pull_request_reviewtool orpull_request_review_writetool withmethod: create) works when authenticated with a GitHub App installation token.However, the other PR review related tools don't work, becuase they try to use the GraphQL API to find the current pendig review, and this API doesn't behave correctly for bot actors.
This fixes it by identifying the pending review using the REST API rather than the GraphQL API. Everything else stays the same.
Why
When authenticated with a GitHub App installation/server-to-server token, GitHub uses the app's bot user as the "viewer" and review author.
The initial
createoperation works because it creates a review directly on the pull request and does not need to rediscover it.The subsequent operations receive only the repository and pull request number, so they must first look up the current caller's pending review:
add_comment_to_pending_review/add_pull_request_review_commentsubmit_pending/submit_pending_pull_request_reviewdelete_pending/delete_pending_pull_request_reviewThat lookup currently fails with an installation token. Live testing showed that the review is successfully created and is visible through REST as
PENDING, but the GraphQL API'sviewerLatestReviewreturnsnull. The follow-up tools therefore report that no pending review exists and cannot comment on, submit, or delete it.We can revisit whether the upstream behavior/API should change for bot viewers, but the MCP server needs to behave correctly with the public APIs available today.
What changed
per_page=100, following pagination until the caller-visiblePENDINGreview is found.node_idwith the existing GraphQL comment, submit, and delete mutations.MCP impact
Tool schemas and response text are unchanged. Existing pending-review operations now work when authenticated with GitHub App installation/server-to-server tokens and acting as the app's bot user.
Prompts tested (tool changes only)
package-lock.json."Security / limits
The live workflow used a GitHub App installation/server-to-server token with pull request write access, causing requests to act as
timrogers-github-app-testing[bot]. REST only exposes pending reviews to their author, so selecting the visiblePENDINGreview does not require login normalization. Review listing is paginated at 100 reviews per request and continues until the pending review is found.Tool renaming
deprecated_tool_aliases.goNote: if you're renaming tools, you must add the tool aliases. For more information on how to do so, please refer to the official docs.
Lint & tests
./script/lint— passed with 0 issues../script/test— passed, including the full race-enabled suite.Additional validation:
go build -o /tmp/github-mcp-server-branch ./cmd/github-mcp-serverpassed.COMMENTEDstate and the comment attached to that exact review.Docs
No tool schema, tool name, configuration, or user-facing workflow changed.