Install
$ agentstack add mcp-drip-cli-drip Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged2 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Destructive filesystem operation.
- high Pipes remote content directly into a shell (remote code execution).
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
DRIP
Delta Read Interception Proxy — sends only file diffs to your LLM agent.
Website · [Install](#installation) · [Benchmarks](./BENCHMARKS.md) · [Architecture](./ARCHITECTURE.md)
[](https://github.com/drip-cli/drip/actions) [](https://crates.io/crates/drip-cli) [](https://github.com/drip-cli/homebrew-drip) [](https://drip-ai.app/) [](./LICENSE) [](./tests) [](./BENCHMARKS.md)
A single Rust binary that sits between your coding agent (Claude Code, Codex, Gemini) and the filesystem. It records a baseline on the first read, then returns just a unified diff or [unchanged] on re-reads. MCP/manual first reads can be semantically compressed for code; Claude Code's native Read first pass stays native full content so Claude's read-before-edit tracker remains correct. Same agent, same workflow, ~60–80 % fewer tokens spent on file reads.
Table of contents
- [The problem](#the-problem)
- [How it works](#how-it-works)
- [Install](#install)
- [Quick start](#quick-start)
- [Commands](#commands)
- [Configuration](#configuration)
- [Compatibility](#compatibility)
- [Privacy & security](#privacy--security)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [License](#license)
The problem
Your agent codes a feature on app.py (400 lines):
read app.py → 400 lines
edit 3 lines → …
read app.py → 400 lines ← already saw 397 of them
edit 2 lines → …
read app.py → 400 lines ← still re-reading the same content
read app.py → 400 lines
read app.py → 400 lines
─────────
2,000 lines sent to the model
With DRIP the same five reads look like this:
read app.py → ~40 lines (semantic-compressed first read)
read app.py → ~6 lines (unified diff)
read app.py → ~4 lines
read app.py → unchanged — 0 lines
read app.py → ~2 lines
─────────
~52 lines sent to the model
Same agent. Same workflow. ~97 % fewer tokens on this loop — that example is illustrative; on a measured 8-language fixture set the workflow means land at 34 % – 88 % depending on the mix of unchanged re-reads (high) vs. live edits (lower) — see [BENCHMARKS.md](./BENCHMARKS.md) for the full breakdown across 8 languages, 4 workflow styles, and verified signature/import/type preservation on every fixture.
How it works
DRIP intercepts file-read calls before they reach the agent's tool result and replaces them with the smallest payload that brings the agent up to date.
┌─────────────────────────────────┐
Agent ────► │ DRIP hook (Read / MCP) │ ────► smallest payload
└────────────┬────────────────────┘ │
│ SHA-256(content) │
▼ │
┌─────────────────────────────────┐ │
│ ~/.local/share/drip/sessions.db │ ◄──────────┘
│ (session_id, file) → baseline │
└─────────────────────────────────┘
Per (session_id, file_path) DRIP picks one outcome:
| Outcome | What the agent receives | |--------------------------------------|--------------------------------------------------------| | First read | Full content. MCP/manual substitutions are semantically compressed when applicable; Claude Read first pass stays native full content | | Same hash as last read | [DRIP: unchanged] (zero-byte body) | | Different hash, small diff | Unified diff via similar | | Diff would cost more than file | Auto-fallback to full content | | Partial read with baseline, same | [DRIP: unchanged (lines X-Y)] — window-scoped 0-byte | | Partial read with baseline, drifted | Unified diff scoped to the requested window only | | Partial read on unknown file | Native passthrough (no baseline to compare against) | | File deleted | [DRIP: file deleted since last read] | | Read after your own edit | [DRIP: edit verified \| hash: …] certificate (file hash + touched ranges, ~390 B) | | First read past Claude's Read 25 k-token limit | Semantic-compressed view substituted via deny (signatures + [DRIP-elided] stubs) — the agent sees the file's shape instead of the native exceeds maximum allowed tokens error | | Path matches .dripignore | `` placeholder |
Tokens, in practice. Every row below is measured, not estimated, on a real fixture in this repo. Re-run with bash scripts/bench_multilang.sh (~30 s on Apple Silicon).
| Scenario | Without DRIP | With DRIP | Saved | |--------------------------------------------------------------|---------------:|-----------------:|-------------:| | First read of a 731-line Python file (semantic-compressed) | 6,774 tok | 2,575 tok | 62 % | | 5 reads of the same Python file — 1 first + 4 unchanged | 33,870 tok | 2,806 tok | 92 % | | Edit cycle on a 744-line Java file (4 reads, 1 edit + cert) | 28,306 tok | 5,206 tok | 82 % | | 7-read refactor session, 3 edit cycles (8 langs combined) | 364,496 tok | 188,287 tok | 48 % |
> Bonus — DRIP reads files Claude's Read tool can't. Claude > refuses anything past ~25 000 tokens with File content (X tokens) > exceeds maximum allowed tokens (25000). DRIP detects the threshold, > runs semantic compression even on the native-passthrough path, and > substitutes the compressed view. **Live numbers: a 130 KB, > 1 980-line Python module that native Read flat-out refuses comes > back as 1 781 tokens of structured signatures + [DRIP-elided] > stubs — a 95 % reduction on a file the agent otherwise couldn't > open at all.** The agent navigates the file's shape, then uses > partial Read(offset, limit) to drill into specific bodies for > editing. Threshold tunable via DRIP_CLAUDE_READ_TOKEN_BUDGET.
Live numbers from your own session are always one command away:
drip meter # cumulative since install
drip meter --session # current Claude/Codex/Gemini session only
drip meter --history # per-command savings over time
Concrete dollar impact at typical solo-dev usage (5 sessions/day, 22 work-days/month), linearly extrapolated from the multi-edit refactor workload above (read the caveat in [BENCHMARKS.md section 3](./BENCHMARKS.md#3-cost-projection) — this is not a prediction of your real monthly invoice, just a back-of-envelope sense of scale on file-read traffic): ~\$50/month on Sonnet 4.6, ~\$249/month on Opus 4.6, ~\$166/month on GPT-5/Codex. To estimate your own case, run drip meter --history against a real session and override the price with DRIP_PRICE_PER_MTOK=N.
> ⚠ Caveat — prompt caching cuts the headline. The figures above > assume the full per-token price for every read. If your agent > uses Anthropic's prompt caching > (or any provider equivalent), repeated reads of the same file hit > the cache at ~10% of the price. In that world, DRIP's > unchanged/delta savings stack on top of caching for a smaller > additional gain — order 1/3 to 1/2 of the headline $ figure in > the typical case. DRIP still wins on first-read compression (large > files past the 25k Read budget that the agent couldn't open at all) > and on cross-session orientation, but the $ projection above is the > no-caching upper bound, not the cache-aware one.
Full reproducible benchmarks (per-language compression, latency, 8-language workload, signature-preservation audit) live in [BENCHMARKS.md](./BENCHMARKS.md).
State lives in a single SQLite file. There is no daemon, no network call, no telemetry. For the design rationale (why per-session, why SQLite, why similar, edge cases) see [ARCHITECTURE.md](./ARCHITECTURE.md).
What DRIP also does well
- Reads files Claude's
Readtool can't. Claude'sReadrefuses
anything past ~25 000 tokens with File content (X tokens) exceeds maximum allowed tokens (25000) — files of that size are simply unreadable from the agent's side. DRIP detects the threshold before process_read even runs, routes through the DripRendered entry point so semantic compression executes (skipped on the native passthrough path by default), and substitutes the compressed view via permissionDecision: deny. The agent sees the file's full structure — signatures, class declarations, imports, plus [DRIP-elided] stubs for bodies — and then drills into specific regions with partial Read(offset, limit) reads (which populate the harness's edit-tracker for the window). Live numbers from a 130 KB / 1 980-line Python fixture: native errored out; DRIP returns 1 781 tokens of structure (95 % reduction) on a file that's otherwise totally unreadable. Threshold tunable via DRIP_CLAUDE_READ_TOKEN_BUDGET (default 10 000 DRIP tokens ≈ 24-26 k Claude tokens, since Claude's tokenizer runs ~2.5× tighter than DRIP's bytes/4 heuristic). When compression isn't available (non-code file, raw data, DRIP_NO_COMPRESS=1) the hook falls back to allow so the native error still points the agent at offset/limit.
- Semantic compression on first reads. 13 languages recognised
— Python, Rust, JS/TS, Go, Java, C, C++, C#, Kotlin, Swift, Scala, PHP. Function bodies are elided, signatures + imports + class declarations preserved (verified zero structural loss on the 8 benchmarked fixtures). Compression ratio varies by file density: measured 60 % on Python, 44 % on Go, 43 % on C++, 42 % on TypeScript, 38 % on Java, 36 % on Rust, 36 % on Kotlin, 33 % on C# — see [BENCHMARKS.md section 1](./BENCHMARKS.md#1-semantic-compression-on-first-reads) for the full per-language table. The C-family parser handles both K&R (signature {) and Allman (signature + lone-{ line) brace styles plus attributes / primary constructors / records.
- Javadoc / KDoc / JSDoc compression. Long doc blocks (≥ 6
lines) collapse to summary + @param / @return / @throws tags, with a [DRIP-javadoc-elided: N lines] marker for the prose / examples that were removed. Disable with DRIP_COMPRESS_JAVADOC=0.
.dripignore— gitignore-style. Filters reads, glob results,
and grep results at the source. Built-in defaults for lock files, node_modules, build artefacts, binaries, fonts, video.
- Edit certificates. Read a file immediately after editing it
and DRIP returns a compact [DRIP: edit verified | hash: …] attestation (file hash + touched line ranges + symbol names parsed from the diff, ~390 B) instead of letting the harness ship the full file. Disable with DRIP_CERT_DISABLE=1.
- Session keying — crash-resistant, branch-isolated. Session id
derives from (cwd, git branch, worktree) so a relaunched agent on the same branch reuses its prior baselines, and a branch switch isolates them.
- Cross-session file registry. First reads in a new session
carry an ↔ unchanged since last session or ↕ changed since last session orientation header so the agent doesn't restart blind.
Install
macOS
# Homebrew (recommended) — Apple Silicon + Intel
brew install drip-cli/drip/drip
# Or via the install script
curl -fsSL https://raw.githubusercontent.com/drip-cli/drip/main/install.sh | sh
Linux
# Install script (recommended) — drops the binary into ~/.local/bin.
# Pulls the static musl build, which runs unmodified on every distro
# (glibc, Alpine, NixOS) without an interpreter mismatch.
curl -fsSL https://raw.githubusercontent.com/drip-cli/drip/main/install.sh | sh
# Or via Homebrew (linuxbrew)
brew install drip-cli/drip/drip
If ~/.local/bin is not on your PATH, the script prints the exact line to add to your shell rc.
Windows
# 1. Download the latest archive from
# https://github.com/drip-cli/drip/releases/latest
# (file: drip-x86_64-pc-windows-msvc.zip)
# 2. Extract `drip.exe` somewhere on your PATH, e.g. C:\Users\\bin
# 3. Verify
drip --version
A native PowerShell installer is on the roadmap. WSL users can follow the Linux instructions instead.
Cross-platform (any OS with a Rust toolchain ≥ 1.74)
# From crates.io — installs the `drip` binary
cargo install drip-cli
# Or from source
git clone https://github.com/drip-cli/drip
cd drip
cargo install --path .
Updating
drip update # auto-detects install method (brew / cargo / script)
drip update --dry-run # show what would happen, don't run anything
drip update detects how DRIP is installed by inspecting the binary path (/opt/homebrew/, ~/.cargo/bin/, ~/.local/bin/) and runs the matching upgrade command. Already up-to-date is a clean no-op.
Uninstalling
First, remove DRIP's hooks from your agent — this preserves any hand-edited content in CLAUDE.md / AGENTS.md:
drip uninstall # default: --agent claude (project-level)
drip uninstall -g # remove the global Claude hooks (~/.claude/)
drip uninstall --agent codex # remove Codex CLI integration
drip uninstall --agent gemini # remove Gemini CLI integration
Then remove the binary itself, depending on how you installed it:
brew uninstall drip # Homebrew install
brew untap drip-cli/drip # also drop the tap if you're done with it
cargo uninstall drip-cli # `cargo install drip-cli` install
rm ~/.local/bin/drip # install-script install
# Windows: delete drip.exe from wherever you put it on PATH
To purge cached state too (SQLite DB + on-disk file cache):
rm -rf ~/.local/share/drip # Linux
rm -rf "~/Library/Application Support/drip" # macOS
# Windows (PowerShell): Remove-Item -Recurse -Force "$env:LOCALAPPDATA\drip"
(or set DRIP_DATA_DIR=... to relocate state — drip doctor shows the current path).
Quick start
Wire DRIP into your agent — one command, idempotent, non-destructive:
drip init # Claude Code, project-level (./.claude/)
drip init -g # Claude Code, global (~/.claude/)
drip init --agent codex # Codex CLI (~/.codex/, always global — no project-level)
drip init --agent gemini # Gemini CLI, project-level (./.gemini/)
drip init -g --agent gemini # Gemini CLI, global (~/.gemini/)
That's it. The agent now goes through DRIP for every file read. You never call drip read yourself.
Verify the install:
drip doctor # ✅ / ⚠️ / ❌ report on every component
drip meter # token savings since install
Remove cleanly:
drip uninstall # local
drip uninstall --global # global
drip uninstall --agent codex # one specific agent
uninstall only removes the bytes DRIP wrote — hand-edited config, pre-existing hooks, and unrelated MCP servers are left intact.
Commands
drip init [--agent ] [-g] # Wire DRIP into an agent
drip uninstall [--agent ] [-g] # Remove DRIP from an agent
drip update [--dry-run] # Upgrade DRIP via brew / ca
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [drip-cli](https://github.com/drip-cli)
- **Source:** [drip-cli/drip](https://github.com/drip-cli/drip)
- **License:** Apache-2.0
- **Homepage:** https://drip-ai.app/en/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.