leather
releases | changelog | pkg.go.dev | leather.sh | pate.sh
Local agent infrastructure in one stdlib-only Go binary.
Leather runs declarative agents on your workstation, server, or Raspberry Pi: scheduled jobs, one-shot runs, webhook-driven workflows, tool calling, and auditable outputs.
No Python stack. No hosted control plane. No broker, telemetry, or dependency pile.
cat > summarizer.agent.md <<'EOF'
---
name: summarizer
---
You are a concise planning assistant. Output bullet points only.
EOF
leather validate --agent-dir .
leather run summarizer.agent.md
See it run
Seventeen demos in examples/, each one make target away.
cp examples/env.example examples/.env
$EDITOR examples/.env
make example-02
make example-06
Measured, not asserted
Two claims carry this project, each with its evidence one click away:
- The runtime doesn't get in the way. The same code path runs a profiled 100-webhook burst — 500 LLM calls, 965K tokens, five fan-out/fan-in stages — end to end in 190s at 6.5% avg host CPU and no measurable IO pressure. Leather isn't the bottleneck; the model is. → examples/11-high-volume-ci
- The runtime is where the accuracy lives. The same frozen 4B model spans 62.4% → 81.6% on a 250-issue gold corpus depending only on the design around it — a 22-arm × 2-rig ablation with paired per-issue verdicts and a measured noise floor. The floor isn't the bare model; it's a bad harness. → findings in plain language: examples/14-sig-triage · every cell and verdict: matrix / verdicts · raw run archives committed — auditable without a GPU
What it does
| Agents | *.agent.md — Markdown front and a system prompt with 0-N turns and variable support. |
| Tools | Skills, toolsets, MCP server support, and shell-mcp (make build-shell-mcp) for turning shell commands into agent tools. |
| Curings | Bind agents to queues for flexible multi-stage routing. |
| Queues | Filesystem FIFO — configurable depth, backpressure, concurrency, dead-letter routing, and single-use parameterized queues. |
| Workers | Goroutines with hooks into queues. |
| Tannery | Pipelines connecting agents, curings, workers, and artifacts, with fan-in / fan-out routing. |
| DevTools | Stdlib-JS UI with session timeline, event inspector, curing flow diagram, and live SSE. |
| Notifications | Telegram and Signal backends. |
Build one
A complete agent:
---
name: summarizer
---
You are a concise planning assistant. Output bullet points only.
A schedule for it (*.lifecycle.yaml, optional):
agent: summarizer
schedule: "0 9 * * *"
model: llama3
prompt: Summarize the three most important things to do today.
Run it:
leather validate # check everything parses
leather run ~/.leather/agents/summarizer.agent.md # run once
leather serve --pretty --stats # run on schedule
Chaining two agents behind a webhook — one triages, one reviews, an artifact comes out the other end — is the same primitives composed: see the GUIDE.md: two-agent pipeline recipe and examples/06-multi-agent-curing.
Install
From source:
git clone https://github.com/TGPSKI/leather
cd leather
make build && make build-shell-mcp
make install
With go install:
go install github.com/TGPSKI/leather/cmd/leather@latest
go install github.com/TGPSKI/leather/cmd/shell-mcp@latest
Verify the install — no LLM endpoint required:
leather --version # prints version
make example-01 # runs a mock-LLM example end-to-end
Model and endpoint
Every command above needs a model and an LLM endpoint from somewhere. All
three forms set the same values — flag wins over env var, env var wins over
config.yaml:
# flag
leather run agent.md --model llama3 --llm-endpoint http://localhost:11434
# env var
export LEATHER_MODEL=llama3
export LEATHER_LLM_ENDPOINT=http://localhost:11434
# config.yaml
model: llama3
llm_endpoint: http://localhost:11434
leather speaks the OpenAI Chat Completions API, so cloud endpoints work the
same way. The bearer token resolves inline value → pass → env var, in that
order:
export LEATHER_LLM_API_KEY="sk-..."
leather serve --llm-endpoint https://api.openai.com --model gpt-4o-mini
# config.yaml + unix pass
llm_endpoint: https://api.openai.com
model: gpt-4o-mini
llm_api_key:
pass: openai/api-key # `pass show openai/api-key`
env: OPENAI_API_KEY # fallback when pass is empty or unavailable
Go deeper
Pick your path by the question you're asking; each row starts approachable and descends as far as you want to go.
| you want to… | start here | then |
|---|---|---|
| build an agent, pipeline, or tool | docs/GUIDE.md — every file format, plus a recipe for each pattern above | examples/ (17 runnable demos) · docs/CONVENTIONS.md (env-var reference) · docs/TEMPLATES.md |
| check the claims above | examples/14-sig-triage — findings in plain language | matrix / verdicts → experiment design → claim ledger → raw archives |
| see a real deployment | docs/REFERENCE-TANNERY.md — six agents, four queues, running unattended, with measured run records and an honest A/B against a frontier control | the system itself: TGPSKI/catnip/tannery |
| understand the internals | docs/ARCHITECTURE.md — package layout and data flow | docs/modules/ (per-package) · docs/GLOSSARY.md |
| contribute (human or agent) | AGENTS.md — the routing table | .subagents/ domain guides · CHANGELOG.md |
No comments yet
Be the first to share your take.