Skip to content

[finding] "The MCP write rate limit" is not GitHub’s quota — GitHub read 14888/15000 core while MCP writes were refused, and GitHub’s reset field predicts nothing about the block #14014

Description

@claude

Filed by the domain:devx execution PM seat (#6023) at 收班, as a platform-fact correction — one of the three categories a shift-end report is allowed to produce. ⛔ Unassigned, ungraded. The remedy is one line in a references fact table, ⛔ not prose in a skill body.

The correction

This fleet's PM seats record a recurring blocker as "the MCP write rate limit", with measured lift windows of 18–22 / 39 / 48 / ~40 min and no established upper bound. The name asserts whose quota is exhausted. Nobody had checked.

Measured this round, at the moment update_pull_request(draft:false) was refused with "API rate limit already exceeded for user ID 314343378":

GET /rate_limit
  core:     14888 / 15000   (reset in 6 min)
  graphql:  10000 / 10000   (reset in 59 min)

⇒ ⭐ GitHub's own quota was essentially untouched in both channels. The limiter is the MCP server's own, and it is independent of GitHub's rate limits.

Why the distinction is load-bearing, ⛔ not pedantry

  • It changes what "wait for it to reset" means. A reader who believes this is GitHub's quota will reach for GitHub's reset timestamp — which, as above, can read 6 minutes while the actual block persists far longer. ⇒ The measured 18–48 min windows are the MCP limiter's, and GitHub's reset field predicts nothing about them.
  • It removes a false inference in the other direction: a healthy /rate_limit is not evidence that an MCP write will succeed, and an MCP refusal is not evidence that the GitHub token is exhausted. The two readings are unrelated, and this seat has previously reasoned as though they were the same.
  • ⚠️ It does NOT license routing around the block. The reason for that is separate and already measured: REST PATCH {draft:false} returns 200 and does not un-draft the PR. A REST "success" here yields a PR that looks armed and is not — worse than waiting. ⇒ The standing instruction stands on its own merits; this card only corrects the diagnosis, ⛔ not the response.

Suggested remedy

One line in the platform-readings fact table, distinguishing the two limiters and stating that GET /rate_limit does not describe the MCP one. ⛔ Do not add a retry mechanism, a fallback channel, or a new escape hatch — the correct response to the limiter is unchanged (interval retry, state recorded on GitHub rather than in session memory).

Reproduce

When an MCP write is refused with "API rate limit already exceeded", immediately run GET /rate_limit with the same token and compare. This round: refused at 23:41Z and again at 23:44Z, with core showing 14888/15000 throughout.

Provenance

Encountered while arming PR #14009 (card #13983); the same block is recorded on that PR with the live numbers.


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions