Summa
by lcgm
README.md
<div align="center">
# Summa
**Read big files, logs, and web pages without filling your agent's context.**
[](LICENSE)





</div>
Summa is a plugin for Claude Code and Hermes Agent. When a tool returns more than 8,000 characters, Summa saves the full text on your computer. The agent gets the first 3,000 and last 1,000 characters, plus a note pointing to the rest. When it needs something from the middle, it searches and gets back one passage.
Your context fills up more slowly, so long sessions get compacted less often. When they are, Summa reminds the agent which files it changed and which tasks are still open.
```
/plugin marketplace add lcgm/summa
/plugin install summa@summa
```
> [!NOTE]
> Everything Summa stores stays in one SQLite file on your computer. Summa itself never connects to the internet.
## At a glance
Characters that reach the agent's context:
| Task | Without Summa | With Summa | Saved |
| --- | ---: | ---: | ---: |
| Search a codebase (Grep) | 86,051 | 4,302 | **95%** |
| Read a source file | 58,472 | 4,302 | **93%** |
| Read a changelog | 55,419 | 4,302 | **92%** |
| Run a command (`pydoc`) | 41,071 | 4,302 | **90%** |
| Read a web page (browser tool) | 24,576 | 4,236 | **83%** |
| Find one fact in the changelog | 55,419 | ~1,700 | **97%** |
[BENCHMARK.md](BENCHMARK.md) has how these numbers were measured and how to run the test yourself (the web page is a Wikipedia article read with a browser tool, measured separately). Your results depend on your files.
## How it works
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/how-it-works-dark.svg">
<img alt="A tool returns 24,576 characters; Summa saves the full text on disk; the agent sees 4,236 characters and searches for the part it needs" src="docs/how-it-works-light.svg">
</picture>
Summa checks every `Read`, `Grep`, `Bash`, and MCP tool call (browser tools included). The agent does not need to know which document holds the answer: `search` looks through everything stored in the project.
### What the agent sees
A Wikipedia article read with a browser tool, after Summa:
```text
<the first 3,000 characters of the page>
[... middle omitted by summa ...]
<the last 1,000 characters of the page>
[summa] Output shortened: 24,576 characters, saved locally as doc 5. Only the start and end are
shown above. To get the rest, call summa `search` with a few specific words, or `read` with doc_id=5.
```
## Tools
| Tool (Claude Code) | Hermes | What it does |
| --- | --- | --- |
| `search` | `summa_search` | Keyword search (FTS5, BM25 ranking). Returns short snippets with `doc_id` and `start` |
| `read` | `summa_read` | Read up to 8,000 characters of a stored document, from any position |
| `save_file` | `summa_index_file` | Index a whole file: `.md`, `.txt`, `.csv`, `.json`, `.log`, and text PDFs |
| `save_text` | | Store a piece of text under a label of your choice |
| `stats` | `summa_stats` | How much was kept out of context, in characters and approximate tokens |
| `forget` | `summa_forget` | Delete everything stored under one label (asks first) |
| `purge` | `summa_purge` | Delete everything Summa stored, after you confirm (see [Deleting everything](#deleting-everything)) |
In Claude Code you can also type `/summa:stats` or `/summa:purge`.
`search` and `read` see only the current project. Pass `all_projects=true` when you want everything.
### Knowledge base
Anything stored, whether shortened automatically or indexed on purpose, is searchable later in the same project. Index a manual, a long log, or a folder of notes once with `save_file`, then ask questions: the agent pulls back the matching passages instead of the whole file. Long files are split into parts that `forget` removes together.
### Session continuity
When Claude Code compacts a long conversation, details get lost. Summa keeps a small log of what the tools did and gives it back after compaction.
| | |
| --- | --- |
| **Recorded** | Files edited or created, task titles and status, terminal errors (redacted, one line each) |
| **Never recorded** | Your messages, file contents, command output that is not an error |
| **Restored** | On `compact` or `resume`: a summary of at most 2,000 characters. A fresh session gets nothing |
| **Kept** | Up to 500 events per session; older ones are dropped |
## Questions
**Will my agent miss something that was cut?**
It can, if it never looks. The note after every preview says the rest is saved, and `search` returns the passage in one call. The 4 lookups in [BENCHMARK.md](BENCHMARK.md) all found their answer.
**Does my code or data leave my computer?**
Summa stores everything in one local SQLite file and makes no network calls. What the agent reads still goes to your model provider, as it always does.
**What if an output is small?**
Under 8,000 characters, nothing changes. Rule files such as `CLAUDE.md` and `AGENTS.md` are never shortened.
**How do I undo it?**
`forget` deletes one stored output, `purge` deletes everything, and `SUMMA_DISABLE=1` turns the hook off.
## Install
### Claude Code
Requires [uv](https://docs.astral.sh/uv/), which installs the right Python version on its own.
```
/plugin marketplace add lcgm/summa
/plugin install summa@summa
```
Restart Claude Code after installing.
### Hermes Agent
The Hermes plugin brings its own tools, so you do not need the MCP server.
1. Install and enable: `hermes plugins install lcgm/summa --enable`
(or link this folder to `$HERMES_HOME/plugins/summa`; on Windows, a junction works without admin rights, then run `hermes plugins enable summa`).
2. To use `summa_index_file`, set `SUMMA_ROOTS` in `$HERMES_HOME/.env` to the folders it may read. There is no default, because Hermes often runs from the home folder.
3. Optional: set `SUMMA_DIR` in `$HERMES_HOME/.env` to choose where the database lives (default: `$HERMES_HOME/summa`).
4. Optional: `pip install pypdf` in the Hermes environment to index PDFs.
Session continuity after compaction is Claude Code only for now.
## Security and privacy
Summa reads your files, command output, and web pages, so it is built to keep that data on your machine and under your control.
| Concern | What Summa does |
| --- | --- |
| Where data goes | One SQLite file on your machine: `SUMMA_DIR`, else the plugin data folder, else `~/.summa`. Never inside the code folder. On Linux and macOS, only its owner can read it |
| Projects | Each document is tagged with its project folder. `search`, `read`, `forget`, and `stats` see only the current project, so content from one client's repo never shows up in another. Documents stored by Summa 0.2 or older have no project and appear only with `all_projects` |
| Network | Summa itself makes none: no telemetry, no update checks, no URL fetching. On first launch (and after a cache clear), `uv` downloads the pinned `mcp` and `pypdf` packages and their dependencies from PyPI |
| What is captured | Large text outputs of `Read`, `Grep`, `Bash`, and MCP tools (never images); their sizes before and after, for `stats`; and, for session continuity, edited file paths, task titles and status, and redacted terminal errors. Your prompts are never captured |
| Rule files | `CLAUDE.md`, `AGENTS.md`, `SKILL.md`, `SOUL.md`, and anything under `.claude/` are never shortened: not by `Read`, not by a Bash command that names them (`cat AGENTS.md`), not by a Grep whose path is one of them |
| Partial reads | A `Read` with `offset` or `limit` is never shortened |
| Secrets | Removed before saving, in the text and in its labels: Anthropic, OpenAI, Stripe, GitHub, and AWS keys, JWTs, `Bearer` tokens, private key blocks, passwords in URLs, assignments such as `DB_PASSWORD=` or `"client_secret":`, card numbers (Luhn-checked), and CPF numbers (check digits verified). The value is replaced by `[REDACTED:<kind>]`, so it never reaches the disk |
| File import | `save_file` only reads files inside allowed folders (`SUMMA_ROOTS`; default: the project folder in Claude Code, none in Hermes). Credential folders (`.ssh`, `.aws`, `.docker`, `.kube`, `.gnupg`, `.azure`, `gcloud`) and `.env` files are refused even inside them. Files over 20 MB are refused |
| Deletion | `forget(source)` deletes one label in the current project and is marked destructive, so your client asks before running it. Deleting everything needs your confirmation (see below). Nothing expires unless you set `SUMMA_MAX_AGE_DAYS` or `SUMMA_MAX_STORED_MB` |
| Failure | If the hook fails for any reason, the original output is used, so a tool call never breaks |
### Deleting everything
Ask the agent ("clear everything Summa stored") or type `/summa:purge`. Summa deletes its copies of outputs, session events, and the savings counter, in every project. Your own files are never touched.
| Client | How you confirm |
| --- | --- |
| Claude Code | Summa opens a confirmation dialog. Only you can answer it: the agent cannot, so text injected into a page or file cannot wipe your data on its own |
| Hermes, or a client without dialogs | Nothing is deleted. The agent shows you a command to run in a terminal on that computer, which asks you to type `DELETE EVERYTHING` and refuses piped input |
> [!CAUTION]
> Do not configure an `Elicitation` hook that answers Summa's dialogs automatically. That would let an agent confirm on your behalf.
> [!WARNING]
> **What Summa does not protect**
> - The preview and anything the agent reads with `search` or `read` still go to the model provider, as any context does. Summa reduces that volume; it does not keep content away from the model.
> - The database holds the full text of large outputs in plain SQLite. If you read sensitive files, a copy of what was stored stays there until you `forget` it or `purge` everything.
> - Secret redaction is best-effort, not a guarantee. Formats it does not know are stored as they are.
> - The preview is the tool's own output, not Summa's words, and it can contain prompt injection like any page or file. Summa only makes sure content cannot imitate its markers: a literal `[summa]` inside content is shown as `[summa (quoted)]`.
> - Never add `forget` to an allowlist of tools that run without asking.
## Configuration
| Variable | Default | Purpose |
| --- | --- | --- |
| `SUMMA_DIR` | plugin data folder, else `~/.summa` | Where the database lives |
| `SUMMA_PROJECT` | `CLAUDE_PROJECT_DIR`, else the current folder | Which project new content belongs to and which project is searched |
| `SUMMA_ROOTS` | the project folder (Hermes: none) | Folders `save_file` may read (separated by `;` on Windows, `:` elsewhere) |
| `SUMMA_MAX_CHARS` | `8000` | Outputs larger than this are stored and shortened |
| `SUMMA_MAX_FILE_MB` | `20` | `save_file` refuses larger files. PDFs are also capped at 500 pages and all files at 5 million characters |
| `SUMMA_MAX_AGE_DAYS` | unset | Delete stored documents older than this many days (checked on each save) |
| `SUMMA_MAX_STORED_MB` | unset | Keep at most this much stored text, deleting the oldest documents first |
| `SUMMA_STRIP_IMAGES` | unset | Set to `1` to replace images from MCP tools with a short note (the image is not stored) |
| `SUMMA_DISABLE` | unset | Set to `1` to turn the hook off |
## Limits
- Automatic shortening works in Claude Code and Hermes Agent. Other agents can use the MCP server, but without automatic shortening.
- Search is keyword-based (SQLite FTS5), not semantic.
- No URL fetching: Summa indexes what your tools already brought in, such as a page read with a browser tool.
- PDFs: only PDFs with a real text layer. Scanned PDFs and PDFs with a broken text layer (letters mapped to wrong characters) give no useful text; there is no OCR. On Hermes, install `pypdf` if it is missing.
- Images are not indexed.
## Development
```
uv run --with "mcp==1.30.0" --with "pypdf==6.20.1" python -m unittest discover -s tests -t .
python eval/benchmark.py
python eval/retrieval_eval.py eval/example-doc.md eval/example-cases.json
```
## Acknowledgments
Summa was inspired by [context-mode](https://github.com/mksglu/context-mode) by Mert Koseoglu, which showed how much context an agent saves when large tool outputs stay out of it. Summa is a separate implementation written from scratch in Python, with no code taken from context-mode. It focuses on keeping everything on your machine.
## License
[MIT](LICENSE)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues