Repository navigation
Description
Summary
The REST client is built with a transport chain (http.DefaultTransport → user-agent → bearer-auth) that has no response-cache or conditional-request layer, so pull-request tools (pull_request_read with get / get_files / get_commits / get_reviews / get_status, and list_pull_requests) issue unconditional GET requests. Repeated identical reads within or across sessions re-download full responses even when nothing has changed; the ETag GitHub returns is never captured or replayed as If-None-Match.
Where
- Client/transport construction (single site):
internal/ghmcp/server.go—createGitHubClients()wiresUserAgentTransport{ Transport: http.DefaultTransport }(andBearerAuthTransport) with no caching transport. - Transport package has only user-agent / bearer / graphql-features round-trippers:
pkg/http/transport/. - PR tool handlers call
client.PullRequests.Get/ListFiles/ListCommits/ListReviews/Listunconditionally:pkg/github/pullrequests.go.
Impact on users
GitHub's REST API supports conditional requests: replaying the previous ETag as If-None-Match returns 304 Not Modified when nothing changed, and 304 responses don't count against the token's primary rate limit. Agentic sessions frequently re-read the same pull request (e.g. get → get_files → get_reviews, retries, multi-step reasoning). Without conditional requests, each re-read is a full response that spends rate-limit budget and bandwidth, making the token's limit easier to hit and slowing tool calls.
Example prompts that trigger repeated reads
- "Summarize PR Issue: Fix incorrect VS Code installation URL (both buttons point to Insiders) #123, then list its changed files, then show review comments." (multiple reads of the same PR)
- "Watch PR Issue: Fix incorrect VS Code installation URL (both buttons point to Insiders) #123 and tell me when checks pass." (repeated
get_status/get) - "Compare the files and commits in PR Issue: Fix incorrect VS Code installation URL (both buttons point to Insiders) #123 and PR Fix VS Code installation link #124." (list + per-PR reads)
Suggested change
Insert an ETag-revalidating http.RoundTripper at the single client-construction site in createGitHubClients(), below the user-agent transport: cache {etag, body} keyed by (auth scope, method, URL), send If-None-Match on GETs, and return the cached body on 304. An always-revalidate ETag transport keeps tool results fresh (no stale window) while turning unchanged reads into cheap 304s. The GraphQL client is unaffected (POST). This keeps results identical while reducing rate-limit pressure and bandwidth.
Activity
Use strings.SplitSeq for Cache-Control and Vary parsing
Add ETag conditional requests to the REST transport
Use strings.SplitSeq for Cache-Control and Vary parsing
Use strings.SplitSeq for Cache-Control and Vary parsing
Add ETag conditional requests to the REST transport