[FEATURE]: Scope per-user rate limits by MCP server in cpex-rate-limiter
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
Research direction
Start in plugins/rust/python-package/cpex-rate-limiter/ by reading RateLimiterEngine, EngineConfig, RateLimiterPluginCore, and the .pyi stub, then trace check() and check_async() for memory and Redis paths. Review plugin-manifest.yaml and the existing rate-limit tests. Done means server-scoped UUID keys, global-scope compatibility, documented migration impact, and coverage for both acceptance scenarios.
Written by the indexing model from the issue text.
Description
Summary
Upstream requirement tracked in IBM/mcp-context-forge#6230.
ContextForge gateway operators need the RateLimiterPlugin (cpex-rate-limiter) to track per-user quotas independently per MCP server, so that exhausting a user's budget on MCP-A does not block that user from reaching MCP-B.
Current behaviour
The Rust engine's check() / check_async() accept user, tenant, and tool as dimensions. The resulting Redis key shape is effectively:
{prefix}:user:{user_id}:{window}
Exhausting this bucket blocks the user across all MCP servers simultaneously.
Required behaviour
Add a stable server_id dimension so the bucket key becomes:
{prefix}:user:{user_id}:server:{server_id}:{window}
A user-facing user_scope config knob (e.g. user_scope: "server") should opt in to this behaviour, with the current global-user scope remaining the default for backward compatibility:
by_user: "60/m"
user_scope: "server" # new; default: "global" (existing behaviour)
Acceptance criteria
Scenario: Exhausting one MCP server does not consume another server's quota
Given RateLimiterPlugin is configured with user_scope: server and by_user: X/m
When User-1 invokes Tool-A on MCP-A X times within the current minute
Then the next invocation by User-1 on MCP-A is rejected with RATE_LIMIT
When User-1 invokes Tool-B on MCP-B during that same minute
Then the MCP-B invocation succeeds
Scenario: Backward-compatible default
Given RateLimiterPlugin is configured WITHOUT user_scope (or user_scope: global)
Then behaviour is identical to cpex-rate-limiter <= 0.1.8
Implementation notes
- Key on the catalog UUID (not name/slug) to avoid quota resets on server rename.
- Document that
by_user: X/mwithuser_scope: servermeans X/m per server, so a user with access to N servers has an effective ceiling of N×X/m;by_tenantbecomes the primary global control. - At rollout, changing the Redis key shape orphans all in-flight fixed-window counters. Consider reading both key shapes for one window length during migration, or document the cut-over impact clearly.
- The
context_prefixparameter onRateLimiterEngine.check()handles tenant/team namespace isolation;server_idis a separate, orthogonal dimension. - Both
check()andcheck_async()(sync/memory and async/Redis paths) need the new parameter.
Affected components
plugins/rust/python-package/cpex-rate-limiter/— Rust engine (RateLimiterEngine,EngineConfig), Python shim (RateLimiterPluginCore), and stub (.pyi)plugin-manifest.yaml— adduser_scopetodefault_configs- Tests covering the new key shape (memory and Redis backends) and backward-compatibility
References
- IBM/mcp-context-forge#6230 — gateway-side feature request with full acceptance criteria and operator notes
- Dominant language
- Rust
- Stars
- 10
- Forks
- 1
- Avg merge
- 3d 19h
- Merged PRs (30d)
- 7
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from IBM/cpex-plugins
-
security
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
IBM/cpex-plugins#185 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
IBM/cpex-plugins#171 ·
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
IBM/cpex-plugins#167 ·
-
IBM/cpex-plugins#162 · 1 assignee ·
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
IBM/cpex-plugins#158 ·
All issues in IBM/cpex-plugins
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
gitbutlerapp/gitbutler#15998 · 1 comment ·
-
bug triage:deciding
Difficulty 1/5 Under an hour Newbie friendliness 88/100
open-telemetry/otel-arrow#4132 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100