Mcp-CacheForge
Integrates with OpenAI's API by injecting prompt_cache_key into requests to leverage OpenAI's cloud prefix cache, with metrics for tokens read and written from the provider cache.
⚠️ NOTICE — The rest of this repository (code, comments, scripts, docs, commits, issues) is written in French. Only this README is in English.
✅ SWAP DONE — 2026-10-24. IcyCache was renamed from CacheForge. The universal multi-upstream gateway is now the single active service on
:8080, and the historical server holds the MCP layer.
src/server.py→ the gateway (18 upstreams inconfig/icycache.gateway.json: OmniRoute, LM Studio, Ollama, OpenAI, Anthropic, NVIDIA, Groq, Cerebras, OpenRouter, Kilo, Nous, Copilot, AI Gateway, HuggingFace, Google AI Studio, LLM7.io, Mistral, Cloudflare).
src/mcp_server.py→ the MCP layer (SSE:8081, Streamable HTTP:8084, stdio).Both start together via
tray.py;:8080is the single entry point for all LLM traffic.Legacy entry point kept:
python src/server.py --port 8090for isolated testing.DELTA-002 — upstream resilience + opt-in semantic cache (2026-10-26)
BUG-001 — 502 stuck after a 400: the httpx client is now drained, recycled, and the request retried once (
src/upstream_client.py). The gateway recovers instead of staying stuck.Number normalization:
"two plus two"→2+2. 11 new rules (1111 → 1122).Semantic cache: implemented (
src/icy_semantic.py) but off by default (semantic_enabled: false).Tool registry: the 100 verified MCP tool anchors (DELTA-001) are registered and asserted at startup.
Available MCP transports (all three active at once)
Transport
Endpoint
Target client
stdio
python mcp_stdio.pyClaude Desktop, IDEs, any stdio client
SSE (legacy)
http://127.0.0.1:8081/sseHermes, older clients
Streamable HTTP (standard)
http://127.0.0.1:8084/mcpRecent MCP clients, MCP Inspector
In stdio mode, go through
mcp_stdio.py: it reserves stdout for JSON-RPC. (Nothing is written to stdout anymore, but the wrapper remains the safety net.)
🔥 IcyCache — Universal LLM Gateway with local cache
"Forge the cache, not the answer." HTTP gateway that sits between any client and any upstream (local or cloud), caches responses and serves them back instantly — no CPU regeneration.
📖 Full configuration guide :
docs/CONFIGURATION.md— multi-upstream routing, per-client setup (Hermes, Claude Desktop, Cursor, VS Code, Ollama, direct SDK), MISS→HIT proof, troubleshooting, firewall enforcement.
Related MCP server: qualixar/superlocalmemory
The problem
Problem | Consequence |
Latency | An identical request burns CPU/RAM again for an already-computed answer |
No semantic cache | Standard systems hash the raw prompt: |
No observability | Impossible to measure the tokens and time actually saved |
Traffic bypassing the proxy | Every client talking directly to its provider breaks the cache promise |
IcyCache attacks all four: normalization before hashing, SQLite cache with TTL, exportable metrics, and a single entry point for all LLM traffic.
Semantic cache status: implemented but opt-in (
semantic_enabled: falseby default). It needs an embedding endpoint (LM Studio on:1234) and a Qdrant instance; when either is missing the cache degrades silently to a miss instead of failing the request. Seeconfig/semantic_cache.json.
Target architecture
Any client (Hermes, Claude Code, scripts, IDE, SDK, CLI)
base_url = http://127.0.0.1:8080
│
▼
┌───────────────────────────────────────────────────────────────────────┐
│ ICYCACHE GATEWAY 127.0.0.1:8080 (src/server.py) │
│ │
│ ROUTING URL prefix /<upstream>/v1/... │
│ header X-IcyCache-Upstream: lmstudio │
│ body "upstream": "ollama" │
│ default gateway.default_upstream (config) │
│ │
│ NORMALIZATION NFKD → lowercase → Aho-Corasick → accents → punctuation│
│ CACHE KEY SHA256 of the NORMALIZED payload (+ upstream + endpoint)│
│ DECISION HIT → instant response | MISS → forward + save │
│ TOKENS REAL usage from the upstream. Never an estimate. │
│ OBSERVABLE WebSocket /ws/events : live deltas + final │
│ MCP (facade) stats / clear / search / realtime / tool-cache │
└───────────────────────────────────────────────────────────────────────┘
│ ▲ │
▼ │ same path back │
{ OmniRoute | LM Studio | Ollama | OpenAI | Anthropic | … }
│
▼
SQLite db/cache.db (events: upstream, real tokens, latencies, ttft)Rule: everything that leaves a client and comes back to it goes through IcyCache. OmniRoute is no longer the entry point: it is one upstream among others.
Components
File | Role |
| Universal multi-upstream gateway (FastAPI): routing, cache, real tokens, WebSocket |
| MCP facade of the gateway: 7 tools, tool-cache, loop guard, mirror REST API |
| Shared core: DB ( |
| Standalone normalization engine (faithful port, no import side effects) |
| LLM cache store (compatible |
| Usage normalization, headers, cache_control/prompt_cache_key mutation, SSE meter |
| stdio bridge: reserves stdout for MCP JSON-RPC, logs and prints to stderr |
| MCP server (FastMCP): tools, tool-cache, loop guard — listens on :8081 (SSE) / :8084 (HTTP) |
| Gateway config: upstreams, cache, loop guard, tool cache |
| 1122 normalization rules (incl. number words → digits) |
| Resilient upstream client — one pool per base URL, drain + recycle + retry |
| Opt-in semantic cache — embeddings + Qdrant store, silent miss when unavailable |
| Semantic cache settings ( |
| Registry of the 100 verified MCP tool anchors (DELTA-001) |
| Real multi-upstream smoke test (isolated ports, temp DB) |
| Firewall rules: makes bypass impossible |
| Proof: can the client still reach an upstream directly? |
| 10 isolated tests (mock upstream, temp DB) |
| Semantic cache unit tests |
| Upstream recovery / retry tests (BUG-001) |
| Normalization anchor tests (DELTA-002) |
Routing: pick your upstream
Method | Example | Priority |
URL prefix |
| 1 |
Header |
| 2 |
Body |
| 3 |
Config default |
| 4 |
No implicit default in the code: without an explicit source, the request is rejected with
400 listing the available upstreams. An unknown upstream is rejected with 404.
HTTP routes (gateway)
Route | Method | Role |
| POST | OpenAI-compatible (streaming and non-streaming) |
| POST | Native Anthropic ( |
| POST | Embeddings (cached) |
| GET | Upstream models |
| * | Explicit routing by prefix |
| WS | Realtime events: live |
| GET | Health, reachable upstreams |
| GET | Metrics (dashboard shapes) |
| GET | Agent / tool-cache events |
| POST | Empty the cache — header |
| GET | Web dashboard (read-only) |
Confirmation headers: X-IcyCache-Confirm (unified naming). The old X-CacheForge-Confirm
is still accepted by the gateway for compatibility.
Tokens: the rule of the real
Source | Value |
| always authoritative |
OpenAI streaming |
|
Anthropic streaming |
|
Usage absent |
|
HIT |
|
events columns: upstream, client, prompt_tokens, completion_tokens, cached_tokens,
cache_write_tokens, latency_ms, ttft_ms.
MCP tools (facade)
MCP server (src/mcp_server.py) — 11 tools
Tool | Role |
| Entries, hits, breakdown by upstream/model |
| Empty the cache ( |
| Preview of normalization + cache key |
| Search in normalized prompts |
| Call a tool on a target MCP server (tool calling) |
| Batch call of target tools |
| Routable MCP servers |
| Tools exposed by a target server |
| Tool-cache state + agent events |
| Empty the tool cache ( |
| Detect an agent loop in an LLM history |
Gateway server (src/mcp_gateway.py) — 11 tools
The 7 observability tools (get_cache_stats, clear_cache, normalize_preview,
search_cached_prompts, get_realtime_tokens, list_upstreams, tool_cache_stats)
plus the 4 relay tools (proxy_tool, proxy_tools, list_proxy_servers,
list_proxy_tools).
MCP is a facade: it observes and drives. It is not in the request path (an MCP client calls its tools deliberately — you cannot intercept an OpenAI/Anthropic stream with it). The request path is the HTTP gateway.
Agent loops: icy_core.llm_loop_check() detects the same tool called again with the same
arguments and the same results (Anthropic and OpenAI formats). Threshold: 3 repetitions = warning.
Tool calling: safety rules
The tool proxy (src/tool_proxy.py) relays calls to target MCP servers.
Three non-negotiable rules:
An MCP error is never cached and never returns
ok: true. AnisError: truebecomesok: falsewith the real message (no opaqueExceptionGroup).Write tools are never cached. Replaying a cached response must have no side effect; otherwise a write is silently skipped.
cache_toolspresent → strict allowlist (only tools listed astrueare cached).otherwise
cache: true→ anti-write heuristic (create_,write_,delete_,push_, … excluded).otherwise → no cache.
MCP sessions are persistent (one process per server, not per call). Without this, every tool call respawned a process: 21s measured on
npx, 12s onuvx.
Example
// via any MCP client
{"server": "github", "tool": "search_repositories", "args": {"query": "icycache"}}
// -> {"ok": true, "cached": false, "latency_ms": 4867, "result": {...}}Target server configuration
config/icycache.json → tool_proxy.servers. Two portability tokens:
Token | Value |
| project root (moving IcyCache needs no edit) |
| project venv interpreter (the only one with |
On Windows, .cmd commands (like npx) are resolved automatically:
CreateProcess cannot launch an npx.cmd script without a shell.
Enforcement: making bypass impossible
# 1. Install the rules (ELEVATED PowerShell)
powershell -ExecutionPolicy Bypass -File tools\enforce_gateway.ps1 -Action apply `
-TargetProgram "C:\Users\Tech\AppData\Local\hermes\hermes-agent\apps\desktop\release\win-unpacked\Hermes.exe" `
-AllowPort 8080 -BlockPorts 20128,1234,11434
# 2. The proof: can the client still reach an upstream directly?
python tools\verify_enforcement.py --program "D:\IcyCache\venv\Scripts\python.exe" --allow-port 8080Strategy (Windows Firewall, per program): block upstream local ports including on
127.0.0.1, block all remote traffic, explicitly allow 127.0.0.1:8080.
The verify_enforcement.py program runs with the client binary (rules are per program)
and checks that only IcyCache remains reachable.
Environment variables (unified naming)
Variable | Role | Old name (still read by |
| Cache DB path |
|
| Log path |
|
| Config file (gateway) | — |
| Upstream override (isolated tests) |
|
| Tool-proxy config (default: | — |
Installation
The registry publication is pending. The repository, the PyPI distribution and the npm package all carry the same name —
icycache— and the packages are built, tagged and ready to publish (v0.3.2). The names were free on both registries, andicycache-mcpis the second binary the npm package exposes.The registry commands below are the final ones, but they return a 404 until the first publish. Install from source in the meantime:
pip install "icycache @ git+https://github.com/MlkBlk-IT/icycache.git".
uv tool install icycache # or: pip install icycacheRegistry | Package | Page |
PyPI |
| |
npm |
|
This gives you the icycache console script:
icycache serve # the gateway, http://127.0.0.1:8080
icycache mcp # the MCP layer (SSE :8081 / HTTP :8084 / stdio)
icycache doctor # diagnostic: paths, config, upstreams, databaseInstalled packages never write into site-packages: db/ and logs/ go to
%LOCALAPPDATA%\IcyCache (Windows) or ~/.local/share/IcyCache.
Full guide: docs/INSTALL.md.
npm (Node-only clients)
The npm package is icycache — the same name as the repository. It exposes two binaries:
npx -y icycache --help # the CLI (serve / mcp / doctor)
npx -y -p icycache icycache-mcp # MCP server on stdioFrom source (Windows)
# 1. Environment (Python 3.12.10)
python -m venv venv
.\venv\Scripts\Activate.ps1
pip install -e ".[dev]"
# 2. Manual start
.\start_icycache.ps1
# 3. Start at login (Task Scheduler, or Startup fallback without admin)
.\install_autostart.ps1Build the packages yourself
python -m build # -> dist/icycache-<version>-py3-none-any.whl + .tar.gzBuilding and publishing this package: see
PUBLISHING.md.
Tests
# Isolated suite (mock upstream, temp DB, no port occupied)
.\venv\Scripts\python.exe -m pytest tests\test_gateway.py -v
# Isolated integration suite (temp DB + fake upstream :8190/:8191)
.\venv\Scripts\python.exe tests\run_isolated.py
# Offline PrefixProxy test (fake provider, no external call)
.\venv\Scripts\python.exe tests\test_prefix_proxy.py
# Real smoke test (LM Studio / OmniRoute, port 8090, temp DB)
.\venv\Scripts\python.exe tools\smoke_gateway.py --port 8090
# DELTA-002 suite (semantic cache, upstream recovery, normalization anchors)
.\venv\Scripts\python.exe -m pytest tests\test_semantic_cache.py tests\test_upstream_recovery.py tests\test_anchors.py -vThe smoke test touches neither the production service (:8080) nor the dashboard.
tests\run_isolated.py uses a temporary database (ICYCACHE_DB) and never touches
the production database.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
LLM caching proxy (x402 USDC on Base) - exact + semantic cache. Free health.
LLM Observability & Orchestration Agent
Related MCP Servers
- AlicenseAqualityAmaintenanceEnterprise-grade (40m+ lines) codebase intelligence in a zero-setup, private and local MCP: managed indexing, hybrid semantic search, polyglot code dependency graphs, and DB/API/infra knowledge. Benchmark: 61% less tokens, 84% fewer calls, 37x faster than standard AI grep.262,001 npm3,354AGPL 3.0
- AlicenseNot gradedqualityAmaintenancePersistent AI memory MCP server with 4-channel retrieval (semantic, BM25, entity graph, temporal). 74.8% on LoCoMo benchmark with zero cloud dependency. Works with Claude, Cursor, VS Code Copilot, and 17+ AI tools. EU AI Act compliant. MIT license.1,144 npm546 PyPI255AGPL 3.0
- AlicenseAqualityBmaintenanceSecurity, cost, and health governance proxy for MCP infrastructure. Enforces YAML-configurable security policies (blocklists, rate limits, token budgets), tracks real token costs via tiktoken, monitors server health with live JSON-RPC probes. Features OAuth 2.1/OIDC with RBAC, web dashboard, payload normalization, semantic shell AST analysis, mTLS, and a formal STRIDE threat model.459 npm4MIT
- AlicenseAqualityAmaintenanceSemantic tool-routing gateway for MCP servers that cuts 70-90% of context tokens, with RBAC, API-key auth, response caching, hot-reload config, and a real-time observability dashboard.313MIT