AXIOM
Transactional write gate for coding agents: plan, canonical manifest, checks, two-phase apply.
Install
Add this to your client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: .cursor/mcp.json; VS Code and others use the same "mcpServers" shape).
@codai/axiom-mcpclaude mcp add axiom -e 'AXIOM_SIGNING_KEY=<your axiom_signing_key>' -- npx -y @codai/axiom-mcp@3.0.0 mcp --root
{
"mcpServers": {
"axiom": {
"command": "npx",
"args": [
"-y",
"@codai/axiom-mcp@3.0.0",
"mcp",
"--root"
],
"env": {
"AXIOM_SIGNING_KEY": "<your axiom_signing_key>"
}
}
}
}
Environment variables
AXIOM_SIGNING_KEYsecret Optional Ed25519 private key (base64 PKCS#8 or raw seed) used by axiom_sign; never stored under a root.
Documentation
From the project's README on GitHub, refreshed weekly. Links open on GitHub.
Contents
Docs · Quickstart · Install · Harnesses · Packages · Changelog · Contributing
AXIOM is the transactional write gate for coding agents. It sits between an agent and your repository: every write and shell command the agent attempts is judged before it runs, and a change set the agent submits is applied as one transaction you can undo byte for byte.
What you get
- A gate in 12 harnesses: Claude Code, Copilot CLI, VS Code, Codex, Cursor, Windsurf, Gemini CLI, Junie, Cline, Kiro, OpenCode and any ACP client. One policy file decides which paths, secrets and shell commands (
git push --force,git reset --hard,rm -rf /, …) are allowed, asked about or denied. - Digest-confirmed apply: a change set is compiled to a canonical manifest;
applyruns only with the digest you inspected, re-checks every file's prior hash at commit (two-phase), and rolls back to the byte-identical tree on any failure. - Session undo:
axiom journal undo --session <id>restores every file one agent session wrote, including allowed writes outside the repository. - A journal you can read: relaxed and recorded decisions go to
.axiom/decisions.jsonl(redacted);axiom explain lastsays which rule decided, from which profile, and how to fix it;axiom reportrenders a static HTML report. - Attestations: DSSE (Ed25519) signatures and in-toto statements (apply, agent decision) that
gh attestation verifycan check.
No telemetry. AXIOM sends nothing anywhere. It reads and writes only the roots you allow
and ~/.axiom/; the only outbound network access is a ref source fetch you opt into with
--allow-net.
Quickstart
npm i -g @codai/axiom-mcp
cd your-repo
axiom setup init # detects the harness, writes the hook + MCP entry + .axiom policy
axiom setup doctor # bin on PATH, hook wired, gate latency, policy valid (exit 2 = a check failed)
setup init writes an enforcing policy: the built-in deny list (.git/**, .env*,
lockfiles, node_modules, …), the house command pack, and four hard codes that no mode or
override can relax: house.forcePush, house.resetHard, house.cleanForce,
house.worktreeRemoveForce. Preview it first with axiom setup init --dry-run.
Now ask the agent to force-push, or to write .env. The harness blocks the call and the agent
is told why (the hook also prints the reason on stderr):
AXIOM GATE DENY house.forcePush: Force-push rewrites remote history, --force-with-lease included; ask the user first.
AXIOM GATE DENY path.deny: path matches a denied glob (.env)
Ask why, at any time:
axiom explain last # decision, rule, profile, the command or path, and FIX: what to do instead
With "undo": true in the gate policy, the gate keeps the pre-image of every file it lets
through, so one session can be rolled back after the fact:
axiom journal undo --session <agent-session-id> --dry-run # what would be restored
axiom journal undo --session <agent-session-id> # restore it; conflicts are skipped and reported
Trying the gate before enforcing it? Set "mode": "warn": denies become warnings the agent
sees (hard codes still deny), and axiom setup stats / axiom setup suggest-profile show what
would have been blocked. Every key: profiles.md.
The full walk-through, including a first transactional apply:
quickstart.
[!WARNING] Hooks need the global bin.
npxtakes seconds to resolve, the harness times the hook out, and every harness fails open on a timeout.
Install
| Channel | How | Notes | |
|---|---|---|---|
| VS Code Marketplace | dragoscv.axiom-axm | "AXIOM": gate status bar, Doctor / Init / Stats / Explain commands, .axm language support | |
| Open VSX | dragoscv/axiom-axm | the same extension for Cursor, VSCodium, Windsurf, Gitpod | |
| npm, global bin | npm i -g @codai/axiom-mcp | bins axiom, axgate, axiom-mcp; Node ≥ 22.14; required for hooks | |
| npm, no install | npx -y @codai/axiom-mcp mcp --root . | MCP server only | |
| Standalone binary | `curl -fsSL https://dragoscv.github.io/axiom/install.sh \ | sh` | linux-x64/arm64, darwin-x64/arm64; no Node |
| Standalone binary | `irm https://dragoscv.github.io/axiom/install.ps1 \ | iex` | win-x64; no Node |
| Homebrew | brew install dragoscv/tap/axiom | the same binary | |
| GitHub Action | uses: dragoscv/axiom/action@v2 | verify a tree against a manifest, upload an attestation | |
| MCP Registry | io.github.dragoscv/axiom | any registry-aware MCP client |
The bin is also installed as axgate. Axiom, Inc. ships an unrelated
CLI named axiom; if it is first on your PATH, call AXIOM as axgate (axgate setup init,
axgate gate --stdin …). Binaries ship with SHA256SUMS and Sigstore provenance, npm packages
with npm provenance: SECURITY.md. Every channel:
install.md.
Harnesses
axiom setup init --harness <name> wires one; auto (the default) detects it from the files in
the repository.
| Harness | --harness |
|---|---|
| Claude Code | claude |
| GitHub Copilot CLI | copilot |
| VS Code (agent mode) | vscode |
| Codex | codex |
| Cursor | cursor |
| Windsurf | windsurf |
| Gemini CLI | gemini |
| Junie | junie |
| Cline | cline |
| Kiro | kiro |
| OpenCode | opencode |
| ACP clients (Zed, …) | none: run the agent through axiom acp-proxy --root . -- <agent> |
Hook files, payload formats, how a deny reaches each agent, and per-harness caveats: harnesses.md.
How it works
flowchart LR
accTitle: AXIOM in front of an agent
accDescr: A tool call from an agent goes through the gate, which allows, asks, warns or denies it. A change set goes through compile, checks and a digest-confirmed two-phase apply that writes the journal and can be rolled back.
A[Agent] -->|tool call| G{gate<br/>policy and rules}
G -->|allow or warn| T[Repository tree]
G -->|ask| H[Human]
G -->|deny and reason| A
A -->|Plan| P[compile<br/>canonical Manifest]
P --> C[checks<br/>whole change set]
C -->|pass| X[apply<br/>confirmDigest and 2PC]
X --> T
X --> J[(journal<br/>decisions and undo)]
J -.->|rollback or undo| T
Policy lives in .axiom/: the gate reads .axiom/axiom.json ({ version: 3, gate, checks, extends }),
and check profiles are built-in or .axiom/profiles/<name>.json.
The gate judges each tool call in milliseconds (a resident daemon answers hooks in a few
milliseconds). The pipeline checks a whole change set ("touch the schema, touch the
migration", dependency budgets, secrets, paths) and applies it atomically. Terms:
glossary. Concepts: pipeline,
trust model, invariants.
Surfaces
- CLI: noun groups (
axiom plan …,axiom journal …,axiom keys …,axiom hook …,axiom setup …, plusexplain,report,pin,mcp,serve,snapshot,gc,schema), generated from one command table;axiom <command> --helpprints that command only. The 2.x verbs (axiom gate,axiom init,axiom apply, …) keep working as hidden aliases until 4.0. Every command: cli.md. - MCP server:
axiom mcp --root <dir>, stdio or Streamable HTTP. 19 tools; the defaultcoreset is the 6 an agent needs to write through AXIOM (axiom_write,axiom_status,axiom_check,axiom_apply_dry_run,axiom_apply,axiom_rollback);--tools fulladds the plan, manifest and task plumbing. mcp-tools.md. - Hook:
axiom gate --stdin --format <harness>, fail-closed, or the resident daemonaxiom hook daemon. hooks.md. - GitHub Action: fail a PR whose tree does not match the manifest an agent applied, and upload an attestation. github-action.md.
- VS Code extension: vscode.md.
Packages
| Package | What |
|---|---|
@codai/axiom-mcp | The published bin: CLI, MCP server, gate hook and daemon, standalone-binary entry |
@codai/axiom-schema | Zod schemas for every wire type, the closed ERROR_CODES, JSON Schemas (published at /schemas/v3/) |
@codai/axiom-canon | JCS (RFC 8785), sha256, in-toto statements, DSSE envelopes |
@codai/axiom-plan | Plan → ManifestBundle compiler: inline, CAS, ref, patch, template sources |
@codai/axiom-checks | 18 predicates (incl. expr.cel, expr.cedar, guard.external), built-in profiles |
@codai/axiom-apply | Containment, two-phase commit, journal, rollback, lock, PR mode, verifyTree |
@codai/axiom-axm | The .axm plan language: parser, formatter, language server (@codai/axiom-axm/lsp, axm-lsp bin) |
@codai/axiom-emitters-web | Optional template emitter, loaded with axiom plan compile --emitter @codai/axiom-emitters-web |
@codai/axiom-axm-lsp | Deprecated re-export of @codai/axiom-axm/lsp, kept through 3.x |
All public packages share one version and release together. schema and canon are leaves;
plan, checks and apply depend only on them; nobody depends on mcp (enforced by
check-package-deps). Design: v2-architecture.md.
Upgrading to 3.0
3.0 keeps 2.x inputs working: axiom.dev/v2 plans parse, old verbs are hidden aliases, and
.axiom/gate-profile.json / .axiom/profiles/*.json are still read.
axiom setup migrate --profile writes the new .axiom/axiom.json. What changed and why:
MIGRATION.md. Release history: CHANGELOG.md.
Decisions and stories: PLAN.md · TRACKER.csv.
Development
pnpm 12 · Node ≥ 22.14 · TypeScript 7 · tsdown · Biome · Vitest 5 · fast-check · Changesets.
pnpm install --frozen-lockfile
pnpm lint # biome check .
pnpm build # before typecheck: exports point at dist/
pnpm typecheck
pnpm test
pnpm guards # node scripts/run-guards.mjs: the repo invariants in scripts/check-*.mjs
All green with the output shown, a .changeset/*.md for any change under packages/*/src,
and the ripple closed. Details: CONTRIBUTING.md and .github/instructions/.
Community
Discussions for questions · Issues for bugs and features · SUPPORT.md · SECURITY.md (private reporting) · CODE_OF_CONDUCT.md · CITATION.cff.
License
MIT © Dragos Catalin Vladulescu.
Frequently asked questions
What is AXIOM?
Transactional write gate for coding agents: plan, canonical manifest, checks, two-phase apply.
How do I install AXIOM?
It runs on your machine. In Claude Code: claude mcp add axiom -e 'AXIOM_SIGNING_KEY=<your axiom_signing_key>' -- npx -y @codai/axiom-mcp@3.0.0 mcp --root. For other clients, paste the JSON configuration from this page into their MCP settings.
Does AXIOM need an API key?
Yes. It expects AXIOM_SIGNING_KEY, which you set in its configuration.
Is AXIOM open source?
Yes. Its code is on GitHub under the MIT license.
Who maintains AXIOM?
It is published by dragoscv. AI.tn lists it but does not maintain or endorse it.
From the official MCP Registry. Listing is not an endorsement: review a server's code and permissions before giving it access to your data.