Add support for issue fields values to issues.read and issues.write#2492
Add support for issue fields values to issues.read and issues.write#2492iulia-b wants to merge 16 commits into
issues.read and issues.write#2492Conversation
There was a problem hiding this comment.
Pull request overview
This PR wires the new IssueFieldValues support (added by the go-github v0.87 upgrade in PR #2452) into the issue_write and issue_read tools. On write, users can pass an issue_fields array specifying field names plus either a raw value or a single-select option name; the server resolves names → IDs via a GraphQL metadata query before calling the REST API. On read, custom field values are now surfaced in the trimmed MinimalIssue output.
Changes:
- Adds
issue_fieldsinput parameter toissue_write(create/update), including a GraphQL-based resolver that maps field/option names to database IDs. - Extends
MinimalIssuewith anissue_field_valuesarray (including single-select option details) populated from the REST response. - Updates README, toolsnap, and unit tests covering the new read/write behavior.
Show a summary per file
| File | Description |
|---|---|
| pkg/github/issues.go | Adds input parsing (optionalIssueWriteFields) and GraphQL-based name→ID resolution; threads IssueFieldValues through CreateIssue/UpdateIssue. |
| pkg/github/minimal_types.go | New MinimalIssueFieldValue/MinimalIssueFieldValueSingleSelectOption types and conversion logic. |
| pkg/github/issues_test.go | Adds tests for reading field values and writing with field-name resolution, plus validation error case. |
| pkg/github/toolsnaps/issue_write.snap | Snapshot updated for the new issue_fields schema entry. |
| README.md | Documents the new issue_fields parameter for issue_write. |
Copilot's findings
- Files reviewed: 5/5 changed files
- Comments generated: 2
| type issueFieldMetadataQuery struct { | ||
| Repository struct { | ||
| IssueFields struct { | ||
| Nodes []issueFieldMetadataNode | ||
| } `graphql:"issueFields(first: 100)"` | ||
| } `graphql:"repository(owner: $owner, name: $repo)"` | ||
| } |
There was a problem hiding this comment.
That's ok we have 25 fields / org limit
| issueFields := make([]IssueWriteFieldInput, 0, len(inputMaps)) | ||
| for _, itemMap := range inputMaps { | ||
| fieldName, err := RequiredParam[string](itemMap, "field_name") | ||
| if err != nil || strings.TrimSpace(fieldName) == "" { |
|
Tested this end-to-end with a Docker build in HTTP mode against 🚨 Blocker:
|
|
Update after testing this against the live GitHub GraphQL + REST APIs — the GraphQL bug is the tip of the iceberg, the resolver is broken in more ways. Posting findings so we can decide how to land this. 1.
|
|
Hey @iulia-b — flagging that #2520 just landed a feature flag ( Here's the suggested gating for what this PR adds, mirroring the pattern from #2520: 1.
|
…ds flag (github#2520) * feat(issues): gate issue-fields features behind remote_mcp_issue_fields flag Gates the recently merged issue-fields work (list_issue_fields tool, field_values enrichment on list_issues/search_issues, and field_filters input on list_issues) behind a new feature flag, also enabled in insiders mode. - list_issues splits into two same-named registrations: the field-aware variant requires the flag, while LegacyListIssues (FeatureFlagDisable) preserves the prior schema and GraphQL selection set so disabled callers don't pay the extra wire/server cost. - search_issues skips the field-values lookup when the flag is off. - list_issue_fields requires the flag to be registered at all. - Adopts <tool>_ff_<flag>.snap naming for flagged toolsnap variants so same-named duplicates each get a distinct snapshot. Co-authored-by: Copilot <[email protected]> * fix: address PR review on issue-fields gating - docs generator: install a no-flags feature checker so README reflects the default user experience (tools enabled with no special flags), fixing duplicate `list_issues` and removing granular/flagged-only tools that were never meant to appear in the default docs. - csv_output: drop the FeatureFlagEnable/Disable exclusion in isCSVOutputTool. Wrapping happens before the per-request flag filter picks the live variant, so flag-gated list_* tools wrap safely; this restores CSV conversion for `list_issues` and enables it for `list_issue_fields` when both flags are on. Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
The bare `github-mcp-server`, `mcpcurl`, and `e2e.test` rules matched those names anywhere in the tree, which silently ignored new files created under `cmd/github-mcp-server/` (the rule treats the directory component as a match). The intent was to ignore the binaries produced by `go build` at repo root, so anchor each rule with a leading slash. The existing `cmd/github-mcp-server/github-mcp-server` rule on line 2 continues to ignore the binary when built inside the cmd directory. Co-authored-by: Copilot <[email protected]>
…ub#2523) The mcp-server-diff action checks the baseline ref out into a separate working directory and runs install_command there. Without prebuilt UI artifacts, pkg/github/ui_dist/ is empty on the baseline side and UIAssetsAvailable() returns false, producing a false-positive diff that "adds" _meta.ui to MCP Apps tools on every PR. Stash the artifacts to RUNNER_TEMP after the workflow's build-ui step, then restore them from install_command so both the baseline and PR checkouts register identical MCP Apps UI metadata. Co-authored-by: Copilot <[email protected]>
github#2521) Adds two auto-generated documentation sections that describe how feature flags shape the tool surface: - docs/insiders-features.md gets a per-flag block under its existing hand-written prose. Each Insiders flag whose tools differ from the default surface is listed with the full tool schema rendered through the same writer used for README, so contributors can see exactly what Insiders Mode adds or changes. - docs/feature-flags.md is new and gives the same treatment to every flag in AllowedFeatureFlags (user-controllable flags). It links back to the Insiders doc for the auto-enabled subset. Both sections are produced by a single generator that diffs the flag-on inventory against the default-flagged inventory and reports any tool that is new or has a different InputSchema/Meta. No reason classification - just tools and their schemas, kept intentionally simple so contributors don't have to update the generator when adding a new flag. Co-authored-by: Copilot <[email protected]>
- Add DatabaseID (int64) to IssueField struct, populated from fullDatabaseId BigInt scalar (returned as string) on all 4 concrete GQL union types - Repeat fullDatabaseId per union fragment (shurcooL/githubv4 cannot use interface-level fragments at union top-level) - Add parseFullDatabaseID helper to parse BigInt string to int64 - Update tests to assert DatabaseID is populated from fullDatabaseId
…abaseId - Look up field IDs via fullDatabaseId (BigInt) from GQL issueFields query - Accept field values as strings; pass option names directly to REST (REST single-select expects option name string, not numeric option ID) - Add issue_fields parameter to issue_write schema with strict-mode additionalProperties:false - Wire field value resolution into CreateIssue and UpdateIssue
…m/iulia-b/github-mcp-server into iunia/reapply-issue-field-commits
|
closed in favour of #2551 |
Summary
This PR is passing issue field values to the issue write & read tools, which now (after #2452) support this.
issues_writeis using that endpointWhy
What changed
MCP impact
Prompts tested (tool changes only)
Security / limits
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./script/testDocs