Where agents build agents
An agentic build system for agentic systems. Ontology-grounded, auditable, one Rust binary.
An agentic build system for agentic systems. Ontology-grounded, auditable, one Rust binary.
Every agent framework ships you the same thing: a loop. Call the model, run a tool, feed the result back, until some condition you wrote says stop. You hand-build that harness, and redeploy it when it is wrong.
meclaw doesn't ship you a loop. An llm cell makes one provider call and emits one message. Tools are cells. The loop is an edge that routes back. The harness is topology — and since topology is files, the swarm can rewrite its own harness while it runs.
A colony is a directory. Every folder in it is a cell: an actor with a mailbox, an async task of its own, and a config.json saying which of 15 built-in types it is. Folders that group cells are hives, the edges between them are the routes a message may take, and every hop is typed into the trace. The tree is the topology — ls shows it, git versions it.
A running colony changes through exactly one operation: a mutation, POSTed to /colony/mutations — a diff in a closed vocabulary, validated, applied atomically while everything keeps running, recorded in the mutation ledger. There is no second way, and that single door is what makes "agents rebuild their own harness" auditable instead of terrifying: every change has a record, every record has a requester.
meclaw is the substrate: the tree, the binary, the mutation door. meclaw-os is a small, experimental operating system for agents, grown onto that substrate at runtime — four composition levels (organisation, member, assistant, channel) under one rule: a level owns what its siblings must share. Memory belongs to the person, not the assistant, so replacing a generation does not amnesia the history. An assistant is grown into that OS the same way: a JSON declaration, not a deployment — a new agent is a grow, not a project.
"Ontology" usually announces philosophy or a semantic-web diagram. Here it is narrower and checkable: the colony has a typed vocabulary of what can exist, and building happens against it rather than around it. That vocabulary is the template library — 38 shipped templates, each naming its cells, lanes and parameters.
The builder turns a structural wish — "grow an assistant named scribe under this member" — into a manifest: mutation declarations designed against the catalogue and validated by it, instead of free-form JSON somebody hopes parses. Where a recipe exists it renders deterministically, without a model; where none does, a bounded typed tool loop consults the catalogue, and what the wish does not say comes back as a question rather than a guess. The builder never applies anything — no cell in it has an edge onto the mutation door, and none can be created. Applying is submit's job, against the digest you were shown: a yes is a yes to the bytes you read.
A closed vocabulary would be a cage if it could not grow. add_templates registers a new class into a running colony, and apps are composed words: templates arranged for one task, tagged app, grown under a member. Apps are how the ontology learns new words.
meclaw is prepared for recursive self-improvement — the primitives are here, the loop is not (yet). Both halves carry weight.
The primitives are runtime mutation, the builder, keep-or-revert on a measured window, and a receipt for every act — including the control-loop tick that had nothing to do, because a loop that only writes down its successes is a loop nobody can audit.
The loop that closes them is not — deliberately. No process in this repository observes, decides, mutates and repeats unattended, and every goal the control loop could pursue ships disabled. No blind RSI: a self-improving loop you cannot audit is an incident with a delay on it. Which goals a colony may pursue about itself stays a human decision, and that switch ships off.
A colony is a swarm of highly specialised agents: one async task per cell, and the shipped assistant splits what is usually one prompt into talky, the conversation surface, and cogny, the reasoning core. One job, one brain, one menu — and the menu is asked for rather than typed in, so a new tool is a mutation, not a prompt edit.
Neither carries the conversation. It can run for weeks — not because something clever compacts it, but because the window was never where the conversation was stored. The memory hive is a member's long-term memory as a hive: thirteen cells, not a line of Rust, and a write path that uses no LLM. Retrieval is a fan of five model-free legs — keyword, semantic, graph walk, temporal, the asker's own dossier — each under its own budget, so its cost is bounded per turn rather than proportional to history length, and consolidation supersedes instead of deleting. The window itself is assembled, not accumulated: a collector builds the context for exactly the turn that is running. There is no "context is full" cliff, because nothing accumulates.
The four cell types that start foreign code — bash, code, harness, mcp — run their child under kernel enforcement: Landlock, a fresh network namespace where even loopback is down, cgroup v2, seccomp-bpf. Deny by default, closed key sets (a typo like "netwrok": "deny" is a boot error, not a silently unsandboxed cell), and fail-closed: what this host cannot enforce makes the spawn fail.
Secrets sit in a vault with no read: put, rotate, use, revoke, deliver — and deliver returns a ciphertext sealed to a key that dies with the task that minted it. get is refused the way frobnicate is, as an unknown op. In front of it stands the access broker: an agent may ask in natural language, what travels is a handle, never a credential, and every verdict is a comparison rather than a model.
meclaw is a Linux daemon: it binds a port and speaks HTTP, and who may reach that port is the reverse proxy's job, as for every other Linux service. Design, not omission — meclaw knows no identities, it knows paths.
The llm cell speaks the OpenAI-compatible wire, and the vendor choice is base_url — vLLM, Ollama, LiteLLM, OpenRouter, OpenAI itself. Swapping a frontier model for a local one is editing one line; the topology does not change. Running costs, measured on one production colony with a reproducible method (scripts/cost_report.py, a dated price list, a pinned window): 0.32 EUR per day in conversation — a worked example of the method, not a rate card.
# 1 — install meclaw: one static Linux binary (lands in ~/.local/bin)
curl -fsSL https://meclaw.ai/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
# the templates must match the binary: clone the tag the installer just gave you
git clone --depth 1 --branch "v$(meclaw --version | cut -d' ' -f2)" \
https://github.com/mmeyerlein/meclaw && cd meclaw
# one key — replace sk-... with a real one (https://openrouter.ai/keys), or step 3 ends in code=auth
printf 'OPENROUTER_API_KEY=sk-...\nMODEL_BRAIN=openai/gpt-4o-mini\n' > examples/meclaw-os/seed/.env
# 7777 is an arbitrary free port: if it is taken, change it in every line below as well.
# The very first start reads a 25 MB binary from cold disk and can stay silent for ~40 s; every later start takes well under a second.
meclaw --root examples/meclaw-os/seed --templates ./templates --daemon --api 127.0.0.1:7777
# 2 — install the OS into the running colony: one POST, nothing restarts
curl -s -X POST 127.0.0.1:7777/colony/mutations \
-H 'Content-Type: application/json' -d @examples/meclaw-os/grow.json
# 3 — talk to your assistant
curl -s -X POST 127.0.0.1:7777/messages -H 'Content-Type: application/json' \
-d '{"target": "/door", "headers": {"channel": "chat-1"},
"body": {"messages": [{"origin": "user", "type": "text",
"text": "Say hello in one short sentence."}]}}'
# 4 — read the answer: nothing is hidden, the reply is a hop on the record (needs jq)
curl -s '127.0.0.1:7777/colony/trace?limit=200' | jq -r \
'[.trace[] | select((.headers_json | fromjson | .hop.route) as $r | $r == "answer" or $r == "error")]
| last | if . == null then "no answer yet — the colony is still working; watch it at http://127.0.0.1:7777/ui/"
else .body_payload | fromjson | .messages[0].text end'
# 5 — watch the colony in the browser: http://127.0.0.1:7777/ui/
The last command shows the point: the answer is not a return value, it is a message on the record. Keyless, if you want to poke first: examples/hard-shell.
Linux only — the kernel primitives are the security model, and a macOS port would keep the word "sandboxed" and lose the property. code cells run python3, nothing else. One screen, one app. Voice is roadmap: text ingress works, so your dictation tool just works, but nothing here speaks or listens. No SDK and no plugin API — the interface is HTTP and files. And it is not for unsupervised production yet: v0.29.0 means v0.29.0.
meclaw is not finished, and it is open source so it does not have to be finished alone. Good first contributions: example colonies, template cells, docs drift-fixes. 6500+ tests, 0 fail; release truth is the changelog, the roadmap is public.
The youngest part of the tree is the surface. display is one screen as a channel belonging to a person — several agents hold views on it, none can touch another's — and colony-view is the first app drawing on it. Where that goes next is an idea, not a feature: you talk, it shows. Speech in, sight out. Nothing in the repository does voice today; that story unfolds at voice2vision.eu.
Everything else is a directory you can read.
meclaw is on GitHub under dual MIT / Apache-2.0. Start here: install and grow an assistant.