Skip to content

Commit f5e26a8

Browse files
feat(issues): gate issue-fields features behind remote_mcp_issue_fields flag (#2520)
* feat(issues): gate issue-fields features behind remote_mcp_issue_fields flag Gates the recently merged issue-fields work (list_issue_fields tool, field_values enrichment on list_issues/search_issues, and field_filters input on list_issues) behind a new feature flag, also enabled in insiders mode. - list_issues splits into two same-named registrations: the field-aware variant requires the flag, while LegacyListIssues (FeatureFlagDisable) preserves the prior schema and GraphQL selection set so disabled callers don't pay the extra wire/server cost. - search_issues skips the field-values lookup when the flag is off. - list_issue_fields requires the flag to be registered at all. - Adopts <tool>_ff_<flag>.snap naming for flagged toolsnap variants so same-named duplicates each get a distinct snapshot. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: address PR review on issue-fields gating - docs generator: install a no-flags feature checker so README reflects the default user experience (tools enabled with no special flags), fixing duplicate `list_issues` and removing granular/flagged-only tools that were never meant to appear in the default docs. - csv_output: drop the FeatureFlagEnable/Disable exclusion in isCSVOutputTool. Wrapping happens before the per-request flag filter picks the live variant, so flag-gated list_* tools wrap safely; this restores CSV conversion for `list_issues` and enables it for `list_issue_fields` when both flags are on. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f929c58 commit f5e26a8

12 files changed

Lines changed: 613 additions & 209 deletions

README.md

Lines changed: 0 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -829,21 +829,6 @@ The following sets of tools are available:
829829
- `owner`: Repository owner (string, required)
830830
- `repo`: Repository name (string, required)
831831

832-
- **add_sub_issue** - Add Sub-Issue
833-
- **Required OAuth Scopes**: `repo`
834-
- `issue_number`: The parent issue number (number, required)
835-
- `owner`: Repository owner (username or organization) (string, required)
836-
- `replace_parent`: If true, reparent the sub-issue if it already has a parent (boolean, optional)
837-
- `repo`: Repository name (string, required)
838-
- `sub_issue_id`: The ID of the sub-issue to add. ID is not the same as issue number (number, required)
839-
840-
- **create_issue** - Create Issue
841-
- **Required OAuth Scopes**: `repo`
842-
- `body`: Issue body content (optional) (string, optional)
843-
- `owner`: Repository owner (username or organization) (string, required)
844-
- `repo`: Repository name (string, required)
845-
- `title`: Issue title (string, required)
846-
847832
- **get_label** - Get a specific label from a repository
848833
- **Required OAuth Scopes**: `repo`
849834
- `name`: Label name. (string, required)
@@ -885,12 +870,6 @@ The following sets of tools are available:
885870
- `title`: Issue title (string, optional)
886871
- `type`: Type of this issue. Only use if the repository has issue types configured. Use list_issue_types tool to get valid type values for the organization. If the repository doesn't support issue types, omit this parameter. (string, optional)
887872

888-
- **list_issue_fields** - List issue fields
889-
- **Required OAuth Scopes**: `repo`, `read:org`
890-
- **Accepted OAuth Scopes**: `admin:org`, `read:org`, `repo`, `write:org`
891-
- `owner`: The account owner of the repository or organization. The name is not case sensitive. (string, required)
892-
- `repo`: The name of the repository. When provided, returns fields for this specific repository (inherited from its organization). When omitted, returns org-level fields directly. (string, optional)
893-
894873
- **list_issue_types** - List available issue types
895874
- **Required OAuth Scopes**: `read:org`
896875
- **Accepted OAuth Scopes**: `admin:org`, `read:org`, `write:org`
@@ -900,7 +879,6 @@ The following sets of tools are available:
900879
- **Required OAuth Scopes**: `repo`
901880
- `after`: Cursor for pagination. Use the endCursor from the previous page's PageInfo for GraphQL APIs. (string, optional)
902881
- `direction`: Order direction. If provided, the 'orderBy' also needs to be provided. (string, optional)
903-
- `field_filters`: Filter by custom issue field values. Each entry takes a field_name and a value; the server looks up the field and coerces the value to its type (single-select option name, text, number, or YYYY-MM-DD date). (object[], optional)
904882
- `labels`: Filter by labels (string[], optional)
905883
- `orderBy`: Order issues by field. If provided, the 'direction' also needs to be provided. (string, optional)
906884
- `owner`: Repository owner (string, required)
@@ -909,22 +887,6 @@ The following sets of tools are available:
909887
- `since`: Filter by date (ISO 8601 timestamp) (string, optional)
910888
- `state`: Filter by state, by default both open and closed issues are returned when not provided (string, optional)
911889

912-
- **remove_sub_issue** - Remove Sub-Issue
913-
- **Required OAuth Scopes**: `repo`
914-
- `issue_number`: The parent issue number (number, required)
915-
- `owner`: Repository owner (username or organization) (string, required)
916-
- `repo`: Repository name (string, required)
917-
- `sub_issue_id`: The ID of the sub-issue to remove. ID is not the same as issue number (number, required)
918-
919-
- **reprioritize_sub_issue** - Reprioritize Sub-Issue
920-
- **Required OAuth Scopes**: `repo`
921-
- `after_id`: The ID of the sub-issue to place this after (either after_id OR before_id should be specified) (number, optional)
922-
- `before_id`: The ID of the sub-issue to place this before (either after_id OR before_id should be specified) (number, optional)
923-
- `issue_number`: The parent issue number (number, required)
924-
- `owner`: Repository owner (username or organization) (string, required)
925-
- `repo`: Repository name (string, required)
926-
- `sub_issue_id`: The ID of the sub-issue to reorder. ID is not the same as issue number (number, required)
927-
928890
- **search_issues** - Search issues
929891
- **Required OAuth Scopes**: `repo`
930892
- `order`: Sort order (string, optional)
@@ -935,13 +897,6 @@ The following sets of tools are available:
935897
- `repo`: Optional repository name. If provided with owner, only issues for this repository are listed. (string, optional)
936898
- `sort`: Sort field by number of matches of categories, defaults to best match (string, optional)
937899

938-
- **set_issue_fields** - Set Issue Fields
939-
- **Required OAuth Scopes**: `repo`
940-
- `fields`: Array of issue field values to set. Each element must have a 'field_id' (string, the GraphQL node ID of the field) and exactly one value field: 'text_value' for text fields, 'number_value' for number fields, 'date_value' (ISO 8601 date string) for date fields, or 'single_select_option_id' (the GraphQL node ID of the option) for single select fields. Set 'delete' to true to remove a field value. (object[], required)
941-
- `issue_number`: The issue number to update (number, required)
942-
- `owner`: Repository owner (username or organization) (string, required)
943-
- `repo`: Repository name (string, required)
944-
945900
- **sub_issue_write** - Change sub-issue
946901
- **Required OAuth Scopes**: `repo`
947902
- `after_id`: The ID of the sub-issue to be prioritized after (either after_id OR before_id should be specified) (number, optional)
@@ -958,57 +913,6 @@ The following sets of tools are available:
958913
- `repo`: Repository name (string, required)
959914
- `sub_issue_id`: The ID of the sub-issue to add. ID is not the same as issue number (number, required)
960915

961-
- **update_issue_assignees** - Update Issue Assignees
962-
- **Required OAuth Scopes**: `repo`
963-
- `assignees`: GitHub usernames to assign to this issue (string[], required)
964-
- `issue_number`: The issue number to update (number, required)
965-
- `owner`: Repository owner (username or organization) (string, required)
966-
- `repo`: Repository name (string, required)
967-
968-
- **update_issue_body** - Update Issue Body
969-
- **Required OAuth Scopes**: `repo`
970-
- `body`: The new body content for the issue (string, required)
971-
- `issue_number`: The issue number to update (number, required)
972-
- `owner`: Repository owner (username or organization) (string, required)
973-
- `repo`: Repository name (string, required)
974-
975-
- **update_issue_labels** - Update Issue Labels
976-
- **Required OAuth Scopes**: `repo`
977-
- `issue_number`: The issue number to update (number, required)
978-
- `labels`: Labels to apply to this issue. ([], required)
979-
- `owner`: Repository owner (username or organization) (string, required)
980-
- `repo`: Repository name (string, required)
981-
982-
- **update_issue_milestone** - Update Issue Milestone
983-
- **Required OAuth Scopes**: `repo`
984-
- `issue_number`: The issue number to update (number, required)
985-
- `milestone`: The milestone number to set on the issue (integer, required)
986-
- `owner`: Repository owner (username or organization) (string, required)
987-
- `repo`: Repository name (string, required)
988-
989-
- **update_issue_state** - Update Issue State
990-
- **Required OAuth Scopes**: `repo`
991-
- `issue_number`: The issue number to update (number, required)
992-
- `owner`: Repository owner (username or organization) (string, required)
993-
- `repo`: Repository name (string, required)
994-
- `state`: The new state for the issue (string, required)
995-
- `state_reason`: The reason for the state change (only for closed state) (string, optional)
996-
997-
- **update_issue_title** - Update Issue Title
998-
- **Required OAuth Scopes**: `repo`
999-
- `issue_number`: The issue number to update (number, required)
1000-
- `owner`: Repository owner (username or organization) (string, required)
1001-
- `repo`: Repository name (string, required)
1002-
- `title`: The new title for the issue (string, required)
1003-
1004-
- **update_issue_type** - Update Issue Type
1005-
- **Required OAuth Scopes**: `repo`
1006-
- `issue_number`: The issue number to update (number, required)
1007-
- `issue_type`: The issue type to set (string, required)
1008-
- `owner`: Repository owner (username or organization) (string, required)
1009-
- `rationale`: One concise sentence explaining what specifically about the issue led you to choose this type. State the concrete signal (e.g. 'Reports a crash when saving' → bug, 'Asks for dark mode support' → feature). (string, optional)
1010-
- `repo`: Repository name (string, required)
1011-
1012916
</details>
1013917

1014918
<details>
@@ -1161,19 +1065,6 @@ The following sets of tools are available:
11611065
- `startSide`: For multi-line comments, the starting side of the diff that the comment applies to. LEFT indicates the previous state, RIGHT indicates the new state (string, optional)
11621066
- `subjectType`: The level at which the comment is targeted (string, required)
11631067

1164-
- **add_pull_request_review_comment** - Add Pull Request Review Comment
1165-
- **Required OAuth Scopes**: `repo`
1166-
- `body`: The comment body (string, required)
1167-
- `line`: The line number in the diff to comment on (optional) (number, optional)
1168-
- `owner`: Repository owner (username or organization) (string, required)
1169-
- `path`: The relative path of the file to comment on (string, required)
1170-
- `pullNumber`: The pull request number (number, required)
1171-
- `repo`: Repository name (string, required)
1172-
- `side`: The side of the diff to comment on (optional) (string, optional)
1173-
- `startLine`: The start line of a multi-line comment (optional) (number, optional)
1174-
- `startSide`: The start side of a multi-line comment (optional) (string, optional)
1175-
- `subjectType`: The subject type of the comment (string, required)
1176-
11771068
- **add_reply_to_pull_request_comment** - Add reply to pull request comment
11781069
- **Required OAuth Scopes**: `repo`
11791070
- `body`: The text of the reply (string, required)
@@ -1193,21 +1084,6 @@ The following sets of tools are available:
11931084
- `repo`: Repository name (string, required)
11941085
- `title`: PR title (string, required)
11951086

1196-
- **create_pull_request_review** - Create Pull Request Review
1197-
- **Required OAuth Scopes**: `repo`
1198-
- `body`: The review body text (optional) (string, optional)
1199-
- `commitID`: The SHA of the commit to review (optional, defaults to latest) (string, optional)
1200-
- `event`: The review action to perform. If omitted, creates a pending review. (string, optional)
1201-
- `owner`: Repository owner (username or organization) (string, required)
1202-
- `pullNumber`: The pull request number (number, required)
1203-
- `repo`: Repository name (string, required)
1204-
1205-
- **delete_pending_pull_request_review** - Delete Pending Pull Request Review
1206-
- **Required OAuth Scopes**: `repo`
1207-
- `owner`: Repository owner (username or organization) (string, required)
1208-
- `pullNumber`: The pull request number (number, required)
1209-
- `repo`: Repository name (string, required)
1210-
12111087
- **list_pull_requests** - List pull requests
12121088
- **Required OAuth Scopes**: `repo`
12131089
- `base`: Filter by base branch (string, optional)
@@ -1260,17 +1136,6 @@ The following sets of tools are available:
12601136
- `repo`: Repository name (string, required)
12611137
- `threadId`: The node ID of the review thread (e.g., PRRT_kwDOxxx). Required for resolve_thread and unresolve_thread methods. Get thread IDs from pull_request_read with method get_review_comments. (string, optional)
12621138

1263-
- **request_pull_request_reviewers** - Request Pull Request Reviewers
1264-
- **Required OAuth Scopes**: `repo`
1265-
- `owner`: Repository owner (username or organization) (string, required)
1266-
- `pullNumber`: The pull request number (number, required)
1267-
- `repo`: Repository name (string, required)
1268-
- `reviewers`: GitHub usernames to request reviews from (string[], required)
1269-
1270-
- **resolve_review_thread** - Resolve Review Thread
1271-
- **Required OAuth Scopes**: `repo`
1272-
- `threadID`: The node ID of the review thread to resolve (e.g., PRRT_kwDOxxx) (string, required)
1273-
12741139
- **search_pull_requests** - Search pull requests
12751140
- **Required OAuth Scopes**: `repo`
12761141
- `order`: Sort order (string, optional)
@@ -1281,18 +1146,6 @@ The following sets of tools are available:
12811146
- `repo`: Optional repository name. If provided with owner, only pull requests for this repository are listed. (string, optional)
12821147
- `sort`: Sort field by number of matches of categories, defaults to best match (string, optional)
12831148

1284-
- **submit_pending_pull_request_review** - Submit Pending Pull Request Review
1285-
- **Required OAuth Scopes**: `repo`
1286-
- `body`: The review body text (optional) (string, optional)
1287-
- `event`: The review action to perform (string, required)
1288-
- `owner`: Repository owner (username or organization) (string, required)
1289-
- `pullNumber`: The pull request number (number, required)
1290-
- `repo`: Repository name (string, required)
1291-
1292-
- **unresolve_review_thread** - Unresolve Review Thread
1293-
- **Required OAuth Scopes**: `repo`
1294-
- `threadID`: The node ID of the review thread to unresolve (e.g., PRRT_kwDOxxx) (string, required)
1295-
12961149
- **update_pull_request** - Edit pull request
12971150
- **Required OAuth Scopes**: `repo`
12981151
- `base`: New base branch name (string, optional)
@@ -1306,41 +1159,13 @@ The following sets of tools are available:
13061159
- `state`: New state (string, optional)
13071160
- `title`: New title (string, optional)
13081161

1309-
- **update_pull_request_body** - Update Pull Request Body
1310-
- **Required OAuth Scopes**: `repo`
1311-
- `body`: The new body content for the pull request (string, required)
1312-
- `owner`: Repository owner (username or organization) (string, required)
1313-
- `pullNumber`: The pull request number (number, required)
1314-
- `repo`: Repository name (string, required)
1315-
13161162
- **update_pull_request_branch** - Update pull request branch
13171163
- **Required OAuth Scopes**: `repo`
13181164
- `expectedHeadSha`: The expected SHA of the pull request's HEAD ref (string, optional)
13191165
- `owner`: Repository owner (string, required)
13201166
- `pullNumber`: Pull request number (number, required)
13211167
- `repo`: Repository name (string, required)
13221168

1323-
- **update_pull_request_draft_state** - Update Pull Request Draft State
1324-
- **Required OAuth Scopes**: `repo`
1325-
- `draft`: Set to true to convert to draft, false to mark as ready for review (boolean, required)
1326-
- `owner`: Repository owner (username or organization) (string, required)
1327-
- `pullNumber`: The pull request number (number, required)
1328-
- `repo`: Repository name (string, required)
1329-
1330-
- **update_pull_request_state** - Update Pull Request State
1331-
- **Required OAuth Scopes**: `repo`
1332-
- `owner`: Repository owner (username or organization) (string, required)
1333-
- `pullNumber`: The pull request number (number, required)
1334-
- `repo`: Repository name (string, required)
1335-
- `state`: The new state for the pull request (string, required)
1336-
1337-
- **update_pull_request_title** - Update Pull Request Title
1338-
- **Required OAuth Scopes**: `repo`
1339-
- `owner`: Repository owner (username or organization) (string, required)
1340-
- `pullNumber`: The pull request number (number, required)
1341-
- `repo`: Repository name (string, required)
1342-
- `title`: The new title for the pull request (string, required)
1343-
13441169
</details>
13451170

13461171
<details>

cmd/github-mcp-server/generate_docs.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ func init() {
2929
rootCmd.AddCommand(generateDocsCmd)
3030
}
3131

32+
// noFeatureFlagsChecker reports every feature flag as disabled. It models the
33+
// default user experience used by the generated documentation.
34+
func noFeatureFlagsChecker(_ context.Context, _ string) (bool, error) {
35+
return false, nil
36+
}
37+
3238
func generateAllDocs() error {
3339
for _, doc := range []struct {
3440
path string
@@ -51,9 +57,16 @@ func generateReadmeDocs(readmePath string) error {
5157
// Create translation helper
5258
t, _ := translations.TranslationHelper()
5359

54-
// (not available to regular users) while including tools with FeatureFlagDisable.
60+
// The README documents the default user experience: tools that are
61+
// enabled with no special flags set. Installing a checker that reports
62+
// every flag as disabled excludes tools gated by FeatureFlagEnable and
63+
// keeps the legacy variants of tools gated by FeatureFlagDisable, so
64+
// flag-gated duplicates don't appear twice.
5565
// Build() can only fail if WithTools specifies invalid tools - not used here
56-
r, _ := github.NewInventory(t).WithToolsets([]string{"all"}).Build()
66+
r, _ := github.NewInventory(t).
67+
WithToolsets([]string{"all"}).
68+
WithFeatureChecker(noFeatureFlagsChecker).
69+
Build()
5770

5871
// Generate toolsets documentation
5972
toolsetsDoc := generateToolsetsDoc(r)

pkg/github/__toolsnaps__/list_issues.snap

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,6 @@
1818
],
1919
"type": "string"
2020
},
21-
"field_filters": {
22-
"description": "Filter by custom issue field values. Each entry takes a field_name and a value; the server looks up the field and coerces the value to its type (single-select option name, text, number, or YYYY-MM-DD date).",
23-
"items": {
24-
"properties": {
25-
"field_name": {
26-
"description": "Name of the custom field (e.g. \"Priority\"). Case-insensitive.",
27-
"type": "string"
28-
},
29-
"value": {
30-
"description": "Value to filter on. For single-select fields, the option name (e.g. \"P1\"). For dates, YYYY-MM-DD. For numbers, the numeric value as a string. For text, the text value.",
31-
"type": "string"
32-
}
33-
},
34-
"required": [
35-
"field_name",
36-
"value"
37-
],
38-
"type": "object"
39-
},
40-
"type": "array"
41-
},
4221
"labels": {
4322
"description": "Filter by labels",
4423
"items": {

0 commit comments

Comments
 (0)