zeno is a code-mode agent runtime. It exposes a single MCP tool, eval, over a
live, long-lived, shared Clojure image. An external agent (for example Claude
Code) connects over MCP and drives orchestration by composing Clojure in one live
session; defs persist across calls and across sessions, so the image is a durable
core that outlives any client.
- Kernel (like Emacs' C core): eval loop, MCP transport, the live SCI image. Impl-free -- it holds no capabilities of its own; it is handed a map of capability bindings and serves eval over them.
- Base layer (
zeno.caps, like Emacs' bundled Elisp): the default capabilities exposed to the image --context,ask,spawn,spawn-all,propose. Concrete backends (which model endpoint, which agent CLI, where proposals go) come from config, never hardcoded. - Workspace
~/.zeno(like~/.emacs.d): PURE DATA -- config, state, proposals. No code, no build. Created and git-initialized on first run.
The binary reads ~/.zeno (override with $ZENO_HOME or --dir), creating it on
first run, and serves the daemon:
nix run # from this repo, or nix run <ref> from anywhere
Dev, without the packaged binary:
nix develop --impure
clojure -M:serve # serves 127.0.0.1:7332, workspace ~/.zeno
--port overrides the port. A stdio transport (clojure -M:mcp) exists for
debugging; the daemon is the real deployment.
The workspace's ~/.zeno/.mcp.json (scaffolded on first run) points Claude Code
at the running daemon over HTTP:
{ "mcpServers": { "zeno": { "type": "http", "url": "http://127.0.0.1:7332/" } } }
Then the eval tool is available and every connection shares the same live image.
Declarative and host-independent: committer identity (:git, a bot), the cheap
model endpoint (:model, any OpenAI-compatible URL -- local Ollama, OpenRouter,
...), the port, and secret refs. The engine only needs a model endpoint to exist;
it does not care where or how models run.