Skip to content

Refactor workflows, enhance documentation, and add new tools#2537

Draft
turbotenant-sync wants to merge 590 commits into
github:nextfrom
turbotenant-sync:main
Draft

Refactor workflows, enhance documentation, and add new tools#2537
turbotenant-sync wants to merge 590 commits into
github:nextfrom
turbotenant-sync:main

Conversation

@turbotenant-sync
Copy link
Copy Markdown

Summary

Why

Fixes #

What changed

MCP impact

  • No tool or API changes
  • Tool schema or behavior changed
  • New tool added

Prompts tested (tool changes only)

Security / limits

  • No security or limits impact
  • Auth / permissions considered
  • Data exposure, filtering, or token/size limits considered

Tool renaming

  • I am renaming tools as part of this PR (e.g. a part of a consolidation effort)
    • I have added the new tool aliases in deprecated_tool_aliases.go
  • I am not renaming tools as part of this PR

Note: 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

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

Docs

  • Not needed
  • Updated (README / docs / examples)

SamMorrowDrums and others added 30 commits January 12, 2026 15:45
Sort all JSON object keys alphabetically at every level in toolsnaps by
unmarshaling and remarshaling. This leverages Go's built-in behavior where
json.Marshal automatically sorts map keys alphabetically, ensuring
consistent field ordering and eliminating noop churn in diffs.

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
* get it working

* clean up approach by moving cleantools inside builder, this simplifies remote server too

* add tests for trimming and deduplication

* error out in the builder if there are unrecognized tools

---------

Co-authored-by: Sam Morrow <info@sam-morrow.com>
- Added optional custom_instructions parameter to tool schema
- Updated implementation to pass custom instructions to agent assignment
- Added test case to verify custom_instructions works correctly
- Updated toolsnaps and documentation

The custom_instructions parameter allows users to provide additional
context, constraints, or guidance to the Copilot agent beyond what's
in the issue body, addressing the issue where additional context
would otherwise be lost.

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
- Add http.StatusNoContent (204) to the list of accepted success status codes
- Add test case for 204 response when marking notification as done
- Retain existing test for 200 response for backwards compatibility

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
* wip injecting ff function into tool as dep

* remove debug

* fix linter

* add better test

* adding compile time check

* move experimental to seperate config/ff value

* adding test var

* fixing test

* adding flag and possibility to call feature checker

* fixing name
Enhances the assign_copilot_to_issue tool to automatically poll for
the PR created by the Copilot coding agent after assignment.

Changes:
- Add findLinkedCopilotPR() to query issue timeline for CrossReferencedEvent
  items from PRs authored by copilot-swe-agent
- Add polling loop (9 attempts, 1s delay) matching remote server latency
- Return structured JSON with PR details when found, or helpful note otherwise
- Add PollConfig for configurable polling (used in tests to disable)
- Add GraphQLFeaturesTransport for feature flag header support

The returned response now includes:
- issue_number, issue_url, owner, repo
- pull_request object (if found during polling)
- Note with instructions to use get_copilot_job_status if PR not yet created
When polling for a linked PR after assigning Copilot to an issue,
we now capture the assignment time before the mutation and filter
to only return PRs created after that time. This prevents the tool
from incorrectly returning old PRs from previous Copilot assignments.
- Document GraphQLFeaturesTransport is for library consumers
- Convert githubv4.Int/String to native Go types in result map
- Remove misleading log comment since tool handlers lack logger access
Replace inline GraphQL-Features header logic in bearerAuthTransport with
the exported GraphQLFeaturesTransport. This removes code duplication and
ensures the transport is actually used, not just exported.
…to_issue

Add MCP progress notifications during the PR polling loop to provide
real-time status updates while waiting for Copilot to create a PR.

Changes:
- Use the request parameter to access the ServerSession for notifications
- Send an initial progress notification when polling starts
- Send progress updates on each polling attempt with attempt count
- Only send notifications when progressToken is provided by the client

This aligns with the behavior in create_pull_request_with_copilot tool
and improves the user experience during the waiting period.
* Add default label to all new issues

* Run on all issues

* Update .github/workflows/issue-labeler.yml

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

* Update .github/workflows/issue-labeler.yml

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

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
….5.0 (github#1798)

* build(deps): bump github.com/go-viper/mapstructure/v2

Bumps [github.com/go-viper/mapstructure/v2](https://github.com/go-viper/mapstructure) from 2.4.0 to 2.5.0.
- [Release notes](https://github.com/go-viper/mapstructure/releases)
- [Changelog](https://github.com/go-viper/mapstructure/blob/main/CHANGELOG.md)
- [Commits](go-viper/mapstructure@v2.4.0...v2.5.0)

---
updated-dependencies:
- dependency-name: github.com/go-viper/mapstructure/v2
  dependency-version: 2.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: regenerate license files

Auto-generated by license-check workflow

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: JoannaaKL <joannaakl@github.com>
* Add tool search CLI

* Update comments

* Update docs

* Generate docs

* Dont document other commands

* Licenses

* chore: regenerate license files

Auto-generated by license-check workflow

* Try to unlock checks

* generate docs

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Pin go-licenses to v2.0.1 for reproducible builds

Fixes code scanning alerts github#10 and github#11 by removing the @latest
version for local development and using the pinned v2.0.1 version
consistently across all environments.

This ensures deterministic builds and addresses the CWE-494
'Download of Code Without Integrity Check' security concern.

* Build full package in Dockerfile to include all commands
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…add_project_item

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>

Fix tests and update toolsnaps for consolidated projects tools

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
- Extract dual-fetch logic into listProjectsFromBothOwnerTypes helper
- Rename addProjectItemWithResolution to addProjectItem (old function removed)
- Add GraphQL test coverage for add_project_item using githubv4mock
- Tests cover both org/issue and user/pull_request success paths
Replace custom script/conformance-test with the reusable
mcp-conformance-action GitHub Action. This provides:

- Standardized MCP conformance testing across all MCP servers
- Automatic comparison between PR branch and merge-base
- Support for multiple configurations with different flags
- Custom message support for dynamic toolset testing
- Detailed conformance reports with timing comparisons
- Artifact upload for test results

All 16 original test configurations are preserved including
the dynamic tool call tests for toolset management.

Action: https://github.com/marketplace/actions/mcp-conformance-test
Related: github#1826
- Use checkout@v6 for consistency with other workflows
- Pin mcp-conformance-action to SHA for security
dependabot Bot and others added 26 commits May 19, 2026 09:05
github#2497)

Bumps distroless/base-debian12 from `9dce90e` to `58695f4`.

---
updated-dependencies:
- dependency-name: distroless/base-debian12
  dependency-version: 58695f439f772a00009c8f6be4c183f824c1f556d74b313c30900f167e4772f8
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…b#2500)

Bumps [reproducible-containers/buildkit-cache-dance](https://github.com/reproducible-containers/buildkit-cache-dance) from 3.3.2 to 3.4.0.
- [Release notes](https://github.com/reproducible-containers/buildkit-cache-dance/releases)
- [Commits](reproducible-containers/buildkit-cache-dance@1b8ab18...5422eac)

---
updated-dependencies:
- dependency-name: reproducible-containers/buildkit-cache-dance
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ithub#2499)

Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 7.2.1 to 7.2.2.
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](goreleaser/goreleaser-action@1a80836...5daf1e9)

---
updated-dependencies:
- dependency-name: goreleaser/goreleaser-action
  dependency-version: 7.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
….20260403154220-27f29c1cef3b to 1.6.0 (github#2498)

* build(deps): bump github.com/modelcontextprotocol/go-sdk

Bumps [github.com/modelcontextprotocol/go-sdk](https://github.com/modelcontextprotocol/go-sdk) from 1.5.1-0.20260403154220-27f29c1cef3b to 1.6.0.
- [Release notes](https://github.com/modelcontextprotocol/go-sdk/releases)
- [Commits](https://github.com/modelcontextprotocol/go-sdk/commits/v1.6.0)

---
updated-dependencies:
- dependency-name: github.com/modelcontextprotocol/go-sdk
  dependency-version: 1.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: regenerate license files

Auto-generated by license-check workflow

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…CI (github#2501)

* chore(ui): migrate vite 6 -> 8 and plugin-react 4 -> 6

Supersedes the auto-generated bump in github#2496, which only updated vite and
left @vitejs/plugin-react on a peer range that excludes vite 8, breaking
the UI build (and every Go job that embeds the UI assets) with ERESOLVE.

- vite ^6.0.0 -> ^8.0.13
- @vitejs/plugin-react ^4.3.0 -> ^6.0.2 (peers vite ^8.0.0 only)
- vite-plugin-singlefile ^2.0.0 -> ^2.3.3 (peers already allowed v8)
- engines.node >=20 -> ^20.19.0 || >=22.12.0 (Vite 7+ requirement)

Vite 8 ships Rolldown instead of Rollup, which rejects bundle mutation in
generateBundle. The rename-output plugin was doing exactly that to flatten
the singlefile-inlined HTML from src/apps/<app>/index.html down to
<app>.html. Refactored it to hoist the file in closeBundle (post-write)
and renamed it to flatten-output to reflect what it actually does.

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

* chore(ui): give flatten-output a clearer error when the HTML is missing

Addresses Copilot review feedback on github#2501: if the singlefile-inlined HTML
isn't where we expect it (e.g. because a future Vite/Rolldown change alters
the output path), throw with the app name and expected path instead of
letting renameSync surface a bare ENOENT.

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

* perf(ui+ci): cache build artifacts and run vite in single process

Introduce a content-addressable cache for the embedded UI HTML and refactor
the build script to invoke vite once per Node process instead of three
times.

* New ui/scripts/build.mjs runs vite build() in a loop within one process,
  removing the cross-env dev dependency and avoiding redundant plugin/JIT
  warm-up. Local build time drops from ~2.4s to ~1.5s.

* New .github/actions/build-ui composite action restores
  pkg/github/ui_dist/{get-me,issue-write,pr-write}.html from cache keyed on
  hashes of ui/ sources and the lockfile. On cache hit it skips Node setup
  and the build entirely; on miss it sets up Node and runs script/build-ui
  as before. Saves ~6s per workflow on Go-only PRs, which is the common
  case across seven workflows.

* Replace the duplicated setup-node + Build UI pair in seven workflows
  (go, lint, docs-check, license-check, goreleaser, mcp-diff, code-scanning)
  with a single uses: ./.github/actions/build-ui line. code-scanning keeps
  a dedicated setup-node for the JavaScript CodeQL path.

Output files are byte-identical to the pre-refactor build.

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

* perf(ci): share UI artifact cache across runner OSes

The cached HTML output is platform-independent, so set
enableCrossOsArchive on the cache step. With this any OS can restore
the cache populated by any other OS — one shared cache instead of three.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: guard CompletionsHandler against nil params/ref

A malformed completion/complete request with missing or empty
parameters caused a nil pointer dereference in CompletionsHandler,
panicking the process. Reject such requests with a clear error
before dispatching on Ref.Type.

Reported by @manthanghasadiya (GHSA-w4q6-qw23-4rg7).

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

* Align error wording with repo convention

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

---------

Co-authored-by: manthanghasadiya <68530736+manthanghasadiya@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ma (github#2489)

The `pull_request_read` tool description tells clients that
`get_review_comments` uses cursor-based pagination (`perPage`, `after`),
and the handler does plumb `after` through to the GraphQL query, but the
input schema only declared `page` and `perPage` (via `WithPagination`).
Because `after` was not advertised in `inputSchema`, MCP clients had
no way to request it, leaving cursor pagination effectively broken:
`perPage: 1` returned only the first thread with no way to advance, and
`page` was silently ignored by the GraphQL path.

This change adds `after` to the schema (string, optional) with a
description making clear it only applies to `get_review_comments`. All
other methods continue to ignore it. No handler behavior is changed.

- Add `after` schema property after `WithPagination` in `PullRequestRead`
- Regenerate `__toolsnaps__/pull_request_read.snap` and update README
- Add a regression test asserting `after` is in the schema and a new
  table-driven case verifying the cursor is forwarded to the GraphQL query

Fixes github#2122 (for the `get_review_comments` pagination part). The
remaining concerns in github#2122 about unbounded response sizes for `get`,
`get_diff`, and `get_reviews` are deferred to follow-up design.

Co-authored-by: Sam Morrow <info@sam-morrow.com>
- Rename NewServerToolWithRawContextHandler -> NewServerTool. This is the
  preferred constructor for raw mcp.ToolHandler tools because it avoids
  creating closures at registration time, which matters for per-request
  servers that re-register all tools on every request.
- Rename deprecated generic NewServerTool[In, Out] -> NewServerToolWithDeps
  to free up the simpler name and make its closure-based nature explicit.
  The dynamic tools package is the only legitimate user of this constructor
  because DynamicToolDependencies differs from the standard ToolDependencies.
- Remove deprecated NewServerToolFromHandler. Its only callers can use the
  new NewServerTool directly via context-injected deps.
- Update all call sites in dependencies.go, dynamic_tools.go, and
  registry_test.go.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* refactor: simplify NewServerTool naming

- Rename NewServerToolWithRawContextHandler -> NewServerTool. This is the
  preferred constructor for raw mcp.ToolHandler tools because it avoids
  creating closures at registration time, which matters for per-request
  servers that re-register all tools on every request.
- Rename deprecated generic NewServerTool[In, Out] -> NewServerToolWithDeps
  to free up the simpler name and make its closure-based nature explicit.
  The dynamic tools package is the only legitimate user of this constructor
  because DynamicToolDependencies differs from the standard ToolDependencies.
- Remove deprecated NewServerToolFromHandler. Its only callers can use the
  new NewServerTool directly via context-injected deps.
- Update all call sites in dependencies.go, dynamic_tools.go, and
  registry_test.go.

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

* fix: return isError for argument validation failures

When tool argument unmarshalling fails (wrong types, malformed JSON),
return a CallToolResult with IsError: true instead of a Go error.
Returning a Go error is converted by the SDK into a JSON-RPC protocol
error (-32603), which is invisible to agents and prevents self-correction.
Returning IsError: true with the validation message lets agents see the
problem and retry with corrected arguments.

Affects:
- NewServerToolWithDeps (was NewServerTool prior to the rename in github#2510)
- NewServerToolWithContextHandler

Fixes github#1952.
Re-applies github#2488 by @blackwell-systems on top of the NewServerTool rename.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: blackwell-systems <236632453+blackwell-systems@users.noreply.github.com>
…ithub#2512)

Dynamic toolset discovery (the meta-tools enable_toolset, list_available_toolsets,
get_toolset_tools and the --dynamic-toolsets / GITHUB_DYNAMIC_TOOLSETS switch)
was a local-only feature never offered by the remote server. Removing it
deletes a meaningful chunk of branching, configuration surface and tests
for a path no longer in active use.

The deprecated closure-based NewServerToolWithDeps generic constructor was
only kept around for the dynamic tool registration path and is removed
together with it. Going forward there are exactly two constructors:

- NewServerTool — raw mcp.ToolHandler, no closure, no unmarshalling
- NewServerToolWithContextHandler[In, Out] — typed handler, deps via context

Inventory methods that only existed for the dynamic path
(ToolsForToolset, IsToolsetEnabled, EnableToolset, EnabledToolsetIDs)
are removed. ResolvedEnabledToolsets loses its dynamic flag.

Also strips dynamic references from the README, server configuration
docs, copilot-instructions, mcp-diff workflow, and conformance-test
script.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Adding rationle for fields and labels in issues_granular

Co-authored-by: Copilot <copilot@github.com>

* removed descriptions

* test: update update_issue_labels toolsnap schema text

* removed descriptions

Co-authored-by: Copilot <copilot@github.com>

* fixed snaps

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Sam Morrow <info@sam-morrow.com>
* Include custom issue field values in list_issues response

Adds Issues 2.0 custom field values to each issue returned by the
list_issues GraphQL query, exposed on MinimalIssue as field_values:
[{field, value}]. Filtering by field is a separate concern (needs the
GraphQL IssueFilters input updated upstream) and is not included here.

shurcooL/graphql's response decoder walks every inline fragment of a
union regardless of __typename, so IssueFieldNumberValue.value is
aliased to valueNumber to avoid a Float-vs-String type clash when the
runtime variant is, e.g., a SingleSelectValue.

* Extend list_issues tests to cover Date/Number/Text field value variants

---------

Co-authored-by: Sam Morrow <info@sam-morrow.com>
…ce (github#2513)

The current `search_code` query description is hand-wavy and gives the
model little usable guidance on GitHub code search syntax, which (per
analysis in github#2390 across thousands of agent sessions) leads to repeated
422 ERROR_TYPE_QUERY_PARSING_FATAL responses from agents that guess at
plausible-but-invalid syntax.

Re-applies the spirit of github#2442 by @jluocsa, originally suggested by
@danmoseley in github#2390, but corrected against the actual endpoint this
tool calls.

Critically, this tool uses go-github's `client.Search.Code`, which hits
the legacy REST `/search/code` endpoint — NOT the new code search
("Blackbird"). Verified against the live API:

  symbol:WithContext repo:github/github-mcp-server  -> 0
  /Get|Set/ repo:github/github-mcp-server           -> 0
  path:**/*.go func repo:github/github-mcp-server   -> 0
  filename:*.md repo:github/github-mcp-server       -> 0
  (Foo OR Bar) -path:vendor language:go             -> 422

So `symbol:`, `/regex/`, path globs, filename globs, and parenthesized
boolean groups — features the proposal in github#2442 listed — silently
return zero or fail. Documenting them would teach the model syntax
that doesn't work on this endpoint.

The new description focuses on what's actually supported by legacy
code search and the real bugs observed in github#2390:

- `path:dir` is a prefix, NOT a glob (displaces `path:**/*.ts` guesses).
- `filename:exact.ext` is exact, NOT a glob (displaces `filename:*.md`).
- `/regex/` and `\|` inside quotes don't work — call this out so the
  model stops generating them.
- `symbol:` doesn't work on this endpoint — call this out.
- Parenthesized boolean groups 422 — call this out so the model
  stops wrapping `OR` chains in parens.
- Adds `extension:`, `in:file`, `in:path`, `size:`, `filename:`, `user:`
  qualifiers that the previous text omitted.
- Implicit AND, `OR`, `NOT`, and `"quoted phrase"` for exact match are
  documented positively.
- 256-char query limit.

All four examples in the new description are verified against the live
GitHub API and return non-zero results.

Co-authored-by: jluocsa <103165870+jluocsa@users.noreply.github.com>
Co-authored-by: danmoseley <6385855+danmoseley@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add field_values to search_issues results

* remove dupe keys

* Fix advanced search not enabled for fields

---------

Co-authored-by: Sam Morrow <info@sam-morrow.com>
* feat(code_scanning): add pagination to list_code_scanning_alerts (github#2363)

* feat(dependabot): add pagination to list_dependabot_alerts (github#2363)

* feat(secret_scanning): add pagination to list_secret_scanning_alerts (github#2363)

* test(code_scanning): pagination expectations + new test case (github#2363)

* test(dependabot): pagination expectations + new test case (github#2363)

* test(secret_scanning): pagination expectations + new test case (github#2363)

* test(toolsnaps): refresh list_code_scanning_alerts with page/perPage (github#2363)

* test(toolsnaps): refresh list_dependabot_alerts with page/perPage (github#2363)

* test(toolsnaps): refresh list_secret_scanning_alerts with page/perPage (github#2363)

* docs: regenerate README for new pagination params

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

---------

Co-authored-by: Sam Morrow <info@sam-morrow.com>
Co-authored-by: sammorrowdrums <sam.morrowdrums@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* add `SearchCommits` tool

* run test

* run script/generate-docs

* Potential fix for pull request finding

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

* refactor(search_commits): share commit conversion, surface repo, tighten query docs

- Extract newMinimalCommitFromCore to share field mapping between
  convertToMinimalCommit (RepositoryCommit) and the new
  convertCommitResultToMinimalCommit (CommitResult), removing ~50
  lines of duplicated logic from the search_commits handler.
- Add MinimalRepoRef and a search-only MinimalCommitSearchItem type
  (embedding MinimalCommit) so cross-repo commit search results
  identify the repo each commit came from. Keeping the field off
  MinimalCommit avoids paying for a never-populated field on the
  get_commit/list_commits output types.
- Rewrite the query description to teach the model the actual
  commit-search qualifier surface (repo:/org:/user: scoping, author/
  committer/date qualifiers, hash/tree/parent, merge:, is:public)
  and reword the sort description to drop redundancy with the enum.
- Extend tests to assert the repository field is surfaced and to
  cover commits with no resolved GitHub user (nil Author/Committer).
- Refresh README and toolsnap.

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

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Sam Morrow <info@sam-morrow.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix return Thread ID in get_review_comments response

* Fix syntax error in convertToMinimalReviewThread

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

---------

Co-authored-by: Jui Desai <juidesai@MacBook-Pro.local>
Co-authored-by: Sam Morrow <info@sam-morrow.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add list_org_issue_fields tool

* Clean up code

* complete struct fields & rename option type

* Drop created_at/updated_at from IssueField and IssueSingleSelectFieldOption

* Address feedback

* Address Copilot review: close resp.Body, set expectError=true for missing org test

* Adjust to list_issue_fields

* Add feature flag

* Allow tool to support read:org or repo

* Docs

* address comments

* Add repo_issue_fields flag

---------

Co-authored-by: Michael Jacholke <46944669+michaeljacholke@users.noreply.github.com>
* Add custom field filtering to list_issues

* Flatten schema

* add repo fields flag

* test fix

---------

Co-authored-by: Sam Morrow <sammorrowdrums@github.com>
Tool title annotations should be consistent with the rest of the tool catalog and render cleanly in agent UIs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Sam Morrow <info@sam-morrow.com>
github#2450)

* Add CSV output for list tools under insiders mode

* fix: resolve rebase feature flag conflicts

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

* Simplify feature-flag handling: collapse CSV dual-variant + skip filtering when no checker (github#2516)

* refactor: generic toolset+name sort, clarify feature flag intent

Address review feedback on github#2450:

- Collapse the three near-identical sort helpers in pkg/inventory/filters.go
  into a generic sortByToolsetThenName so adding new inventory item types
  doesn't require copying the comparator.
- Expand the doc comments on the three *WithoutFeatureFiltering helpers to
  spell out why they exist: HTTP mode builds a static (process-wide)
  inventory as an upper bound, but per-request feature flags from headers
  (X-MCP-Features, X-MCP-Insiders) are evaluated later, so feature-flagged
  variants must be preserved here.
- Strengthen the doc comment on ResolveFeatureFlags to make the contract
  explicit: user-supplied flags are validated against AllowedFeatureFlags,
  but insiders expansion deliberately is not — InsidersFeatureFlags may
  include server-controlled flags that are not user-toggleable.

CORS comments are intentionally left for the PR author.

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

* docs(feature-flags): clarify allowed and insiders sets are independent

Also add tests covering:
- a user-toggleable flag (FeatureFlagIssuesGranular) that insiders does
  not turn on automatically
- insiders mode not turning on user-only allowed flags

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

* refactor(inventory): collapse three *WithoutFeatureFiltering helpers into StaticUpperBound

The three parallel methods (AvailableToolsWithoutFeatureFiltering,
AvailableResourceTemplatesWithoutFeatureFiltering,
AvailablePromptsWithoutFeatureFiltering) were always called as a triple
in exactly two places: HTTP buildStaticInventory and its test mirror.
They exist because the dual-variant pattern (sibling tools with mirrored
FeatureFlagEnable / FeatureFlagDisable on the same name, e.g. CSV output)
makes feature filtering at static-build time impossible — both variants
must be kept and resolved per-request.

Replace the three with one method, Inventory.StaticUpperBound(ctx), that
returns (tools, resources, prompts) and carries the rationale in its
doc comment. Reduces API surface, eliminates the triplication, and makes
the single "skip feature filtering" concept obvious to readers.

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

* refactor: simplify feature-flag handling

Two related simplifications, both about treating insiders as a meta flag
that expands once at startup and then stops mattering:

- Collapse CSV's dual-variant pattern into a single tool whose handler
  performs a runtime feature-flag check via deps.IsFeatureEnabled. CSV
  is a pure response-format toggle, not a schema change, so it does not
  need the dual-name pattern that genuine schema variants (granular
  issues/PRs) still use.

- When no feature checker is installed, skip feature-flag filtering and
  return the full upper bound. The static HTTP inventory now uses plain
  AvailableTools/Resources/Prompts; the per-request inventory always
  installs a checker, so MCP registration (which serves a tool name once)
  always sees a deduplicated set. The bespoke StaticUpperBound helper and
  the isToolEnabledWithFeatureFlags split go away.

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

* ci(mcp-diff): add insiders + per-feature configs

The mcp-diff matrix now includes:
  - --insiders (and --insiders --read-only)
  - one config per github.AllowedFeatureFlags entry, generated by
    script/print-mcp-diff-configs so new user-controllable flags get
    diffed automatically without editing the workflow

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

* docs(insiders): explain feature-flag resolution for contributors

Adds a 'How feature flags are resolved' section covering:
  - Insiders is a meta flag, like 'all'/'default' for toolsets
  - User input -> allowlist filter -> insiders expansion ->
    server-side fallback (remote only)
  - AllowedFeatureFlags vs InsidersFeatureFlags are independent
  - How to add a new feature flag, including the
    TestGitHubPackageDoesNotReadInsidersMode guard

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

* refactor(inventory): make feature-flag gating a regular ToolFilter

Move tool feature-flag evaluation out of isToolEnabled and into a
ToolFilter installed at the head of the pipeline by Build() when
WithFeatureChecker received a non-nil checker. The 'no checker = no
filtering' contract is now expressed structurally (the filter isn't
installed) instead of by a runtime nil check inside the helper.

Resources and prompts have no filter pipeline, so they call the now-pure
featureFlagAllowed helper behind an explicit r.featureChecker != nil
guard at the iteration site.

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

* perf(inventory): cache extracted toolset IDs in sort comparator

Avoid evaluating the extractor closures up to three times per comparison.

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

---------

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

* fix: correct MCP features header in cors

* docs: regenerate README for CSV output toolset

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

* fix: remove duplicate MCPFeaturesHeader from CORS headers

* ci(mcp-diff): add streamable-http job with header-based configs

Adds a sibling mcp-diff-http job that exercises the streamable-http
transport against a shared HTTP server, with per-config settings supplied
via X-MCP-* request headers — mirroring how the remote server is invoked
in production (server-side defaults + per-user header overrides).

The config generator gains a -transport flag:
- stdio (default, unchanged behaviour)
- http-headers (emits headers-only configs targeting a shared server)

Two new combined entries layer multiple headers together as a smoke test
for header-merging regressions.

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

* docs: regenerate after merging main

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Sam Morrow <info@sam-morrow.com>
Co-authored-by: sammorrowdrums <sammorrowdrums@github.com>
…ds flag (github#2520)

* feat(issues): gate issue-fields features behind remote_mcp_issue_fields flag

Gates the recently merged issue-fields work (list_issue_fields tool,
field_values enrichment on list_issues/search_issues, and field_filters
input on list_issues) behind a new feature flag, also enabled in
insiders mode.

- list_issues splits into two same-named registrations: the field-aware
  variant requires the flag, while LegacyListIssues (FeatureFlagDisable)
  preserves the prior schema and GraphQL selection set so disabled
  callers don't pay the extra wire/server cost.
- search_issues skips the field-values lookup when the flag is off.
- list_issue_fields requires the flag to be registered at all.
- Adopts <tool>_ff_<flag>.snap naming for flagged toolsnap variants so
  same-named duplicates each get a distinct snapshot.

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

* fix: address PR review on issue-fields gating

- docs generator: install a no-flags feature checker so README reflects
  the default user experience (tools enabled with no special flags),
  fixing duplicate `list_issues` and removing granular/flagged-only
  tools that were never meant to appear in the default docs.
- csv_output: drop the FeatureFlagEnable/Disable exclusion in
  isCSVOutputTool. Wrapping happens before the per-request flag filter
  picks the live variant, so flag-gated list_* tools wrap safely; this
  restores CSV conversion for `list_issues` and enables it for
  `list_issue_fields` when both flags are on.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The bare `github-mcp-server`, `mcpcurl`, and `e2e.test` rules matched
those names anywhere in the tree, which silently ignored new files
created under `cmd/github-mcp-server/` (the rule treats the directory
component as a match). The intent was to ignore the binaries produced
by `go build` at repo root, so anchor each rule with a leading slash.

The existing `cmd/github-mcp-server/github-mcp-server` rule on line 2
continues to ignore the binary when built inside the cmd directory.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ub#2523)

The mcp-server-diff action checks the baseline ref out into a separate
working directory and runs install_command there. Without prebuilt UI
artifacts, pkg/github/ui_dist/ is empty on the baseline side and
UIAssetsAvailable() returns false, producing a false-positive diff that
"adds" _meta.ui to MCP Apps tools on every PR.

Stash the artifacts to RUNNER_TEMP after the workflow's build-ui step,
then restore them from install_command so both the baseline and PR
checkouts register identical MCP Apps UI metadata.

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

Adds two auto-generated documentation sections that describe how
feature flags shape the tool surface:

- docs/insiders-features.md gets a per-flag block under its existing
  hand-written prose. Each Insiders flag whose tools differ from the
  default surface is listed with the full tool schema rendered through
  the same writer used for README, so contributors can see exactly what
  Insiders Mode adds or changes.
- docs/feature-flags.md is new and gives the same treatment to every
  flag in AllowedFeatureFlags (user-controllable flags). It links back
  to the Insiders doc for the auto-enabled subset.

Both sections are produced by a single generator that diffs the
flag-on inventory against the default-flagged inventory and reports any
tool that is new or has a different InputSchema/Meta. No reason
classification - just tools and their schemas, kept intentionally
simple so contributors don't have to update the generator when adding
a new flag.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@turbotenant-sync turbotenant-sync requested a review from a team as a code owner May 24, 2026 23:31
@turbotenant-sync turbotenant-sync marked this pull request as draft May 24, 2026 23:32
@turbotenant-sync turbotenant-sync marked this pull request as ready for review May 24, 2026 23:32
@turbotenant-sync turbotenant-sync marked this pull request as draft May 24, 2026 23:33
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.