A self-hosted, self-improving agent framework. mantl combines three patterns into one always-on system:
- A compiled knowledge wiki (Karpathy's LLM Wiki pattern) — immutable sources in
wiki/raw/, LLM-maintained pages inwiki/compiled/, browsable as an Obsidian vault. - A decoupled agent runtime (Anthropic's Managed Agents pattern) — brain, hands, and session as independent, replaceable components. The brain is model-agnostic; the default is Claude Code invoked headlessly.
- An eval-driven self-improvement loop (Karpathy's AutoResearch pattern) — the agent improves its own harness files, one atomic change at a time, measured by binary eval assertions. Git commits for wins, git reverts for losses.
The wiki accumulates knowledge. The agent acts on it. The improvement loop refines the agent. Each feeds back into the others.
Discord (human) → Session (SQLite event log) → Brain (claude -p) → Hands (execute) → back to Discord
│
AutoResearch: hypothesis → guard → eval → keep/revert
Prerequisites: Node.js 20+, Claude Code with a subscription that covers headless claude -p calls, a Discord bot token. See docs/quickstart.md for the full walkthrough.
git clone https://github.com/AAARRRCCC/mantl.git && cd mantl
npm install
cp .env.example .env # fill in DISCORD_BOT_TOKEN, DISCORD_CHANNEL_ID
npm run build
npm startThen talk to the bot in your configured channel.
| Command | What it does |
|---|---|
!autoresearch [<suite>] <N> |
Run N AutoResearch iterations on an eval suite (default wiki-schema) |
!autoresearch list |
Show eval suites discovered in autoresearch/evals/ |
!autoresearch resume |
Resume the most recently interrupted run's remaining iterations |
!ingest [<source>|all] |
Ingest un-ingested raw sources into the wiki (no arg: list them) |
!query <question> |
Query the wiki: cited answer, substantial ones filed as synthesis pages |
!lint [deep] |
Wiki health check; deep adds a brain pass for contradictions/stale claims |
!clip <url>... |
Clip web pages into wiki/raw/ with Clipper-compatible frontmatter |
!intake [path] |
Normalize firecrawl output (default .firecrawl/) into wiki/raw/ |
!status |
AutoResearch run status / resumable interrupted runs |
Anything else is a conversation: the daemon assembles context from the session log and wiki schema, invokes the brain, and replies.
Secrets live in .env; everything else aims to live in config/ (in progress — see issue #11).
| Variable | Default | Purpose |
|---|---|---|
DISCORD_BOT_TOKEN |
— | Bot token (required) |
DISCORD_CHANNEL_ID |
— | Channel the bot listens on (required) |
BRAIN_MODEL / BRAIN_EFFORT |
opus / max |
Hypothesis & conversation brain |
EVAL_MODEL / EVAL_EFFORT |
sonnet / max |
AutoResearch eval brain |
EVAL_TRIALS |
5 |
Ingest-eval trials per source (majority vote) |
EVAL_CONCURRENCY |
5 |
Max concurrent eval brain invocations |
PANGRAM_API_KEY |
— | Only for the pangram-rewrite eval suite |
core/ daemon, session (SQLite), brain (claude -p), hands, discord bot, clip, intake
wiki/ CLAUDE.md schema + raw/ sources + compiled/ pages (the Obsidian vault)
autoresearch/ eval suites: eval.json + program.md (+ results.tsv per run)
config/ user-specific configuration (framework vs config separation)
data/ runtime SQLite database (gitignored)
Orientation for agents working on this repo lives in CLAUDE.md. The full architecture spec is mantl-architecture.md; the design vision is mantl-project-bootstrap.md.
The conversational brain can route work to execution hands by emitting <dispatch hand="name">…</dispatch> blocks; the daemon executes them, records tool_call/tool_result session events, and re-invokes the brain with the results (bounded agentic loop). This is per-hand opt-in — set dispatch: true in config/hands.yaml — and ships off, since enabling it lets conversation execute shell commands on your machine.
- Model-agnostic brain — the brain interface encodes no Claude Code specifics; it could be backed by API calls or a local model.
- Framework vs config separation — someone else clones, configures, runs.
- Minimal code, maximal configuration — the value is in the patterns and the CLAUDE.md / program.md files, not framework code.
- Evals over vibes — harness improvements are measured with binary assertions, not felt.
- Harness assumptions go stale — every component encodes an assumption about what the model can't do; question those on each model upgrade.
MIT — see LICENSE.