feat(mcp): apply rate_limit_rpm live and expose it in settings#70
Merged
Conversation
The MCP rate limiter captured rate_limit_rpm when the /mcp app was mounted at startup, so a config change only took effect after an API restart. Resolve the limit per request instead (a Callable read from the live config), so a save binds on the next MCP call — the middleware is built once and never rebuilt, but now reads the value each time. A lowered limit re-clamps an already-full bucket on the next call; a raised one widens it immediately. Add a matching MCP section to the settings config page to edit the limit, and bound the field with ge=1 (0 would deny every request; a negative rate accrues token debt that outlives the correction, since the bucket is never rebuilt) so a bad value is a clean 422 rather than a live lockout. Regenerate docs/openapi.yaml and update the README / MCP guide accordingly.
jaymeklein
pushed a commit
that referenced
this pull request
Jul 21, 2026
Integrate the live MCP rate-limit (#70), sticky pagination (#71), and indexing retry-failed (#72) work that landed on main. Resolved two conflicts in the MCP layer: build_mcp_middleware keeps #70's live rate_limit_rpm callable alongside this branch's per-user resolve_principal, dropping the now-obsolete master_key param (auth is DB-backed via authenticate_api_key, which already handles the master key). The middleware tests construct TokenBucketRateLimiter with a callable to match #70's new signature.
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.
What
The MCP per-key rate limit (
mcp.rate_limit_rpm) can now be changed from Settings → Config → MCP server and takes effect on the next MCP request — no restart.Why
The limiter captured its rpm when the
/mcpapp was mounted at startup, so a config PUT persisted toconfig.yamland updated live config but left the running limiter on the boot-time value until an API restart.apply_configswaps the config singleton, never the mount.How
TokenBucketRateLimitertakesrpmas aCallable[[], int], resolved on everyallow()from live config viaget_mcp_config()(mirrors the existingget_search_config()). A lowered limit re-clamps an already-full bucket on the next call; a raised one widens it immediately.enabled/max_resultsuntouched.MCPConfig.rate_limit_rpmis boundedge=1: 0 denies every request and a negative rate accrues token debt that outlives the fix (the bucket is never rebuilt), so a bad value is now a clean 422 instead of a live lockout.Tests / gate
New regression tests: the limit change applies without rebuilding the limiter; a lowered limit bites immediately; config rejects rpm < 1. ruff + mypy + unit/integration green;
docs/openapi.yamlregenerated (addsminimum: 1).