main
132 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a7c3b494e6 |
test(http): cover authorization server override wiring
Verify the HTTP-only configuration surface, unchanged host-derived default, and explicit override propagation through OAuth metadata. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> |
||
|
|
0ae533c163 |
feat(http): add --authorization-server flag to override OAuth AS URL
When deploying the MCP server behind an OAuth proxy (e.g. for GHES, which does not natively support RFC 8414, RFC 7591, or PKCE), the /.well-known/oauth-protected-resource endpoint currently always derives the authorization_servers URL from GITHUB_HOST. There is no way to point clients at a different authorization server without intercepting that endpoint at the ingress/proxy layer. The oauth.Config struct already has an AuthorizationServer field with the conditional logic in place (pkg/http/oauth/oauth.go), but it was never wired to any configuration surface. This commit exposes it as: - --authorization-server CLI flag on the http subcommand - GITHUB_AUTHORIZATION_SERVER environment variable (via viper's existing GITHUB_ prefix + automatic env mapping) When set, the value is passed through ServerConfig into oauth.Config, and the protected resource metadata advertises it directly instead of calling apiHost.AuthorizationServerURL(). |
||
|
|
3bad3bc651 | fix(http): make server lockdown mode an upper bound over requests (#3112) | ||
|
|
769340d6a1 |
fix(lockdown): harden pull_request_read get_commits handling
pull_request_read's get_commits method previously returned commit messages without any lockdown check, unlike get_diff and get_files which restrict the whole result when the PR author lacks push access. Commit content is part of the same untrusted head branch as the diff and file list, so GetPullRequestCommits now reuses enforcePullRequestLockdown for consistent, fail-closed behavior without adding a per-commit permission lookup. Also updates the lockdown documentation in README.md and docs/server-configuration.md to: - list pull_request_read:get_diff, get_files, and get_commits among the tools that error when the PR author lacks push access (get_diff and get_files were already implemented this way but undocumented) - clarify that lockdown mode is a best-effort content filter to reduce prompt-injection risk, not an authorization boundary - document the existing intentional trusted-bot exception (github-actions[bot], copilot) accurately Fixes #3105 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> |
||
|
|
8ec62491c6 |
Add confirmed repository deletion tool (#3076)
* feat(repos): add confirmed repository deletion Add a destructive delete_repository tool that requires an exact owner/repo confirmation through multi-round-trip elicitation. Gate the tool to MCP protocol 2026-07-28 and newer across local and remote transports. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 * refactor(inventory): generalize tool availability guards Gate protocol-restricted tools on required elicitation capabilities and enforce direct calls inside the registered handler so SDK result finalization remains intact. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 * feat(http): protect MRTR request state Seal repository deletion targets for self-hosted HTTP with a stable AES-256-GCM key. Hide only delete_repository when no key is configured and expose an optional sealer interface for remote integrators. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 * fix(repos): expire deletion confirmations Bind sealed repository deletion state to the immutable repository ID and a ten-minute expiry. Re-check identity before deletion so replay cannot affect a recreated repository. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 * fix(http): preserve tool and scope restrictions Apply static allowlists before removing unavailable tools and fail closed on invalid configured tool names. Model independent OAuth requirements as conjunctive groups so repository deletion requires both delete_repo and repo. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 * fix(repos): require protected confirmation state Give stdio a process-local request-state sealer and make deletion fail closed without one. Preserve legacy any-of OAuth behavior globally while documenting and enforcing delete_repository's conjunctive delete_repo and repo requirements. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 * fix(oauth): request repository deletion scope Include delete_repo in the supported OAuth scope set used by stdio login, HTTP protected-resource metadata, and tool filtering. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 * fix(oauth): require deletion scope opt-in Keep delete_repo in protected-resource discovery for step-up authorization while excluding it from the default stdio OAuth grant. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 * refactor(oauth): derive scope sets from catalog Generate protected-resource supported scopes and the lower-risk default OAuth grant from one canonical scope definition list. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 * refactor(scopes): own OAuth scope catalog Move supported and default OAuth scope policy into pkg/scopes so protected-resource metadata and stdio grants derive from the scope domain package. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 * fix(scopes): require workflow scope opt-in Keep workflow and codespace in protected-resource discovery while excluding both from the default OAuth grant alongside delete_repo. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 --------- Copilot-Session: 4b04480c-c2e9-483e-9b0f-34830b76a2f8 |
||
|
|
1b3f89a90a |
Add non-default find_duplicate tool gated by duplicate_detection flag (#3020)
* Add non-default find_duplicate tool gated by duplicate_detection flag * Trim find_duplicate output to spec fields and relax confidence_threshold bounds * Attach repo-visibility IFC label to find_duplicate results |
||
|
|
e7f7bb8b31 |
Support removing issue types (#2999)
* Render union types in generated docs Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea8faa5c-7f26-4e2d-bf9c-6f0b5f173e8c * Support clearing issue types with issue_write Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea8faa5c-7f26-4e2d-bf9c-6f0b5f173e8c * Support clearing issue types with granular tool Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea8faa5c-7f26-4e2d-bf9c-6f0b5f173e8c * Validate duplicate closures before updates Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea8faa5c-7f26-4e2d-bf9c-6f0b5f173e8c --------- Copilot-Session: ea8faa5c-7f26-4e2d-bf9c-6f0b5f173e8c |
||
|
|
456fae9d04 |
Make fields parameter available by default (#2952)
* Promote fields parameter beyond Insiders Keep fields_param as an independently controlled feature flag while removing it from the Insiders expansion. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Make fields parameter available by default Remove the fields_param feature flag and legacy tool variants so selected read tools always advertise and honor fields. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c43cc70-27b5-47b4-bbd1-99d20f42d61b --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c43cc70-27b5-47b4-bbd1-99d20f42d61b |
||
|
|
a217a7f43a |
Add MCP App form deferral opt-out
Allow clients to keep MCP App views enabled while making form-backed write tools execute directly when explicitly configured. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
ea4e3960b8 |
refactor(auth): isolate GitHub App auth to stdio startup
Keep PEM loading and installation-token provider construction at the CLI leaf, then pass a generic refreshing token provider through the existing HTTP transports. Rebase the feature onto current main and keep the HTTP command unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 646357dd-c89f-4973-9a5c-e6c5fc18818c |
||
|
|
e05a38403f |
feat(auth): add GitHub App server-to-server authentication for stdio
Add non-interactive GitHub App installation authentication to the stdio server, so headless deployments (CI, Kubernetes, background agents) can authenticate without a browser, device code, or elicitation. This is the outstanding follow-up tracked in #1333: OAuth login shipped the interactive user-to-server flows, but PEM-based server-to-server auth was still needed to remove the interactive requirement. The new internal/githubapp package signs a short-lived RS256 JWT with the app's private key, exchanges it for an installation access token, and refreshes it transparently before expiry. It exposes a Provider whose AccessToken method mirrors oauth.Manager so it plugs into the existing BearerAuthTransport token provider. Only the standard library and golang.org/x/oauth2 are used. The private key is injected safely: a file path (GITHUB_APP_PRIVATE_KEY_PATH, preferred — mountable as a secret and kept off argv and out of the environment) or an inline GITHUB_APP_PRIVATE_KEY env var. There is intentionally no flag for the key contents, which would otherwise leak via the process command line. App auth is mutually exclusive with a PAT and with OAuth login. A loud startup warning and a dedicated docs page (docs/github-app-auth.md, with Docker and Kubernetes examples) cover the security considerations: this injects a high-privilege credential alongside the agent and is not recommended without an independent security review. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
9d130049e9 |
Add opt-in intent-aware Copilot issue assignment tool (#2909)
* Add opt-in intent-aware Copilot issue assignment tool Add `assign_copilot_to_issue_with_intent` in a new non-default toolset `copilot_issue_intents`. The tool uses GraphQL's object-form `assignees: [AssigneeUpdateInput!]` so intent metadata (rationale, confidence, is_suggestion) is attached to the Copilot entry only, while existing assignees are preserved. - Reuses the existing Copilot actor lookup, target-repository resolution, base_ref, custom_instructions, GraphQL-Features header, and direct-assignment PR polling behavior. - `is_suggestion: true` records a pending Copilot assignment intent, returns a suggestion-shaped result, and does not launch Copilot or poll for a linked PR. - `rationale` is capped at 280 characters (schema + runtime); `confidence` is validated against `LOW`/`MEDIUM`/`HIGH`. - Toolset is non-default so its inputs do not add schema bloat to the default tool surface; available via `copilot_issue_intents`, `all`, or explicit tool selection. Includes unit tests for direct assignment (with existing assignees and with base_ref/custom_instructions), the suggestion path, invalid rationale length, invalid confidence, and Copilot-not-available; a generated toolsnap; regenerated docs; and an e2e test for the suggestion path. Refs: github/plan-track-agentic-toolkit#683 * Address review: tighten description, require intent fields Per review feedback on #2909: - Trim the tool description to mirror assign_copilot_to_issue and add "Prefer this tool over assign_copilot_to_issue when available", removing the verbose is_suggestion narrative from the schema. - Make rationale, confidence, and is_suggestion required inputs (schema and runtime). is_suggestion is now always sent explicitly on the Copilot AssigneeUpdateInput entry. - Update unit tests to supply the newly-required fields and cover the missing-rationale and missing-confidence rejection paths. - Regenerate toolsnap and README. * Address review: dedupe copilot, require is_suggestion, update doc link Per @RossTarrant review feedback on #2909: - Reject requests where `is_suggestion` is omitted from the raw args before decoding. `mapstructure.WeakDecode` defaults missing bools to false, which would silently launch Copilot instead of recording a suggestion. Presence-check the raw map so callers make the choice explicit. - Skip the copilot-swe-agent actor when copying existing assignees so we don't send its actorId twice (once without metadata and once with intent metadata) when Copilot is already assigned. - Update the stale about-assigning-tasks-to-copilot reference to the redirect target (about-cloud-agent). Applied to the const message, both tool descriptions, and the e2e/unit-test literals that assert on that message. New unit tests cover the missing-is_suggestion rejection and the copilot-dedup behavior. Regenerated toolsnaps. |
||
|
|
7629b6e733 |
Enable fields param in Insiders mode
Docker / build (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
GoReleaser Release / release (push) Has been cancelled
MCP Server Diff / mcp-diff (push) Has been cancelled
MCP Server Diff / mcp-diff-http (push) Has been cancelled
Publish to MCP Registry / publish (push) Has been cancelled
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> |
||
|
|
439ec711fa |
Add fields param to six more list/search tools (#2810)
* Add fields param to six more list/search tools Extend the optional `fields` response-filtering parameter (gated behind the `fields_param` feature flag, with adoption/savings telemetry) to six more read tools, following the dual-variant pattern already used by search_code and get_file_contents: - list_issues, list_pull_requests, list_commits, list_releases - search_issues, search_pull_requests For each tool, `X` is the flag-enabled variant that advertises `fields` and filters each result item to the requested subset, while `LegacyX` exposes the original schema and never filters, acting as a kill switch when the flag is off. Exactly one variant survives inventory filtering for any flag state via mutually exclusive FeatureFlagEnable / FeatureFlagDisable annotations. Wrapped responses (list_issues, search_issues, search_pull_requests) preserve their count / pagination envelope and only filter the item list; bare-array responses keep their array shape. Filtering reuses the shared filterEachField helper. A new fieldsSchemaProperty helper builds the `fields` schema (search_code and get_file_contents now use it too), and a shared recordFieldsUsageFor helper centralizes the telemetry full-size computation. Each field enum lists only the JSON fields the specific tool actually emits: list_commits omits stats/files (requested without per-file detail) and list_issues lists only the fields its GraphQL fragment populates. Adds per-tool field-filtering, telemetry, and Legacy definition tests, extends the mutual-exclusivity gating test to all eight gated tools, and regenerates the `_ff_fields_param` toolsnaps and feature-flag docs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Remove duplicate tool doc comments Address review: drop the leftover one-line doc comment above each dual-variant tool constructor (list_issues, list_pull_requests, list_commits, list_releases, search_issues, search_pull_requests); the detailed variant comment remains. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> |
||
|
|
3b8ff504c0 |
Add fields param to search_code and get_file_contents (#2775)
* Add fields param to search_code and get_file_contents Add an optional `fields` array parameter to the `search_code` and `get_file_contents` tools so callers can request only the fields they need, reducing tool response size and context usage. - search_code: filters each result item to the selected fields while preserving the total_count / incomplete_results wrapper. - get_file_contents: filters each directory entry when listing a directory; ignored for single-file responses. Adds shared filterFields / filterEachField helpers and per-tool field enums, plus unit tests and regenerated toolsnaps and docs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Gate fields param behind fields_param flag and add usage telemetry Register search_code and get_file_contents as two mutually exclusive variants gated by the new `fields_param` feature flag, following the existing dual-variant flag pattern: - The flag-enabled variant advertises the optional `fields` parameter and filters each result to the requested subset. It owns the `<tool>_ff_fields_param` toolsnap. - The Legacy* variant exposes the original schema with no `fields` parameter and never filters, acting as a kill switch when the flag is off. It owns the canonical toolsnap. Add best-effort, low-cardinality telemetry at each tool's filter point to measure adoption and realized savings: - `mcp.fields.tool_call` (increment) tagged by tool and whether the response was filtered. - `mcp.fields.bytes_full` / `bytes_sent` / `bytes_saved` (counters) tagged by tool, emitted only when a response was filtered. Tags are limited to `tool` and `filtered` to bound cardinality; repo, owner, user, query, and the requested field list are never tagged. The local server discards these via the noop metrics sink, while hosted deployments inject a real sink. Metrics accessors now fall back to a noop sink when no exporter is configured so emitting telemetry never panics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Drop mcp.fields.bytes_saved metric Remove the mcp.fields.bytes_saved counter. It is derivable on the dashboard from the two remaining byte counters, since sum(bytes_full) - sum(bytes_sent) equals the total saved at any rollup, so emitting it separately is redundant. Keeping only bytes_full and bytes_sent shrinks the emitted telemetry surface. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
6787f08569 |
Reimplement issue dependencies on go-github v89 REST API (#2839)
* Reimplement issue dependencies on go-github v89 REST API Issue dependencies (blocked_by / blocking) were implemented on GraphQL via githubv4. Because the pinned githubv4 library predates the dependency mutations, the code hand-declared AddBlockedByInput / RemoveBlockedByInput and resolved issue numbers to node IDs with a custom aliased query. go-github v89 adds first-class REST methods (ListBlockedBy, ListBlocking, AddBlockedBy, RemoveBlockedBy), so switch issue_dependency_read and issue_dependency_write to those. This removes the workaround, aligns the tools with the rest of the REST-based issue tooling, and simplifies tests. - Rewrite issue_dependencies.go on REST: page-based pagination for reads, and a single Issues.Get to resolve the blocking issue's database ID for writes. Preserve the tool surface, self-dependency guard and cross-repo support. - Rewrite the issue dependency tests on the REST mock helpers. - Regenerate the read toolsnap (cursor -> page pagination) and docs. Refs #950 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Normalize issue dependency ref state to match other tools The REST issue-dependency endpoints return lower-case issue states (open/closed), whereas the previous GraphQL implementation and the sibling get_parent tool populate MinimalIssueRef.State from the GraphQL IssueState enum (OPEN/CLOSED). Upper-case the state in issueToDependencyRef so the field stays consistent across every tool that emits a MinimalIssueRef, and guard against a nil issue while here. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> |
||
|
|
74c34cd71b |
Add rationale and confidence to closing an issue (#2802)
* Add rationale and confidence to closing an issue * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Fix review feedback for update_issue_state validation/docs --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Roberto Nacu <kerobbi@github.com> |
||
|
|
49abf1557c |
Add is_suggestion + rationale to update_issue_assignees (#2821)
* Add is_suggestion + rationale to update_issue_assignees * Align assignee confidence to uppercase LOW/MEDIUM/HIGH; add non-string/object test |
||
|
|
8cd03c0185 |
Add reaction tools for issues and pull requests (#2732)
Docker / build (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
GoReleaser Release / release (push) Has been cancelled
MCP Server Diff / mcp-diff (push) Has been cancelled
MCP Server Diff / mcp-diff-http (push) Has been cancelled
Publish to MCP Registry / publish (push) Has been cancelled
* Add reaction tools for issues and pull requests 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> * Make reaction tools available in both granular and non-granular modes 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> * Update toolsnaps with aligned reaction tool descriptions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Align reaction tool descriptions with codebase style Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Improve reaction tool responses and wording 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> * Expose reactions through default comment tools 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> * Clarify PR review comment IDs for reactions 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> * Support issue comment reactions in add_issue_comment 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> * Harden combined comment reaction tools 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> * Group reaction tools with granular registrations 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> * Align granular reaction tool constructors 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> * Require issue number for comment reactions Make issue_number required on the consolidated add_issue_comment tool even when reacting to a specific issue comment, keeping the default tool input shape explicit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address issue comment feedback Return structured GitHub API errors for issue comment creation failures and assert MCP error results in tests. Also reject comment_id with body on the consolidated comment tool to avoid ambiguous comment-plus-comment-reaction requests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Validate issue comment reaction target Use the required issue_number to verify issue comment reaction targets before creating the reaction, and remove overlapping add_issue_comment test coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Validate positive comment IDs Reject non-positive issue and pull request comment IDs in handlers and add the missing schema minimum for pull request review comment IDs. 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 <sammorrowdrums@github.com> Co-authored-by: Sam Morrow <info@sam-morrow.com> |
||
|
|
067756a00a |
Add issue dependency read/write MCP tools (#2751)
* Add issue dependency read/write MCP tools Add two feature-flagged tools for issue blocked-by / blocking relationships, gated behind the issue_dependencies flag so they stay off the default tool surface (auto-enabled for insiders only): - issue_dependency_read: get_blocked_by / get_blocking via the Issue.blockedBy / Issue.blocking GraphQL connections, cursor-paginated. - issue_dependency_write: add / remove x blocked_by / blocking via the addBlockedBy / removeBlockedBy mutations. Accepts issue numbers and resolves them to node IDs in a single aliased query; "blocking" is the inverse of "blocked_by" with the subject/related roles swapped. Closes the MCP gap behind the gh CLI dependency verbs (cli/cli#13057). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fail fast on self-dependency in issue_dependency_write Reject a write where the subject and related issue are identical before resolving node IDs or issuing a mutation, avoiding two API round-trips. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert addition of `any of` for required ui_get scopes --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
0503f2f2c5 |
fix(mcp-apps): reconcile the show/defer contract — render results, remove show_ui (#2774)
* fix(ui): render success view when an MCP App tool executed up-front The create_pull_request / issue_write / update_pull_request Views decided form-vs-success from in-app submit state only, ignoring the tool-result the host delivers on render. Per the MCP Apps 2026-01-26 spec the host renders a View whenever the tool carries _meta.ui.resourceUri — independent of whether the server deferred or executed. So when the server executed up-front (e.g. show_ui=false, or parameters the form can't represent) the View still showed its "Create pull request" input form over an already-created PR, which reads as a bug (it even shows a PR number). Drive the Views off the result instead: a new shared completedToolResult() helper returns parsed data only for a genuine completed success, and returns null for the awaiting_user_submission deferral sentinel, errors, or no result. Each write View now shows its success card when that completed result is present, so the form is only ever shown while the action is genuinely deferred. Reconciles the show/defer state machine at the View (decision layer that the host result feeds). See github/copilot-mcp-core#1864. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(ui): scope tool-result to the current invocation Address review feedback: the write Views derive their success card from `toolResult`, but it wasn't cleared when a new invocation arrived (only the in-app `successPR`/`successIssue` was reset on `toolInput` change). A completed result from a previous invocation could briefly render a stale success card over the next, still-deferred form. Clear `toolResult` whenever a new `tool-input` notification arrives. The spec guarantees `tool-input` precedes that invocation's `tool-result`, so this scopes the result to the current invocation centrally in the hook — fixing all three Views without per-app invocation keys. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor(mcp-apps): remove show_ui — it can't suppress app rendering show_ui promised "skip the form and execute directly", but it can't deliver: the host renders an MCP App for any tool that carries _meta.ui.resourceUri, and the 2026-01-26 MCP Apps spec has no per-call/per-result way to opt out of rendering. show_ui only flipped the server's defer decision, so show_ui=false created the PR/issue up-front yet the host still rendered the app — exactly the contradiction this work set out to fix. And show_ui is only ever exposed to clients that support UI, i.e. precisely the clients that always render the app. Remove it entirely: - Drop the show_ui schema property, the form-param allowlist entry, and the showUI term from the defer predicate in create_pull_request and issue_write. The gate is now FF && clientSupportsUI && !_ui_submitted && !hasNonFormParams. - Delete the now-unused UI-only schema-property strip machinery in pkg/inventory (uiOnlySchemaProperties, stripUIOnlySchemaProperties, stripSchemaProperties) and the exported ConditionalSchemaPropertyDescriptions, which existed solely to surface show_ui to UI-capable clients. _meta.ui stripping is untouched. - Drop the conditional-property annotation from the docs generator. - Update toolsnaps, generated docs, and tests. With the up-front-execution Views now rendering the result (success card), the remaining contract is simple: when MCP Apps are enabled the form is the path, and the form is only shown while the action is genuinely deferred. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor(mcp-apps): centralize the show/defer decision (single source of truth) The defer-to-form predicate was triplicated across create_pull_request, update_pull_request, and issue_write, each with its own near-identical *HasNonFormParams function. As more MCP App tools are added this duplication would grow and the copies could silently drift. Extract one shared gate in ui_capability.go: - shouldDeferToForm(ctx, deps, req, args, formParams) — the single show/defer decision (MCP Apps enabled, client supports UI, not a form submission, and no non-form params). - hasNonFormParams(args, formParams) — one generic helper replacing the three per-tool functions. - uiSubmitted(args) — small shared predicate. Each handler is now a one-line `if shouldDeferToForm(...) { return awaiting }`. The per-tool form-parameter allowlists and the user-facing messages stay per-tool (that is the genuine per-tool config). Pure refactor — behavior unchanged; existing tests now exercise the generic helper. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
fab5fc5ff2 |
docs: lead local/stdio install with OAuth login (#2776)
* docs: lead local/stdio install with OAuth login Surface OAuth 2.1 login as a first-class option above the Personal Access Token in the README install section and in every local-capable installation guide, each in that client's own config syntax, linking to the dedicated docs/oauth-login.md guide. The github.com OAuth example needs no token; in Docker it publishes a fixed callback port to loopback (-p 127.0.0.1:8085:8085). The PAT block is retained below it and noted as taking precedence over OAuth. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(oauth): correct PKCE/client-secret explanation The previous "How it works" text claimed PKCE removes the need for a client secret. In practice GitHub requires the client secret at the token endpoint for both OAuth Apps and GitHub Apps, and the implementation sends it alongside the PKCE verifier (Manager.oauth2Config populates ClientSecret; flow.go exchanges with VerifierOption). The secret is baked into the distributed binary and is not truly confidential; PKCE is what actually secures the flow. Reword to reflect this accurately. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: don't frame OAuth login as github.com-only The intro line said "On github.com you can skip the token entirely", which implied OAuth login only works on github.com. OAuth works on GitHub Enterprise too — you just supply your own app credentials there. Reword to lead with OAuth as the mechanism and scope the zero-config claim correctly: on github.com the official image already includes the app credentials, so the user provides none. Enterprise / bring-your-own-app is covered by the linked OAuth guide. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
8ce77e3c16 |
feat(oauth): add stdio OAuth 2.1 login core library (1/4) (#2704)
* feat(oauth): add stdio OAuth 2.1 stdio login Introduce internal/oauth, a self-contained library that performs the user-facing GitHub OAuth login the stdio server uses to obtain a token without a pre-provisioned PAT. It is independent of MCP: client concerns (elicitation) sit behind the Prompter interface so the flows are testable without a live session. What it provides: - Authorization-code + PKCE flow with a local loopback callback server, state/CSRF validation, and XSS-safe result pages. - Device-authorization flow as a fallback (headless, containers). - A Manager that selects the most secure available channel (browser auto-open -> URL elicitation -> last-resort user action), runs a single flow at a time, and exposes a refreshing token source. Both GitHub OAuth Apps and GitHub Apps are supported without special casing: the token is modeled as an x/oauth2 refreshing TokenSource, so expiring GitHub App user tokens are renewed transparently (the gap that made a stored-token approach silently die after ~8h). When a client lacks secure URL elicitation and the flow falls back to a tool-response message, the message advises the user that their agent/CLI/ IDE does not appear to support URL elicitation and suggests requesting it for improved security. Tests exercise real protocol behavior against an httptest GitHub stand-in: PKCE challenge/verifier, GitHub App refresh-on-expiry, device polling, URL elicitation, declined prompts, the last-resort action with advisory, and single-flight concurrency. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(oauth): reap browser launcher and keep native callback on loopback Address code review: - openBrowser: reap the launcher process asynchronously so it does not linger as a zombie for the lifetime of the server. - listenCallback: take an explicit bindAll flag and bind to all interfaces only inside a container (where the published port arrives via eth0). A native run, even with a fixed callback port, now stays on 127.0.0.1 instead of 0.0.0.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(oauth): fail fast when a fixed callback port is unavailable A fixed --oauth-callback-port is registered with the OAuth app and chosen deliberately, so a bind failure means another process holds the port and could intercept the authorization redirect. Treat that as fatal instead of silently downgrading to the device flow, which would mask the conflict. Also warn, when binding the callback inside a container, that the listener is on all interfaces and should be published to loopback only so the authorization code is not exposed on the container network. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(oauth): surface refresh failures, bound refresh, prefer device flow when headless Addresses pre-merge review of the OAuth stdio core: - Log a one-time warning when token refresh fails instead of silently returning an empty access token, so a forced re-login isn't a surprise. - Bound each background token refresh with a 30s HTTP client timeout so a stalled GitHub token endpoint can't block tool calls indefinitely. - On a headless host (no display server) with a random callback port, fall back to the device-code flow — the only channel reachable from a browser on another machine — instead of dead-ending on an unreachable localhost redirect. A generic browser-open failure still offers the manual URL. - Mark the callback bind failure with a sentinel so the fixed-port-busy fatal path can't misreport an unrelated error as a port conflict. - Export NormalizeHost so callers can recognize the default github.com host (consumed by the build-time baked-in credential guard). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(oauth): wire stdio OAuth 2.1 login into the server (2/4) (#2710) * feat(oauth): wire stdio OAuth 2.1 login into the server Connect the internal/oauth core library to the stdio MCP server so users can authenticate with an OAuth App or GitHub App client ID instead of a static personal access token. - BearerAuthTransport gains a TokenProvider that is consulted per request, letting the lazily-acquired, auto-refreshing OAuth token take effect without rebuilding the client. - createGitHubClients uses BearerAuthTransport (and skips go-github's WithAuthToken, which would pin a static token) when a TokenProvider is set. - RunStdioServer starts without a token and installs receiving middleware that runs the authorization flow on the first tool call, surfacing the auth URL or device code via elicitation (or a tool result as a fallback). - Tool filtering uses the requested OAuth scopes; the default supported set hides nothing, while a narrower --oauth-scopes both narrows the grant and filters tools accordingly. - A sessionPrompter adapts the MCP server session to oauth.Prompter, keeping the authorization URL off the model's context. - New stdio flags: --oauth-client-id/-client-secret/-scopes/-callback-port. This is stdio-only and deliberately does not touch MCP-HTTP auth. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor(oauth): address review — omit empty bearer header, guard token/oauth - BearerAuthTransport omits the Authorization header entirely when the token is empty (pre-authorization) rather than sending an empty "Bearer " value. - RunStdioServer rejects the ambiguous combination of a static Token and an OAuthManager up front, enforcing the documented mutual exclusivity. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(oauth): clarify SupportedScopes is the stdio default and tool filter Document that stdio OAuth login requests these scopes by default and then filters the exposed tools to the scopes actually granted, so a tool whose required scope is absent from this list is hidden under default OAuth even though a PAT carrying that scope would expose it. Keep the list in sync with tool scope requirements when scopes change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Distinguish undeliverable auth prompts from user declines An elicitation prompt that the client cannot deliver (a transport or protocol failure) was treated the same as a user actively declining: any display error cancelled the flow. That conflated a system failure with a deliberate "no", so a client that advertised URL elicitation but failed to deliver it would hard-fail the login instead of degrading. Add an ErrPromptUnavailable sentinel alongside ErrPromptDeclined and have the MCP adapter return it when Elicit fails at the transport level. The manager now falls back to the manual user-action channel on an undeliverable prompt (keeping the background flow alive so the user can still authorize out of band), while a genuine decline still aborts. A context-cancelled prompt is checked first so an ending flow is never misread as a transport failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * build(oauth): bake in default OAuth credentials for official releases (3/4) (#2711) * build(oauth): bake in default OAuth credentials via build-time ldflags Inject the public OAuth client credentials (stored as the OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET repo secrets) at build time via -ldflags so official binaries and images ship a working default app for zero-config login. Security relies on PKCE, not on the secret. Local/dev builds leave the values empty and continue to require an explicit token or --oauth-client-id. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(oauth): recognize github.com host aliases for the baked-in client Match the default host via oauth.NormalizeHost instead of only an empty host string, so an explicit GITHUB_HOST=github.com (or api.github.com) still counts as the default and keeps zero-config baked-in login working. GHES and ghe.com users continue to bring their own --oauth-client-id. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(oauth): document stdio OAuth login; make PAT optional in install config (#2717) Add a dedicated Local Server OAuth Login guide (docs/oauth-login.md) covering the PKCE/device flows, display channels and the URL-elicitation security advisory, scope-based tool filtering, the fixed-port Docker recipe and its loopback/port-safety behavior, bringing your own OAuth or GitHub App, and the GitHub Enterprise Server / ghe.com requirement to register an app on that host (custom --gh-host directs login at that instance's authorization server). Reflect that the local server now logs in with OAuth by default on github.com: - README: make the stdio Docker install badges OAuth-first (fixed callback port 8085 published to loopback), drop the PAT prompt, and reframe the PAT as an optional alternative with a pointer to the new guide. - server.json: make GITHUB_PERSONAL_ACCESS_TOKEN optional and publish the OAuth callback port so the registry default works without a token. 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> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
3c4749d234 |
Show issue_write MCP App form for labels/assignees/milestone/type (#2767)
The issue_write form-gating logic uses issueWriteFormParams to decide whether to render the MCP App form or execute directly: a call carrying any parameter outside that allowlist bypasses the form. The form prefills and re-submits labels, assignees, milestone and type, but those four were absent from the allowlist, so passing any of them skipped the confirmation form even though the form fully supports them. Add labels, assignees, milestone and type to issueWriteFormParams so the form is shown when they are present. The allowlist now covers every input-schema property, leaving issueWriteHasNonFormParams as a forward-compatibility safety net for properties added without form support. Also correct the now-inaccurate show_ui guidance on issue_write and create_pull_request: both descriptions claimed the form "does not collect" fields it actually collects (labels/assignees/milestone/type/issue_fields, and reviewers respectively). Update unit tests and regenerate toolsnaps and docs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
a37837027f |
Promote issue fields and deprecate legacy issue write tool (#2696)
* Promote issue fields FF and remove legacy issue write methods * Remove legacy issue_write methods * Remove feature flag * Update tests * Update tool snaps * Update docs * Remove legacy issue write from issues test * Update tool snap * Fix docs * Include issue_fields in doc * Remove issue fields FF check in ui tools * Update UI tools test * update docs * Regenerate doc |
||
|
|
4f73cfd1db |
Add repo-scoped support to list_issue_types tool (#2692)
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
MCP Server Diff / mcp-diff-http (push) Has been cancelled
Publish to MCP Registry / publish (push) Has been cancelled
* Add repo-scoped support to list_issue_types tool * Render multi-scope tools as "any of" in generated docs * Clarify issue type field description for repo-scoped list_issue_types |
||
|
|
6830c4d394 |
Change confidence enum to use uppercase values to match GraphQL schema (#2715)
* Fix enum values to match those expected by gql * Update test * Update doc and snaps * Normalize lower case confidence values --------- Co-authored-by: Ross Tarrant <rosstarrant@github.com> |
||
|
|
f9a4dc5412 |
Add tool for getting code quality findings (#2604)
Co-authored-by: Sam Morrow <info@sam-morrow.com> |
||
|
|
4e8eb81dac |
MCP Apps with extra functionality (#1974)
* PoC full flow (hello world example) * add avatar resource domain * add postmessage logic and richer UI * add create issue ui * update ui for issue creatioon * fix * ignore banner * update docs after rebase * update toolsnap for get_me * new UI changes * update docs * update workflows that need ui build * add UI diff * fix build ui step for windows runners to use git bash * fix UI diff * refactor issue creation UI * add AvatarWithFallback component and update UserCard to use it; enhance CreateIssueApp to manage existing issue data * fix formatting of button labels * add create pull request functionality with UI support and insiders * update docs * add test for insiders mode handling in ServerTool schema * remove `show_ui` param for now * make insiders mode metadata stripping generic * remove ui diff * fix CI * remove redundant mention of old app name * add node types to fix ide issues for ts code * remove unused TriangleDownIcon import * update @primer/behaviors and electron-to-chromium versions in package-lock.json * add check to ensure base and head are not the same when creating a new PR * remove old show_ui * fix gitignore for dist so builds dont break * add tests for insiders mode handling and metadata stripping in ServerTool * remove unused state and components from CreatePRApp * fix ui build * update docker build to fix npm issue * remove reference to show_ui * allow insiders to work for non-ui features * formalise insiders inventory support * update docs * fix overflow issues and replace pull request dropdown with matching UI from dotcom * fix createpullrequest test * consolidate fetching tools under `ui_get` tool to remove toolset deps * fix issue data prefill in issue_write form * fix link component when updating issue * fix avatar URL * fix broken issue update logic * remove dbg * fix for new GetFlags * revert to original required fields for create_pull_request * fix for UI form submission * Simplify MCP App UIs for basic branch Remove advanced features to be kept in mcp-ui-apps-advanced: - Strip labels, assignees, milestones, issue types, repo picker from issue-write - Strip repo picker, branch selectors from pr-write - Delete ui_get tool (ui_tools.go, ui_tools_test.go, ui_get.snap) - Remove UIGet registration from tools.go Basic forms retain: title, body, submit with _ui_submitted, draft/regular split button (PR), MarkdownEditor, and SuccessView. * Fix header spacing in issue-write and pr-write UIs Add proper spacing between icon, title text, and repo name in the header bar for both issue-write and create-pull-request forms. * fix UI spacing * Revert "Simplify MCP App UIs for basic branch" This reverts commit 24174b91e222e45b47913ff6b760db809f48660b. * Undo dependency downgrades in ui/package-lock.json * Update ui/src/apps/pr-write/App.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update ui/src/apps/issue-write/App.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Implement pagination for uiGetBranches (#2012) * Initial plan * Implement pagination for uiGetBranches function 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> * update to new insiders feature flag func * ensure transient state is reset on successive tool calls * Mark ui_get as app-only visibility ui_get backs only the MCP App views and has no business in the agent's tool list. Per the MCP Apps 2026-01-26 spec, omitting _meta.ui.visibility defaults to ["model","app"], which exposes the tool to the model. Declare visibility ["app"] so the host hides it from tools/list while the views can still invoke it via tools/call. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update ui_get toolsnap for app-only visibility Regenerated via UPDATE_TOOLSNAPS to capture the new _meta.ui.visibility. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Assert ui_get declares app-only visibility Locks in the _meta.ui.visibility ["app"] contract so a future edit can't silently re-expose the UI data tool to the model. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add ui_get to insiders feature docs Regenerated docs/feature-flags.md and docs/insiders-features.md to include the ui_get tool entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address ui_get review feedback - Paginate the labels GraphQL query (cursor-based) so repos with more than 100 labels return a complete list instead of silently truncating. - Emit an empty due_on for milestones without a due date instead of formatting the zero time as "0001-01-01". - Use NewGitHubAPIErrorResponse in uiGetIssueTypes to preserve GitHub response context, matching the other REST-backed methods. - Extend tests to cover the labels (GraphQL), milestones (including the no-due-date case) and issue_types methods, plus the issue_types error path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix repo reset and stale base-branch in MCP App views - Re-initialize selectedRepo from toolInput inside the reset-on-invocation effect instead of a separate effect. The two effects both depended on toolInput and ran in declaration order, so the reset wiped the just- initialized repo and the picker never reflected the invocation's owner/repo. - Set the default base branch with a functional update in pr-write so a base prefilled from toolInput.base (or chosen by the user) isn't overwritten by a stale baseBranch value captured before the branches request resolved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Fix issue-write repo owner mapping and clear stale UI state on reset - issue-write: derive owner/name from full_name since search_repositories minimal output omits the owner object (mirrors pr-write) - pr-write/issue-write: clear available branch/label/assignee/milestone/type lists and filters in the toolInput reset effect so prefill effects can't match against the previous repo's stale data Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Merge remote-tracking branch 'origin/main' into mcp-ui-apps-advanced * feat: add pull request editing functionality with reviewers support * feat: implement interactive form handling for issue and pull request creation and updates * Close response body per page in ui_get pagination loops Avoids leaking HTTP connections when paging through assignees, milestones, branches, collaborators, and teams. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Cache pr-edit.html in build-ui action The build-ui cache only saved get-me/issue-write/pr-write HTML, so once a cache entry was stored it restored an incomplete ui_dist on later runs and skipped the rebuild, leaving pr-edit.html absent and panicking the tests. Add pr-edit.html to the cached paths and bump the cache key to v2 to evict the incomplete entries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: tommaso-moro <tommaso-moro@github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
d27540ff67 |
Add explicit show_ui parameter to UI-enabled write tools (#2601)
* Add explicit show_ui parameter to UI-enabled write tools
Today the server decides whether to route issue_write and create_pull_request
through the MCP App form using two implicit signals: _ui_submitted (set by
the form on submit) and a heuristic that bypasses the form when the call
carries any parameter the form cannot represent (labels, assignees,
issue_fields, state, reviewers, etc.). The model had no first-class,
documented way to say "execute directly, do not show a form".
Add a show_ui boolean parameter to the input schema of IssueWrite,
LegacyIssueWrite, and CreatePullRequest. It defaults to true and is
visible only to clients that advertise MCP App UI support: the strip
happens per-request in inventory.ToolsForRegistration via a new
stripUIOnlySchemaProperties helper, gated by the same predicate that
already strips _meta.ui (shouldStripMCPAppsMetadata). The two strips share
one decision so the schema and metadata stay in lock-step.
Form-routing predicate becomes:
MCPApps FF on && client supports UI &&
!_ui_submitted && show_ui && !hasNonFormParams
show_ui=false is a new explicit way for the model to opt out. The existing
non-form-param auto-bypass stays as a safety net, and the React forms keep
sending _ui_submitted=true on submit unchanged. get_me is out of scope
because its UI is pure client-side card rendering with no server-side
gating to replace.
The current strip gate ("strip when FF is off OR capability explicitly
absent") mirrors today's _meta.ui behavior exactly, including the
"capability unknown" case. For stdio that means UI-capable schemas are
exposed to any FF-enabled client. The handler-side clientSupportsUI check
still gates form execution at call time, so it is functionally a no-op for
non-UI stdio clients. A separate follow-up will tighten the gate to
"strip on unknown too" and wire an InitializedHandler in stdio to
re-register the un-stripped surface only after a UI-capable client has
advertised; the two changes must ship together to avoid breaking stdio.
docs/feature-flags.md and docs/insiders-features.md include an unrelated
"reviewers" description update picked up by script/generate-docs from
commit
|
||
|
|
1209da8eba |
feat: add get_file_blame tool for retrieving git blame information (#1538)
* feat: add get_file_blame tool * feat: implement cursor-based pagination for get_file_blame tool * resolve annotated tags to their target commit in get_file_blame * Regenerate get_file_blame toolsnap and docs after merge with main The cursor-pagination parameter description changed on main; regenerate the toolsnap and README so docs-check and toolsnap tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: gate get_file_blame behind file_blame feature flag The git blame tool adds a new tool to the inventory, which carries a context-footprint cost for every client. Gate it behind a new file_blame feature flag (user opt-in via --features / X-MCP-Features) that is also auto-enabled in insiders mode, so it is not advertised by default. Regenerated README, feature-flags.md and insiders-features.md docs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Sam Morrow <sammorrowdrums@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
918a42f05a | feat: implement cursor pagination for dependabot alerts (#2651) | ||
|
|
8bbd902b9e |
Update title annotations for issue_write and add_issue_comment tools to reflect that they also work with pull requesta (#2664)
* Clarify issue tool titles for PR context Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix issue_write_ff_remote_mcp_issue_fields snap title Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Re-generate docs after upstream merge Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
457f59932a |
Add confidence parameter to issue mutation MCP tools (#2605)
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
MCP Server Diff / mcp-diff-http (push) Has been cancelled
Publish to MCP Registry / publish (push) Has been cancelled
Add an optional confidence integer parameter (0–100) to update_issue_type, update_issue_labels, and set_issue_fields MCP tools. The confidence score is passed through to the REST/GraphQL API on mutation calls. - Rename structs to WithIntent (labelWithIntent, issueTypeWithIntent) - Add confidence schema property (integer, min 0, max 100) with prompt guidance describing what different confidence levels represent - Update tool descriptions to encourage including confidence scores - Pass confidence in the API request body alongside rationale/suggest Closes github/plan-track-agentic-toolkit#219 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
b0d9854388 |
docs: also advertise /x/all meta toolset
The default toolset row covers /mcp/ but /x/all is still a real, useful meta toolset that enables every toolset at once. Render both as special rows above the per-toolset list. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
830ad2c613 | docs: clarify that / uses default toolset in remote MCP server | ||
|
|
d6b9dc9411 |
docs: address review feedback on env-var examples
- Linux/macOS: actually set GITHUB_PAT instead of inlining via subshell, matching the heading. - PowerShell: use Select-Object -First 1, split with max 2 parts, and trim quotes/whitespace so common .env formats work. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
03da19109e |
docs: improve Claude installation guide with Windows PowerShell support
- Fix README.md: Remove non-existent 'Claude Web' from description - Add Windows PowerShell environment variable example for loading PAT from .env file The previous documentation only showed bash syntax for loading environment variables from .env files, which doesn't work on Windows PowerShell. This adds a PowerShell equivalent to help Windows users set up the GitHub MCP Server correctly. |
||
|
|
29a86780bf |
docs: add installation guides for Zed and OpenCode
Adds two new installation guides under docs/installation-guides/ covering MCP host applications that are not yet documented:
- install-zed.md: covers Zed's 'context_servers' settings key (command + args shape), the official GitHub MCP extension as an easier alternative, remote/local setup, the 'mcp:<server>:<tool>' permission key format introduced in Zed v0.224.0, and OAuth-vs-PAT trade-offs.
- install-opencode.md: covers OpenCode's 'mcp' config block (type-discriminated local/remote, command-as-array, 'environment' instead of 'env'), the 'oauth: false' opt-out needed when using a PAT, the '{env:VAR}' interpolation pattern, and the per-agent tool-gating pattern recommended for token-heavy servers like GitHub.
Also adds both hosts to:
- docs/installation-guides/README.md installation-guides index and the support-by-host-application table.
- README.md 'Install in other MCP hosts' and 'Install in Other MCP Hosts' lists.
Closes #2531.
|
||
|
|
014fd17fa3 |
feat: gate issue_write and get_issue behind remote_mcp_issue_fields flag
Ports the gating from PR #2553 onto main (the original merge landed on a stack base that did not make it to main). Changes: - pkg/inventory: FeatureFlagDisable becomes []string (any-listed-on → hide). FeatureFlagEnable stays as a single string. This avoids the AND-of-enable semantics from the earlier proposal, which encoded dependencies rather than rollout knobs and had no real call site. Disable-OR is the case that does need the slice (LegacyIssueWrite below). - pkg/github/issues.go: split IssueWrite into IssueWrite (flag-enabled, exposes issue_fields) and LegacyIssueWrite (flag-disabled, omits it). Both register as 'issue_write'; mutually exclusive flag annotations pick exactly one at runtime. Refactored into a shared buildIssueWrite helper instead of duplicating the ~250-line tool definition. - pkg/github/issues.go: GetIssue field_values enrichment now requires the flag at runtime. The verbose REST IssueFieldValues is always cleared from the response. - Existing single-flag Disable call sites converted to slices. - New toolsnap variant issue_write_ff_remote_mcp_issue_fields.snap; the canonical issue_write.snap is owned by LegacyIssueWrite. - README + flag docs regenerated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
13e6b8bae1 |
Add consistency to code block language
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
001f5e3c31 | docs: clarify auth in Codex CLI instructions | ||
|
|
d661abf4ca |
Boazreicher/add suggest to labels and issue fields (#2557)
* adding suggestions for labels and fields * fixing suggestions * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * updaing --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> |
||
|
|
2b7807bcb7 | add delete support and merge logic | ||
|
|
2f8c7e63d2 | docs: regenerate after issue_fields schema update | ||
|
|
dff18de98e | docs update | ||
|
|
b91c3b5b3a |
feat(issue-fields): support issue_fields in issue_write using fullDatabaseId
- Expose fullDatabaseId (BigInt) in list_issue_fields - Add issue_fields parameter to issue_write for setting field values - Support single-select fields via field_option_name resolution - Add REST API field value extraction in get_issue responses - Update minimal types with IssueFieldValue for REST responses Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
b473a5afd1 |
feat(http): ignore proxy forwarding headers by default
X-Forwarded-Host and X-Forwarded-Proto were unconditionally honored when constructing OAuth resource metadata URLs. In HTTP-mode deployments that do not set --base-url and are not fronted by a proxy that strips these headers, this lets an on-path client influence the URL advertised in WWW-Authenticate and the /.well-known/oauth-protected-resource body. This is a hardening change rather than a true vulnerability — exploiting it requires HTTP without --base-url plus an attacker already positioned to inject the header — but the unsafe default is worth closing. Default behavior now derives host/scheme from r.Host and the TLS state. Setups that rely on a trusted internal forwarder (e.g. an in-cluster gateway that needs to preserve the originating hostname per request) can opt back in with --trust-proxy-headers / GITHUB_TRUST_PROXY_HEADERS=1. --base-url continues to take precedence in all cases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
1add5fe231 |
docs: auto-generate per-flag tool lists for insiders and feature flags (#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> |
||
|
|
f929c58c6b |
feat: Add CSV output format for default list tools under insiders mode (#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 (#2516) * refactor: generic toolset+name sort, clarify feature flag intent Address review feedback on #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> |