Optimize context usage for getting an issue using the issue_read tool#2022
Merged
tommaso-moro merged 4 commits intomainfrom Feb 17, 2026
Merged
Optimize context usage for getting an issue using the issue_read tool#2022tommaso-moro merged 4 commits intomainfrom
issue_read tool#2022tommaso-moro merged 4 commits intomainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR optimizes context window usage for the issue_read tool by introducing a MinimalIssue type that reduces token consumption by approximately 82% (from 1527 to 274 tokens). The optimization follows the established minimal types pattern already used in the codebase for commits, pull requests, and repositories. The changes streamline issue payloads by preserving only essential fields while dropping verbose nested objects and redundant API URLs.
Changes:
- Introduced
MinimalIssueandMinimalReactionstypes with only essential fields for model reasoning - Implemented
convertToMinimalIssueconverter function following established patterns - Updated
GetIssuefunction to return minimal issue format viaMarshalledTextResulthelper - Updated test assertions to validate against
MinimalIssuestructure
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| pkg/github/minimal_types.go | Added MinimalReactions and MinimalIssue struct definitions, plus convertToMinimalIssue converter function |
| pkg/github/issues.go | Updated GetIssue to use convertToMinimalIssue and MarshalledTextResult helper instead of direct JSON marshalling |
| pkg/github/issues_test.go | Updated test assertions to unmarshal and validate against MinimalIssue fields instead of full github.Issue |
mattdholloway
approved these changes
Feb 17, 2026
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
This PR reduces the context window usage by up to ~82% when getting a single issue using the
issue_readtool.It does so by using the minimal types pattern (which is already used elsewhere in the codebase for the same reason) to reduce the payload that is sent back to the model when the tool is used. Specifically, some irrelevant fields are removed, and nested objects are largely optimized by keeping only the strictly necessary fields.
Tests & Metrics
Tested using this issue: #949
Results: tokens consumption went from 1527 to 281, achieving a ~82% reduction in tokens usage.
Tokens were measured using the OpenAI Tokenizer
Fields preserved
number,title,body,state,state_reason,author_association,draft,locked,html_url,user(asMinimalUser),labels(name strings),assignees(login strings),milestone(title string),comments,reactions(but removed theurlfield from the reactions object),created_at,updated_at,closed_at,closed_by(login string),issue_type(name string)Fields dropped
id,node_id, fullUserobjects (~17 fields × 3 for user/assignee/closed_by), fullLabelobjects (~7 fields each), singularassignee(redundant withassignees), fullMilestoneobject, fullIssueTypeobject (~6 fields), API URL templates (url,comments_url,events_url,labels_url,repository_url)Before
Old payload (1527 tokens)
{ "id": 3346259195, "number": 949, "state": "closed", "state_reason": "completed", "locked": false, "title": "Add ability to specify reason why issue is being closed, when closing issue", "body": "The `update_issue` tool allows to mark an issue as closed, but doesn't allow for specifying a reason (e.g. closed as "Not Planned")", "author_association": "MEMBER", "user": { "login": "tommaso-moro", "id": 37270480, "node_id": "MDQ6VXNlcjM3MjcwNDgw", "avatar_url": "https://avatars.githubusercontent.com/u/37270480?v=4", "html_url": "https://github.com/tommaso-moro", "gravatar_id": "", "type": "User", "site_admin": true, "url": "https://api.github.com/users/tommaso-moro", "events_url": "https://api.github.com/users/tommaso-moro/events{/privacy}", "following_url": "https://api.github.com/users/tommaso-moro/following{/other_user}", "followers_url": "https://api.github.com/users/tommaso-moro/followers", "gists_url": "https://api.github.com/users/tommaso-moro/gists{/gist_id}", "organizations_url": "https://api.github.com/users/tommaso-moro/orgs", "received_events_url": "https://api.github.com/users/tommaso-moro/received_events", "repos_url": "https://api.github.com/users/tommaso-moro/repos", "starred_url": "https://api.github.com/users/tommaso-moro/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/tommaso-moro/subscriptions" }, "labels": [ { "id": 8241186948, "url": "https://api.github.com/repos/github/github-mcp-server/labels/enhancement", "name": "enhancement", "color": "a2eeef", "description": "New feature or request", "default": true, "node_id": "LA_kwDOODGMVM8AAAAB6zaIhA" } ], "assignee": { "login": "kerobbi", "id": 206091669, "node_id": "U_kgDODEi1lQ", "avatar_url": "https://avatars.githubusercontent.com/u/206091669?v=4", "html_url": "https://github.com/kerobbi", "gravatar_id": "", "type": "User", "site_admin": true, "url": "https://api.github.com/users/kerobbi", "events_url": "https://api.github.com/users/kerobbi/events{/privacy}", "following_url": "https://api.github.com/users/kerobbi/following{/other_user}", "followers_url": "https://api.github.com/users/kerobbi/followers", "gists_url": "https://api.github.com/users/kerobbi/gists{/gist_id}", "organizations_url": "https://api.github.com/users/kerobbi/orgs", "received_events_url": "https://api.github.com/users/kerobbi/received_events", "repos_url": "https://api.github.com/users/kerobbi/repos", "starred_url": "https://api.github.com/users/kerobbi/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/kerobbi/subscriptions" }, "comments": 1, "closed_at": "2025-09-12T14:04:01Z", "created_at": "2025-08-22T18:08:53Z", "updated_at": "2025-09-12T14:04:01Z", "closed_by": { "login": "tonytrg", "id": 40869903, "node_id": "MDQ6VXNlcjQwODY5OTAz", "avatar_url": "https://avatars.githubusercontent.com/u/40869903?v=4", "html_url": "https://github.com/tonytrg", "gravatar_id": "", "type": "User", "site_admin": true, "url": "https://api.github.com/users/tonytrg", "events_url": "https://api.github.com/users/tonytrg/events{/privacy}", "following_url": "https://api.github.com/users/tonytrg/following{/other_user}", "followers_url": "https://api.github.com/users/tonytrg/followers", "gists_url": "https://api.github.com/users/tonytrg/gists{/gist_id}", "organizations_url": "https://api.github.com/users/tonytrg/orgs", "received_events_url": "https://api.github.com/users/tonytrg/received_events", "repos_url": "https://api.github.com/users/tonytrg/repos", "starred_url": "https://api.github.com/users/tonytrg/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/tonytrg/subscriptions" }, "url": "https://api.github.com/repos/github/github-mcp-server/issues/949", "html_url": "https://github.com/github/github-mcp-server/issues/949", "comments_url": "https://api.github.com/repos/github/github-mcp-server/issues/949/comments", "events_url": "https://api.github.com/repos/github/github-mcp-server/issues/949/events", "labels_url": "https://api.github.com/repos/github/github-mcp-server/issues/949/labels{/name}", "repository_url": "https://api.github.com/repos/github/github-mcp-server", "reactions": { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "confused": 0, "heart": 0, "hooray": 0, "rocket": 0, "eyes": 0, "url": "https://api.github.com/repos/github/github-mcp-server/issues/949/reactions" }, "assignees": [ { "login": "kerobbi", "id": 206091669, "node_id": "U_kgDODEi1lQ", "avatar_url": "https://avatars.githubusercontent.com/u/206091669?v=4", "html_url": "https://github.com/kerobbi", "gravatar_id": "", "type": "User", "site_admin": true, "url": "https://api.github.com/users/kerobbi", "events_url": "https://api.github.com/users/kerobbi/events{/privacy}", "following_url": "https://api.github.com/users/kerobbi/following{/other_user}", "followers_url": "https://api.github.com/users/kerobbi/followers", "gists_url": "https://api.github.com/users/kerobbi/gists{/gist_id}", "organizations_url": "https://api.github.com/users/kerobbi/orgs", "received_events_url": "https://api.github.com/users/kerobbi/received_events", "repos_url": "https://api.github.com/users/kerobbi/repos", "starred_url": "https://api.github.com/users/kerobbi/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/kerobbi/subscriptions" } ], "node_id": "I_kwDOODGMVM7Hc9z7", "type": { "id": 69, "node_id": "IT_kwDNJr9F", "name": "Feature", "description": "A request, improvement, or new functionality", "color": "blue", "created_at": "2023-10-09T13:30:49Z", "updated_at": "2025-06-09T18:18:24Z" } }After
New payload: 281 tokens
{ "number": 949, "title": "Add ability to specify reason why issue is being closed, when closing issue", "body": "The `update_issue` tool allows to mark an issue as closed, but doesn't allow for specifying a reason (e.g. closed as "Not Planned")", "state": "closed", "state_reason": "completed", "html_url": "https://github.com/github/github-mcp-server/issues/949", "user": { "login": "tommaso-moro", "id": 37270480, "profile_url": "https://github.com/tommaso-moro", "avatar_url": "https://avatars.githubusercontent.com/u/37270480?v=4" }, "labels": [ "enhancement" ], "assignees": [ "kerobbi" ], "comments": 1, "reactions": { "total_count": 1, "+1": 1, "-1": 0, "laugh": 0, "confused": 0, "heart": 0, "hooray": 0, "rocket": 0, "eyes": 0 }, "created_at": "2025-08-22T18:08:53Z", "updated_at": "2025-09-12T14:04:01Z", "closed_at": "2025-09-12T14:04:01Z", "closed_by": "tonytrg", "issue_type": "Feature" }Why
The full
github.Issuepayload returned by the GitHub API is unnecessarily verbose for model reasoning. Most of its size comes from fullUserobjects (17 fields each) repeated foruser,assignee,assignees, andclosed_by, fullLabelobjects (7 fields each), a fullIssueTypeobject, and several API URL template strings. None of this extra metadata is useful for model reasoning but it burns context window on every call.What changed
MinimalIssuetype tominimal_types.go, following the existingMinimalCommit/MinimalRepository/MinimalPullRequestpatternconvertToMinimalIssueconverter functionGetIssueto returnMinimalIssueviaMarshalledTextResultinstead of rawjson.Marshal(issue)MinimalIssuefieldsMCP 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