Skip to content

Add reaction tools for issues and pull requests#2732

Open
timrogers wants to merge 12 commits into
github:mainfrom
timrogers:timrogers/planning-reaction-tools
Open

Add reaction tools for issues and pull requests#2732
timrogers wants to merge 12 commits into
github:mainfrom
timrogers:timrogers/planning-reaction-tools

Conversation

@timrogers

@timrogers timrogers commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Add reaction support for issues, issue comments, and pull request review comments while keeping standalone reaction tools behind the granular tool feature flags.

Default users can add reactions through existing comment tools to avoid adding more default tools:

  • add_issue_comment can add an issue/PR comment, add a reaction to an issue/PR, add a reaction to an issue/PR timeline comment, or combine a comment with a reaction.
  • add_reply_to_pull_request_comment can reply to a pull request review comment, add a reaction to a pull request review comment, or do both.

Granular users also get standalone tools:

  • add_issue_reaction
  • add_issue_comment_reaction
  • add_pull_request_review_comment_reaction

Why

Reactions are a fundamental part of GitHub's interaction model. Clients should be able to add reactions programmatically just as they can create issues, comments, and reviews, without increasing the default tool surface more than necessary.

What changed

  • Added granular standalone reaction tools for issues, issue comments, and PR review comments.
  • Extended default comment tools with optional reaction parameters.
  • Clarified numeric comment ID requirements, especially for PR review comments where callers must use the numeric #discussion_r... ID rather than a GraphQL review thread node ID.
  • Added validation so reaction/comment combinations are explicit and do not silently ignore comment IDs.
  • Ordered combined reaction+comment operations so the idempotent reaction happens before creating the non-idempotent comment/reply, reducing duplicate-comment risk on retries.
  • Updated tests, toolsnaps, and generated docs.

MCP impact

  • New tool added
    • Three standalone reaction tools are added to granular issue and pull request toolsets.
  • Existing tool changed
    • add_issue_comment and add_reply_to_pull_request_comment now support reactions.

Prompts tested (tool changes only)

  • "Add a reaction to issue 42 in my-repo"
  • "Add a reaction to the issue comment I just made"
  • "Add a reaction to the PR review comment feedback"
  • "Reply to this PR review comment and add a rocket reaction"

Security / limits

  • No security or limits impact
    • Reactions follow existing GitHub API permissions and use the same client authentication/error handling as other write tools.

Tool renaming

  • I am not renaming existing MCP tools as part of this PR

Lint & tests

  • Linted locally with ./script/lint
  • Tested locally with ./script/test

Docs

  • Updated (README / docs / examples)
    • README.md and generated docs updated via script/generate-docs.
    • Toolsnaps updated in pkg/github/__toolsnaps__/.

Closes #2757

@timrogers timrogers requested a review from a team as a code owner June 19, 2026 16:06
Copilot AI review requested due to automatic review settings June 19, 2026 16:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds three new MCP write tools that let clients create emoji reactions on GitHub issues, issue comments, and pull request review comments, extending the server’s “write” surface area to cover a core GitHub interaction.

Changes:

  • Added three new tools: add_issue_reaction, add_issue_comment_reaction, and add_pull_request_review_comment_reaction.
  • Wired the tools into the global tool inventory and added handler tests with mocked HTTP endpoints.
  • Updated generated documentation and added new tool schema snapshots (__toolsnaps__).
Show a summary per file
File Description
README.md Documents the three new tools and their parameters in the generated tool listing.
pkg/github/tools.go Registers the three new tools in AllTools so they’re available to clients.
pkg/github/issues_granular.go Implements add_issue_reaction and add_issue_comment_reaction tool schemas and handlers.
pkg/github/pullrequests_granular.go Implements add_pull_request_review_comment_reaction tool schema and handler.
pkg/github/helper_test.go Adds mocked endpoint patterns for the reactions REST endpoints.
pkg/github/granular_tools_test.go Adds toolsnap coverage and handler tests for the new reaction tools.
pkg/github/toolsnaps/add_issue_reaction.snap New snapshot for add_issue_reaction tool schema.
pkg/github/toolsnaps/add_issue_comment_reaction.snap New snapshot for add_issue_comment_reaction tool schema.
pkg/github/toolsnaps/add_pull_request_review_comment_reaction.snap New snapshot for add_pull_request_review_comment_reaction tool schema.

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 3

Comment thread pkg/github/issues_granular.go
Comment thread pkg/github/issues_granular.go Outdated
Comment thread pkg/github/pullrequests_granular.go Outdated
timrogers and others added 4 commits June 19, 2026 17:25
Implement three granular-only tools for adding emoji reactions:
- add_issue_reaction: Add reaction to an issue
- add_issue_comment_reaction: Add reaction to an issue comment
- add_pull_request_review_comment_reaction: Add reaction to a PR review comment

All tools are feature-flagged with FeatureFlagEnable set to enable them
only when clients request granular toolsets. Tools use go-github's
Reactions service and return minimal ID response on success (HTTP 201).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove feature flag gates from reaction tools so they're available to all
clients regardless of granular toolset preference. Reaction tools are
naturally atomic operations and work equally well in both modes.

Updates test expectations to exclude reaction tools from granular-only
test assertions, since they're now always available.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@timrogers timrogers force-pushed the timrogers/planning-reaction-tools branch from 44c2a5e to 94c6f2c Compare June 19, 2026 16:26
A-Georgiou
A-Georgiou previously approved these changes Jun 19, 2026

@A-Georgiou A-Georgiou left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me 🚀

@timrogers

Copy link
Copy Markdown
Contributor Author

Tested manually locally and this is all working. We could consider adding tools to remove reactions, but I think this is a good incremental step and we can choose to add more later.

Return reaction URLs in minimal responses and clarify issue tools apply to pull requests where applicable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
A-Georgiou
A-Georgiou previously approved these changes Jun 19, 2026

@phillipschandler19-web phillipschandler19-web left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal/ghmcp/server_test.go.github/actions/build-ui/action.ymlREADME.mdhttps://github.com/modelcontextprotocol/modelcontextprotocol/issues/1489

Keep the standalone reaction tools behind granular feature flags to avoid expanding the default tool count. Add optional reaction support to the existing issue comment and pull request comment reply tools, requiring at least one of body or reaction.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Document that PR review comment reaction inputs require the numeric review comment ID, not the GraphQL review thread node ID returned by review thread APIs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add optional comment_id support so the default add_issue_comment tool can react to a specific issue or pull request comment without exposing a separate default reaction tool. Keep body creation tied to issue_number and require reaction targets to provide either issue_number or comment_id.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@SamMorrowDrums SamMorrowDrums requested a review from Copilot June 23, 2026 13:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 16/16 changed files
  • Comments generated: 4

Comment thread pkg/github/issues_test.go
Comment on lines 611 to 627
{
name: "comment creation fails",
mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{
PostReposIssuesCommentsByOwnerByRepoByIssueNumber: http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusUnprocessableEntity)
_, _ = w.Write([]byte(`{"message": "Invalid request"}`))
}),
}),
requestArgs: map[string]any{
"owner": "owner",
"repo": "repo",
"issue_number": float64(42),
"body": "",
"body": "This is a test comment",
},
expectError: false,
expectedErrMsg: "missing required parameter: body",
expectedErrMsg: "failed to create comment",
},
Comment thread pkg/github/issues.go Outdated
Comment on lines +1210 to +1213
createdComment, resp, err := client.Issues.CreateComment(ctx, owner, repo, issueNumber, comment)
if err != nil {
return utils.NewToolResultErrorFromErr("failed to read response body", err), nil, nil
return utils.NewToolResultErrorFromErr("failed to create comment", err), nil, nil
}
Comment thread pkg/github/issues.go
Comment on lines +1190 to +1192
if hasReaction && !hasIssueNumber && !hasCommentID {
return utils.NewToolResultError("issue_number or comment_id is required when reaction is provided"), nil, nil
}
Comment thread pkg/github/tools.go Outdated
Comment on lines +215 to +219
ListIssueFields(t),
IssueWrite(t),
AddIssueComment(t),
AddIssueReaction(t),
AddIssueCommentReaction(t),
Apply reactions before creating comments or replies so retrying a failed combined call cannot duplicate the non-idempotent comment operation.

Also reject issue comment IDs without a reaction target to avoid silently ignoring the field.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 16/16 changed files
  • Comments generated: 6

Comment thread pkg/github/issues.go
Comment on lines +1187 to +1195
if hasBody && !hasIssueNumber {
return utils.NewToolResultError("issue_number is required when body is provided"), nil, nil
}
if hasReaction && !hasIssueNumber && !hasCommentID {
return utils.NewToolResultError("issue_number or comment_id is required when reaction is provided"), nil, nil
}
if hasCommentID && !hasReaction {
return utils.NewToolResultError("comment_id can only be provided when reaction is provided"), nil, nil
}
Comment thread pkg/github/issues_granular.go
Comment thread pkg/github/issues_granular.go Outdated
Comment on lines +1202 to +1204
// AddIssueReaction adds a reaction to an issue or pull request.
func AddIssueReaction(t translations.TranslationHelperFunc) inventory.ServerTool {
st := NewTool(
Comment thread pkg/github/issues_granular.go
Comment thread pkg/github/pullrequests_granular.go
Comment thread pkg/github/pullrequests_granular.go Outdated
Comment on lines +761 to +763
// AddPullRequestReviewCommentReaction adds a reaction to a pull request review comment.
func AddPullRequestReviewCommentReaction(t translations.TranslationHelperFunc) inventory.ServerTool {
st := NewTool(
Keep standalone reaction tool registrations next to the granular issue and pull request tools they belong with, so the default compound tool sections stay focused.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 16/16 changed files
  • Comments generated: 4

Comment thread pkg/github/issues_granular.go
Comment thread pkg/github/pullrequests_granular.go
Comment thread pkg/github/issues.go
Comment thread pkg/github/pullrequests.go
Rename the standalone reaction tool constructors to match the granular tool naming convention and clarify issue comment reaction IDs for pull request comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Comments suppressed due to low confidence (1)

pkg/github/issues_test.go:631

  • In this test, the failure case sets expectedErrMsg but the assertion path does not verify the tool call actually returned an error result (result.IsError). This can allow regressions where the tool returns a non-error result containing the substring. Align the failure handling with the rest of the suite by asserting result.IsError and reading the error via getErrorResult().
			expectedErrMsg: "failed to create comment",
		},
	}

	for _, tc := range tests {
  • Files reviewed: 16/16 changed files
  • Comments generated: 0 new

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Track: reaction tools for issues and pull requests (#2732)

5 participants