Add list_org_issue_fields tool#2438
Conversation
| } | ||
|
|
||
| reqURL := fmt.Sprintf("orgs/%s/issue-fields", org) | ||
| req, err := client.NewRequest(http.MethodGet, reqURL, nil) |
There was a problem hiding this comment.
Note: Using raw client.NewRequest/client.Do here because the issue-fields API isn't yet in go-github.
There was a problem hiding this comment.
Fair. Pls link the go github issue that is tracking updating to the new rest version. It's from March or so. We should have it in mind to update this once the lib is updated
|
|
||
| - **list_org_issue_fields** - List organization issue fields | ||
| - **Required OAuth Scopes**: `read:org` | ||
| - **Accepted OAuth Scopes**: `admin:org`, `read:org`, `write:org` |
There was a problem hiding this comment.
Hm can you check pls the rest endpoint? I think repo should be there too
There was a problem hiding this comment.
Had a look and the endpoint is org-scoped so I don't think we need the repo param
| // IssueFieldOption represents an option for a single_select issue field. | ||
| type IssueFieldOption struct { | ||
| ID int64 `json:"id"` | ||
| Name string `json:"name"` |
There was a problem hiding this comment.
Please double check this with the rest schema. I think color is there too
| } | ||
|
|
||
| // IssueFieldOption represents an option for a single_select issue field. | ||
| type IssueFieldOption struct { |
There was a problem hiding this comment.
We might add multiselct
| type IssueFieldOption struct { | |
| type IssueSingleSelectFieldOption struct { |
| } | ||
|
|
||
| reqURL := fmt.Sprintf("orgs/%s/issue-fields", org) | ||
| req, err := client.NewRequest(http.MethodGet, reqURL, nil) |
There was a problem hiding this comment.
Fair. Pls link the go github issue that is tracking updating to the new rest version. It's from March or so. We should have it in mind to update this once the lib is updated
There was a problem hiding this comment.
Pull request overview
Adds a new read-only MCP tool (list_org_issue_fields) to the GitHub MCP Server to fetch organization-level issue field definitions (including single-select options), enabling agents to discover valid custom field metadata before creating/updating issues.
Changes:
- Implemented
list_org_issue_fieldstool that callsGET /orgs/{org}/issue-fields. - Added unit tests + toolsnap coverage for the new tool.
- Registered the tool in the Issues toolset and documented it in
README.md.
Show a summary per file
| File | Description |
|---|---|
| README.md | Adds generated documentation entry for list_org_issue_fields, including required/accepted scopes and parameters. |
| pkg/github/tools.go | Registers ListOrgIssueFields in the Issues toolset (AllTools). |
| pkg/github/issue_fields.go | Implements the new tool, response types, and the GitHub API call to list org issue fields. |
| pkg/github/issue_fields_test.go | Adds unit tests covering success, 404→empty list, missing param, and error cases. |
| pkg/github/toolsnaps/list_org_issue_fields.snap | Adds the tool schema snapshot for CI/toolsnap validation. |
Copilot's findings
- Files reviewed: 5/5 changed files
- Comments generated: 2
| resp, err := client.Do(ctx, req, &fields) | ||
| if err != nil { | ||
| if resp != nil && resp.StatusCode == http.StatusNotFound { | ||
| // Org doesn't have issue fields enabled — return empty list | ||
| result, marshalErr := json.Marshal([]*IssueField{}) | ||
| if marshalErr != nil { | ||
| return utils.NewToolResultErrorFromErr("failed to marshal response", marshalErr), nil, nil | ||
| } | ||
| return utils.NewToolResultText(string(result)), nil, nil | ||
| } | ||
| return utils.NewToolResultErrorFromErr("failed to list issue fields", err), nil, nil | ||
| } |
| name: "forbidden returns error", | ||
| mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{ | ||
| "GET /orgs/testorg/issue-fields": mockResponse(t, http.StatusForbidden, `{"message": "Forbidden"}`), | ||
| }), | ||
| requestArgs: map[string]any{ | ||
| "org": "testorg", | ||
| }, | ||
| expectError: false, | ||
| expectedErrMsg: "failed to list issue fields", | ||
| }, | ||
| { | ||
| name: "internal server error returns error", | ||
| mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{ | ||
| "GET /orgs/testorg/issue-fields": mockResponse(t, http.StatusInternalServerError, `{"message": "Internal Server Error"}`), | ||
| }), | ||
| requestArgs: map[string]any{ | ||
| "org": "testorg", | ||
| }, | ||
| expectError: false, | ||
| expectedErrMsg: "failed to list issue fields", | ||
| }, |
|
closing in favour of #2445 - same PR, just with comments addressed since I couldn't push to |
Summary
Add a new
list_org_issue_fieldsMCP tool that retrieves issue field definitions for a GitHub organization, including field names, types, and single-select options.Why
Enables AI agents to discover available custom issue fields for an organization, which is necessary for workflows that create or update issues with custom field values.
Fixes https://github.com/github/plan-track-agentic-toolkit/issues/38
What changed
issue_fields.gowithListOrgIssueFieldstool implementation, callingGET /orgs/{org}/issue-fieldsissue_fields_test.gowith unit tests covering success, 404 (empty list), and missing parameter casestools.gounder the issues toolsetlist_org_issue_fields.snapREADME.mdwith tool documentationMCP impact
list_org_issue_fields— a read-only tool that lists organization-level issue field definitions (text, number, date, single_select) and their options. Requiresread:orgscope.Prompts tested (tool changes only)
Security / limits
Requires
read:orgOAuth scope. Returns empty list on 404 (org doesn't have issue fields enabled) rather than exposing error details.Tool renaming
deprecated_tool_aliases.goLint & tests
./script/lint./script/testDocs