Skip to content

Commit 2d5ad6e

Browse files
SamMorrowDrumsCopilotgithub-actions[bot]
authored
refactor(actions): type consolidated MCP tools (#3398)
* feat(inventory): add typed MCP tool registration foundation Use the MCP SDK's generic registration for concrete input/output types, with protocol-gated output schemas and structured results. Keep raw handlers compatible and apply shared middleware on both paths. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * test: cover legacy typed CSV results Exercise the typed array and object paths through an initialized 2025-11-25 MCP session. Verify CSV text is returned once without structured output or the SDK JSON fallback. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(inventory): normalize legacy typed arguments Add a raw JSON input normalizer that runs before SDK schema validation so migrated tools can retain legacy input coercions without widening their published schemas. Test case-folded issue states, numeric string IDs, validation failures and replacement registrations. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * test(inventory): preserve typed input optionality Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(inventory): stabilize typed schema compatibility Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(inventory): cover protocol isolation across clients Exercise simultaneous legacy and modern sessions against one typed tool, plus stateless HTTP requests with modern, legacy, and absent protocol headers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(inventory): harden typed schema registration contracts Cache immutable schema variants and enum overrides, preserve runtime input compatibility and request-era output behavior, and normalize dynamic scope challenges before dispatch. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(inventory): cache warm schemas and guard typed preflight Avoid repeated canonical schema serialization and header annotation for cache-owned immutable pointers while retaining content-based lookup for caller-owned schemas. Run typed authorization and availability middleware before preflight and preserve tool-result error semantics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(inventory): preserve schema metadata isolation Advertise the SDK-compatible object schema for typed any input and deep-clone mutable JSON Schema metadata before caching or deriving runtime variants. Add legacy/modern registration and mutation isolation coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(inventory): detach numeric schema bounds and dedupe default traversal Two Copilot findings on 431b7a2: - CloneSchemas only deep-copies subschema nodes, so pointer-valued numeric validation keywords (Minimum, Maximum, MinLength, MinItems, etc.) remained aliased with the caller-owned schema after CloneSchema/CachedSchema. A caller mutating one of those pointers after caching could race with concurrent cached-schema serialization or silently change the cached validation bounds. Clone every *int/*float64 keyword explicitly alongside the existing collection/metadata cloning. - CloneSchemaWithoutDefaults's removeSchemaDefaults visited every map/pointer child twice: once via two literal child-collection loops, and again via schemaChildren, which already covers the same fields. This doubled traversal at every nested level, making default removal exponential for deeply nested object/array schemas. Traverse only the single comprehensive schemaChildren list. Add regression coverage across CloneSchema, CachedSchema, schema inference option cloning, and CloneSchemaWithoutDefaults: every *int/*float64 keyword is isolated from caller mutation (including under concurrent marshaling), and a 48-level deep chain is used for every schema-child field kind to confirm linear, non-exponential default removal. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(inventory): gate typed output on supported protocol range Select modern typed output for SDK-supported ISO-date protocol versions from 2026-07-28 onward. Missing, malformed, and unsupported future versions retain legacy behavior. Cover a later supported version through the selector list seam and verify the public path against the SDK supported set. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(inventory): unwrap pointer inputs before schema inference Match SDK input inference by unwrapping one pointer level before the cached input key and inference. Preserve nullable output pointer schemas. Cover both public constructors with actual modern and legacy discovery and calls, including structured null output. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(inventory): reuse encoded schema cache for typed tools Key output encodings by their source definitions while preserving the SDK-registered schema guard. Keep header routing metadata available for legacy and unknown protocol clients. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(context): add typed tool schemas and outputs Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(context): preserve legacy input acceptance Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(context): preserve input schema roots and optionality Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(context): validate direct team member calls Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(context): pin structured output and legacy text fixtures Describe profile timestamps and validate null and empty team outputs against modern schemas while retaining exact legacy text. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(context): emit structured empty team collections Keep legacy null text while returning nonnil typed slices so modern clients receive structured content for empty successful results. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(context): preserve legacy team input schemas Keep empty identifier rejection in the handler without tightening the published input schema. Pin modern text to structured output and preserve the legacy formatter fixtures. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(context): preserve advertised input schema compatibility Keep legacy-visible schemas byte-compatible while applying unknown-field acceptance only to the cached runtime validation schema. Verify modern DTO text parity and preserve legacy formatted text. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(context): reject explicit null team user arguments Preserve the legacy optional user type error before typed decoding, without changing omitted or empty user fallback. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(context): preserve exact routing argument keys Ignore case-variant routing aliases before typed decoding while retaining canonical fields and unrelated unknown arguments. Cover direct handlers and legacy/modern registered calls, authenticated fallback, canonical null rejection, and missing identifiers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(comments): add typed visibility tool inputs and outputs Preserve legacy argument normalization and text responses while exposing protocol-gated structured results for six hide/unhide tools. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * chore: regenerate license files Auto-generated by license-check workflow * test(comments): pin protocol output parity and reason metadata Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(comments): reuse cached visibility output schema Clarify supported negotiated protocol versions without expanding runtime support. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(search): add typed projected result outputs * fix(search): preserve field_values presence and add nested schema fixtures Address review findings on the typed search/list projected-output tools (search_code, search_issues, search_pull_requests, list_issues, list_pull_requests, list_branches, list_tags): - issues.go/pullrequests.go: change FieldValues to a pointer-to-slice (*[]MinimalFieldValue) so a successful-but-empty [] is preserved in structuredContent, matching legacy text output instead of being dropped by omitempty. - search.go: related adjustments to keep typed search outputs aligned with the field_values presence fix. - typed_search_outputs_test.go: add representative nested/non-empty projected item fixtures so schema-conformance tests actually exercise item shapes instead of only validating empty collections. - Add/update toolsnaps for list_branches, list_issues, list_pull_requests, list_tags, search_code, search_issues, and search_pull_requests to reflect the schema. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test: bound encoded schema parity registration work Reuse each immutable HTTP server across pagination requests and share the SDK schema cache across parity variants without changing wire comparisons. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(security): add typed alert outputs Add typed protocol-gated outputs for code quality, code and secret scanning, Dependabot, and security advisories while preserving existing text responses. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(security): preserve compatibility with compact typed outputs Keep advertised input defaults while disabling runtime default injection for security filters. Normalize null CWE filters, compact findings, and verify modern wire outputs alongside exact legacy formatting. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat: type discussion and notification tool outputs Migrate all eleven tools to typed registration and compact output DTOs. Preserve legacy text, parameter compatibility, pagination, and mutation validation while publishing honest modern output unions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix: tighten discussion and notification output contracts Trim notification hypermedia, preserve useful HTML links, and record all modern schemas in canonical snapshots. Preserve source presence during discussion read normalization and cover the Copilot review regression alongside empty/null outputs, IFC labels, sanitization, and output enums. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test: cover empty-object discussion read requests and modern-text==DTO expectations Add an explicit {} (fully-empty args) case to TestDiscussionReadRequiredArguments proving the normalizer never synthesizes placeholder owner/repo/discussionNumber values that would let an empty request satisfy SDK required-schema validation and reach GraphQL; verified both protocols reject it pre-handler with zero GraphQL calls (addresses readiness-audit re-flag of already-fixed Copilot review comment 4171698931 in 578e9929). Also record the pending modern-text==structuredContent DTO contract (2026-07-28 protocol) in test expectations; these assertions are intentionally red pending the coordinator's central once-marshal wrapper in pkg/inventory/typed_output.go, which this branch does not yet have. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(notifications): preserve plain status output content Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(repos): add typed commit tool outputs Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(repos): restore commit pagination defaults Normalize omitted and explicit zero pagination to page 1 and perPage 30 for get_commit and list_commits. Cover legacy and modern wire calls and direct handlers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(repos): return typed projected commit lists Use an optional-field commit DTO for full and projected modern outputs while retaining exact legacy text. Cover SHA and nested commit projections, empty lists, and output schema conformance. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * test(repos): snapshot modern commit tools and strengthen wire coverage Capture canonical modern schemas, exercise null lists and error suppression with IFC labels, and drop unrelated generated Linux license drift noted by Copilot review. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(repos): distinguish legacy and modern commit text Keep exact-main byte assertions for the legacy protocol and verify modern text represents the same typed DTO as structured content. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(repos): sync commit snapshots with parent DTO metadata Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(issues): add typed metadata comment and dependency outputs Preserve legacy text and argument coercions while exposing protocol-gated structured issue outputs. Add modern, legacy, unknown-version, union-schema and API-error contracts. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * chore: regenerate license files Auto-generated by license-check workflow * fix(issues): preserve zero pagination for duplicate search Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(issues): preserve compact typed output contracts Cache DTO schema inference, retain byte-exact handler text, and cover protocol, pagination and schema contracts. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(issues): bound encoded schema parity registration work Reuse immutable HTTP comparison servers and the SDK schema cache across the full parity matrix. Refresh inherited user timestamp descriptions in issue snapshots. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(repos): complete typed repository tool outputs Migrate the remaining 17 repository tools to concrete inputs and outputs. Preserve existing content, mutations, scopes, filtering, and protocol gating; add wire and schema conformance coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore(repos): exclude unrelated snapshot formatting drift Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(repos): compact typed repository outputs Replace raw REST output schemas with compact repository DTOs, retain one canonical snapshot per tool, and align modern JSON text with structured output while pinning legacy content. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(issues): add typed consolidated issue tool contracts Preserve raw helper APIs and exact legacy text while exposing concrete output unions for modern protocols. Retain explicit awaiting statuses and real null responses without exposing SDK-generated error fallbacks. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * refactor(issues): minimize consolidated typed outputs Project compact method-discriminated DTOs from API responses while preserving the separate legacy text formatter and explicit app-awaiting status. Cache strict schemas and keep only canonical snapshots. Strengthen null-member presence, schema size, and lockdown projection regressions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(issues): keep union property schemas portable Preserve forbidden variant properties as annotated schema objects rather than boolean schemas emitted by jsonschema-go. Cover Inspector's input paths and IFC labels on every issue-read method across protocols. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(issues): cover strict sub-issue output variants Reject unknown methods, states, field types, opaque values and API URL properties while covering nullable and empty method data. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(issues): pin compact comment user redaction Pin unchanged legacy profile/avatar fields separately from compact modern user projections and assert identical lockdown filtering and sanitization across protocols. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(issues): restore main-identical advertised input schema Remove added custom-field union constraints and sentinel enums from the advertised issue-write input. Preserve runtime exactly-one validation and private strict-schema tests. All three scoped input schemas compare exactly equal to main. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(issues): restore protocol output parity Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * refactor(issues): minimize granular structured outputs Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> # Conflicts: # pkg/github/__toolsnaps__/add_sub_issue.snap # pkg/github/__toolsnaps__/remove_sub_issue.snap # pkg/github/__toolsnaps__/reprioritize_sub_issue.snap # pkg/github/granular_issue_types.go # pkg/github/issues_granular.go # pkg/github/typed_granular_issue_outputs_test.go # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # interactive rebase in progress; onto 1973eee # Last command done (1 command done): # pick 5b8f9d19 # refactor(issues): minimize granular structured outputs # No commands remaining. # You are currently rebasing. # # Changes to be committed: # modified: pkg/github/__toolsnaps__/add_issue_comment_reaction.snap # modified: pkg/github/__toolsnaps__/add_issue_reaction.snap # modified: pkg/github/__toolsnaps__/add_sub_issue.snap # modified: pkg/github/__toolsnaps__/create_issue.snap # modified: pkg/github/__toolsnaps__/hide_issue_comment.snap # modified: pkg/github/__toolsnaps__/remove_issue_comment_reaction.snap # modified: pkg/github/__toolsnaps__/remove_issue_reaction.snap # modified: pkg/github/__toolsnaps__/remove_sub_issue.snap # modified: pkg/github/__toolsnaps__/reprioritize_sub_issue.snap # modified: pkg/github/__toolsnaps__/set_issue_fields.snap # modified: pkg/github/__toolsnaps__/unhide_issue_comment.snap # modified: pkg/github/__toolsnaps__/update_issue_assignees.snap # modified: pkg/github/__toolsnaps__/update_issue_body.snap # modified: pkg/github/__toolsnaps__/update_issue_labels.snap # modified: pkg/github/__toolsnaps__/update_issue_milestone.snap # modified: pkg/github/__toolsnaps__/update_issue_state.snap # modified: pkg/github/__toolsnaps__/update_issue_title.snap # modified: pkg/github/__toolsnaps__/update_issue_type.snap # modified: pkg/github/comment_minimize_test.go # new file: pkg/github/granular_issue_types.go # modified: pkg/github/granular_tools_test.go # modified: pkg/github/issues_granular.go # new file: pkg/github/typed_granular_issue_outputs_test.go # * refactor(search): use typed account repository and commit tools Preserve legacy text and search semantics while publishing protocol-gated concrete structured outputs. Cover modern, legacy, and unknown clients, full repository JSON unions, defaults, IFC labels, and errors. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(search): compact typed repository search output Replace the full REST repository mirror with MinimalRepository-based structured items plus purpose-built full-mode details. Legacy text remains unchanged, and canonical snapshots now hold the modern output schema. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(search): expose repository visibility enum Remove the derivable node_id from compact full repository search output and publish the visibility enum in the static output schema. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(search): align snapshots with protocol wrapper Keep the modern text assertion aligned with structured content after the shared output wrapper change. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(pull-requests): migrate consolidated PR tools to typed inputs and outputs Convert pull_request_read, create_pull_request, update_pull_request, merge_pull_request, update_pull_request_branch, pull_request_review_write (both feature variants), add_comment_to_pending_review and add_reply_to_pull_request_comment to NewTool with concrete inputs and output DTOs. Input normalizers replay legacy handler checks so legacy coercions and error text are preserved. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(pull-requests): align modern text with typed outputs Use curated output DTOs for modern JSON text while preserving legacy serialization. Cover successful null responses, empty check runs, and Link-header page traversal. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(pull-requests): preserve legacy validation order Replay parameter checks in handler order and scope cursor validation to review-thread reads. Keep commit message schema descriptions distinct from operation messages. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(pull-requests): simplify compatibility validation Remove normalization and test assertions that only pinned which invalid argument wins. Keep per-field validation, accepted coercions, and response-shape behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(pull-requests): type granular MCP tools Preserve exact legacy validation and response text while advertising concrete protocol-gated outputs for all granular PR mutations and both thread-resolution variants. Make the inherited overflow assertion architecture-independent. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * fix(pull-requests): preserve granular tool compatibility Keep advertised schemas exact while applying legacy-compatible runtime validation, and verify protocol-era output parity. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * test(pull-requests): compare schema sets semantically Treat required properties and enum values as unordered sets in the schema audit. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(pull-requests): retain granular schema descriptions Keep the original enum guidance in input descriptions while preserving actual JSON Schema enum constraints. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(actions): type consolidated MCP tools Preserve legacy Actions payloads, validation ordering, coercions, IFC labels, and scope annotations while exposing concrete method-specific output unions to supported clients. Reject unrecognized versions in the shared structured-output capability gate without changing tool availability rules. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(actions): add typed Actions tool outputs Expose compact method-discriminated outputs for Actions tools while preserving legacy behavior, input coercions, and pagination forwarding. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(repos): complete typed repository tool outputs Migrate the remaining 17 repository tools to concrete inputs and outputs. Preserve existing content, mutations, scopes, filtering, and protocol gating; add wire and schema conformance coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore(repos): exclude unrelated snapshot formatting drift Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(repos): compact typed repository outputs Replace raw REST output schemas with compact repository DTOs, retain one canonical snapshot per tool, and align modern JSON text with structured output while pinning legacy content. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(issues): add typed consolidated issue tool contracts Preserve raw helper APIs and exact legacy text while exposing concrete output unions for modern protocols. Retain explicit awaiting statuses and real null responses without exposing SDK-generated error fallbacks. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * refactor(issues): minimize consolidated typed outputs Project compact method-discriminated DTOs from API responses while preserving the separate legacy text formatter and explicit app-awaiting status. Cache strict schemas and keep only canonical snapshots. Strengthen null-member presence, schema size, and lockdown projection regressions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(issues): keep union property schemas portable Preserve forbidden variant properties as annotated schema objects rather than boolean schemas emitted by jsonschema-go. Cover Inspector's input paths and IFC labels on every issue-read method across protocols. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(issues): cover strict sub-issue output variants Reject unknown methods, states, field types, opaque values and API URL properties while covering nullable and empty method data. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(issues): pin compact comment user redaction Pin unchanged legacy profile/avatar fields separately from compact modern user projections and assert identical lockdown filtering and sanitization across protocols. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(issues): restore main-identical advertised input schema Remove added custom-field union constraints and sentinel enums from the advertised issue-write input. Preserve runtime exactly-one validation and private strict-schema tests. All three scoped input schemas compare exactly equal to main. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(issues): restore protocol output parity Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * refactor(issues): minimize granular structured outputs Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> # Conflicts: # pkg/github/__toolsnaps__/add_sub_issue.snap # pkg/github/__toolsnaps__/remove_sub_issue.snap # pkg/github/__toolsnaps__/reprioritize_sub_issue.snap # pkg/github/granular_issue_types.go # pkg/github/issues_granular.go # pkg/github/typed_granular_issue_outputs_test.go # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # interactive rebase in progress; onto 1973eee # Last command done (1 command done): # pick 5b8f9d19 # refactor(issues): minimize granular structured outputs # No commands remaining. # You are currently rebasing. # # Changes to be committed: # modified: pkg/github/__toolsnaps__/add_issue_comment_reaction.snap # modified: pkg/github/__toolsnaps__/add_issue_reaction.snap # modified: pkg/github/__toolsnaps__/add_sub_issue.snap # modified: pkg/github/__toolsnaps__/create_issue.snap # modified: pkg/github/__toolsnaps__/hide_issue_comment.snap # modified: pkg/github/__toolsnaps__/remove_issue_comment_reaction.snap # modified: pkg/github/__toolsnaps__/remove_issue_reaction.snap # modified: pkg/github/__toolsnaps__/remove_sub_issue.snap # modified: pkg/github/__toolsnaps__/reprioritize_sub_issue.snap # modified: pkg/github/__toolsnaps__/set_issue_fields.snap # modified: pkg/github/__toolsnaps__/unhide_issue_comment.snap # modified: pkg/github/__toolsnaps__/update_issue_assignees.snap # modified: pkg/github/__toolsnaps__/update_issue_body.snap # modified: pkg/github/__toolsnaps__/update_issue_labels.snap # modified: pkg/github/__toolsnaps__/update_issue_milestone.snap # modified: pkg/github/__toolsnaps__/update_issue_state.snap # modified: pkg/github/__toolsnaps__/update_issue_title.snap # modified: pkg/github/__toolsnaps__/update_issue_type.snap # modified: pkg/github/comment_minimize_test.go # new file: pkg/github/granular_issue_types.go # modified: pkg/github/granular_tools_test.go # modified: pkg/github/issues_granular.go # new file: pkg/github/typed_granular_issue_outputs_test.go # * refactor(search): use typed account repository and commit tools Preserve legacy text and search semantics while publishing protocol-gated concrete structured outputs. Cover modern, legacy, and unknown clients, full repository JSON unions, defaults, IFC labels, and errors. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(search): compact typed repository search output Replace the full REST repository mirror with MinimalRepository-based structured items plus purpose-built full-mode details. Legacy text remains unchanged, and canonical snapshots now hold the modern output schema. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(search): expose repository visibility enum Remove the derivable node_id from compact full repository search output and publish the visibility enum in the static output schema. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(search): align snapshots with protocol wrapper Keep the modern text assertion aligned with structured content after the shared output wrapper change. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(pull-requests): migrate consolidated PR tools to typed inputs and outputs Convert pull_request_read, create_pull_request, update_pull_request, merge_pull_request, update_pull_request_branch, pull_request_review_write (both feature variants), add_comment_to_pending_review and add_reply_to_pull_request_comment to NewTool with concrete inputs and output DTOs. Input normalizers replay legacy handler checks so legacy coercions and error text are preserved. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(pull-requests): align modern text with typed outputs Use curated output DTOs for modern JSON text while preserving legacy serialization. Cover successful null responses, empty check runs, and Link-header page traversal. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(pull-requests): preserve legacy validation order Replay parameter checks in handler order and scope cursor validation to review-thread reads. Keep commit message schema descriptions distinct from operation messages. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(pull-requests): simplify compatibility validation Remove normalization and test assertions that only pinned which invalid argument wins. Keep per-field validation, accepted coercions, and response-shape behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(pull-requests): type granular MCP tools Preserve exact legacy validation and response text while advertising concrete protocol-gated outputs for all granular PR mutations and both thread-resolution variants. Make the inherited overflow assertion architecture-independent. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * fix(pull-requests): preserve granular tool compatibility Keep advertised schemas exact while applying legacy-compatible runtime validation, and verify protocol-era output parity. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: regenerate license files Auto-generated by license-check workflow * test(pull-requests): compare schema sets semantically Treat required properties and enum values as unordered sets in the schema audit. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(pull-requests): retain granular schema descriptions Keep the original enum guidance in input descriptions while preserving actual JSON Schema enum constraints. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(actions): type consolidated MCP tools Preserve legacy Actions payloads, validation ordering, coercions, IFC labels, and scope annotations while exposing concrete method-specific output unions to supported clients. Reject unrecognized versions in the shared structured-output capability gate without changing tool availability rules. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(actions): add typed Actions tool outputs Expose compact method-discriminated outputs for Actions tools while preserving legacy behavior, input coercions, and pagination forwarding. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent da2cbc8 commit 2d5ad6e

73 files changed

Lines changed: 12403 additions & 528 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎README.md‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,13 +616,17 @@ The following sets of tools are available:
616616

617617
## Tools
618618

619-
Repository tools expose output schemas and typed `structuredContent` to clients using MCP protocol `2026-07-28` or later. Older clients, or clients with an unknown protocol version, receive the existing content without an output schema or structured output.
619+
Repository tools expose output schemas and typed `structuredContent` when the negotiated MCP protocol version is a supported version `2026-07-28` or newer. Older clients, clients with an unknown protocol version, and clients omitting the version receive the existing content without an output schema or structured output. Unknown versions are not treated as supported merely because they sort after `2026-07-28`.
620620

621621
For `get_file_contents`, directory results (including field projections) are structured arrays. File downloads and metadata-only responses use a `content` array of typed text, embedded-resource, or resource-link blocks, preserving status messages, text, base64 blobs, empty files, and download links. Text-only repository mutations such as starring and deletion also return a structured `message`; fork responses distinguish a repository reference from an in-progress message. Repository deletion still requires its existing confirmation flow before returning a completed result.
622622

623623
Structured repository results use compact DTOs rather than raw REST objects. Release lookups share the compact release shape with release listings; Git references retain the ref, object type, and SHA; annotated tags retain tag/message/tagger/target information; deletion commits retain SHA, message, authors, tree SHA, parent SHAs, and a human-facing `html_url` when available. Directory entries retain file metadata and useful HTML/download links, but omit API and hypermedia routing URLs even when those fields were requested in a projection. Legacy and unknown protocol versions retain the original text byte-for-byte; modern text-only JSON responses serialize the same compact DTO as `structuredContent`. Non-text resource blocks and tool errors retain their existing content behavior. Structured projections use the same sanitized and filtered source as the legacy formatter.
624624

625-
The issue metadata (`list_issue_types`, `list_issue_fields`), comment (`add_issue_comment`, `update_issue_comment`), dependency (`issue_dependency_read`, `issue_dependency_write`), and duplicate-detection (`find_duplicate`) tools provide typed `outputSchema` and `structuredContent` for protocol `2026-07-28` and newer. Older or unknown protocol versions retain the same text responses without these fields. Tool errors do not return structured content. Dependency and duplicate-detection tools retain their existing feature gates.
625+
For `get_repository_tree`, `list_gists`, `get_gist`, `create_gist`, and `update_gist`, gist results retain file names, contents, sizes, language/type information, timestamps, visibility, and compact owner profiles, while omitting API/node and Git transport URLs. Tree entries omit their derivable API URLs. Create/update gist results contain the gist ID and HTML URL. Modern JSON text and structured content serialize the same compact result. Older or unknown protocol versions retain byte-for-byte legacy text without an output schema or structured content.
626+
627+
The issue metadata (`list_issue_types`, `list_issue_fields`), comment (`add_issue_comment`, `update_issue_comment`), dependency (`issue_dependency_read`, `issue_dependency_write`), and duplicate-detection (`find_duplicate`) tools provide typed `outputSchema` and `structuredContent` for negotiated supported protocol versions `2026-07-28` or newer. Older or unknown protocol versions retain the same text responses without these fields. Tool errors do not return structured content. Dependency and duplicate-detection tools retain their existing feature gates.
628+
629+
For negotiated supported protocol versions `2026-07-28` or newer, the consolidated Actions tools (`actions_list`, `actions_get`, `actions_run_trigger`) return structured objects with a `method` discriminant and a method-specific typed field; JSON text contains the same compact projection. Workflow, job, and artifact projections omit API/hypermedia URLs while retaining browser links and useful identifiers, states, timestamps, and usage durations. Run usage lists billable runner environments in deterministic name order. Older and unknown-protocol text responses remain unchanged; `get_job_logs` retains its typed content, URL, or failed-job collection variants.
626630

627631
<!-- START AUTOMATED TOOLS -->
628632
<details>

‎docs/error-handling.md‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,12 @@ return ghErrors.NewGitHubGraphQLErrorResponse(ctx, message, err), nil
6060
### Typed Tool Results
6161

6262
Tools registered with concrete `NewTool[In, Out]` types expose output schemas and
63-
`structuredContent` only when the negotiated protocol is `2026-07-28` or newer.
64-
Older or unknown protocols retain the original text responses without these
65-
typed-output additions. Ordinary API and validation errors never expose the
66-
SDK-generated zero-value structured output.
63+
`structuredContent` when the negotiated protocol version is a supported version
64+
`2026-07-28` or newer. Older, unknown, or omitted protocol versions retain the
65+
original text responses without these typed-output additions. Unknown versions
66+
are not treated as supported merely because they sort after `2026-07-28`.
67+
Ordinary API and validation errors never expose the SDK-generated zero-value
68+
structured output.
6769

6870
Handler-provided structured statuses are distinct from generated error output.
6971
For example, `issue_write` can return `IsError: true` with

‎docs/feature-flags.md‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,23 +237,23 @@ as output formatting) won't appear here.
237237
- `path`: The relative path of the file to comment on (string, required)
238238
- `pullNumber`: The pull request number (number, required)
239239
- `repo`: Repository name (string, required)
240-
- `side`: The side of the diff to comment on (LEFT or RIGHT, optional) (string, optional)
240+
- `side`: The side of the diff to comment on (optional) (string, optional)
241241
- `startLine`: The start line of a multi-line comment (optional) (number, optional)
242-
- `startSide`: The start side of a multi-line comment (LEFT or RIGHT, optional) (string, optional)
243-
- `subjectType`: The subject type of the comment (FILE or LINE) (string, required)
242+
- `startSide`: The start side of a multi-line comment (optional) (string, optional)
243+
- `subjectType`: The subject type of the comment (string, required)
244244

245245
- **add_pull_request_review_comment_reaction** - Add Pull Request Review Comment Reaction
246246
- **OAuth Challenge Scopes**: `repo`
247247
- `comment_id`: The numeric pull request review comment ID. Use the number from a #discussion_r... anchor, not the GraphQL thread node ID (PRRT_...). (number, required)
248-
- `content`: The emoji reaction type (+1, -1, laugh, confused, heart, hooray, rocket, or eyes) (string, required)
248+
- `content`: The emoji reaction type (string, required)
249249
- `owner`: Repository owner (username or organization) (string, required)
250250
- `repo`: Repository name (string, required)
251251

252252
- **create_pull_request_review** - Create Pull Request Review
253253
- **OAuth Challenge Scopes**: `repo`
254254
- `body`: The review body text (optional) (string, optional)
255255
- `commitID`: The SHA of the commit to review (optional, defaults to latest) (string, optional)
256-
- `event`: The review action to perform (APPROVE, REQUEST_CHANGES, or COMMENT). If omitted, creates a pending review. (string, optional)
256+
- `event`: The review action to perform. If omitted, creates a pending review. (string, optional)
257257
- `owner`: Repository owner (username or organization) (string, required)
258258
- `pullNumber`: The pull request number (number, required)
259259
- `repo`: Repository name (string, required)
@@ -300,7 +300,7 @@ as output formatting) won't appear here.
300300
- **submit_pending_pull_request_review** - Submit Pending Pull Request Review
301301
- **OAuth Challenge Scopes**: `repo`
302302
- `body`: The review body text (optional) (string, optional)
303-
- `event`: The review action to perform (APPROVE, REQUEST_CHANGES, or COMMENT) (string, required)
303+
- `event`: The review action to perform (string, required)
304304
- `owner`: Repository owner (username or organization) (string, required)
305305
- `pullNumber`: The pull request number (number, required)
306306
- `repo`: Repository name (string, required)
@@ -341,7 +341,7 @@ as output formatting) won't appear here.
341341
- `owner`: Repository owner (username or organization) (string, required)
342342
- `pullNumber`: The pull request number (number, required)
343343
- `repo`: Repository name (string, required)
344-
- `state`: The new state for the pull request (open or closed) (string, required)
344+
- `state`: The new state for the pull request (string, required)
345345

346346
- **update_pull_request_title** - Update Pull Request Title
347347
- **OAuth Challenge Scopes**: `repo`
@@ -402,8 +402,8 @@ as output formatting) won't appear here.
402402
- `confidence_threshold`: Minimum similarity threshold a candidate must meet to be returned; higher values are stricter. When omitted, the API's high-precision default is used. The scale is defined by the API, so no client-side bounds are enforced. (number, optional)
403403
- `issue_number`: The number of the existing issue to find duplicates for (number, required)
404404
- `owner`: The owner of the repository (string, required)
405-
- `page`: Page number for pagination (min 1). An explicit 0 is forwarded to the API as-is rather than being replaced with 1. (number, optional)
406-
- `perPage`: Results per page for pagination (min 1, max 100). An explicit 0 is forwarded to the API as-is rather than being replaced with 30. (number, optional)
405+
- `page`: Page number for pagination (min 1) (number, optional)
406+
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
407407
- `repo`: The name of the repository (string, required)
408408

409409
### `thread_resolution_reason`

‎docs/typed-tool-schemas.md‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Typed tool schemas
22

33
Typed tool registrations use concrete Go input and output types with the MCP
4-
Go SDK's `mcp.AddTool` path. The SDK infers schemas when the tool definition
5-
does not provide them, validates arguments before the handler runs, and
6-
validates typed output. Keep business rules that JSON Schema cannot express
4+
Go SDK's `mcp.AddTool` path. Inventory infers missing schemas and validates
5+
arguments against the cached input schema before the handler runs; the SDK
6+
adapts and validates typed output. Keep business rules that JSON Schema cannot express
77
in the handler or a preflight callback.
88

99
Input inference unwraps one pointer level, matching the SDK's object input
@@ -31,13 +31,13 @@ schemas; do not mutate the returned pointers.
3131

3232
When compatibility requires a broader runtime input contract than the one
3333
advertised to clients, provide `ValidationInputSchema`. The tool's declared
34-
`InputSchema` remains visible while the SDK validates calls against the
34+
`InputSchema` remains visible while inventory validates calls against the
3535
runtime-only schema. Use `Preflight` for checks that need raw arguments or
3636
request dependencies before typed decoding; it may return a derived context
3737
for the handler. Input normalizers are only for compatibility transformations,
3838
not a replacement for schema validation.
3939

40-
The SDK applies defaults from the runtime input schema before decoding. If an
40+
Inventory applies defaults from the runtime input schema before decoding. If an
4141
omitted field must remain omitted, build the runtime schema with
4242
`inventory.CloneSchemaWithoutDefaults` before applying validation-only
4343
changes. Use `inventory.CloneSchema` when deriving other runtime-only schema
@@ -46,6 +46,14 @@ subschemas. Default removal visits each child once per parent. The advertised
4646
schema can retain its defaults; the constructor caches the runtime schema
4747
without mutating either caller-owned schema.
4848

49+
Availability and authorization guards run before preflight, normalization,
50+
and input validation. A guard or preflight result is passed through the
51+
registered SDK handler without decoding the original arguments or invoking
52+
user code, so the SDK still finalizes multi-round-trip results with
53+
`resultType: "input_required"` (or `"complete"`). The permissive SDK input
54+
envelope used for this handoff is never advertised and does not replace the
55+
original validation schema for real calls.
56+
4957
The output schema and `structuredContent` are exposed only for a negotiated,
5058
SDK-supported protocol version `2026-07-28` or later. Unknown versions are
5159
treated as legacy, including unsupported future dates; older, absent, and
@@ -58,4 +66,7 @@ request-scoped server.
5866
If a handler intentionally returns non-JSON text or content blocks, set
5967
`PreserveHandlerContent` in `TypedSchemaOptions`, or call
6068
`inventory.PreserveToolHandlerContent(ctx)` from the handler middleware for
61-
request-dependent output such as CSV.
69+
request-dependent output such as CSV. This is for intentional non-DTO responses
70+
such as resources, errors, or CSV; ordinary declared structured success must
71+
retain shared DTO serialization, with modern JSON text equal to
72+
`structuredContent`, even when legacy handler text was a plain mutation message.

‎go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ require (
1212
github.com/microcosm-cc/bluemonday v1.0.27
1313
github.com/modelcontextprotocol/go-sdk v1.8.0
1414
github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021
15+
github.com/segmentio/encoding v0.5.4
1516
github.com/shurcooL/githubv4 v0.0.0-20260209031235-2402fdf4a9ed
1617
github.com/shurcooL/graphql v0.0.0-20240915155400-7ee5256398cf
1718
github.com/spf13/cobra v1.10.2
@@ -32,7 +33,6 @@ require (
3233
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
3334
github.com/sagikazarmark/locafero v0.11.0 // indirect
3435
github.com/segmentio/asm v1.1.3 // indirect
35-
github.com/segmentio/encoding v0.5.4 // indirect
3636
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
3737
github.com/spf13/afero v1.15.0 // indirect
3838
github.com/spf13/cast v1.10.0 // indirect

0 commit comments

Comments
 (0)