Repository navigation
Stop rate limiting MCP OAuth discovery and trust only real proxies - #432
Merged
paulocastellano merged 3 commits intoOct 16, 2026
Merged
Conversation
added 3 commits
October 15, 2026 21:03
Codex desktop fetches the OAuth protected-resource metadata before every connection, once per thread, and the shared per-IP throttle answered 429, so the TryPost server never started and its tools did not appear. - The /.well-known/oauth-* metadata is never throttled. - POST /oauth/register keeps 30 a minute per IP, with no limit for the egress ranges OpenAI and Anthropic publish, which register for all of their users from shared addresses. - trustProxies(at: '*') let any client fake its IP with X-Forwarded-For. config/trustedproxy.php now trusts Cloudflare's published ranges by default, overridable with TRUSTED_PROXIES.
…tion The mcp-oauth limiter now decides it all: GET/HEAD metadata and ChatGPT or Claude registrations are unlimited, any other POST /oauth/register gets 30 a minute per IP. HostedMcpClient is inlined into the limiter, its only caller.
paulocastellano
deleted the
fix/mcp-oauth-rate-limit-and-trusted-proxies
branch
October 16, 2026 00:27
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.
Why
Codex desktop (and other MCP clients) fetch the OAuth protected-resource metadata before every connection, even with a stored token. Codex does it once per thread, from the user's own IP. All MCP OAuth routes shared one throttle of 30 requests a minute per IP, so the metadata answered 429 and Codex dropped the server:
The TryPost tools then never showed up, or showed up a minute later, after the model had already told the user they were not available.
Checking the fix also showed that
trustProxies(at: '*')lets any client fake its IP withX-Forwarded-For. In production, a forged header opened a new rate-limit bucket.What changed
Mcp::oauthRoutes()route sits in onethrottle:mcp-oauthgroup, and the limiter decides what is limited. The/.well-known/oauth-*GET/HEAD metadata is public static JSON with no limit.POST /oauth/register(public, writes anoauth_clientsrow) gets 30 a minute per IP, with no limit for the egress ranges OpenAI (chatgpt-connectors.json) and Anthropic (160.79.104.0/21,MCP_CLAUDE_IP_RANGES) publish, because each registers for all of its users from shared addresses.bootstrap/app.phpno longer callstrustProxies(at: '*').config/trustedproxy.php, the key Laravel'sTrustProxiesreads, trusts Cloudflare's published ranges (ips-v4/ips-v6) by default. Another install overrides it withTRUSTED_PROXIES: a comma-separated list, or*.Heads-up for self-hosted installs
An install behind a proxy other than Cloudflare used to trust it implicitly through
*. It now needs to setTRUSTED_PROXIES. Otherwise Laravel sees the proxy's IP, and HTTPS detection throughX-Forwarded-Protomay break. This is documented in.env.example.Tests
tests/Feature/Mcp/OAuthRegistrationTest.php: registration is limited for a regular IP, not limited from ChatGPT or Claude, and the 4 metadata routes pass 30 requests.tests/Feature/TrustedProxiesTest.php: Cloudflare over IPv4 and IPv6, a direct request, a listed proxy, and*.Checklist after deploy
/.well-known/oauth-protected-resource/mcp/trypostanswers withoutx-ratelimit-*headers.X-Forwarded-Forno longer changes the client IP:POST /oauth/registerlimit buckets stay the same with and without the header.