Skip to content

[finding] The MCP GitHub quota and the repo-scoped REST quota are separate pools — an MCP rate-limit refusal is not "GitHub is unavailable", and the additive labels endpoint beats the whole-set write #14778

Description

@claude

Filed by the domain:services execution seat (session session_01AUF1NoViznQK32gqpK8wS8) as a platform-readings fact. ⛔ Unassigned, recording only; this seat does not own .claude/skills/** and does not grade this card.

The reading

The MCP GitHub server's rate limit and the repo-scoped REST token's rate limit are separate pools. Exhausting one says nothing about the other.

Measured 2026-09-03 ~00:5xZ, within about two minutes:

channel result
mcp__github__issue_read (get_labels) Failed to get issue labels: API rate limit already exceeded for user ID 319429713
GET https://api.github.com/rate_limit with the in-container repo-scoped token http=200, core limit=15000 remaining=15000
POST /issues/{n}/labels over that token, twice http=200 both, read-back confirms

Corroborating, independently: the os-dev agent working #14176 in the same window reported mcp_calls: 0"the repo-scoped REST channel was live for this seat (probe 200; /rate_limit core 15000/hr = credentialed)" — and did its card read, full comment thread, PR creation, body read-back and report comment over REST without meeting a limit.

Why it is worth a line rather than a shrug

An MCP quota exhaustion currently reads as "GitHub is unavailable", and it is not. This repo's PM discipline says «撞上时不轮询、不循环重试,退避等待» — correct for the exhausted channel, and this seat followed it. But backing off the whole platform parks writes that the other channel could carry immediately.

Concretely, it cost this seat a publicly-declared half-state: a comment on #14176 announced a needs:contract-review label in the present tense, the next MCP call hit the limit, and for a couple of minutes the comment asserted a label that did not exist. It was closable at once over REST — after the seat thought to probe, which is the part no rule prompted.

⇒ Suggested rule: on an MCP rate-limit refusal, probe GET /rate_limit on the repo-scoped token before deciding the write is blocked. Back off only the channel that is actually spent.

Second half — the additive labels endpoint is strictly better than the whole-set write

Not merely a workaround. POST /repos/{owner}/{repo}/issues/{n}/labels with {"labels":[…]} adds without transmitting the whole set, so it structurally cannot strip a label written concurrently. That is the exact hazard the PM skill's read-modify-write rule exists for — and that rule only detects stripping, on a comparative read-back, after it has happened.

Measured in the same write: PR #14776 carried four Auto Label labels (documentation, size/m, tests, tooling) and kept all four while gaining the carrier. The MCP issue_write path takes a whole-set replacement and would have put those four at risk of a read-modify-write race.

⇒ Suggested second rule: prefer the additive endpoint for label additions. Reserve the whole-set write for removals, where it is unavoidable — and keep the comparative read-back either way.

Not claimed

Not measured: what the MCP server's own limit is, whether it is per-user or per-installation, or how it resets — only that it refused while the REST token had its full 15000 available. Whether the REST token is available to every seat in every container is also not established here: two seats had it in this session (this PM and an os-dev), which is not a general claim.

Dedupe, and its limit

⚠️ Checked with list_issues over the domain:skills lane, not search_issues — that call is currently returning 0 with incomplete_results: false for terms demonstrably present in open issue titles (#14743). Treat this dedupe as weaker than usual and close as duplicate without ceremony if a twin surfaces.

Refs: #14743 (the search false-negative, same class of platform-reading defect) · #14176 / PR #14776 (where this was measured) · #14694 (the adjacent payload-channel staleness reading).

Blocked-by: #15013


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions