517 Commits

Author SHA1 Message Date
Iulia Bejan 1861a351f8 Upgrade go-github from v82 to v87 (#2452)
Breaking changes addressed:
- raw.NewClient: Use WithHTTPClient/WithEnterpriseURLs options, pass ctx to
  NewRequest, return (*Client, error)
- internal/ghmcp/server.go: Use functional options for REST client creation,
  replace UserAgent field mutation with UserAgentTransport wrapper, add
  restUATransp field to githubClients struct
- pkg/github/dependencies.go: Use functional options for REST client creation,
  handle raw.NewClient error return
- pkg/github/actions.go: Handle new WorkflowDispatchRunDetails return value
  from CreateWorkflowDispatchEventByID/ByFileName
- pkg/github/issues.go: Replace IssueListOptions with ListOptions for
  SubIssue.ListByIssue
- pkg/github/notifications.go: MarkThreadDone now takes string instead of
  int64; remove ParseInt and strconv import
- pkg/github/projects.go: Remove pointer indirection from
  ListProjectsPaginationOptions and ListProjectsOptions fields
- pkg/github/issues_granular.go: Pass ctx to NewRequest, remove ctx from Do
- Test files: Add mustNewGHClient helper, replace all NewClient calls,
  fix stubClientFnFromHTTP signature, fix lockdown_test.go BaseURL handling,
  fix raw_test.go, remove invalid threadID test case

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 14:36:23 +02:00
Ross Tarrant 8a48d0749f feat: Add tool for discussion comment write operations (#2427)
* Add discussion comment write operation tools

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

* Address comments from Copilot review

* Update includeReplies description to specify GitHub API maximum replies limit

* Consolidate into single tool

* add tests cases for checking param presence

* Enhance validation on discussion comment operations

* Enhance discussion_write tool description

Co-authored-by: Roberto Nacu <kerobbi@github.com>

* Remove redundant param

Co-authored-by: Roberto Nacu <kerobbi@github.com>

* Refactor tests

* Fix failing build

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Roberto Nacu <kerobbi@github.com>
2026-05-15 15:16:36 +01:00
JoannaaKL 46d220fba5 Add tool to list repo collaborators (#2477)
* Add tool to list repo collaborators

* Simplify tool description

* Fix test

* Return pagination info

* Return page parameters

* Update defaults
2026-05-15 11:20:30 +02:00
Gökhan Arkan 39d86b80af Replace ingress IFC reader list with private marker (#2478)
* Replace ingress IFC reader list with private marker

Switches the ingress IFC labels from emitting a per-repo collaborator
list to a single 'private' marker. The CLI engine now fetches readers
from the GitHub endpoint on demand at egress decision time (P-F check),
with pagination + caching, which removes a wire-bloat ceiling for repos
with thousands of collaborators.

Drops the per-call FetchRepoCollaborators from list_issues, issue_read,
get_file_contents, search_issues, and search_repositories. The shared
LabelSearchIssues helper collapses to a single []bool argument; the
intersection logic and length-mismatch failure mode go away.

This is a breaking wire-format change for _meta.ifc consumers — coordinate
with the CLI cut-over.

Refs github/copilot-mcp-core#1389.

* format

* Update FetchRepoCollaborators doc comment for marker-only ingress

Addresses Copilot review on #2478. The helper is no longer called by the
server itself; ingress emits a 'private' marker and the client engine
resolves readers on demand. Kept exported per the library-consumer
convention; updated the comment to reflect the new role.

* Address review: drop FetchRepoCollaborators and make confidentiality a scalar

Per Joanna's review on #2478:

- Remove FetchRepoCollaborators entirely (no callers left after the marker
  switch). Drops the GetReposCollaboratorsByOwnerByRepo mock route too.
- Change SecurityLabel.Confidentiality from []Confidentiality to a scalar
  Confidentiality. Wire format is now {integrity, confidentiality} where
  confidentiality is a single 'public' or 'private' string. Updated all
  tests and the LabelSearchIssues helper accordingly.
2026-05-14 12:52:37 +02:00
Sam Morrow fbf68b2079 feat: return minimal code search results with text match snippets (#2476)
* feat: return minimal code search results with text match snippets

Return a MinimalCodeSearchResult type from search_code instead of the
raw GitHub API CodeSearchResult. This reduces token usage by ~4x by:

- Projecting the repository object to just the full_name string instead
  of the full ~3KB repository payload repeated per result
- Enabling the text-match Accept header so code snippets (fragments)
  are included in results, which were previously missing

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

* refactor: drop html_url from MinimalCodeResult

The URL is derivable from repository + path + sha, so it's redundant
token cost per result.

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

* fix: add minimal_output opt-out and Accept header test for code search

Address PR review feedback:

1. Add minimal_output parameter (default: true) to search_code, matching
   the pattern from search_repositories. When false, returns the full
   GitHub API CodeSearchResult for backward compatibility.

2. Add Accept header assertion to tests via a new withHeaders() helper
   on partialMock, verifying the text-match Accept header is actually
   requested (not just mocked in the response).

3. Add test case for minimal_output=false path.

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

* refactor: remove minimal_output opt-out from search_code

The full CodeResult only adds a bloated Repository object (~3KB of
template URLs) and a derivable HTMLURL. Nothing in the full output is
useful beyond what the minimal type already provides, so always return
the compact form.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-14 12:07:15 +02:00
Gökhan Arkan 3a4bc2666f Add ifc label for search_repositories tool (#2459)
Emits an IFC SecurityLabel on the search_repositories tool result when
the InsidersMode flag is enabled, mirroring the pattern landed for
get_me (#2432), list_issues (#2453), get_file_contents (#2454),
search_issues (#2456), and issue_read (#2457).

Search results may span multiple repositories, so the join math
(integrity always untrusted; private wins by intersecting collaborator
sets across the matched private repos only) is shared with search_issues
via ifc.LabelSearchIssues. Visibility is read directly off the search
response's repo.Private field — no extra API call. Collaborators are
fetched only for private hits, and any failure causes the label to be
omitted entirely (consistent with search_issues / issue_read /
get_file_contents).

Refs github/copilot-mcp-core#1623, github/copilot-mcp-core#1389.
2026-05-13 15:59:49 +03:00
Gökhan Arkan 883f58d979 Add ifc label for issue_read tool (#2457)
* Add ifc label for search_issues tool

Emits an IFC SecurityLabel on the search_issues tool result when the
InsidersMode flag is enabled, mirroring the pattern landed for get_me
in #2432, list_issues in #2453, and get_file_contents in #2454.

Search results may span multiple repositories, so the label is the IFC
join of the per-repository labels:

  - Integrity is always untrusted (issues are user-authored).
  - If any matched repository is public, the joined readers are
    ["public"] (the public side dominates the lub).
  - Otherwise the joined readers are the intersection of the
    collaborator sets across all matched private repositories.
  - Empty result sets are labelled public-untrusted (no data leaked).

The shared searchHandler in search_utils.go gains an additive variadic
'searchOption' hook so SearchIssues can attach _meta.ifc without
duplicating the search call. SearchPullRequests is unaffected; it does
not pass any options.

If any per-repository visibility or collaborators lookup fails the label
is omitted entirely, consistent with get_file_contents, to avoid
misclassifying the result.

Refs github/copilot-mcp-core#1623, github/copilot-mcp-core#1389.

Note: this PR is chained on #2454 (gokhanarkan/fides-get-file-contents)
because it depends on the FetchRepoIsPrivate and FetchRepoCollaborators
helpers introduced there. GitHub will retarget the base to main once
#2454 merges.

* search_issues: address Copilot review findings

- LabelSearchIssues now returns (SecurityLabel, bool); the bool is
  false when len(repoVisibilities) != len(readerSets), so callers can
  omit the label rather than emit one computed from inconsistent
  inputs.
- searchIssuesIFCPostProcess no longer substitutes [owner] when the
  collaborators API returns an empty list. The substitution was
  inconsistent with the cross-repo intersection semantics: the owner
  could appear in another matched private repo's collaborator list and
  thereby widen the joined reader set incorrectly. Empty collaborator
  sets are now passed through unchanged.
- Add a subtest exercising the collaborators-failure branch (500 on
  /repos/{owner}/{repo}/collaborators), asserting the tool still
  succeeds and result.Meta["ifc"] is absent.
- Extend the LabelSearchIssues table tests with the slice-length
  mismatch case.

Addresses the three Copilot findings on #2456.

* search_issues: flip IFC join to intersection (private wins)

Address Joanna's review feedback on #2456: a reader of a multi-repo result
must be authorised to read every matched private repository, so the IFC
join is the meet (intersection over private repos) rather than the join.
Public matches contribute the universe set and drop out of the
intersection without shrinking it.

- LabelSearchIssues: collect only the private reader sets, then intersect.
  Empty result and all-public remain public-untrusted.
- TestLabelSearchIssues: flip the mixed public+private expectation and add
  a 'two private + one public' case to lock in the new semantics.
- Test_SearchIssues_IFC_InsidersMode: mixed subtest now expects the
  private repo's reader set instead of public.

* Add ifc label for issue_read tool

Emits an IFC SecurityLabel on the issue_read tool result when the
InsidersMode flag is enabled, mirroring the pattern landed for get_me
in #2432, list_issues in #2453, get_file_contents in #2454, and
search_issues in #2456.

issue_read operates on a single issue in a single repository so the
label has the same per-repo semantics as list_issues; the helper
ifc.LabelListIssues is reused directly. Integrity is always untrusted
(issue contents, comments, and label descriptions are user-authored).
Public repos are labelled PublicUntrusted; private repos are labelled
PrivateUntrusted with the repository's collaborator logins, falling
back to [owner] when the collaborators lookup fails.

The IssueRead handler dispatches to four sub-functions (GetIssue,
GetIssueComments, GetSubIssues, GetIssueLabels). The IFC label is
attached at the dispatch site via a single attachIFC closure, so all
four method branches emit the label without changes to the underlying
helpers. Visibility-lookup failures cause the label to be omitted
entirely (consistent with get_file_contents and search_issues).

A future cleanup PR can extract attachIFC into a shared helper now that
get_file_contents, search_issues, and issue_read use near-identical
closures; intentionally not bundled here to keep the diff minimal.

Refs github/copilot-mcp-core#1623, github/copilot-mcp-core#1389.

Note: chained on #2456 (gokhanarkan/fides-search-issues), which is in
turn chained on #2454. GitHub will retarget the base to main once those
merge.

* issue_read: simplify attachIFC by dropping unused lazy-cache

Address Joanna's review feedback on #2457: the dispatch switch returns
on exactly one branch, so attachIFC runs at most once per request. The
ifcLabelKnown / ifcIsPrivate / ifcReaders cache variables were never
reused across calls and only added complexity.

Inline the visibility and collaborators lookups directly into the
closure and drop the cache. Behaviour is identical; a follow-up can
add real per-request caching across handlers if needed.
2026-05-13 15:48:52 +03:00
Gökhan Arkan 9ad99c52c8 Add ifc label for search_issues tool (#2456)
* Add ifc label for search_issues tool

Emits an IFC SecurityLabel on the search_issues tool result when the
InsidersMode flag is enabled, mirroring the pattern landed for get_me
in #2432, list_issues in #2453, and get_file_contents in #2454.

Search results may span multiple repositories, so the label is the IFC
join of the per-repository labels:

  - Integrity is always untrusted (issues are user-authored).
  - If any matched repository is public, the joined readers are
    ["public"] (the public side dominates the lub).
  - Otherwise the joined readers are the intersection of the
    collaborator sets across all matched private repositories.
  - Empty result sets are labelled public-untrusted (no data leaked).

The shared searchHandler in search_utils.go gains an additive variadic
'searchOption' hook so SearchIssues can attach _meta.ifc without
duplicating the search call. SearchPullRequests is unaffected; it does
not pass any options.

If any per-repository visibility or collaborators lookup fails the label
is omitted entirely, consistent with get_file_contents, to avoid
misclassifying the result.

Refs github/copilot-mcp-core#1623, github/copilot-mcp-core#1389.

Note: this PR is chained on #2454 (gokhanarkan/fides-get-file-contents)
because it depends on the FetchRepoIsPrivate and FetchRepoCollaborators
helpers introduced there. GitHub will retarget the base to main once
#2454 merges.

* search_issues: address Copilot review findings

- LabelSearchIssues now returns (SecurityLabel, bool); the bool is
  false when len(repoVisibilities) != len(readerSets), so callers can
  omit the label rather than emit one computed from inconsistent
  inputs.
- searchIssuesIFCPostProcess no longer substitutes [owner] when the
  collaborators API returns an empty list. The substitution was
  inconsistent with the cross-repo intersection semantics: the owner
  could appear in another matched private repo's collaborator list and
  thereby widen the joined reader set incorrectly. Empty collaborator
  sets are now passed through unchanged.
- Add a subtest exercising the collaborators-failure branch (500 on
  /repos/{owner}/{repo}/collaborators), asserting the tool still
  succeeds and result.Meta["ifc"] is absent.
- Extend the LabelSearchIssues table tests with the slice-length
  mismatch case.

Addresses the three Copilot findings on #2456.

* search_issues: flip IFC join to intersection (private wins)

Address Joanna's review feedback on #2456: a reader of a multi-repo result
must be authorised to read every matched private repository, so the IFC
join is the meet (intersection over private repos) rather than the join.
Public matches contribute the universe set and drop out of the
intersection without shrinking it.

- LabelSearchIssues: collect only the private reader sets, then intersect.
  Empty result and all-public remain public-untrusted.
- TestLabelSearchIssues: flip the mixed public+private expectation and add
  a 'two private + one public' case to lock in the new semantics.
- Test_SearchIssues_IFC_InsidersMode: mixed subtest now expects the
  private repo's reader set instead of public.
2026-05-13 15:45:14 +03:00
Alon Dahari 59fa9a73ba Add optional rationale parameter to update_issue_type tool (#2458)
* Add optional rationale parameter to update_issue_type tool

Add an optional `rationale` string parameter (max 280 chars) to the
`update_issue_type` MCP tool. When provided, the type is sent as an
object `{"name": "...", "rationale": "..."}` to the REST API,
enabling agents to explain their classification decisions. When omitted,
existing behavior is preserved (type sent as a plain string).

This supports the agent rationale experiment for type mutations. The
parameter is always visible in the schema — the API gracefully ignores
the rationale when the server-side feature flag is disabled.

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

* Validate issue type rationale input

* Format issue type rationale tests

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Adam Holt <omgitsads@github.com>
2026-05-13 11:47:41 +01:00
Ross Tarrant e2ff518196 fix: add missing pagination on get_reviews (#2367)
* Add pagination support to pull request reviews and update descriptions

* Add pagination support to GetPullRequestReviews test case

* Remove unintentional whitespace

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

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Roberto Nacu <kerobbi@github.com>
2026-05-12 17:34:11 +01:00
Gökhan Arkan 0cdcd4aa73 Add ifc label for get_file_contents tool (#2454)
* Add ifc label for get_file_contents tool

Emits an IFC SecurityLabel on the get_file_contents tool result when the
InsidersMode flag is enabled, mirroring the pattern landed for get_me in

Public repositories are labelled PublicUntrusted (anyone can author file
content via pull requests). Private repositories are labelled
PrivateTrusted with the repository owner as a placeholder reader, since
only collaborators can land changes there. Full collaborator enumeration
is intentionally deferred to a follow-up shared helper.

A new exported FetchRepoIsPrivate helper wraps Repositories.Get for
visibility lookups; it is invoked lazily and only when InsidersMode is
on, so non-insiders pay no extra round trip. Visibility lookup failures
skip the label rather than fail the user-facing call.

Refs github/copilot-mcp-core#1623, github/copilot-mcp-core#1389.

* get_file_contents: address Copilot review findings

- FetchRepoIsPrivate: tighten doc to 'returns whether a repository is
  private' and close the underlying *github.Response body.
- attachIFC: skip emitting the ifc label when the repository visibility
  lookup fails, instead of falling through to PublicUntrusted (which
  would mislabel a private or unknown-visibility repo as public). The
  failure is no longer cached so a subsequent return path can retry.
- Add a test asserting the tool still succeeds and omits result.Meta  ["ifc"] when the visibility lookup returns 500.
2026-05-12 17:42:15 +03:00
Gökhan Arkan 525951397d Add ifc label for list_issues tool (#2453)
* Add ifc label for list_issues tool

Emits an IFC SecurityLabel on the list_issues tool result when the
InsidersMode flag is enabled, mirroring the pattern landed for get_me
in #2432.

Public repositories are labelled PublicUntrusted; private repositories
are labelled PrivateUntrusted with the repository owner as a placeholder
reader (full collaborator enumeration is intentionally deferred to a
follow-up shared helper).

A new IsPrivate field is added to the ListIssues GraphQL query types so
visibility is available without a second round trip.

Refs github/copilot-mcp-core#1623, github/copilot-mcp-core#1389.

* list_issues: populate readers with repo collaborators

Addresses Joanna's review feedback: for private repositories, populate
the IFC confidentiality reader set with the repository's collaborator
logins instead of the [owner] placeholder.

Adds an exported FetchRepoCollaborators helper in pkg/github/repositories.go
that paginates through Repositories.ListCollaborators. Mirrors the helper
in github-mcp-server-remote (without the cache for now; cache can land in
a follow-up).

The lookup is invoked only for private repos under InsidersMode; if it
fails we fall back to [owner] so the reader set is never empty for a
private repo.
2026-05-12 12:55:04 +03:00
Roberto Nacu c3dedbece0 Handle lightweight tags in get_tag (#2400)
Build and Test Go Project / build (macos-latest) (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Docker / build (push) Has been cancelled
Build and Test Go Project / build (ubuntu-latest) (push) Has been cancelled
Build and Test Go Project / build (windows-latest) (push) Has been cancelled
GoReleaser Release / release (push) Has been cancelled
MCP Server Diff / mcp-diff (push) Has been cancelled
Publish to MCP Registry / publish (push) Has been cancelled
2026-05-11 15:16:15 +01:00
Roberto Nacu f48e82a8f9 Prevent inputs param from being stripped from actions_run_trigger tool schema (#2417)
* add empty properties to inputs param

* add test cases for valid and invalid inputs
2026-05-11 15:07:00 +01:00
JoannaaKL 1be1f38de0 Add ifc label for get_me tool (#2432)
* Add ifc labels

* Add test

* Address PR review: deterministic output, type safety, universe validation, and tests

- Fix grammar in ReadersSecurityLabelFromDict godoc
- Sort GetReaders and FiniteReaderSet.String output for determinism
- Fix godoc example to use UniversalReaders for public label
- Panic on unsupported ReaderSet types in Union/Intersection/IsSubset
- Add universe mismatch validation in PowersetLattice Join/Meet/Leq
- Add comprehensive unit tests for pkg/ifc (lattice laws, serialization, panics)

* Add a test

* Pass parameters

* Remove lattice

* Script update
2026-05-11 11:23:58 +02:00
Aakash Shah 926d04913d improve dependabot error message (#2375) 2026-04-30 12:28:57 -07:00
Roberto Nacu 4bded57e02 Fix lockdown mode permission check (#2361)
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Docker / build (push) Has been cancelled
Build and Test Go Project / build (macos-latest) (push) Has been cancelled
Build and Test Go Project / build (ubuntu-latest) (push) Has been cancelled
Build and Test Go Project / build (windows-latest) (push) Has been cancelled
GoReleaser Release / release (push) Has been cancelled
MCP Server Diff / mcp-diff (push) Has been cancelled
Publish to MCP Registry / publish (push) Has been cancelled
* use REST API for permission checks

* update tests

* skip API call for bots and add github-action[bot] to trusted logins

* improve tests

* add nil guard to IsSafeContent

* add comment clarifying maintain mapping

---------

Co-authored-by: Sam Morrow <info@sam-morrow.com>
2026-04-23 12:21:29 +01:00
Iulia Bejan 3a6a6f6682 Fix set_issue_fields mutation: use correct inline fragments for IssueFieldValue union (#2366)
Docker / build (push) Has been cancelled
GoReleaser Release / release (push) Has been cancelled
MCP Server Diff / mcp-diff (push) Has been cancelled
Publish to MCP Registry / publish (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Build and Test Go Project / build (macos-latest) (push) Has been cancelled
Build and Test Go Project / build (ubuntu-latest) (push) Has been cancelled
Build and Test Go Project / build (windows-latest) (push) Has been cancelled
* Fix set_issue_fields mutation: use correct inline fragments for IssueFieldValue union

The mutation response struct used a single inline fragment
'... on IssueFieldDateValue' with a 'Name' field that doesn't exist
on that type (only IssueFieldSingleSelectValue has 'name'). This
caused GraphQL validation to fail with:

  Field 'name' doesn't exist on type 'IssueFieldDateValue'

Since GraphQL validates the entire document (including response
selection sets) before executing any operation, the mutation never
fired at all — no fields were ever set regardless of input.

Fix by adding correct inline fragments for all four union types:
- IssueFieldTextValue (value)
- IssueFieldSingleSelectValue (name)
- IssueFieldDateValue (value)
- IssueFieldNumberValue (value)

* Update test mock to match corrected inline fragments

* Update handler_test.go formatting
2026-04-22 15:42:25 +01:00
Copilot 569a48d847 Enforce exactly one value key per field in set_issue_fields (#2339)
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Docker / build (push) Has been cancelled
Build and Test Go Project / build (macos-latest) (push) Has been cancelled
Build and Test Go Project / build (ubuntu-latest) (push) Has been cancelled
Build and Test Go Project / build (windows-latest) (push) Has been cancelled
GoReleaser Release / release (push) Has been cancelled
MCP Server Diff / mcp-diff (push) Has been cancelled
Publish to MCP Registry / publish (push) Has been cancelled
* Initial plan

* Enforce exactly one value key per field in set_issue_fields and add tests

Address review feedback:
- Change validation to count value keys and reject when multiple are
  provided (e.g., text_value + number_value, or text_value + delete).
- Add unit tests for multiple value keys and value + delete scenarios.
- Run generate-docs (no doc changes needed; README was already current).

Agent-Logs-Url: https://github.com/github/github-mcp-server/sessions/7e89edb3-5315-42dd-bfa1-6c962f1ba137

Co-authored-by: mattdholloway <918573+mattdholloway@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: mattdholloway <918573+mattdholloway@users.noreply.github.com>
2026-04-16 15:11:24 +02:00
Matt Holloway fc7a7dcdea feat: add granular tool to set issue field values 2026-04-16 15:11:24 +02:00
Sam Morrow a24c0be254 refactor: migrate MCP Apps from insiders mode to feature flag
Rebase PR #2282 onto main (post-#2332) and unify feature flag
allowlists into a single source of truth.

- Add MCPAppsFeatureFlag, AllowedFeatureFlags, InsidersFeatureFlags,
  and ResolveFeatureFlags in feature_flags.go
- AllowedFeatureFlags includes all user-controllable flags (MCP Apps +
  granular), InsidersFeatureFlags only includes MCPAppsFeatureFlag
- HeaderAllowedFeatureFlags() now delegates to AllowedFeatureFlags
- Builder uses feature checker instead of insidersMode bool
- Remove InsidersOnly field from ServerTool and WithInsidersMode from
  Builder
- HTTP feature checker uses ResolveFeatureFlags for per-request
  resolution with insiders expansion
- Tool handlers check MCPAppsFeatureFlag via IsFeatureEnabled instead
  of InsidersMode

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 11:41:19 +02:00
Matt Holloway efcaead5b5 feat(http): update knownFeatureFlags to use HeaderAllowedFeatureFlags() and add tests for feature flag validation 2026-04-15 17:36:32 +02:00
Matt Holloway 7894292b65 Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-15 17:36:32 +02:00
Matt Holloway 3cf4124dcf feat(http): implement HeaderAllowedFeatureFlags for X-MCP-Features header validation 2026-04-15 17:36:32 +02:00
Matt Holloway 62266f804b OSS granular PRs and issues toolsets (#2306)
Build and Test Go Project / build (macos-latest) (push) Has been cancelled
Docker / build (push) Has been cancelled
Build and Test Go Project / build (ubuntu-latest) (push) Has been cancelled
Build and Test Go Project / build (windows-latest) (push) Has been cancelled
MCP Server Diff / mcp-diff (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
GoReleaser Release / release (push) Has been cancelled
Publish to MCP Registry / publish (push) Has been cancelled
* initial OSS granular PRs and issues toolsets

* update docs

* refactor: reuse existing helpers in granular toolsets

Refactor granular issue and PR tools to delegate to existing tested
helper functions instead of reimplementing logic from scratch:

- Sub-issue tools (add/remove/reprioritize) now delegate to existing
  REST-based AddSubIssue, RemoveSubIssue, ReprioritizeSubIssue helpers
- PR review tools (create/submit/delete) now delegate to existing
  CreatePullRequestReview, SubmitPendingPullRequestReview,
  DeletePendingPullRequestReview helpers (fixes viewer filtering bug)
- Review comment tool now uses viewer-safe pattern from
  AddCommentToPendingReview (query viewer, filter by author, validate
  PENDING state, pass PullRequestReviewID)
- Fix milestone param to use RequiredInt instead of float64 cast
- Fix line/startLine params to use OptionalIntParam
- Draft state tool uses typed GraphQL inputs matching existing patterns
- Remove duplicate GraphQL types and helper functions
- Add toolsnap tests for all 20 granular tools
- Update generated docs

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

* refactor: use feature flags instead of separate granular toolsets

Place granular tools in existing issues/pull_requests toolsets with
FeatureFlagEnable, instead of creating separate issues_granular and
pull_requests_granular toolsets. This is simpler and uses the existing
feature flag infrastructure to switch between consolidated and
granular tool variants at runtime.

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

* fix: address review feedback on granular toolsets

- Fix REST response handling: capture resp, close body, use ghErrors
  helpers in issueUpdateTool, prUpdateTool, GranularCreateIssue, and
  GranularRequestPullRequestReviewers
- Add FeatureFlagDisable on consolidated tools (IssueWrite, SubIssueWrite,
  UpdatePullRequest, PullRequestReviewWrite, AddCommentToPendingReview)
  so they are hidden when granular variants are active
- Use OptionalStringArrayParam for assignees, labels, reviewers instead
  of manual loop that silently dropped non-string elements
- Fix side/startSide empty string leak: pass nil pointer when absent
  instead of pointer to empty string in GraphQL mutations
- Fix milestone minimum from 0 to 1 to match RequiredInt rejection of 0
- Return MinimalResponse {id, url} instead of full JSON objects
- Fix RequiredParam[bool] rejecting draft=false by using presence check
- Add handler tests for update_pull_request_draft_state (draft + ready)
  and add_pull_request_review_comment with full GraphQL mocking

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

* fix: address review feedback on granular toolsets

- Fix translation keys to use ALL_CAPS convention (strings.ToUpper)
- Fix assignees/labels clearing: check key presence instead of len==0
- Extract AddCommentToPendingReviewCall helper to deduplicate GraphQL
  logic between consolidated and granular tools
- Add missing granular tools: resolve_review_thread, unresolve_review_thread
  (were in pull_request_review_write but had no granular replacements)
- Add handler tests for new resolve/unresolve tools

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

---------

Co-authored-by: Sam Morrow <info@sam-morrow.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-14 15:40:00 +01:00
Matt Holloway dd239d8443 Initial OSS logging adapter for http (#2008)
* initial logging stack for http

* add metrics adapter

* fix linter issues

* make log fields generic

* Update pkg/github/server_test.go

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

* Remove unused SlogMetrics adapter

The slog-based metrics adapter was never used — OSS always uses
NoopMetrics and the remote server has its own DataDog-backed adapter.

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

* Update pkg/github/dependencies.go

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

* fmt

* change to use slog

* address feedback

* rename noop adapter to noop sink

* Update pkg/http/server.go

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

* [WIP] [WIP] Address feedback on OSS logging adapter for http implementation (#2264)

* Initial plan

* Fix BaseDeps.Logger and BaseDeps.Metrics to return safe defaults when Obsv is nil

Agent-Logs-Url: https://github.com/github/github-mcp-server/sessions/53221b0b-abb4-4138-a147-3ce9e13b379a

Co-authored-by: mattdholloway <918573+mattdholloway@users.noreply.github.com>

* Fix nil metrics in server.go by passing metrics.NewNoopMetrics() to NewExporters

Agent-Logs-Url: https://github.com/github/github-mcp-server/sessions/53221b0b-abb4-4138-a147-3ce9e13b379a

Co-authored-by: mattdholloway <918573+mattdholloway@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: mattdholloway <918573+mattdholloway@users.noreply.github.com>
Co-authored-by: Matt Holloway <mattdholloway@github.com>

* replace nil with stubs

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2026-03-31 13:10:22 +01:00
Artem Sierikov b01f7f5b6a fix: additionalProperties in push_files schema (#2011)
Some MCP clients require array item schemas to explicitly set
`additionalProperties: false`. Without this, `push_files` calls will fail.

Fixes #2011
Research and fix was initially done by @04cb
2026-03-29 04:34:20 +02:00
Lucas Bustamante 24ede6975c feat: add path, since, and until filters to list_commits
Add three optional parameters to the list_commits tool that map to
existing GitHub API query parameters:

- path: filter commits to those touching a specific file or directory
- since: only commits after this date (ISO 8601)
- until: only commits before this date (ISO 8601)

These parameters are already supported by the go-github library's
CommitsListOptions struct but were not exposed by the MCP tool.

The path filter is particularly useful for monorepo workflows where
commit history needs to be scoped to a specific project subdirectory.

Time parsing uses the existing parseISOTimestamp helper (shared with
list_issues and list_gists) which accepts both YYYY-MM-DDTHH:MM:SSZ
and YYYY-MM-DD formats.

Closes #197
2026-03-24 21:34:31 +01:00
Sam Morrow 61a34c1454 docs: document SERVER_NAME and SERVER_TITLE overrides
Add documentation for the server name and title customization feature
to the README i18n section and server-configuration.md quick reference.
This helps users running multiple GitHub MCP Server instances discover
how to configure unique identities via environment variables or the
config JSON file.

Co-authored-by: Anika Reiter <1503135+Anika-Sol@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-16 15:03:13 +01:00
copilot-swe-agent[bot] 74507a00ab Use translation strings for server name/title override
Instead of new CLI flags (--server-name, --server-title), reuse the
existing string override mechanism that already supports tool title/
description overrides throughout the codebase.

Users can now configure the server name and title via:
  - GITHUB_MCP_SERVER_NAME / GITHUB_MCP_SERVER_TITLE env vars
  - "SERVER_NAME" / "SERVER_TITLE" keys in github-mcp-server-config.json

This is consistent with how all other user-visible strings are
overridden (e.g. GITHUB_MCP_TOOL_GET_ME_USER_TITLE). No new struct
fields or CLI flags are needed.

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
2026-03-16 15:03:13 +01:00
copilot-swe-agent[bot] 0fda6f1509 Add configurable server name and title via env/flag
Allows users running multiple GitHub MCP Server instances (e.g., for
github.com and GitHub Enterprise Server) to override the server name and
title in the MCP initialization response.

- Add --server-name / GITHUB_SERVER_NAME flag+env to override name
- Add --server-title / GITHUB_SERVER_TITLE flag+env to override title
- Defaults remain "github-mcp-server" and "GitHub MCP Server"
- Applies to both stdio and HTTP server modes
- Add tests for default and custom name/title

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
2026-03-16 15:03:13 +01:00
Patrick Walters f93e5260a2 feat: add resolve/unresolve review thread methods
Adds `resolve_thread` and `unresolve_thread` methods to the
`pull_request_review_write` tool, enabling users to resolve and
unresolve PR review threads via GraphQL mutations.

- Add ThreadID field to PullRequestReviewWriteParams struct
- Add threadId parameter and new methods to tool schema
- Implement ResolveReviewThread function using GraphQL mutations
- Add switch cases for resolve_thread and unresolve_thread methods
- Add unit tests covering success, error, empty and omitted threadId
- Document that owner/repo/pullNumber are unused for these methods
- Document idempotency (resolving already-resolved is a no-op)
- Update toolsnaps and generated docs

Fixes #1768

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:30:46 +01:00
copilot-swe-agent[bot] f09dd5e774 Use key presence check instead of OptionalParam in UI gate
Build and Test Go Project / build (macos-latest) (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Docker / build (push) Has been cancelled
Build and Test Go Project / build (ubuntu-latest) (push) Has been cancelled
Build and Test Go Project / build (windows-latest) (push) Has been cancelled
GoReleaser Release / release (push) Has been cancelled
MCP Server Diff / mcp-diff (push) Has been cancelled
Publish to MCP Registry / publish (push) Has been cancelled
Check for the "state" key directly in the args map rather than using
OptionalParam and ignoring its error. This ensures that a wrongly-typed
state value bypasses the UI form (falling through to the normal
validation path) instead of silently showing the form.

Co-authored-by: mattdholloway <918573+mattdholloway@users.noreply.github.com>
2026-03-06 15:08:53 +01:00
copilot-swe-agent[bot] 50a04616ea Skip MCP Apps UI form when update includes a state change
When using issue_write with method "update" and a state parameter (e.g.
"closed"), the MCP Apps UI form was incorrectly shown. The form only
handles title/body editing and would lose the state transition. Now when
a state change is requested, the UI form is skipped and the update
executes directly.

Fixes github/github-mcp-server#798

Co-authored-by: mattdholloway <918573+mattdholloway@users.noreply.github.com>
2026-03-06 15:08:53 +01:00
Ksenia Bobrova f58208394a Correctly wrap GraphQl error (#2149) 2026-03-05 15:30:54 +01:00
Jakub Janusz c79439e0e3 fix: handle empty files in get_file_contents (#2042)
1. Empty (0-byte) files caused an unhandled error because the GitHub API
   returns null content with base64 encoding for them; GetContent() fails
   with "malformed response: base64 encoding of null content". Return
   empty text/plain content directly, bypassing decoding entirely.

Co-authored-by: Ksenia Bobrova <almaleksia@github.com>
2026-03-04 15:43:41 +01:00
Ksenia Bobrova ccb9b5308d Fix SHA validation in create_or_update_file (#2134)
* Fix SHA validation in create_or_update_file

* Doc update

* Handle non-404 errors

* Handle directory paths

* Update instructions
2026-03-04 14:34:49 +01:00
Ksenia Bobrova b50a343da5 Gracefully handle numeric parameters passed as strings (#2130)
* Gracefully handle numeric parameters passed as strings
2026-03-04 09:01:15 +01:00
Roberto Nacu bf6467855c Reduce context usage for list_issues (#2098)
* reduce context usage for list_issues

* address copilot feedback, align pagination tags to camelCase
2026-02-26 10:02:51 +00:00
Roberto Nacu b222072346 Reduce context usage for list_releases (#2091) 2026-02-25 18:15:22 +00:00
Matt Holloway 81f4c87a31 make ui submit message prior to click even more insistent (#2096) 2026-02-25 18:02:37 +00:00
Matt Holloway 584d0c9163 clarify user confirmation requirement in issue and pull request creation messages (#2094) 2026-02-25 16:57:15 +00:00
Roberto Nacu 391990ae80 Reduce context usage for list_tags (#2088) 2026-02-25 15:32:21 +00:00
Roberto Nacu c1ac64f1a2 Reduce context usage for list_pull_requests (#2087) 2026-02-25 15:25:52 +00:00
kaitlin-duolingo 91b35e0f77 Get check runs (#1953)
* Add support for get_check_runs

* Run generate-docs

* Address AI code review comment

* make descriptions less ambiguous for model

* lint and docs

* fix lint

---------

Co-authored-by: tommaso-moro <tommaso-moro@github.com>
Co-authored-by: Tommaso Moro <37270480+tommaso-moro@users.noreply.github.com>
2026-02-25 13:42:24 +00:00
Sam Morrow a32a757d70 Fix panic when fetching resources fails due to network error (#1506)
* fix panic due to defer reading body of failed request

---------

Co-authored-by: Adam Holt <omgitsads@github.com>
2026-02-25 12:51:06 +01:00
Matt Holloway 2b55513a9e Update MIME types for UI resources to include profile for MCP Apps (#2078)
* update MIME types for UI resources to include profile for MCP Apps

* make it a const
2026-02-24 16:38:13 +00:00
Matt Holloway a94f95b43f Enhance client support checks for MCP Apps UI rendering (#2051)
* enhance client support checks for MCP Apps UI rendering

* update dependencies and enhance MCP Apps UI support handling

* chore: regenerate license files

Auto-generated by license-check workflow

* retrigger CI

* update test

* introduce constants for client names and remove wrong ide name for mcp apps support

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-24 13:41:19 +00:00
Tommaso Moro c0ba3edcee use minimal types (#2066) 2026-02-24 13:07:45 +00:00
Tommaso Moro 3ffc06b71d reduce context for add_issue_comments using minimal types (#2063) 2026-02-24 11:20:19 +00:00