Skip to main content

The Deterministic Tool Cache for LLM Agents — no LLM decides what to cache. SQLite FTS5, zero deps, MCP multiplexer, zero-trust WAF.

Project description

ToolRecall — The Deterministic Tool Cache for LLM Agents

ToolRecall is a caching layer and security guard for AI agents. It sits between the agent and your tools — SQLite cache for repeated reads, FTS5 knowledge base, MCP multiplexer, and a zero-trust WAF. No LLM decides what to cache. Pure stdlib — pip install toolrecall adds zero dependencies. (Python 3.11+ with sqlite3/tomllib/json)

76 KB, zero pip dependencies, one daemon.


Quickstart

pip install toolrecall    # Zero deps — installs nothing but ToolRecall itself
toolrecall init            # Interactive security setup
toolrecall daemon &         # Start cache daemon
toolrecall mcp              # Connect any MCP agent (Claude Code, Cursor, Cline, Hermes...)

Requirements: Python 3.11+ (stdlib: sqlite3, tomllib, json, http.server, urllib).


What ToolRecall IS / IS NOT

ToolRecall IS ToolRecall IS NOT
Deterministic — byte-exact tool output cache from SQLite, no LLM in the caching loop ❌ Not an LLM-driven Cache Planner — no second agent deciding what to cache
MCP Multiplexer — single daemon manages all external MCP servers ❌ Not a chronological call-graph
Zero-Trust WAF — path canonicalization, secret air-gapping, MCP keyword filter ❌ Not a vector database — no embeddings, no GPU
FTS5 Knowledge Base — zero-dep full-text search over docs and notes ❌ Not a distributed cache — single-node SQLite
Deterministic replay — freeze OS state for 100% reproducible agent runs ❌ Not a replacement for real-time data

Why Not an LLM-Powered Cache?

Some caching frameworks use a second LLM — a "Cache Planner" — to classify tools by cacheability. ToolRecall is deterministic, not heuristic:

Failure mode LLM-Driven Cache ToolRecall (Deterministic)
Misclassification LLM guesses send_message() is STATIC → messages silently dropped ttl=0 means NEVER cache. Binary.
Extra API cost Every new tool needs an LLM call to classify $0 — SQLite FTS5, no API calls
Cold-start latency Must analyze tool metadata before first decision First call executes live, cached on return
Side-effect blindness Relies on tool name/description, not behavior mtime-based auto-invalidation — file edited? next read is fresh.
Reproducibility Non-deterministic — same tool classified differently per run Byte-identical for same args + same mtime

The principle: Intelligent caching doesn't need an intelligence. It needs a filesystem, a clock, and the honesty to say "I don't know — execute it live."


The Core Problem: The Context Snowball

LLM context windows are stateless. Everything accumulates.

Level 1 — File repetition (O(N), linear): A 10,000-token file, read once, stays in context for 100 turns: 10K × 100 = 1,000,000 billed input tokens for the same content.

Level 2 — The real O(N²) snowball (quadratic): Context grows continuously through new tool outputs — not just one file. After 100 turns it hits ~500K tokens. Attention scales at O(N²):

Context size → Attention pairs per turn
   10K     →       50 million
  100K     →      5 billion
  500K     →    250 billion   (after 100 turns without ToolRecall)

ToolRecall breaks both curves:

  1. File cache → file read once, then ~0.6ms from SQLite → 0 tokens for repeats
  2. Micro-RAG → agent drops large outputs from active context, re-fetches byte-exact from cache on demand

Result: 81% fewer input tokens + context stays manageable + attention costs flat.


Universal Agent Compatibility (Drop-In MCP)

ToolRecall exposes a standard stdio MCP interface (toolrecall mcp). It works with any agent — Claude Code, Cursor, Cline, Hermes:

claude mcp add toolrecall toolrecall mcp

No custom plugins. No SDK changes.


Security Architecture (The WAF)

ToolRecall doesn't cure an LLM of being prompt-injected — it cages the agent to neutralize the consequences:

  • Daemon-based IPC: Unix Domain Sockets (Linux/Mac) or TCP localhost fallback (Windows). No open ports — immune to SSRF.
  • Cryptographic path resolution: os.path.realpath blocks ../../../etc/shadow before the OS is touched.
  • Execution blackholes: allow_terminal = false drops RCE attempts into a void.
  • Air-gapped secrets: API keys in ~/.toolrecall/.env — the LLM never sees them.
  • Default-deny init flow: toolrecall init prompts for allowed paths interactively. Without config, ALL paths are blocked.
  • MCP keyword access control: tool_access_control = true blocks MCP tools whose name contains write, delete, push, etc. Substring match — not process isolation.
  • Cognitive Pre-Flight: Deterministic prompt-injection scan on MCP tool arguments. Zero LLM, sub-millisecond hot path.

How ToolRecall Compares

ToolRecall does 3 things in one daemon: cache, WAF, MCP multiplex. Each piece has more polished alternatives — the value is integration.

Your need ToolRecall Alternative
Token reduction / fewer re-reads ✅ SQLite+in-memory cache (~0.6ms) RTK (Rust, hook-based)
Context compression ✅ Micro-RAG (agent drops + re-fetches) headroom MCP
Code/doc search ✅ FTS5 (BM25, zero deps) serena (semantic)
MCP server management ✅ Multiplexer + lazy loading + idle timeout Claude Code native MCP
Server-side prompt cache stability ✅ Freezes OS output for byte-identical prefix Anthropic API (automatic)
Security gate (non-OS) ✅ Path canonicalization, keyword access control, cognitive scan None standalone

ToolRecall wins when: you run multiple agents (Hermes + Claude Code + Cursor), have 3+ MCP servers with cold-start latency, and want a single security config.


How It Saves Cost — Two Mechanisms

1. Local Token Reduction (~81% fewer input tokens)

Repeated tool calls served from local SQLite. In a 13-file project with 3–10× re-reads, this removes ~55–77K tokens per session. Measured hit rate: 67–97%.

2. Server-Side Prompt Caching Discount (up to 90%)

Anthropic and OpenAI offer up to 90% discount on input tokens that match a previous request's prefix. ToolRecall freezes OS tool outputs — every read_file, git status, hostname returns the exact same byte string until the file changes. This makes the server-side discount reliably available instead of randomly busted by OS noise.

3. Deterministic

Byte-identical cache hits = 100% reproducible agent runs. No OS flakiness.

4. Safer

Zero-Trust WAF: cryptographic path resolution, .env air-gapping, allow_terminal=false drops RCE attempts.

5. Universal

toolrecall mcp works with any MCP-speaking agent.


The Hourglass Architecture

  [ Claude Code ]   [ Cursor IDE ]   [ Hermes Agent ]
         \                |                /
          \               |               /
        +───────────────────────────────────+
        │  Standard stdio Protocol (Bridge) │  <- Client Layer
        +─────────────────┬─────────────────+
                          │ Unix Domain Socket (Linux/Mac)
                          │ TCP localhost:8567 (Windows)
        +─────────────────▼─────────────────+
        │         ToolRecall Daemon         │  <- Gateway Layer
        │  ┌─────────────────────────────┐  │
        │  │   In-Memory LRU (Cache)     │  │
        │  └──────────────┬──────────────┘  │
        │  ┌──────────────▼──────────────┐  │
        │  │   SQLite WAL (Persistent)   │  │
        │  └─────────────────────────────┘  │
        │  ┌─────────────────────────────┐  │
        │  │   MCP Server Multiplexer    │  │
        │  └──────────────┬──────────────┘  │
        +─────────────────┼─────────────────+
                          │ Lazy-Loaded stdio Subprocesses
        +─────────────────▼─────────────────+
        │ [ Downstream MCP: GitHub / Time ] │  <- Execution Layer
        +───────────────────────────────────+

Features

Byte-Exact Tool Caching

  • File Cache: Invalidates on file modification (mtime) — no stale reads.
  • Terminal Cache: Caches read-only commands by TTL (git status for 30s, hostname for 1h).
  • Script & Code Cache: cached_run, cached_exec with ttl=0 bypass for state-changing ops.
  • MCP Cache: TTL-based caching for external MCP tool responses (~12× speedup).

Manual Cache Refresh

  • cache_refresh_file: Invalidate and re-read one file. Safe, no security gate.
  • bypass_cache flag: Force fresh read on any single cached_read call.
  • cache_invalidate: Clear ALL caches. Gated behind mcp.allow_invalidate=true.

MCP Multiplexer (AI Gateway)

  • One daemon manages all MCP servers.
  • Lazy loading: Servers boot in 0.01s only when first called.
  • Idle timeout: Inactive MCP subprocesses killed after 15min.
  • Agents connect to one server: toolrecall mcp. Session startup: ~0.01s instead of ~1.7s.

FTS5 Knowledge Base

Zero-dependency full-text search over docs and notes. BM25 ranking, Porter stemming. No embeddings, no GPU, no API calls.

Data Engine (RLHF / SFT Trajectories)

toolrecall export-dataset ~/trajectories.jsonl

Exact (Action → State) pairs from agent sessions. Zero-cost SFT/DPO dataset generation.


Configuration

TOML (default, via stdlib tomllib) or YAML (optional, requires pyyaml).

[mcp]
allowed_paths = ["~/.toolrecall"]  # Home NOT allowed by default
allow_terminal = false
default_ttl = 60

[mcp_multiplex]
enabled = true
idle_minutes = 15

[security]
tool_access_control = false
dangerous_tool_keywords = []

TOOLRECALL_* environment variables override TOML.


Hermes Auto-Cache (Hermes Agent only)

git clone https://github.com/whiskybeer/toolrecall.git
cd toolrecall
bash scripts/setup.sh

Uninstall

pip uninstall toolrecall
python3 scripts/uninstall.py --force

Removes: daemon, systemd service, config, cache DB, logs.


Platform Support

Platform Transport Status
Linux Unix Domain Sockets ✅ Tested in CI (176/176 pass)
macOS Unix Domain Sockets ✅ Should work (POSIX). Not in CI.
Windows TCP localhost:8567 fallback ⚠️ Untested. Transport layer adapted, full suite never run.

Roadmap

  • Live cache dashboard (toolrecall dashboard)
  • Tool-calling profiler (latency breakdown per MCP call)
  • Active cache invalidation on mutation tools
  • Container sandbox for cached_run (Docker backend)
  • Webhook-triggered invalidation

Documentation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

toolrecall-0.4.7.tar.gz (98.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

toolrecall-0.4.7-py3-none-any.whl (74.6 kB view details)

Uploaded Python 3

File details

Details for the file toolrecall-0.4.7.tar.gz.

File metadata

  • Download URL: toolrecall-0.4.7.tar.gz
  • Upload date:
  • Size: 98.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for toolrecall-0.4.7.tar.gz
Algorithm Hash digest
SHA256 8da469ac8b7bb7d495ed224f52410a4676bca921da0c55fad957dd767e3b17d0
MD5 bc2b4f454f543df15773c0aa253c74e9
BLAKE2b-256 3f26258322bf2664865900485d130495a5953d7ed7a094a4eb10ad7b4c78fe76

See more details on using hashes here.

File details

Details for the file toolrecall-0.4.7-py3-none-any.whl.

File metadata

  • Download URL: toolrecall-0.4.7-py3-none-any.whl
  • Upload date:
  • Size: 74.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for toolrecall-0.4.7-py3-none-any.whl
Algorithm Hash digest
SHA256 99ac34db25c3541c376004b41028d2fdabb6db55925a39128eec7e4daba43d25
MD5 05d0609898d93a2acf8860df97e0d269
BLAKE2b-256 03b46b982c476320276fb668b9079877132113fd9576a6301038f95456fccaa7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page