Token-efficient file read / grep / glob for AI agents. Never dump more bytes into a model's context than the question needs.
Zero dependencies. Single file core. Ships with a zero-dep MCP server for Claude Code / any MCP client.
An agent asks "what's in app.py?" and gets 65 KB of source dumped into its context. It greps for self. and gets 92 KB of matches. Most of that is never used — but you pay for it on every subsequent turn, because it sits in the context window forever (or until the agent lobotomizes itself compacting).
In a long agent session, cache reads of bloated context are the dominant cost — not the model's answers.
Three operations, each with a cheap default view and explicit escalation:
| call | small result | large result |
|---|---|---|
read(path) |
full file | structural outline — classes/functions with line numbers + preview |
read(path, focus='run') |
— | just that function/class with context |
read(path, lines='40-80') |
— | just that range |
grep(pattern) |
full matches | file: count summary, sorted by hits |
glob(pattern) |
full list | per-directory counts |
raw=true always gets you everything. The point is that everything becomes an explicit choice instead of the default.
| operation | raw bytes | smart-read bytes | cost |
|---|---|---|---|
read('src/flask/app.py') |
65,423 | 453 (outline) | 0.7% |
read(..., focus='run') |
65,423 | 5,933 | 9.1% |
grep('self\\.') |
92,487 (grep -rn) | 938 (summary) | 1.0% |
grep('import ') |
53,671 | 2,794 | 5.2% |
The outline tells the model what's there; it then fetches exactly the function it needs. Two cheap calls instead of one expensive one — and the expensive bytes never enter the context at all.
Agents grep workspaces. Workspaces contain .env files. A raw cat .env puts live tokens verbatim into the agent transcript — and into whatever logs, memory stores, or training pipelines that transcript feeds.
smart-read redacts secret values (key names preserved) before anything reaches the model:
- secret-bearing files:
.env*,*.pem,*.key,credentials*,secrets*,.netrc,.pgpass,id_rsa, ... - secret-named keys anywhere:
*TOKEN*,*SECRET*,*API_KEY*,*PASSWORD*, ... with secret-shaped values - standalone token lines in secret files (PEM bodies, long base64)
$ smart_read('.env')
[secret-safe: redacted secret values; key names preserved]
API_KEY=<redacted:24b>
DEBUG=true
The agent still sees the structure (which keys exist) — it just never sees the values. This came from a real incident: a live Discord bot token leaked into an agent's knowledge graph via a raw grep.
If your files carry a line-1 AX header (# AX: TAG | SUM: one-line | SIG: v1), grep summaries surface it per matched file — so the model knows what a file is without opening it:
[564 matches in 30 files]
src/flask/app.py: 142
...
[AX headers]
src/flask/app.py: # AX: CORE | SUM: Flask application object | SIG: v3
No install. Copy smart_io.py (the core, ~290 lines, stdlib only) or clone the repo.
As a library:
from smart_io import SmartIO
io = SmartIO("/path/to/workspace")
io.read("src/app.py") # outline if large
io.read("src/app.py", focus="main") # one function
io.grep(r"TODO|FIXME") # summary if many
io.glob("**/*.py")As an MCP server (Claude Code, Codex CLI, any MCP client) — .mcp.json:
{
"mcpServers": {
"smart-read": {
"command": "python3",
"args": ["/path/to/smart-read/mcp_server.py", "/path/to/workspace"]
}
}
}Exposes smart_read, smart_grep, smart_glob. Zero dependencies — the server is plain JSON-RPC over stdio.
All paths resolve inside the workspace root (symlink-escape checked). Container↔host path aliases via SMART_IO_ALIASES="/data/app->/opt/app" — each alias target becomes an additional trusted root. Anything outside raises instead of reading.
Extracted from a production multi-agent platform where these three tools replaced raw Read/Grep for ~all exploration, and cache-read discipline turned out to be the single highest-leverage cost behavior. Sibling tools from the same system:
- ax-headers — one-line machine-readable file headers
- raisin — Python LLMs can read at ~50% of the tokens
- hard-compact — compact prompts that don't lobotomize your agent
- full-review — adversarial code review skill
python3 -m pytest tests/ # 16 tests: read tiers, grep summarization, redaction, trust boundary, MCP end-to-end
MIT.