The most direct way to reduce the tokens a programming agent spends is to keep it from grepping your entire repo and reading complete files just to find a function: give it a local index to query. We tested it with Pensieve, a local open source search engine that connects to Claude Code, Codex, Cursor and any MCP client. On OpenSEO, a real TypeScript repo of about 1,000 files, Claude Code made 47 percent fewer tool calls and used 12 percent fewer tokens per search than with grep alone, and found the right file nearly as often.
yoDEV Tested · October 12, 2026
We ran 160 searches with Claude Code 2.1.296 and Pensieve 0.6.3 on OpenSEO, a real TypeScript repo of about 1,000 files, using the author’s unmodified benchmark harness. The results we report as ours come from that test.
Why does your AI agent spend so many tokens searching for code?
Because it searches by habit, not by meaning. Ask Claude Code “where do we handle charge retry logic after a rejection?” and the usual sequence is: grep “retry”, hundreds of matches, then read file after file until you find the right one. Every file it reads goes into the context window, and you pay for every one of those tokens. In a large repo, the search can cost more than the fix itself.
A local index changes that first step. The agent asks a natural language question and gets back the few most relevant snippets, with file and line, instead of a wall of grep matches. This is what’s known as semantic code search on a local code index.
What is Pensieve?
Pensieve is a local search backend for Mac that indexes three things:
- your documents and folders
- your git repos, including uncommitted changes and worktrees
- your previous Claude Code, Codex and Qwen Code sessions
Then it exposes that index to your agents as an MCP server. It’s developed by Ted Haley, published under MIT license and everything runs on your machine:
- text is converted to embeddings locally with
Qwen3-Embedding-0.6B - the index lives in SQLite, with a full-text index by trigrams for exact matches and turbovec for vector search
- everything is saved in
~/.pensieve
By default, the agent sees eleven tools. The ones that matter for this article are search, read and similar. Search works by meaning (pricing model) and by exact words ("rate limit"), and you can combine both: exact matches are ranked by the meaning of the rest of the query.
It brings more things: a Spotlight-style search panel, a 3D map of your code sorted by meaning, code ownership from git blame and “knowledge gaps” (areas whose authors are no longer active in the repo). This article focuses on the token-saving part.
How much does it really save? Our test with OpenSEO
We ran the author’s own benchmark harness (bench/agent_search.py, at tag v0.6.3, unmodified) on OpenSEO: 1,047 files, of which Pensieve indexed 1,008.
How it works:
- The script takes code snippets from the index.
- Sonnet describes each one in natural language, without allowing identifiers, so grep can’t take shortcuts.
- Claude Code runs in headless mode and is asked which file contains that code, in two configurations:
- Grep: Read, Grep and Glob only.
- Pensieve: the same tools, plus Pensieve’s MCP tools and its “search before grepping” instruction block.
- Runs from both configurations are mixed in the same batch, so prompt cache doesn’t favor either one.
40 tasks × 2 configurations × 2 repetitions = 160 runs. Claude Sonnet on Claude Code 2.1.296, Pensieve 0.6.3, October 12, 2026, zero errors:
| Grep, Glob, Read | With Pensieve | Change | |
|---|---|---|---|
| Files found | 74 / 80 | 76 / 80 | practically the same |
| Tool calls per search | 2.66 | 1.40 | −47% |
| Tokens per search | 36,607 | 32,132 | −12% |
| Cost per search | $0.031 | $0.027 | −11% |
| Time per search | 16.7 s | 13.8 s | −18% |
The clear gain is in steps, not accuracy.
- On accuracy it’s a tie. The two extra files came from a single query type, exact text strings, where Pensieve got 4 out of 4 and grep got 2 out of 4. That’s too few runs to draw conclusions. All other types tied.
- The step savings are real. In 30 out of 40 tasks, the median run with Pensieve used a single call. The biggest difference was one task where grep needed 12 calls and Pensieve needed 1.
- Tokens dropped less than calls. That’s expected: each Pensieve search returns snippets that still go into context, so you save round trips, but each one carries more content.
The agent used Pensieve search in all 80 runs and still fell back to grep 14 times. That’s the instruction block working as designed: search by meaning first, then confirm with grep.
Our 11 percent cost savings matches the author’s figures. He measured between 6 and 15 percent on repos of 500 to 2,400 files, and his biggest savings, 28 percent, on a monorepo of 35,000 files. On a large repo, expect more. The full 160-run test cost us $4.62.
How it compares to the author’s figures. The author published his own results, measured with version 0.5.6 on four repos (504 to 34,847 files) and 144 runs:
- tool calls per search: 1.97 instead of 3.44
- tokens: 16 percent less
- cost per search: 18 percent lower
- time per search: 21 percent faster
- right file: 131 out of 144 runs, versus 123 with grep alone
These are self-reported figures and unreplicated; that’s why we did our own.
Costs are what Claude Code reports at API list prices. They depend on how “warm” the prompt cache is, so compare them only within the same batch, never across articles.
Where does grep still win?
On exact strings. The author’s search-only test (Pensieve versus a single grep, no agent) puts the right file first in these percentages:
| Query type | Pensieve | Grep |
|---|---|---|
| Exact error strings | 88% | 92% |
| Function and class names | 94% | 54% |
| Natural language descriptions | 58% | 0% |
On OpenSEO, Pensieve search alone (no agent) put the right file first for 96 percent of 25 name queries, 81 percent of 16 exact text queries, and 65 percent of 40 descriptions. Our test didn’t include a grep-only comparison, so the author’s table remains the reference for grep’s advantage on error strings.
The idea, then, isn’t to eliminate grep. The instruction block that Pensieve installs tells the agent to search by meaning first and use grep for exact names or to confirm.
Do results change by repo?
Yes, especially by size. Grep gets more expensive as the repo grows, while an index search costs about the same at any scale. That’s why the author saw savings of 6 to 15 percent on medium repos and 28 percent on a 35,000-file monorepo, and why our 1,000-file TypeScript repo landed at 11 percent. Three other factors move the number:
- How “grepable” your code is. On OpenSEO, grep already found most files in two calls, so there wasn’t much to cut.
- File size. Small
.tsxcomponents make each read cheap, which is why tokens dropped less than calls. - What you ask. Exact error strings favor grep; behavior descriptions favor Pensieve.
Also keep in mind that the benchmark measures search only, not a full session: a real session also spends tokens editing, testing and reasoning. The scripts come in the repo for exactly that reason: the figure that counts is yours.
How do you install Pensieve?
The fastest way is a single command (or paste it into your agent and let it run):
curl -fsSL https://tedhaley.ca/pensieve/install.sh | sh
On a Mac with Apple Silicon, this downloads the app and installs the pensieve backend. You don’t need git, Xcode command-line tools or Python. If you’d rather not run a downloaded script directly in your shell, install the backend by hand:
uv tool install git+https://github.com/TedHaley/pensieve
Then choose what to index. Pensieve doesn’t index anything until you finish initial setup:
pensieve setup # lists agent sessions, folders and repos found, with their sizes
pensieve setup recommended # indexes the ones marked with [x]
To index just a specific repo, name it: pensieve setup repos//Users/me/code/app (the absolute path goes after repos/).
What to expect on first use (current as of October 12, 2026, version 0.6.3):
- A large download. Downloads an embedding model of around 1.2 GB.
- Heavy first indexing. Progresses at about 500 code files per minute on Apple Silicon, so a 35,000-file repo takes just over an hour. Plug in the charger.
- A Gatekeeper warning. The app isn’t notarized yet, so macOS may block it the first time. Go to System Settings → Privacy and Security → Open Anyway.
- A setup command that may not take effect. In our test on October 12, 2026,
pensieve setup repos//…didn’t add the repo to the queue. Adding it from Settings → Sources → add repo did work.
How do you add Pensieve as an MCP server in Claude Code, Codex or Cursor?
A single command connects all the agents it finds on your Mac:
pensieve integrate recommended
It detects Claude Code, Codex, Cursor, Gemini CLI, Qwen Code, Windsurf, Claude Desktop and VS Code, and registers Pensieve as an MCP server on each. On Claude Code, it also adds:
- the “search before grepping” block at
~/.claude/CLAUDE.md - the
pensieve-searchskill - two hooks:
- a
PostToolUseone, so new edits can be searched right away - a
SessionStartone, which asks once if you want to index an unknown repo
- a
Don’t skip the instruction block. Without it, agents keep grepping out of habit even if they have Pensieve connected, and our benchmark ran with it on.
If you’d rather add the MCP server to Claude Code by hand, with claude mcp add:
claude mcp add --scope user pensieve -- pensieve mcp
Scopes. By default, each agent is limited to the repo it started in, plus its worktrees and previous sessions. It doesn’t see the rest of your code. For agents that only accept a JSON config over stdio, here’s it:
{"mcpServers": {"pensieve": {"command": "pensieve", "args": ["mcp"]}}}
Restart any agent you already have open so it loads the server.
If you’re interested in cutting tokens in Claude Code other ways, we cover how to do it with hooks, and here how to see token usage in Codex CLI.
Is it free and does anything leave your Mac?
Price: it’s free and open source, under MIT license.
What stays local: indexing and search run on your Mac, and the local server only responds to your machine. Files that look secret never get indexed (.env, keys, credentials, password manager exports). You can turn off any source, and doing so deletes what it had indexed.
What goes out:
- the model download
- an update check on GitHub, which you can turn off
- optional AI summaries, only if you choose Claude Code or Codex to write them. They’re marked as Cloud. The built-in Qwen 3.5 9B or LM Studio keep everything local.
A note for teams. The default sources include ~/Documents, ~/Desktop and ~/Downloads. You choose what gets indexed during setup, so on a work machine, choose wisely.
Does it work on Windows or Linux?
Partially. At version 0.6.3:
- Mac with Apple Silicon (macOS 14 or later): full desktop app.
- Linux and Mac with Intel: the installer sets up the backend from source with uv, so MCP search and the browser map work. The search panel is macOS only, though a Mac with Intel also gets it if it has Xcode command-line tools installed.
- Windows: at time of publication, the documentation doesn’t mention it.
How do you repeat the test on your own repo?
The benchmark scripts come in the repo, so you don’t have to take our word or the author’s. These are exactly the commands we ran:
git clone https://github.com/TedHaley/pensieve && cd pensieve && git checkout v0.6.3
uv run python bench/agent_search.py gen --repo ~/code/myrepo -n 40 --tasks tasks-v2.jsonl
uv run python bench/exact_tasks.py
uv run python bench/agent_search.py find --repo ~/code/myrepo --tasks tasks-v2.jsonl --split all --styles query,desc,mixed,ident,literal
uv run python bench/agent_search.py run --repo ~/code/myrepo --tasks tasks-v2.jsonl --split all --reps 2 --arms grep,guided
uv run python bench/agent_search.py report --repo ~/code/myrepo --tasks tasks-v2.jsonl
Each run has a $1 cap and the run command picks up where it left off if interrupted. If you use Claude Code with a subscription instead of pay-as-you-go, runs count against your usage limits. If you’re looking for other tools that trim what your agent reads, code-review-graph applies the same idea to code review.
And you? How many tool calls does your agent make before finding the file it’s looking for?
- Grep and file reading, nothing else
- A search index or MCP server
- I point out the files by hand
- Some other way (tell us what)
Comment below or, if this article reached you by email, reply directly to the email: your reply gets published here.
Related: How to reduce tokens in Claude Code with hooks and Spotify Portal