Skip to content

enhance update_issue_labels tool with method options#2742

Open
MayorFaj wants to merge 1 commit into
github:mainfrom
MayorFaj:feat/2724-improve-issue-label
Open

enhance update_issue_labels tool with method options#2742
MayorFaj wants to merge 1 commit into
github:mainfrom
MayorFaj:feat/2724-improve-issue-label

Conversation

@MayorFaj

Copy link
Copy Markdown
Contributor

Summary

Adds a method parameter to the feature-flagged update_issue_labels tool so one tool can replace (default), add, or remove issue labels.

Why

Fixes #2724

The tool could previously only replace an issue's entire label set, forcing a full read-modify-write cycle just to add or remove a single label. A method discriminator makes targeted add/remove operations safe and atomic.

What changed

  • Added a method parameter to update_issue_labels: replace (default), add, remove.
  • add → POST .../labels (keeps existing labels); remove → one DELETE .../labels/{name} per label (atomic, avoids the read-modify-write race); replace keeps the existing PATCH behavior with optional per-label rationale/confidence/is_suggestion intent.
  • URL-escape label names on remove so names with spaces or slashes (e.g. status/blocked) stay a single valid path segment.
  • Trim, validate, and de-duplicate label names for add/remove; all methods return the resulting label set for a consistent response shape.
  • Added unit tests, regenerated the toolsnap, and refreshed docs/feature-flags.md.

MCP impact

  • Tool schema or behavior changed — added the method enum and add/remove behaviors to update_issue_labels (behind the issues_granular feature flag).

Security / limits

  • Auth / permissions considered — requires the repo scope; results are tagged with the repo-visibility IFC label (labels are trusted repo metadata), and label names are URL-escaped to avoid malformed or extra path segments.

Tool renaming

  • I am not renaming tools as part of this PR

add/remove are new methods on the existing tool, not new or renamed tools, so no aliases are needed.

Lint & tests

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

Docs

  • Updated (README / docs / examples) — regenerated docs/feature-flags.md.

Copilot AI review requested due to automatic review settings June 21, 2026 08:35
@MayorFaj MayorFaj requested a review from a team as a code owner June 21, 2026 08:35

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 enhances the feature-flagged update_issue_labels MCP tool to support granular label operations via a new method parameter, enabling atomic add/remove behavior without requiring a read-modify-write cycle.

Changes:

  • Added method to update_issue_labels with replace (default), add, and remove behaviors, including URL-escaped label removal for names containing spaces/slashes.
  • Refactored label handling into helpers (issueLabelNames, replaceIssueLabels, addIssueLabels, removeIssueLabels) and attached repo-visibility IFC labeling for label results.
  • Added unit tests and updated the tool snapshot and feature-flag docs to reflect the new input schema/behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pkg/github/issues_granular.go Adds method support and implements add/remove/replace label operations with validation and URL-escaped deletes.
pkg/github/helper_test.go Adds mock endpoint patterns for the new labels POST and label DELETE routes used by tests.
pkg/github/granular_tools_test.go Adds coverage for add/remove behaviors, trimming/dedup validation, escaping, and method normalization.
pkg/github/toolsnaps/update_issue_labels.snap Updates the toolsnap to include the new method parameter and updated labels description.
docs/feature-flags.md Updates feature-flag tool documentation to include the new method parameter and revised labels description.

Comment on lines +536 to +545
r, err := json.Marshal(issue.Labels)
if err != nil {
return utils.NewToolResultErrorFromErr("failed to marshal response", err), nil, nil
}

result := utils.NewToolResultText(string(r))
// Labels are structural repo metadata defined by collaborators
// (trusted); confidentiality follows repo visibility.
result = attachRepoVisibilityIFCLabelLazy(ctx, deps, owner, repo, result, ifc.LabelRepoMetadata)
return result, nil, nil

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The shape change is intentional and not a GA break, this tool is behind the issues_granular feature flag, so there's no stable response contract yet. All three methods (replace/add/remove) return the resulting label set on purpose: add/remove are backed by the labels endpoints, which return []Label and never expose the issue's ID/URL, so emitting MinimalResponse would force an extra GET per call to return less useful data, and reverting only replace would make the tool inconsistent with itself. Returning the labels gives one consistent, useful response across all methods (see

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.

Add granular add_label_to_issue / remove_label_from_issue tools

3 participants