Skip to content

Commit bed1dc6

Browse files
committed
refactor(plugins): replace in-tree rate_limiter with cpex-rate-limiter package
Remove the in-tree rate_limiter plugin and replace it with the cpex-rate-limiter PyPI package, a compiled Rust extension providing the same RateLimiterPlugin class with additional algorithms (sliding-window, token-bucket) alongside the original fixed-window. - Add cpex-rate-limiter>=0.0.2 as a [plugins] optional dependency - Update Containerfile.lite to install the plugins extra - Remove plugins/rate_limiter/ source directory - Remove unit and integration tests that imported plugin internals - Update all config files to use cpex_rate_limiter.RateLimiterPlugin - Disable RateLimiterPlugin in test fixture config (package not available in unit test environment) - Update documentation to reflect the external package Signed-off-by: Jonathan Springer <jps@s390x.com>
1 parent bb521e8 commit bed1dc6

17 files changed

Lines changed: 26 additions & 2853 deletions

File tree

Containerfile.lite

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ RUN chmod 644 /etc/profile.d/use-openssl.sh
144144
# This maximizes Docker layer caching - dependencies change less often
145145
# ----------------------------------------------------------------------------
146146
COPY pyproject.toml /app/
147+
COPY plugins/requirements.txt /app/plugins/requirements.txt
147148

148149
# ----------------------------------------------------------------------------
149150
# Copy Rust plugin wheels from rust-builder stage (if any exist)
@@ -175,6 +176,10 @@ RUN set -euo pipefail \
175176
else \
176177
/app/.venv/bin/uv pip install ".[redis,postgres,observability,granian]"; \
177178
fi \
179+
&& if [ -f /app/plugins/requirements.txt ]; then \
180+
echo "🧩 Installing plugin packages..."; \
181+
/app/.venv/bin/uv pip install --no-cache-dir -r /app/plugins/requirements.txt; \
182+
fi \
178183
&& if [ "$ENABLE_RUST" = "true" ] && ls "/tmp/rust-wheels/"*.whl 1> /dev/null 2>&1; then \
179184
echo "🦀 Installing Rust plugins..."; \
180185
/app/.venv/bin/python3 -m pip install "/tmp/rust-wheels/"*.whl && \

docker-entrypoint.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,18 @@ sys.exit(1)
389389
PY
390390
}
391391

392+
install_plugin_requirements() {
393+
RELOAD_PLUGIN_REQUIREMENTS_TXT="${RELOAD_PLUGIN_REQUIREMENTS_TXT:-false}"
394+
PLUGIN_REQUIREMENTS_TXT_PATH="${PLUGIN_REQUIREMENTS_TXT_PATH:-/app/plugins/requirements.txt}"
395+
396+
if [[ "${RELOAD_PLUGIN_REQUIREMENTS_TXT}" = "true" && -f "${PLUGIN_REQUIREMENTS_TXT_PATH}" ]]; then
397+
echo "🧩 Installing plugin packages from ${PLUGIN_REQUIREMENTS_TXT_PATH}..."
398+
/app/.venv/bin/pip install --no-cache-dir -r "${PLUGIN_REQUIREMENTS_TXT_PATH}"
399+
fi
400+
}
401+
392402
apply_rust_mcp_mode_defaults
403+
install_plugin_requirements
393404
build_server_command "$@"
394405
print_mcp_runtime_mode
395406

docs/docs/testing/unittest.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ The remaining ~93% is DOM manipulation, fetch calls, Chart.js rendering, and HTM
227227
| tests/unit/mcpgateway/plugins/plugins/output_length_guard/test_output_length_guard.py | 5 | 0 | 5 |
228228
| tests/unit/mcpgateway/plugins/plugins/pii_filter/test_pii_filter.py | 18 | 0 | 18 |
229229
| tests/unit/mcpgateway/plugins/plugins/resource_filter/test_resource_filter.py | 15 | 0 | 15 |
230-
| tests/unit/mcpgateway/plugins/plugins/rate_limiter/test_rate_limiter.py | 1 | 0 | 1 |
231230
| tests/unit/mcpgateway/plugins/plugins/response_cache_by_prompt/test_response_cache_by_prompt.py | 19 | 0 | 19 |
232231
| tests/unit/mcpgateway/plugins/plugins/schema_guard/test_schema_guard.py | 1 | 0 | 1 |
233232
| tests/unit/mcpgateway/plugins/plugins/test_init_hooks_plugins.py | 107 | 0 | 107 |

docs/docs/using/plugins/plugins.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Plugins for improving system reliability, performance, and resource management.
4040
|--------|------|-------------|
4141
| [Circuit Breaker](https://github.com/IBM/mcp-context-forge/tree/main/plugins/circuit_breaker) | Native | Trips per-tool breaker on high error rates or consecutive failures and blocks during cooldown |
4242
| [Watchdog](https://github.com/IBM/mcp-context-forge/tree/main/plugins/watchdog) | Native | Enforces maximum runtime for tools with warn or block actions on threshold violations |
43-
| [Rate Limiter](https://github.com/IBM/mcp-context-forge/tree/main/plugins/rate_limiter) | Native | Fixed-window in-memory rate limiting by user, tenant, or tool |
43+
| [Rate Limiter](https://pypi.org/project/cpex-rate-limiter/) | Package | Rate limiting by user, tenant, or tool with fixed-window, sliding-window, and token-bucket algorithms; memory and Redis backends |
4444
| [Cached Tool Result](https://github.com/IBM/mcp-context-forge/tree/main/plugins/cached_tool_result) | Native | Caches idempotent tool results in-memory with configurable TTL and key fields |
4545
| [Response Cache by Prompt](https://github.com/IBM/mcp-context-forge/tree/main/plugins/response_cache_by_prompt) | Native | Advisory response cache using cosine similarity over prompt/input fields with configurable threshold |
4646
| [Retry with Backoff](https://github.com/IBM/mcp-context-forge/tree/main/plugins/retry_with_backoff) | Native | Annotates retry/backoff policy in metadata with exponential backoff on specific HTTP status codes |

llms/plugins-llms.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ Optimization:
175175
- `response_cache_by_prompt` - Response caching
176176
- `circuit_breaker` - Circuit breaker pattern
177177
- `retry_with_backoff` - Retry logic with backoff
178-
- `rate_limiter` - Rate limiting
178+
- `cpex-rate-limiter` - Rate limiting (external package: `cpex_rate_limiter.RateLimiterPlugin`)
179179
- `output_length_guard` - Output length limits
180180

181181
Utilities:

plugins/config-pii-guardian-policy.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ plugins:
208208

209209
# Rate limiter (fixed window, in-memory)
210210
- name: "RateLimiterPlugin"
211-
kind: "plugins.rate_limiter.rate_limiter.RateLimiterPlugin"
211+
kind: "cpex_rate_limiter.RateLimiterPlugin"
212212
description: "Per-user/tenant/tool rate limits"
213213
version: "0.1.0"
214214
author: "Mihai Criveti"

plugins/config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,9 @@ plugins:
206206

207207
# Rate limiter (fixed window, Redis-backed for shared state across instances)
208208
- name: "RateLimiterPlugin"
209-
kind: "plugins.rate_limiter.rate_limiter.RateLimiterPlugin"
209+
kind: "cpex_rate_limiter.RateLimiterPlugin"
210210
description: "Per-user/tenant/tool rate limits"
211-
version: "0.1.0"
211+
version: "0.0.2"
212212
author: "Mihai Criveti"
213213
hooks: ["prompt_pre_fetch", "tool_pre_invoke"]
214214
tags: ["limits", "throttle"]

plugins/rate_limiter/README.md

Lines changed: 0 additions & 132 deletions
This file was deleted.

plugins/rate_limiter/__init__.py

Lines changed: 0 additions & 11 deletions
This file was deleted.

plugins/rate_limiter/plugin-manifest.yaml

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)