feat(github): add typed Copilot and UI outputs - #3403
Open
SamMorrowDrums wants to merge 4 commits into
Open
SamMorrowDrums wants to merge 4 commits into
SamMorrowDrums wants to merge 4 commits into
Conversation
SamMorrowDrums
added this pull request to stack #3385
October 2, 2026 21:43
SamMorrowDrums
marked this pull request as ready for review
October 5, 2026 10:26
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Caller-controlled compatibility metadata can redirect UI dispatch without the corresponding OAuth scope challenge.
Review effort: Balanced
Findings: 1
What changed in this PR
Extends the GitHub MCP Server’s typed-output support to Copilot tools and ui_get, targeting modern clients while retaining legacy text responses.
Changes:
- Adds concrete output types, schemas, and compatibility input normalizers.
- Adds protocol compatibility tests and typed tool snapshots.
| File | Description |
|---|---|
pkg/github/ui_tools.go |
Returns typed UI results. |
pkg/github/ui_tools_test.go |
Uses the typed UI snapshot. |
pkg/github/typed_copilot_ui_outputs.go |
Defines output types, schemas, and normalizers. |
pkg/github/typed_copilot_ui_outputs_test.go |
Tests wire outputs, errors, and schemas. |
pkg/github/copilot.go |
Returns typed assignment and review results. |
pkg/github/copilot_test.go |
Uses typed Copilot snapshots. |
pkg/github/__toolsnaps__/ui_get_typed.snap |
Captures UI output variants. |
pkg/github/__toolsnaps__/request_copilot_review_typed.snap |
Captures the null review output schema. |
pkg/github/__toolsnaps__/assign_copilot_to_issue_with_intent_typed.snap |
Captures intent-aware assignment output. |
pkg/github/__toolsnaps__/assign_copilot_to_issue_typed.snap |
Captures assignment output. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Add protocol-gated output schemas and structured output DTOs for Copilot assignment, review requests, and UI data. Preserve legacy text and validate compatibility normalizers across supported protocol versions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
SamMorrowDrums
force-pushed
the
sammorrowdrums-typed-copilot-ui-outputs
branch
from
October 5, 2026 21:36
647c049 to
2c6d082
Compare
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Completes the typed-output stack with concrete Copilot and app-only
ui_getschemas, letting modern MCP clients validate results without guessing from text. Bundled issue/PR Apps consume both modern envelopes and legacy responses, including reviewer avatars.Why
Final layer of the native stack rooted at #3385, directly based on #3402. Registry audits find schemas for all 134 definitions, including duplicate registrations. Modern clients gain explicit output contracts while legacy clients retain successful handler text.
Fixes # — N/A; completes the stack rather than closing a separate issue.
What changed
ui_getmethod payloads. Canonical snapshots replace duplicate typed-named snapshots.71ef8266e48110974b13aef50b4df6ff9914ff68wording, preserving enums, types, defaults, bounds, and runtime behavior. Updates description assertions, six canonical snapshots, and generated docs.PreserveHandlerContentexceptions. No foundation rebase or optional stateless-era performance patch is included.MCP impact
2026-07-28receivesoutputSchema/typedstructuredContent; ordinary declared success JSON text equals its DTO.2025-11-25, empty/stateless, and literalunknownfixtures receive neither and retain legacy success text.Modern
ui_getis method-tagged rather than flat; Apps support both. Modern review text is{"status":"requested"}, versus empty legacy text. Some DTO fields intentionally differ from legacy: this is not a blanket unchanged-shape claim.Exact registered-input parity on final tree: independent audit against immutable main
71ef8266covers 2,984 configurations / 226,852 comparisons, with zero differences, including descriptions. This is exhaustive all-variant input parity, not just default-catalog parity. Evidence: coordinator artifactsfiles/input-audit-description-fix/summary.json. All input constraints and runtime behavior remain unchanged.Accepted stack error change:
issue_read/get404 changes from main's JSON-RPC error (code 0) toisError: truewith the same message in both eras. Historical Pi/Codex/Inspector checks confirm model-visible execution errors in the protocol's tool-error form; the reverse would be a regression.Prompts tested (tool changes only)
935b77a6Inspector UI evidence: seven methods × main legacy/top legacy/top modern = 21 successes; AJV 7/7 and legacy content parity 7/7. Production parser consumed actual wire outputs, all nine reader integrations were asserted, and 1000-assignee/1000-reviewer avatars passed. Six unknown-method cases made zero measured API calls. Responses are deterministic provider fixtures over actual MCP transports, not live GitHub execution.255c31f6harness reran list-only discovery for 91 Inspector tools: legacy 259,341 B, modern 413,154 B, byte-identical to935b77a6captures in both eras. Nine corrected descriptions are outside this default catalog. Captures:rounds/list-only-255c31f6/{measurements.json,list-captures}. Provider, cold-memory, UI/AJV, and independent full-suite harness were not rerun on final head.Security / limits
935b77a6actual HTTP tests prove compatibility keys cannot redirect dispatch, invalid methods do not challenge, and valid methods retainrepo/read:orgchecks.Accepted payload-cap exception: final 91-tool compact discovery is 413,154 B versus main's 259,341 B (1.593092×), exceeding the self-imposed 1.5× cap (389,011.5 B). This is an accepted exception, not a cap PASS: output schemas are the feature and legacy tool-success text remains unchanged. Restored avatar schema added 88 B to the earlier 413,066 B measurement.
Historical 130-tool real-library HTTP fixture (
935b77a6, not remeasured on255c31f6): main legacy/modern 372,644/374,890 B and top legacy/modern 373,003/546,247 B. Top legacy is byte-identical to prior2c6d0826, not to main's catalog. That follow-up changed only twoui_getavatar string properties and required entries; all other tool objects/input schemas were unchanged. SHA256: legacy3ddac9b5a325cac3f5cd7591e2b4dfcd308fdeca72e56de31cd6e97f76146d2e, modern056f68b5c61f277b9c1c0e7894797a9d0fb6a86566d8df22a017209b2f3d0c82.Historical warm performance (
935b77a6, 8 × 25 iterations, original SDK, no overlays): versus immutable main, registration improves 26.88%, legacy HTTP latency improves 11.46%, and modern latency is statistically unchanged (p=.959)—not faster. Modern B/op/allocations increase 13.05%/13.82%; legacy B/op decreases 1.82% while allocations increase 11.88%. Versus2c6d0826, HTTP timing/B/op/allocations do not regress; registration improves 3.71%. Cache pointers/backing slices remain stable: 203 initial misses, then zero new misses and 266 hits/request.Measurements use
NewHTTPMcpHandlerwith mock scopes/providers, not live authenticated request latency. Historical command:GOPROXY=off go test -mod=mod -modfile=<pinned-arm>.mod -run '^$' -bench '^(BenchmarkLibraryHTTPList|BenchmarkWarmRegistrationProcessSchemaCache)$' -count=8 -benchtime=25x -benchmem, thenbenchstat— performance GO under accepted tradeoffs.TestFinal(AdvertisedSchemas|WireCapture)and diagnosticTestLibraryHTTPPointerIdentity— PASS on935b77a6; diagnostic SDK copy was not used for timing acceptance. Toolchain: Go 1.27.1 linux/amd64, Intel Core Ultra 9 185H, SDK 1.8.0/jsonschema-go 0.4.3.Accepted cold/retained-memory exception: historical
2c6d0826once-per-process definitions+registration 20.207→158.076 ms and approximately +7.22 MiB post-GC global schema retention. These exclude OS launch/package initialization and were not rerun or eliminated on either follow-up.Accepted provider scope/coverage limits: supported GitHub Copilot provider evidence is sufficient for this work; no additional direct-provider validation is required. Historical exact-
2c6d0826supported GitHub Copilot adapters passed input-only checks. Standalone OpenAI/Anthropic/PTC and direct provider acceptance of output schemas were not tested because credentials/supported paths were unavailable; explicitly accepted untested scope, not a compatibility claim. Direct credential-backed GitHub execution remains unverified. Hosted builds are separate from local/independent checks.Inspector warning triage (historical
935b77a6modern 91-tool captures): 734 warnings = 729 type-union warnings (728 output / 1 input) + 5 untyped-schema warnings (3 output / 2 input); no style/description categories. Examples:actions_getoutputproperties.workflowtype[null, object]is legal nullable JSON Schema with a dialect-portability warning;projects_getoutputproperties.item.properties.fields.items.properties.valuepermits arbitrary JSON. All 91 captured output schemas compile with AJV2020 + formats: zero invalid schemas and zero unresolved references. Separately, actual UI outputs validate 7/7; this is not execution coverage for all 91 tools. Strict validation exits 0 with zero errors. Warnings are triaged as nonblocking, not claimed absent. Final-head list-only captures preserve the same default 91-tool catalog; exhaustive input parity is the separate audit above.Tool renaming
deprecated_tool_aliases.goNote: 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
./script/lint— PASS, 0 issues on final tree../script/test— PASS, full race suite on final tree (pkg/github317.569s).Final owner validation applies exactly to tree
0383eef64b606b57354c7c896e4f44b2946b5bc7:UPDATE_TOOLSNAPS=true go test ./pkg/github -run 'Test(GranularToolSnaps|GranularPullRequest|TypedGranularPullRequest|_FindDuplicate)' -count=1— PASS; refreshed snapshots.go test ./pkg/github -run 'Test(TypedInputDescriptionsMatchMain|GranularToolSnaps|GranularPullRequest|TypedGranularPullRequest|_FindDuplicate)' -count=1— PASS.script/lint— PASS, 0 issues.script/test— PASS, full race (pkg/github317.569s).script/generate-docs— PASS.git diff --checkandgit diff --cached --check— PASS; published worktree clean.Current-head
gh pr checks 3403 --repo github/github-mcp-server --watch --interval 30— PASS, exit 0 for hosted workflows. Freshgh pr checks 3403 --repo github/github-mcp-server— PASS, exit 0 on255c31f6; build, lint, docs, licenses, MCP diff/HTTP, and CodeQL checks pass. Subsequent REST read reported 21 checks: 20 completed successfully and a newly requested Copilot review in progress; no final-head review conclusion is claimed.Historical
935b77a6owner checks:UPDATE_TOOLSNAPS=true GOTMPDIR=/dev/shm/copilot-mcp-race-485bd8e4 go test ./...— PASS (pkg/github38.177s); orderedscript/lint— PASS (0 issues),GOTMPDIR=/dev/shm/copilot-mcp-race-485bd8e4 script/test— PASS (full race),script/generate-docs— PASS,git diff --check— PASS. Earlier owner full-race runpkg/github318.432s is historical, not the final-tree run.Historical
935b77a6targeted/UI checks:UPDATE_TOOLSNAPS=true go test ./pkg/github -run 'TestTypedCopilot|TestTypedUIGet|TestUIGet' -count=1— PASS (0.246s);cd ui && npm test— PASS (11/11);npm run typecheck— PASS;npm run build— PASS (four Apps). Registryflags-on,flags-off,all-definitions,each-definition— PASS, 134/134 output schemas.Historical exact-
935b77a6independent harness:go test -race ./pkg/github -run 'Test(TypedCopilotAndUIWireOutputs|TypedUIGet.*|TypedCopilotUIErrorsPreserveLegacyText|TypedCopilotOutputSchemas|ToolDefinitionsUseConcreteOutputTypes)$' -count=1— PASS (3.493s).GOFLAGS=-p=1 script/lint,script/test(full race),script/generate-docs,git diff --check, and clean-tree checks — PASS, exit 0. Independentnpm test(11/11),npm run typecheck,npm run build— PASS afternpm ci --ignore-scripts --no-audit --no-fund. UI runs used Node 22.23.3/npm 10.9.9; package Node ^26 engine warning disclosed. These independent full-suite/UI checks were not rerun on255c31f6.Historical Copilot review on exact
935b77a6reported no findings; all four prior findings have proof-based replies and are resolved. Fresh review was requested via REST on255c31f6and its check was observed in progress; no result yet claimed.Docs
docs/typed-tool-schemas.md; regenerated documentation/canonical snapshots, including nine description corrections.Final signed head
255c31f624d8519cd552716ea1c6bd41a7453582, tree0383eef64b606b57354c7c896e4f44b2946b5bc7, direct base15e359be93f75b4491f07fba7759bc61474862b4. GitHub REST signature verification isverified: true, reasonvalid; head equals live branch ref. Historical pre-correction head was935b77a6dc7a9eee95ce20a2776b9737322251fd, tree8ad8199f787238e3a2daad1a0f159aa3c7cef8f0. This body update changes neither head, native stack metadata, nor lifecycle; no merge is performed.