Axe: single-purpose LLM agents as TOML files and Unix commands
A lightweight cli for running single-purpose AI agents. Define focused agents in TOML, trigger them from anywhere; pipes, git hooks, cron, or the terminal.
At a glance
- What is it?
- Axe is a Go CLI that runs one narrowly scoped LLM agent per TOML file and composes with pipes, cron and git hooks instead of hosting a chat session. The design is disciplined; the cost is that every bit of scheduling, state and orchestration is yours to build.
- Who is it for?
- Adopt Axe if you already have a place to trigger commands (a git hook, a cron entry, a Makefile) and you want each LLM call to be a versioned TOML file rather than a prompt pasted into a chat window. Skip it if you need a scheduler, a web UI, or multi-step pipelines with conditional branching, because the README states plainly that Axe is the executor and not the scheduler.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Axe picks, and who it is aimed at
Most LLM tooling is built around a conversation. You open a session, the context window fills with everything you have ever discussed, and the model answers whatever you ask next. Axe starts from the opposite assumption. Its README argues that good software is small, focused and composable, and that agents should be treated the way Unix treats programs: each one does a single job and communicates over stdin and stdout. The unit of work is an agent defined in a TOML file, and the interface is a command. That framing decides the audience. If your workflow already has a trigger point (a pre-commit hook, a cron line, a CI step, a shell pipeline) and you want an LLM to sit at that point and do exactly one thing, Axe is shaped for you. If you want an assistant you talk to across a long session, it is not, and the README says so directly by contrasting itself with the chatbot model. The pitch is narrower than most agent frameworks and that is the point.
What an agent file actually contains
Each agent has its own system prompt, model selection, skill files, context files, working directory, persistent memory, and the ability to delegate to sub-agents. That list is the whole configuration surface in miniature. Skills are reusable instruction sets stored separately from the agent definition, so several agents can share one SKILL.md instead of duplicating the same instructions. Context files are loaded alongside the prompt. The working directory scopes the built-in file tools (read, write, edit, list), which the README describes as sandboxed to that directory. Memory is timestamped markdown that carries context between runs, and there is a garbage collection path that uses the LLM itself to analyse patterns and trim old entries. Sub-agent delegation happens through LLM tool use, with depth limiting and parallel execution, so an agent can call another agent without recursing without bound. The examples directory ships a code reviewer, a commit message generator and a text summarizer, each with its own focused SKILL.md, which is the fastest way to see how the pieces fit before writing your own.
Providers, tools and the allowlist that constrains them
Axe talks to Anthropic, OpenAI, Ollama for local models, OpenCode, and AWS Bedrock. The README states that all LLM calls use the standard library and that the project has four direct dependencies: cobra, toml, mcp-go-sdk and x/net. That is an unusually small dependency surface for a tool in this category, and it matters if you are the person who has to audit what ships in your binary. Built-in tools cover file operations, shell command execution, URL fetching and web search. The interesting constraint is the output allowlist: url_fetch and web_search can be restricted to specific hostnames, and private or reserved IP addresses are always blocked as SSRF protection. That second half is not optional, which is the right default. MCP support lets you attach external tool servers over SSE or streamable-HTTP transport, so the built-in set is a floor rather than a ceiling. Token budgets cap cumulative usage per run, either through a [budget] section in the agent config or the --max-tokens flag. Retry behaviour is configurable with exponential, linear or fixed backoff for transient provider errors such as 429, 5xx and timeouts. None of this replaces thinking about cost, but it gives you a hard stop and a retry policy in the config file rather than in your head.
Getting an agent from scaffold to first run
The README gives a short path. Run axe config init to create the directory structure under $XDG_CONFIG_HOME/axe/ with a sample skill and a default config.toml for provider credentials. Then axe agents init my-agent to scaffold a new agent, axe agents edit my-agent to open it, and axe run my-agent to execute it. Piping is the part that makes the Unix framing concrete: git diff --cached | axe run pr-reviewer, or cat error.log | axe run log-analyzer. Local agent directories are discovered from <cwd>/axe/agents/ before the global config, and --agents-dir points somewhere else entirely, which is how you keep a project's agents next to the project. axe config path prints the config location, and the examples setup uses it to copy an agent TOML and its skills into place before exporting ANTHROPIC_API_KEY and piping a diff through axe run code-reviewer. The Docker path mirrors this: mount a config directory at /home/axe/.config/axe, pass the API key as an environment variable, and add -i when piping stdin. Without a config volume mounted, the README says axe exits with code 2 because no agent TOML files exist. You can also mount a single agent TOML and its skill to the expected XDG paths, and use --skill to override the skill declared in the TOML, in which case the declared skill is ignored entirely. If the agent declares sub_agents, every referenced TOML and its skills must be mounted too. Memory persists across runs only when a data volume is mounted at /home/axe/.local/share/axe. Dry-run mode inspects the resolved context without calling the LLM, which is the cheapest way to check that the right files and skills are being assembled. JSON output adds metadata for scripting.
Where the executor-only design starts to hurt
The README is explicit that Axe is the executor, not the scheduler, and that it composes with cron, git hooks, pipes and file watchers rather than reinventing scheduling or workflow orchestration. Take that seriously, because it defines the failure mode. Anything with conditional branching, retries across steps, or a dependency graph between agents has to be expressed in the shell, the CI config, or whatever runner you already own. Axe will not help you there and does not pretend to. The same goes for state: memory is markdown logs, which is readable and diffable but is not a database, and the garbage collection step is LLM-assisted, meaning trimming decisions are probabilistic rather than deterministic. If you need reproducible context assembly, that is a design tension worth testing early. Provider credentials live in config.toml or environment variables, and the Docker instructions note that no config.toml is needed when keys are passed through the environment, so secrets handling is your problem, not the tool's. The Go 1.25+ requirement is also a real gate: the README warns that go install fails with invalid go version on older toolchains, and points at pre-built binaries as the workaround. Finally, the built-in shell execution tool is powerful by definition, and the sandbox described in the README covers file operations, not the shell. If you run agents against untrusted input, that is the boundary to examine first.
How it differs from a general agent framework
The closest comparison is a general-purpose agent framework such as LangChain, where you assemble chains, tools and memory inside a Python or JavaScript application and the orchestration logic lives in your code. Axe inverts that. The agent is a declarative TOML file, the runtime is a compiled Go binary, and the integration point is the process boundary rather than an SDK import. That means you cannot call an Axe agent as a library function inside a larger program, but you also do not ship a Python runtime or pin a framework version to run one prompt. A second comparison is a workflow orchestrator like n8n or Temporal, which own scheduling, retries and state transitions. Axe deliberately does none of that, so the two are complementary rather than competing: Axe is the thing a workflow step shells out to. A third is a plain shell script wrapping a provider's HTTP API. Axe adds the parts you would otherwise rebuild: skill and context file loading, memory logs, sub-agent delegation with depth limits, an output allowlist with SSRF blocking, token budgets and configurable backoff. If your script is twenty lines and does one call, the wrapper may not earn its place. If it is growing those features one at a time, Axe already has them.
Maintenance, releases and licence
The repository is not archived, the default branch is master, and the most recent releases listed are v1.10.0, v1.9.0 and v1.8.0, with the latest push after the most recent release. The cadence visible in that list is roughly weekly to biweekly across April and May, which suggests active development, though a release list is not a support commitment and the material here does not describe a deprecation policy or a compatibility guarantee between minor versions. Treat agent TOML files as you would any other config that a fast-moving tool reads: keep them in version control so a schema change is visible as a diff. The licence is Apache-2.0, which permits commercial and private use and includes an explicit patent grant, with the usual obligations around retaining notices and stating changes. That is a permissive licence, but it is not legal advice, and if you redistribute a modified binary or embed Axe in a product, read the licence text and your own counsel's guidance rather than this paragraph. The dependency list is short enough that a licence audit of the transitive tree should be quick: cobra, toml, mcp-go-sdk and x/net are named as the four direct dependencies.
Who should pick it up, and what to check first
Axe fits teams that already have a trigger surface and want each LLM invocation to be a reviewable file. The git hook case is the clearest: pipe git diff --cached into a reviewer agent and the prompt, model and skill are all in the repository where a colleague can comment on them. The cron and CI cases follow the same shape. It fits less well when the work is exploratory, when a human needs to steer mid-task, or when several agents must run in a defined order with branching. For that, keep the orchestration in your existing runner and let Axe be one step inside it. Before adopting, verify three things against your own setup. First, run the agent with dry-run to see the resolved context and confirm the skill, context files and working directory are what you expect. Second, confirm your provider path works end to end, whether that is config.toml, an environment variable, or a local Ollama instance through the included docker-compose.yml. Third, decide deliberately whether the agent needs the shell execution tool at all, since that is the capability the file sandbox does not cover. If all three check out, the TOML file is the artifact you maintain; if any of them is unclear, the tool is doing less for you than the README implies.
Editorial conclusion
Adopt Axe if you already have a place to trigger commands (a git hook, a cron entry, a Makefile) and you want each LLM call to be a versioned TOML file rather than a prompt pasted into a chat window. Skip it if you need a scheduler, a web UI, or multi-step pipelines with conditional branching, because the README states plainly that Axe is the executor and not the scheduler. Before committing, run axe run --dry-run on one agent to see the resolved context, confirm your provider credentials work through config.toml or the environment variable, and check whether the agent's working directory and output allowlist are tight enough for the files and URLs it will touch.
Community notes