Skip to main content
ClaudeWave

Token-efficient code reading for AI coding agents: budgeted, symbol-aware, diff-aware reads over MCP. Built for macOS.

MCP ServersOfficial Registry0 stars0 forks● RustMITUpdated today
ClaudeWave Trust Score
87/100
✓ Trusted
Passed
  • ✓Open-source license (MIT)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Flags
  • !Install pipes a remote script into a shell (curl | sh)
Last scanned: 9/27/2026
Install in Claude Code / Claude Desktop
Method: Manual · speedread
Claude Code CLI
git clone https://github.com/brennengreen/speedread
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "speedread": {
      "command": "speedread"
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
💡 Install the binary first: cargo install speedread (or build from https://github.com/brennengreen/speedread).
Use cases

MCP Servers overview

<p align="center"><img src="docs/assets/banner.jpg" alt="speedread: token-efficient code navigation for AI agents" width="100%"></p>

<p align="center">
<a href="https://github.com/brennengreen/speedread/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/brennengreen/speedread/actions/workflows/ci.yml/badge.svg"></a>
<a href="LICENSE"><img alt="MIT" src="https://img.shields.io/badge/license-MIT-6366f1"></a>
<img alt="macOS · Apple Silicon" src="https://img.shields.io/badge/macOS-Apple%20Silicon-22d3ee">
<img alt="MCP server + CLI" src="https://img.shields.io/badge/MCP-server%20%2B%20CLI-6366f1">
<img alt="Rust" src="https://img.shields.io/badge/Rust-1.90%2B-22d3ee">
</p>

# speedread

**Token-efficient code search and navigation for AI coding agents.** speedread is an MCP server and CLI that gives Claude Code, GitHub Copilot, Codex, Cursor, Gemini CLI and other agents the part of a codebase a question needs, within a token budget: the function around each search hit, a large file's skeleton, a symbol's callers and implementations, or only what changed since the last read. Not whole files and bare grep hits.

**`Read` is the wrong abstraction for coding agents.** Agent code reading should be adaptive, stateful, symbol-aware and token-budgeted instead of byte-oriented. Every model call re-sends the system prompt, tool definitions and conversation so far (18–21k tokens before any code, in our evals), so an agent's cost is driven more by round trips than by bytes. ripgrep returns matches and `cat` returns bytes, so the agent asks again: open the file, find the function, search for the next hop. speedread returns *the minimum useful unit of code for the question*, with enough structure that the next call often isn't needed.

| The agent needs | Built-in tools return | speedread returns |
|---|---|---|
| where something is | file names, or bare matching lines | each hit under its enclosing function or class, with its line range (`search`) |
| one function in a large file | the file in 2,000-line pages, or a guessed range | that symbol's full source (`read path#Symbol`), or a skeleton of the file |
| callers, callees, implementations | a search per hop, then more reads | the relationship in one call, up to three levels deep (`trace`) |
| a file again, after an edit | the file again | only what changed, labelled by symbol (`read path@etag`) |

<p align="center"><img src="docs/assets/race.svg" alt="Recorded transcripts replayed: built-in tools need 4 model calls and 86,629 tokens; speedread needs 2 model calls and 43,514 tokens" width="100%"></p>

One of the ten code-question tasks, replayed from its recorded eval transcripts at recorded speed; all three trials of each condition behaved identically. The built-in `grep` answers with a file name, so the agent has to ask again, twice. speedread's `search` answers with the matching lines under their enclosing declaration. This is the second-largest saving of the ten tasks; two tasks came out about 1% worse, and across all ten, input tokens fell 35%. Full interactive report: [brennengreen.github.io/speedread](https://brennengreen.github.io/speedread/) (also self-contained in [`demo/index.html`](demo/index.html)), generated by [`demo/build.py`](demo/build.py) from [`evals/results/`](evals/results/).

## Measured, not hand-waved

Real agents on real repositories, with the same model (claude-sonnet-5) and harness (GitHub Copilot CLI) in both arms: built-in tools vs speedread as the reader. Every trial, transcript, grader and diff is committed, including the workloads where speedread didn't help.

| Workload (real agent, same model and harness) | Trials per arm | Input tokens | Model time (median) | Quality |
|---|---:|---:|---:|---|
| **Code questions**: find, read, answer | 30 | **−35%** (95% CI −45 to −23%) | **−47%** | pass^3 90% → **100%** |
| **Relationship questions**: callers, callees, implementations | 8 | **−57%** (CI −74 to −20%) | −34% (not significant) | 100% → 100% |
| **Bug fixes**: find, edit, run the test suite (with guidance · exclusive) | 16 | −3% · −1% (not significant) | −24% · −27% (not significant) | 100% → 100%; compression never hid the bug |
| **Installed but not made the reader** (Q&A · bug fixes) | 10 · 16 | **+31% · +46%** (higher on 9 of 10 · 8 of 8 tasks) | — | used in **0 of 26** trials |

- **Round trips drive the savings.** speedread saves where it removes model calls: answers with enclosing context, batched reads, `trace` in one hop. On bug fixes, editing and testing dominate the turns, and read results were about 1% of input, so tokens barely moved.
- **Adoption decides everything.** An unused MCP server is not free: its tool definitions ride along on every call (+2.2k tokens per call, measured). Configure it as [the reader](#make-it-the-reader).
- **Scope.** One model in one harness, and the relationship and bug-fix suites are small. Other clients and models are untested; treat these numbers as evidence for this setup, not a promise for yours.

pass^3 is the share of tasks whose three trials all passed. Intervals are 95% bootstrap intervals on the ratio of means ([`evals/stats.py`](evals/stats.py)). Per-suite detail: [Results](#results) · method: [`evals/README.md`](evals/README.md) · every table: [`evals/RESULTS.md`](evals/RESULTS.md) · raw trials and transcripts: [`evals/results/`](evals/results/)

## Quick start

**1. Install** (macOS on Apple Silicon, Rust 1.90+; a clean build took 80 s on an M4, plus downloads):

```sh
cargo install --locked --git https://github.com/brennengreen/speedread
# or: brew install brennengreen/tap/speedread
```

Prebuilt binaries, a one-click Claude Desktop bundle, other platforms, and why the tap name: [Install](#install).

**2. Add it to your agent as the reader, not as one more tool.** Installed alongside the built-in tools with no guidance, it went unused and made runs more expensive ([above](#measured-not-hand-waved)).

```sh
# GitHub Copilot CLI: add the server, then remove the built-in readers (edit and bash stay)
copilot mcp add speedread -- speedread mcp
copilot --excluded-tools view grep glob

# Claude Code: keep Read, because Edit requires it
claude mcp add --scope user speedread -- speedread mcp
claude --disallowedTools Grep Glob
```

VS Code, Cursor, Codex, Gemini CLI, Zed and Claude Desktop: [Configuration](#configuration). Where the built-in tools can't be removed, add the [reading instructions](#make-it-the-reader) to `AGENTS.md`, `CLAUDE.md` or `.github/copilot-instructions.md`.

**3. Or try it by hand** in any repository:

```sh
speedread map --symbols                      # structure, with each file's top-level definitions
speedread search 'handleRequest'             # hits grouped under their enclosing function
speedread trace '#handleRequest' --depth 2   # callers of callers; --direction callees|refs|impls
speedread read 'src/app.ts#Server.start' src/util.ts:40-80   # several targets, one call, one budget
```

## The primitives

Four tools over MCP, mirrored by the CLI:

| Primitive | Job | Returns |
|---|---|---|
| **map** | locate structure | budgeted repo tree with line counts, importance-weighted; top-level symbols on request |
| **search** | locate text | ripgrep's engine; every hit grouped under its enclosing function or class, with line range |
| **trace** | locate relationships | callers, callees, references, implementations: syntactic and receiver-aware |
| **read** | obtain exact evidence | batched targets and `path#Symbol`s under one token budget; `path@etag` returns only what changed |

### `read`: batched, budgeted, symbol-aware

One call takes any mix of targets. They share one token budget (default 8,000).

| Target | Returns |
|---|---|
| `src/app.ts` | The whole file. If it doesn't fit, a **skeleton**: signatures, types and docs, with bodies collapsed as `A-B ⋯`. If that's still too big, an **outline**. Never a blind cut. |
| `src/app.ts:120-180`, `src/app.ts:120` | Those lines; a single line (or `file:line:col` from a compiler error) returns the enclosing function or class. |
| `src/app.ts#handleRequest`, `#Server.start` | That symbol's full source, including docs and decorators. `#Name` alone finds the definition anywhere. |
| `README.md#Install`, `package.json#scripts` | A Markdown section, or a JSON, YAML or TOML key. |
| `src/**/*.test.ts` | A glob (.gitignore-aware); large sets degrade largest-first. |
| `src/app.ts@<etag>` | **Only what changed** since the version whose etag appeared in a header. |

A real skeleton of flask's 1,628-line `app.py` (excerpt) costs 3.4k tokens, against 21k for the file:

```
==> src/flask/app.py @… (1,628 lines) [skeleton]
110	class Flask(App):
111	    """The flask object implements a WSGI application and acts as the central
112-205	    ⋯
366	    def get_send_file_max_age(self, filename: str | None) -> int | None:
367	        """Used by :func:`send_file` to determine the ``max_age`` cache
368-391	        ⋯
```

**Symbol-aware re-reads.** After an edit, `path@etag` returns `unchanged`, the appended tail for a growing log, or a diff that names what changed. Hunks carry git-style function context, and `mode=outline` returns only the symbol summary. From [`tests/mcp.rs`](tests/mcp.rs):

```
==> src/lib.rs @… (was @…): 1 hunk, +1 -1, now 131 lines
symbols:
  add [1-7]: body changed, signature unchanged
@@ -2,5 +2,5 @@ add
 pub fn add(a: i32, b: i32) -> i32 {
     let c = a + b;
-    let d = c;
+    let d = c * 2;
     let e = d;
```

A signature edit reads ``f3 [25-27]: signature changed: `pub fn f3() -> u32` → `pub fn f3(k: u32) -> u32` ``; a new function reads ``g [133-135]: added `pub fn g() -> u8` ``.

**Etags are 64-bit.** An etag is the full 64-bit xxh3 of the content, printed as 16 hex digits, and snapshots of what the agent has seen live in a 256 MB LRU keyed by it. Two *different* contents would have to collide in 64 bits to alias. Across 100,000 snapshots in one session that chance is about 3 × 10⁻¹⁰. Identical conten
ai-agentsclaude-codeclicode-navigationcode-searchcodexcoding-agentscontext-engineeringcopilot-clicursordeveloper-toolsgithub-copilotllm-toolsmacosmcpmcp-servermodel-context-protocolrusttoken-optimizationtree-sitter

What people ask about speedread

What is brennengreen/speedread?

+

brennengreen/speedread is mcp servers for the Claude AI ecosystem. Token-efficient code reading for AI coding agents: budgeted, symbol-aware, diff-aware reads over MCP. Built for macOS. It has 0 GitHub stars and its last recorded update is dated 2026-09-27.

How do I install speedread?

+

You can install speedread by cloning the repository (https://github.com/brennengreen/speedread) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is brennengreen/speedread safe to use?

+

Our security agent has analyzed brennengreen/speedread and assigned a Trust Score of 87/100 (tier: Trusted). See the full breakdown of passed checks and flags on this page.

Who maintains brennengreen/speedread?

+

brennengreen/speedread is maintained by brennengreen. The last recorded GitHub activity is dated 2026-09-27, with 0 open issues.

Are there alternatives to speedread?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy speedread to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: brennengreen/speedread
[![Featured on ClaudeWave](https://claudewave.com/api/badge/brennengreen-speedread)](https://claudewave.com/repo/brennengreen-speedread)
<a href="https://claudewave.com/repo/brennengreen-speedread"><img src="https://claudewave.com/api/badge/brennengreen-speedread" alt="Featured on ClaudeWave: brennengreen/speedread" width="320" height="64" /></a>

More MCP Servers

speedread alternatives