Architecture
System shape, data flows, and conventions for contributors.
ashlr-plugin is a multi-host plugin for Codex and Claude Code that wraps file, search, edit, and shell workflows with lower-token alternatives and adds a lightweight observability layer over tool usage and cost.
Two value propositions
Token efficiency. ashlr__read, ashlr__grep, and ashlr__edit replace the built-in Read, Grep, and Edit tools. Large file reads are snip-compacted or LLM-summarized; grep calls route through a per-project genome index (RAG) when one exists, cutting tokens by ~84% on warm queries; edits send only diffs, not full file contents.
Observability. Every tool call is accounted in ~/.ashlr/stats.json (per-session + lifetime counters) and appended to ~/.ashlr/session-log.jsonl. The status line in Claude Code's UI surfaces savings continuously. The genome scribe loop extracts architectural knowledge from tool results into .ashlrcode/genome/, which feeds back into future grep routing.
MCP server map
The canonical MCP wiring is one router entry. Claude Code uses .claude-plugin/plugin.json; Codex uses .codex-plugin/plugin.json plus .mcp.json. Both launch servers/_router.ts through the bootstrap or ashlr-mcp path, and servers/_router-handlers.ts imports each handler module so its tools register with the shared registry.
The router exposes 40 tools, including ashlr__read, ashlr__grep, ashlr__edit, ashlr__multi_edit, ashlr__bash, ashlr__tree, ashlr__savings, and the genome tools. Run ashlr tools for the current registered list.
Key shared modules
| File | Role |
|---|---|
servers/_stats.ts | Shared read/write for ~/.ashlr/stats.json |
servers/_events.ts | Shared append for ~/.ashlr/session-log.jsonl |
servers/_summarize.ts | LLM summarizer, confidence badge, snip-compact |
servers/_genome-cache.ts | In-process genome retriever cache |
servers/_genome-live.ts | Genome refresh after edits |
servers/_http-helpers.ts | HTML extraction, JSON elision, private-host check |
Adding a new MCP tool
- Add the handler in a focused
servers/*-handlers.tsmodule. - Register the tool through
registerTool. - Import the handler module from
servers/_router-handlers.ts. - Call
recordSavingfromservers/_stats.tsin the tool handler. - Call
logEventfromservers/_events.tsfor session log entries. - Add a test in
__tests__/.
See also
Full architecture doc: docs/architecture.md in the repo root.