caveman-mcp
by alexruco
README.md
<p align="center">
<img
width="200"
height="200"
src="https://raw.githubusercontent.com/alexruco/caveman-mcp/refs/heads/main/images/caveman-mcp.png"
alt="hammer"
>
</p>
<div class="install-box">
### Install caveman-mcp
<pre><code class="bash">
pip install caveman-mcp
</code></pre>
</div>
<p class="install-alt">
or run without installing: <code>uvx caveman-mcp</code>
</p>
<h1 align="center">caveman-mcp</h1>
<p align="center">
<strong>MCP server that cuts 65% of tokens by compressing markdown files and activating caveman speak.</strong><br/>
Thinner and simpler than the original — no file distribution, no sync. No API key. Works everywhere.
</p>
<p align="center">
<a href="https://pypi.org/project/caveman-mcp"><img src="https://img.shields.io/pypi/v/caveman-mcp?style=flat&color=blue" alt="PyPI"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat" alt="License"></a>
<a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/MCP-compatible-green?style=flat" alt="MCP"></a>
</p>
---
## Why
Every token you send costs money and fills context. Long markdown files — `CLAUDE.md`, memory files, notes, docs — get read on every session. Caveman compresses them in place, preserving all code and structure, cutting prose by 65%.
| Without caveman (69 tokens) | With caveman (19 tokens) |
|----------------------------------|------------------------------|
| "The reason your React component is re-rendering is likely because you're creating a new object reference on each render cycle. When you pass an inline object as a prop, React's shallow comparison sees it as a different object every time, which triggers a re-render. I'd recommend using useMemo to memoize the object." | "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`." |
**Same fix. 75% fewer tokens.**
## Why MCP
Caveman prompts used to require a file in every project. With MCP:
- **Register once** — works across all projects, all agents
- **No file to sync** — no copy-pasting prompts into repos
- **Tools included** — compress any markdown file directly from the agent
- **Any client** — Claude Code, Cursor, Windsurf, Cline, or any MCP-compatible host
## Install
```bash
pip install caveman-mcp
```
Or run without installing:
```bash
uvx caveman-mcp
```
## Connect
**Claude Code** (global — recommended):
Edit `~/.claude/settings.json`:
```json
{
"mcpServers": {
"caveman-mcp": {
"command": "uvx",
"args": ["caveman-mcp"]
}
}
}
```
Or per-project via CLI:
```bash
claude mcp add caveman-mcp uvx -- caveman-mcp
```
**Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"caveman-mcp": {
"command": "uvx",
"args": ["caveman-mcp"]
}
}
}
```
**Cursor** (`.cursor/mcp.json`):
```json
{
"mcpServers": {
"caveman-mcp": {
"command": "uvx",
"args": ["caveman-mcp"]
}
}
}
```
**Windsurf** (`~/.codeium/windsurf/mcp_settings.json`):
```json
{
"mcpServers": {
"caveman-mcp": {
"command": "uvx",
"args": ["caveman-mcp"]
}
}
}
```
**Cline** (MCP settings panel → Add Server):
```json
{
"command": "uvx",
"args": ["caveman-mcp"]
}
```
> **Note:** Claude Code CLI and Claude desktop app both support local (stdio) MCP servers. Claude.ai web app only supports remote (HTTP/SSE) connectors.
**Without uvx** (local clone):
```json
{
"command": "/path/to/.venv/bin/python",
"args": ["-m", "caveman_mcp.server"]
}
```
## Prompts
Once connected, activate caveman speak from any agent with `/caveman`, "talk like caveman", or "caveman mode". Stop with "stop caveman" or "normal mode".
| Prompt | What it does |
|--------|--------------|
| `caveman` | Activate caveman compression |
| `caveman-commit` | Terse commit message style |
| `caveman-review` | One-line code review comments |
| `caveman-help` | Quick-reference card |
### Intensity levels
| Mode | Effect |
|------|--------|
| `lite` | Drop filler, keep full sentences and articles |
| `full` | Default — drop articles, fragments OK, short synonyms |
| `ultra` | Abbreviate (DB/auth/req/res/fn), strip conjunctions, X→Y causality |
| `wenyan-lite` | Semi-classical Chinese register |
| `wenyan-full` | Full 文言文, 80–90% character reduction |
| `wenyan-ultra` | Extreme, ancient scholar feel |
## Compress Tools
Compress any markdown file in three steps — the agent does the work, caveman-mcp handles the I/O and validation.
### `compress_prepare(filepath)`
Reads the file, returns content + compression instructions. The agent compresses the prose, then calls `compress_write`.
```
compress_prepare("CLAUDE.md")
→ { filepath, original_content, instructions }
```
Refuses: sensitive files (`~/.ssh/`, `.env`, credentials), existing backups, non-text formats, files > 500 KB.
### `compress_write(filepath, compressed_content)`
Writes compressed content. Auto-creates a `.original.md` backup on first call. Returns `{ valid, errors }` — validates that all headings, code blocks, and URLs are intact.
### `compress_restore(filepath)`
Restores from `.original.md` backup. Call if something goes wrong.
**Flow:**
```
compress_prepare("CLAUDE.md") ← read + get instructions
→ agent compresses prose
compress_write("CLAUDE.md", result) ← write + validate
→ { valid: true, errors: [] }
```
The result:
```
CLAUDE.md ← compressed (65% fewer tokens every session)
CLAUDE.original.md ← full backup (edit this, re-compress anytime)
```
## Auto-compress with Claude Code hook
Compress files automatically whenever Claude reads them — no manual invocation needed.
**1. Create the hook script** (`~/bin/caveman-hook`):
```python
#!/usr/bin/env python3
"""PostToolUse hook: compress .md files via caveman MCP when auto mode is on."""
import json, os, sys
flag = os.path.expanduser("~/.claude/caveman-auto")
if not os.path.exists(flag):
sys.exit(0)
data = json.load(sys.stdin)
filepath = data.get("tool_input", {}).get("file_path", "")
if not filepath.endswith(".md"):
sys.exit(0)
backup = filepath.replace(".md", ".original.md")
if os.path.exists(backup):
sys.exit(0)
print(json.dumps({
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": (
f"caveman-auto is ON. Compress {filepath} now using the three-step workflow: "
"compress_prepare → compress the prose → compress_write. "
"Do this silently without announcing it."
)
}
}))
```
```bash
chmod +x ~/bin/caveman-hook
```
**2. Create the toggle script** (`~/bin/caveman-toggle`):
```python
#!/usr/bin/env python3
import os
flag = os.path.expanduser("~/.claude/caveman-auto")
if os.path.exists(flag):
os.remove(flag)
print("caveman: OFF")
else:
open(flag, "w").close()
print("caveman: ON")
```
```bash
chmod +x ~/bin/caveman-toggle
```
**3. Register the hook** in `~/.claude/settings.json`:
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Read",
"hooks": [
{
"type": "command",
"command": "python3 /Users/you/bin/caveman-hook",
"statusMessage": "caveman check..."
}
]
}
]
}
}
```
**Toggle:** run `python3 ~/bin/caveman-toggle` to turn auto-compress on or off. To use as a bare command, add `~/bin` to PATH via `~/.zprofile` (not `.zshrc`):
```bash
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zprofile
```
Files with an existing `.original.md` backup are skipped automatically.
## Attribution
Fork of [JuliusBrussee/caveman](https://github.com/JuliusBrussee/caveman) — MIT licence, copyright © 2026 Julius Brussee. Original prompt design and caveman concept by Julius Brussee. This fork repackages caveman as a single MCP server with file compression tools.
## License
MIT
TDQS
A3.9/5.0
Scored across 3 tools
Disambiguation5/5
Each tool has a distinct role in the compression workflow: compress_prepare reads and provides compression instructions, compress_write writes compressed content with backup, and compress_restore reverts. No overlap.
Naming Consistency5/5
All tools follow the 'compress_[verb]' pattern with clear verbs (prepare, restore, write), ensuring predictability and readability.
Tool Count4/5
Three tools is minimal but well-scoped for a focused compression utility. The set covers the essential operations without unnecessary bloat.
Completeness4/5
The tools cover the key operations: read/prepare, write/compress with backup, and restore. Missing an explicit compression tool is acceptable since the server delegates compression to the agent.
Maintenance
ActivityInactive
ResponsivenessUnresponsive