edgar
The agent harness you can read in an afternoon. Any model. No hidden calls. Nothing is done until it's verified.
uvx edgar-harness # interactive
git diff | edgar -p "review this" --mode read-only
edgar -p "bump httpx and fix what breaks" --mode auto --verify "just check"
Status: design complete (spec v0.4). Implementation has started with milestone M0, the package skeleton; nothing runs yet beyond
edgar --version. The documents indocs/are the spec being built against.
Why edgar
- Small enough to read. The core is under 5,000 lines, with a size budget enforced in CI. Fork it and change it without first learning 40,000 lines.
- Any model. OpenAI, Azure, Anthropic, OpenRouter, Ollama, or any OpenAI-compatible server as a config block. API keys, not a vendor's subscription. Works with small local models too.
- No hidden calls. edgar never contacts a host you did not configure, has no telemetry, and its system prompt is a short file you can read and replace.
- Done means verified. A turn that changed something ends when your check passes, not when the model says it is finished.
What it is
edgar runs an LLM in a tool-using loop, in the directory you launched it from, against OpenAI, Azure, Anthropic, OpenRouter, Ollama or any OpenAI-compatible server. It has permissions, a verify-before-done gate, context compression, custom tools for CLIs and APIs, skills, subagents, memory, MCP and extensions.
It ships in three tiers, each with a size budget:
| Tier | What you get | Size |
|---|---|---|
| Core (0.x) | The loop, five providers, built-in and custom tools, skills, permissions, verify gate, staged compaction, sessions, REPL and pipes | ≤ 5,000 lines |
| v1.0 | Memory, MCP, subagents, routing and fallback, extensions and hooks, an embedding API. Extension formats frozen | ≤ 8,000 lines |
| v2.0 | Learning from what you type and what breaks, skill synthesis, a controller, scheduling | ≤ 11,000 lines |
None of that is unusual. What is unusual is that the whole thing is small enough to read in an afternoon, and the parts usually hidden behind an SDK are written out plainly: how tool calls differ between providers, how compaction avoids corrupting a transcript, how a permission decision is actually made.
It is a teaching artifact first and a usable tool second. Where those two goals conflict, teaching wins. That trade is why some things are simpler than they could be (SQLite FTS instead of embeddings) and some are stricter than they need to be (a 150 ms startup budget enforced in CI).
Why it exists
Agent harnesses come in two sizes. Toys that teach you nothing beyond a while
loop and a function call, and production systems whose complexity buries the
interesting parts. There is a gap in the middle: a harness that implements the
genuinely hard bits honestly, at a size a person can hold in their head.
What it does
Terminal-native. Interactive REPL for daily use, -p for one-shot and pipes.
Result on stdout, status on stderr, real exit codes. Composes with the rest of
your shell.
Five providers, two adapters, any compatible server. OpenAI, Azure, OpenRouter and Ollama share one OpenAI-compatible adapter driven by a quirks table; Anthropic has its own. Any other OpenAI-compatible server is a config block. Anything else is one module and one registry entry, or a provider plugin package.
Subagents with their own models. Declared in markdown, not code. Run a cheap local model for exploration and an expensive one for review, in parallel, each with its own tool allowlist and budget.
Model routing that isn't magic. Declarative rules pick the model before the turn, as a pure function with zero model calls. Escalation and fallback are kept separate from routing and from each other, because "not capable enough" and "not reachable" want different responses. Every switch is announced.
Extend it without Python. Give the agent a CLI with a command tool (an argv
template, never a shell) or an API with an HTTP tool (a request template with the
host fixed and secrets from the environment). Add MCP servers, skills in Claude's
SKILL.md format, subagents in markdown, and hooks that can veto a tool call.
Bundle any of it into an extension folder and share it by copying.
Long sessions that stay valid. Context is compressed in stages, cheapest first: big outputs spill to disk, old tool results become stubs, old turns fold into one summary. It never splits a tool call from its result, and the full record stays on disk.
Memory that stays trustworthy. Hand-authored instructions and machine-learned facts live in separate places, on purpose. Only what you type, or an error the harness classified itself, becomes a fact. When the model wants to remember something, it asks you first. Tool output and web pages never reach memory.
Safe to point at a repo you just cloned. Project hooks, MCP servers and tools
run only after you trust the project. The agent cannot edit its own config without
asking, and auto mode tightens after it reads untrusted content.
A controller that cannot hurt you (v2). Deterministic checks after each turn; a cheap model runs only when one trips. It returns typed proposals from a fixed whitelist, dry-run by default, fully logged, and it can only ever tighten policy. It cannot write your instruction files — it proposes a diff and you apply it.
Scheduling without a daemon (v2). One tick command plus one host cron entry.
Agents can schedule themselves, with guardrails.
Easy to build on. -p --json for one result, -p --events for the live event
stream as JSON Lines, and edgar.run() from Python. No daemon, no HTTP API.
What it deliberately is not
No MCP server mode. No daemon or HTTP API. No vector store. No multi-user. No GUI. No race to support fifty providers. The full list with reasoning is in PRD §5.2, written down so scope creep has something to argue with.
Documentation
| PRD | What it does and why, numbered requirements |
| Blueprint | Architecture, module map, data model, interfaces |
| ADRs | Decisions, with the alternatives that were rejected |
| Decisions | The v0.3 and v0.4 revisions in one page: tiers, context, memory, extensions, security, ports |
| Field review | What 11,647 Hacker News comments say about agent harnesses |
| Roadmap | Seventeen milestones in three tiers, each one shippable |
| Testing | How you test something nondeterministic |
| Brainstorm | The original design conversation |
| AGENTS.md | Instructions for AI agents working on the code |
Reading the source
Once it exists, in this order:
core/message.pyandcore/units.py— the vocabulary and the invariantcore/loop.py— the whole thing in 200 linestools/base.pyandtools/execute.py— the contract and its pipelinepermissions/policy.py— one pure functioncontext/compact.py— where the subtlety istools/custom.py— command and HTTP toolsproviders/routing.py— the same shape as permissions, deciding models instead of access
Licence
AGPL-3.0-or-later. Use it, fork it and change it freely. If you distribute a modified edgar, or run one as a service for others, you share your changes under the same licence. The reasoning is in ADR-0026.
Release files for edgar-harness 0.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| edgar_harness-0.0.1.tar.gz | 21.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| edgar_harness-0.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.0 kB
Release files / edgar_harness-0.0.1.tar.gz
| Download URL | edgar_harness-0.0.1.tar.gz |
|---|---|
| Size | 21.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6b8fb02a2fc2fd45d4692c5fc27585b351464c20af761fb29e33c29a7caef21c
|
|
BLAKE2b-256 checksum How to use checksums |
003fe26082fcd742f3153f25ede7b79841d8f969dca70cc6759a63b83e6a1b08
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency logRelease files / edgar_harness-0.0.1-py3-none-any.whl
| Download URL | edgar_harness-0.0.1-py3-none-any.whl |
|---|---|
| Size | 19.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f950b54b052707ec38b66fb9604d058de611b5443d51009c7ae892917174d300
|
|
BLAKE2b-256 checksum How to use checksums |
31fd81463cafdc75054755e2c59ecab16e14e6a4e3bbc4412fecc1e44d500e53
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency log