mcpField
A
AXIOM

AXIOM

本地服务
dragoscv.github.io开发工具02 周前更新

关于 AXIOM

AXIOM 是面向编码 Agent 的事务性写入管控工具,提供 MCP 服务和命令行界面。它通过计划、清单校验、哈希确认的两阶段应用及日志,控制代码库更改。

主要功能

  1. 01计划编译为规范清单
  2. 02写入前执行集合检查
  3. 03哈希门控的两阶段应用
  4. 04变更日志与回滚
  5. 05stdio 和 Streamable HTTP 传输

适用场景

  1. 01在应用前审查多文件代码更改
  2. 02检查代码库变更是否存在冲突
  3. 03追踪或回滚已应用的变更

MCP 相关

AXIOM 以 stdio 或 Streamable HTTP 运行 MCP 服务,向编码 Agent 暴露计划、检查、写入、应用、状态和回滚等工具,并可配置核心或完整工具集。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"dragoscv-axiom": {
"command": "npx",
"args": [
"-y",
"@codai/axiom-mcp"
],
"env": {
"AXIOM_SIGNING_KEY": "<AXIOM_SIGNING_KEY>"
}
}
}
}
启动命令npx -y @codai/axiom-mcp
需要配置的环境变量
AXIOM_SIGNING_KEY密钥Optional Ed25519 private key (base64 PKCS#8 or raw seed) used by axiom_sign; never stored under a root.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@codai/axiom-mcp3.0.0

工具

18

收录的工具列表 · 更新于 2 周前

参数类型必填说明
planobject是Plan 文档(apiVersion axiom.dev/v2、kind Plan)

详细介绍

@codai/axiom-mcp

AXIOM v2 的 MCP 服务(stdio 或 Streamable HTTP)和 CLI——为编码 Agent 提供事务性写入关卡: Plan → 规范化的 ManifestBundle → 集合级检查 → 哈希门控的两阶段 apply → 日志。 dist/cli.js(轻量入口)+ dist/cli-main.js(延迟加载引擎;MCP SDK v2 和 zod 打包在 mcp-lazy / http-lazy 分块中);无运行时依赖。

安装与运行

npx @codai/axiom-mcp mcp --root /abs/path/to/repo          # stdio MCP server
npx @codai/axiom-mcp mcp --root /abs/path/to/repo --http 127.0.0.1:3411   # Streamable HTTP at /mcp
npx @codai/axiom-mcp --help                                # CLI verbs

--root 可以重复指定。每个工具的 root 参数都必须等于其中一个目录,或位于其中一个目录下;恰好指定一个 root 时,它就是默认值。不会回退到环境变量或 cwd(ERR_ROOT_REQUIRED / ERR_ROOT_NOT_ALLOWED)。

协议修订版本 — --wire 2026|2025|2026-only

基于 MCP TypeScript SDK v2(@modelcontextprotocol/server 2.0.0)构建。服务端支持 2026-07-28 修订版(无 initialize,每个请求都带 _meta 信封、server/discover、 列表结果包含 ttlMs/cacheScope),以及 2025 年时期的修订版(initialize 握手、 HTTP 会话),并通过同一入口提供服务——SDK 会将每个 stdio 连接固定到客户端打开连接时使用的时期, 或将每个 HTTP 请求路由到对应时期。--wire 2026(默认值)和 --wire 2025 都支持这两个时期; --wire 2026-only 会拒绝使用 2025 协议打开连接,并返回“不支持的协议版本”错误。使用 SDK v1 的客户端 无需更改。详情:docs/reference/mcp-tools.md。

VS Code — .vscode/mcp.json
{
  "servers": {
    "axiom": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@codai/axiom-mcp", "mcp", "--root", "${workspaceFolder}"]
    }
  }
}
Streamable HTTP — --http <host:port>
axiom mcp --root /abs/repo --http 127.0.0.1:3411            # loopback, no token needed
axiom mcp --root /abs/repo --http 0                          # random port; URL logged at info level
AXIOM_HTTP_TOKEN=$(openssl rand -hex 32) axiom mcp --root /abs/repo --http 0.0.0.0:3411 --log-level info
  • 端点:POST /mcp(2026-07-28 请求以无状态方式提供服务;2025 initialize 会打开一个 会话并返回 Mcp-Session-Id,之后每个 2025 请求都必须携带该 ID)、GET /mcp (独立 SSE 流,每个 2025 会话一个)、DELETE /mcp(关闭会话)、GET /health → { ok, name, version }(无需身份验证)。其他请求均返回 404 JSON。
  • 默认绑定到环回地址。 除非环境变量(由 --http-token-env <NAME> 指定,默认 AXIOM_HTTP_TOKEN)中存在 Bearer 令牌(长度 ≥ 16 个字符),否则非环回主机无法启动。客户端发送 Authorization: Bearer <token>;令牌比较采用恒定时间算法。环回地址上无需令牌。
  • 对环回绑定启用 DNS 重绑定防护(Host 必须为 <host>:<port>、localhost:<port> 或 127.0.0.1:<port>;否则返回 403)。超过 4 MiB 的请求正文返回 413。
  • 闲置 30 分钟的 2025 会话会被逐出;每个会话(以及每个 2026 请求)都通过同一个工厂创建独立的 服务端实例(roots、发现的子 roots 和防护设置共享)。传输层位于 dist/http-lazy.js,仅在使用 --http 时加载,并基于原生 node:http——运行时不依赖 express/hono。
  • VS Code:{ "type": "http", "url": "http://127.0.0.1:3411/mcp" };设置令牌时添加 "headers": { "Authorization": "Bearer ${input:axiom-token}" }。

符合性测试:packages/conformance 会在 CI 中使用预期失败基线(packages/conformance/baseline.yml) 通过此传输运行 @modelcontextprotocol/conformance server。

Claude Desktop — claude_desktop_config.json
{
  "mcpServers": {
    "axiom": { "command": "npx", "args": ["-y", "@codai/axiom-mcp", "mcp", "--root", "/abs/path/to/repo"] }
  }
}

工具

工具集(3.0,D-43)

axiom mcp 默认提供核心工具集——Agent 通过关卡写入所需的六个工具:axiom_write、 axiom_status、axiom_rollback、axiom_check、axiom_apply、axiom_apply_dry_run。使用 --tools full 启动服务端,还会公开下方的计划 / 清单 / 任务相关工具(未标记为核心的每一行)。 spec/tools.json 和 spec/codai-tools.json 列出所有工具,并标注 "toolset": "core" | "full"。 库用户传入 createServer(policy, { toolset: "full" }) / serverFactory(policy, { toolset }); parseToolset(value) 会映射标志值(否则返回 ERR_USAGE)。

工具风险输入输出
axiom_plan_validateREAD{ plan }{ ok, planDigest?, errors[] }
axiom_plan_compileACT{ plan, store?: inline|cas, root? }ManifestBundle(指定 root 时,仅写入 <root>/.axiom/ 下的内容——CAS blob 和存储的清单)
axiom_manifest_verifyREAD{ bundle, root? }{ ok, manifestDigest, canonical, signed, missing[], errors[], signatures?: { trustFile, keyids[], findings[], ok, code? } }——仅当 root 包含 .axiom/trust/keys.json 时才返回 signatures;当 ok 为 false 时,code 为 ERR_SIGNATURE_MISSING | ERR_SIGNATURE_INVALID
axiom_check 核心READ{ bundle, profile?, root? }CheckReport(verdict: pass|fail|error,preImage: verified|drifted|unverified)
axiom_check_startREAD{ bundle, profile?, root? }{ taskId, tool, status: "working", pollIntervalMs, ttlMs, elapsedMs }——与 axiom_check 执行相同的评估,并立即作为 任务 返回,因此耗时较长的 guard.external 测试套件(每个 guard 最长 15 分钟)不会受客户端单次调用超时限制(S-406 / D-24)
axiom_task_getREAD{ taskId }任务完成后返回描述符和 result: CheckReport;任务失败或取消后返回描述符和 error: { code, message };ID 未知或已过期时 → ERR_TASK_NOT_FOUND
axiom_task_cancelACT{ taskId }描述符;终止所有正在运行的 guard 进程树,任务以 cancelled 状态结束,并返回 ERR_TASK_CANCELLED(对已结束的任务重复调用不会产生影响)
axiom_plan_beginACT计划头部:{ name, intent, profile?, capabilities?, checks?, counter?, metadata? }{ sessionId, artifacts: 0, bytes: 0, limits: { maxArtifacts, maxBytes }, ttlMs }——为 JSON 大小会超过 4 MiB 调用上限的计划开启 分块计划会话
axiom_plan_addACT{ sessionId, artifacts[] }(每次调用 ≤ 4 MiB)会话描述符;跨块路径重复 → ERR_INVALID_PLAN;超出预算(2000 个工件 / 64 MiB)或会话已封存 → ERR_PLAN_SESSION_STATE
axiom_plan_sealACT{ sessionId, store?: inline|cas, root? }ManifestBundle——使用与 axiom_plan_compile 相同的代码路径编译,因此摘要与一次性编译组装后的计划相同(已通过属性测试);会话随即销毁
axiom_apply_dry_run 核心READ{ bundle, root, profile? }ApplyResult{mode:"dry-run", diff}
axiom_apply 核心SENSITIVE{ bundle, root, profile?, confirmDigest, mode?, branch?, commitMessage?, lockTimeoutMs? (0..600000), keepBackups? (0..1000) }ApplyResult——error.details 在 ERR_CONFLICT 时包含 { otherDigest, paths },在 ERR_LOCKED 时包含 { holder, waitedMs, queuePosition }
axiom_write 核心SENSITIVE{ root, files[]: { path, content?, encoding?: utf8|base64, op?: write|delete, mode? }, intent?, profile?, confirmDigest?, lockTimeoutMs?, keepBackups? }单工具写入(2.5.0):不提供 confirmDigest → status: "preview"(试运行 + 检查、diff、manifestDigest、next;不会触及 .axiom/ 之外的内容);同一组文件 + confirmDigest → 像 axiom_apply 一样原子应用(日志、单步 axiom_rollback)。预览后目标已更改 → ERR_CONFIRM_DIGEST_MISMATCH。多文件或敏感更改优先使用此工具
axiom_rollback 核心SENSITIVE{ root, manifestDigest }{ status:"rolled-back", phase, steps }
axiom_manifest_diffREAD{ a: bundle|"sha256:…", b }{ added[], removed[], changed[] }
axiom_axm_parseREAD{ source }(.axm 文本){ plan?, diagnostics: [{ severity, code, message, range: { start: {line, column}, end } }] }
axiom_roots_listREAD{}{ roots: [{ path, writable, hasGit }] }
axiom_status 核心READ{ root? }{ root, lock: { held, holder?: { pid, host?, digest?, since?, stale }, queue[], intents[] }, interrupted[], corrupt[], lastApplied?, chain: { ok, entries, head, firstBad?, missingJournals } }——与 axiom status --json 相同;从不获取锁
axiom_repo_snapshotREAD{ root?, include?[], exclude?[], maxFiles? (20000, cap 50000), maxBytes? (64 MiB), respectGitignore? (true), withContentDigest? (true) }RepoSnapshot { snapshotDigest, body: { files: [{ path, bytes, sha256?, mode, kind }], truncated, counts } }——已排序,不含时间戳或绝对路径;始终跳过 .git/、.axiom/;记录符号链接,但绝不跟随(docs/guides/snapshot.md)
每个工具都带有 MCP annotations(readOnlyHint、destructiveHint、idempotentHint、openWorldHint)
和一个 outputSchema;structuredContent 是完整结果,content[0].text 是简短摘要(摘要、判定、计数、前 20 条发现)。错误以 isError: true 和 { code, message, path? } 的形式返回,错误代码来自封闭的 ERROR_CODES 枚举——处理程序不会抛出异常。spec/tools.json 由同一注册表生成(pnpm build:spec),并由一致性测试校验。spec/codai-tools.json 使用 codai 的 packages/agent-core/spec/tools-v2.json 条目格式 { name, risk, toolset, description, parameters },同样来自该注册表——参见 docs/integration/codai.md。

资源:axiom://manifest/{sha}、axiom://report/{sha}、axiom://applied/{sha}、 axiom://profile/{name}、axiom://schema/{Plan|Manifest|ManifestBundle|CheckReport|ApplyResult|Profile|Journal|RepoSnapshot}、 axiom://emitters(通过 --emitter <pkg> 加载的模板生成器——默认为空,自 3.0 起如此;在仓库旁安装 @codai/axiom-emitters-web 并传入 --emitter @codai/axiom-emitters-web,参见 docs/guides/emitters.md), axiom://lock(为每个允许列表中的根目录提供 { roots: [{ root, held, holder?, queue[], intents[] }] };只读)。

信任模型

  • 启动时会对根目录执行 realpath 解析;根目录必须是目录,且目录集合会被冻结。请求的根目录也会执行 realpath 解析(Windows 上进行大小写不敏感的包含检查);任何位于根目录之外的路径都会导致硬错误。
  • axiom_apply 要求 confirmDigest === bundle.manifestDigest——回传你在 dry-run 中看到的摘要。 应用前检查会依据配置文件运行(默认是 default,或 <root>/.axiom/profiles/<name>.json); 若判定不是 pass,则会在任何写入发生前以 ERR_CHECKS_FAILED 中止。
  • 超过 4 MiB 的负载会立即被拒绝(ERR_BUNDLE_TOO_LARGE)。
  • 任务和计划会话存放在服务的进程中(由该进程服务的所有连接/请求共享;绝不会写入磁盘)。重启后会丢失; 已完成的任务可轮询 10 分钟,空闲会话在 30 分钟后过期;并发运行的任务最多为 8 个(超出时返回 ERR_EBUSY)。停止 服务会中止所有正在运行的任务,并终止其守护进程树。
  • .axiom/lock 确保每个根目录上同时只有一个写入操作;日志记录机制确保操作可安全应对崩溃并可逆。
  • 标准输出仅承载 JSON-RPC。日志以 JSON 行格式写入标准错误(--log-level error|warn|info|debug,默认 warn)。
  • 除非进程以 --allow-guards 启动,且配置文件设置了 facts.allowGuards: true,否则外部守护程序(guard.external)默认关闭。相对命令必须位于 <root>/scripts/ 下; 绝对命令必须通过 --guard-allowlist <abs> 明确列出(可重复指定)。守护程序通过参数数组启动(绝不使用 shell),使用经过清理的环境变量和墙钟超时,并且必须输出 GuardOutput JSON——参见 docs/guides/checks.md。
  • 签名清单(docs/guides/signing.md):根目录可在 .axiom/trust/keys.json 中固定 Ed25519 公钥;若配置文件设置了 manifest.requireSigned,则会拒绝未签名、遭篡改或 不受信任的捆绑包;若设置了 antiRollback: true,则会拒绝任何 counter ≤ .axiom/trust/state.json#lastCounter。 只有当 status: "applied" 时,axiom_apply 才会更新该状态。私钥绝不会进入服务: 签名通过 axiom sign 配合 AXIOM_SIGNING_KEY 或 --key-file 执行。

CLI

axiom mcp     [--root <abs>]... [--allow-guards] [--guard-allowlist <abs>]... [--log-level warn]
              [--http <host:port>] [--http-token-env AXIOM_HTTP_TOKEN] [--require-human]
axiom init    [--root .] [--harness auto|copilot|claude|codex|vscode|cursor|windsurf|gemini|junie|cline] [--daemon]
              [--profile-name <name>] [--force] [--upgrade] [--managed --out <dir>] [--json]
              (.vscode/mcp.json + Pre/PostToolUse hooks + .axiom/profiles/<name>.json + .axiom/gate-profile.json + .gitignore; idempotent)
axiom doctor  [--root .] [--json]               (exit 0 = no failing check, 2 = at least one fail; warnings exit 0)
axiom stats   [--root .] [--since 7d] [--json]  (gate decisions, p50/p95, per harness; silent-gate alarms)
axiom undo    --session <agent> [--root .] [--dry-run] [--force] [--since <iso>]   (restore one session's writes; exit 1 = conflicts)
axiom import-guard <guard.ps1> [-o profile.json]   (PowerShell guard tables → gate profile "commands")
axiom status  [--root .] [--json]               (lock holder/queue/intents, interrupted journals, last applied, chain)
axiom log     [--root .] [--limit 20] [--json]  (journal chain, newest first)
axiom compile <plan.json|plan.yaml|plan.axm> [-o out.json] [--store cas --root .] [--allow-net [--net-allow host[,host]]] [--allow-file]
axiom verify  <bundle.json> [--root .]          (--root: also verify signatures against .axiom/trust/keys.json)
axiom verify  --journal --root .                (journal hash chain; broken → exit 1 + code ERR_JOURNAL_CHAIN)
axiom verify  <bundle.json> --tree <root> [--pre] [--attest out.intoto.json]   (tree matches manifest? docs/guides/verify-tree.md)
axiom check   <bundle.json> --root . [--profile p] [--json | --format text|json|sarif] [--allow-guards] [--guard-allowlist <abs>]...
axiom apply   <bundle.json> --root . [--dry-run] [--profile p] [--confirm <digest>] [--lock-timeout <ms>] [--keep-backups <n>]
              [--pr [--branch b] [--message m]] [--allow-guards] [--guard-allowlist <abs>]...
axiom rollback <digest> --root .
axiom gc      --root . [--dry-run] [--older-than 30d] [--keep all-manifests|journal] [--undo-ttl 7d]   (CAS garbage collection; CLI only, no MCP tool)
axiom diff    <a.json> <b.json>
axiom schema  <Plan|Manifest|ManifestBundle|CheckReport|ApplyResult|Profile|Journal|RepoSnapshot>
axiom emitters [--json]
axiom keygen  [--out <dir>] [--name <label>]     (ed25519; private key → <dir>/axiom-signing-<id>.key 0600, public entry → stdout)
axiom sign    <bundle.json> [--key-file <path>] [-o out.json] [--root-id <id>]   (key from --key-file or $AXIOM_SIGNING_KEY; --root-id = root-bound envelope)
axiom sign    <bundle.json> --keyless [--bound --root . | --root-id <id>] [-o out.json]
              (Sigstore via ambient OIDC → bundle.keylessSignatures; no OIDC → exit 1 ERR_KEYLESS_UNAVAILABLE)
axiom trust   add <pub.json> --root . | remove <keyid> --root . | list --root . | root-id [<id>|--clear] --root .
axiom gate    --stdin [--post] [--format <harness>] [--root <dir>] [--profile <file>] [--fail-open] [--no-shell-scan] [--no-root-discovery]
              [--track-reads] [--deny-exit 0|2] [--log-level warn]
axiom serve   --hook --root <abs>... [--host 127.0.0.1] [--port 47861] [--token-env <NAME>] [--otel]
axiom migrate v1 <manifest.json> [-o plan.json] [--profile default] [--cas <root>] [--content <dir>] [--overwrite]
                                               (v1 manifest → v2 Plan, lazy chunk; exit 1 = migrated with warnings — docs/guides/migrate.md)
axiom snapshot --root . [-o snap.json] [--include <glob>]... [--exclude <glob>]... [--max-files n] [--max-bytes n] [--no-gitignore] [--no-digest]
axiom snapshot-diff <a.json> <b.json>          (RepoSnapshot → { added, removed, changed })

退出代码:0 成功 · 1 判定失败/应用失败/日志链断裂/无密钥时不可用 · 2 用法或错误 (doctor:2 = 检查失败)。非 mcp 动词会将 JSON 输出到 stdout(init、doctor、status、log、check、emitters:除非指定 --json,否则输出人类可读的行)。

ref 来源({ type: "ref", uri, digest })默认离线:已存在于 <root>/.axiom/cas 中的摘要无需联网即可解析,其他情况均为 ERR_NET_DISABLED。--allow-net 仅获取 https:(不跟随重定向,超时 30 秒,大小上限 32 MiB),可选通过 --net-allow 限制主机(*.example.com 通配符),验证固定的摘要并将 blob 存入 CAS——摘要不匹配时不会存储任何内容(ERR_DIGEST_MISMATCH)。apply 不会获取内容。MCP axiom_plan_compile 工具没有网络开关。请参阅 docs/reference/plan-format.md 和 docs/concepts/cas.md。

Hook 模式 — axiom gate --stdin

适用于 Claude Code、Copilot CLI 和 VS Code Agent Hook 的 PreToolUse hook。它从标准输入读取一个 harness 负载(支持 {tool_name, tool_input, cwd} 和 {toolName, toolArgs, cwd} 两种大小写形式;toolArgs 可以是 JSON 字符串),提取 Write|Edit|MultiEdit|NotebookEdit、create_file|replace_string_in_file|insert_edit_into_file|apply_patch|multi_replace_string_in_file|edit_notebook_file 和通用 write|edit 的写入目标,并扫描 shell 工具(Bash、run_in_terminal 等)中的写入原语(>、>>、tee、rm、mv、cp、sed -i、git checkout|reset|clean、PowerShell Set-Content/Remove-Item 等——这是一种启发式检测,详见 docs/getting-started/hooks.md),仅运行快速谓词:包含性检查 + RelPath 规则(..、CON、NTFS ADS → ERR_CONTAINMENT / ERR_PATH_*)、path.deny、path.allow、content.noSecrets,以及在负载包含新内容时对其执行的 content.maxBytes 检查。失败时默认拒绝(D-18):无法给出答复即拒绝。

结果退出码stdoutstderr
允许 / 非写入、非 shell 工具0——
拒绝0(使用 --deny-exit 2 时为 2)单个对象:hookSpecificOutput{…}(Claude)+ 扁平的 permissionDecision/permissionDecisionReason(Copilot)+ axiom{verdict, code, path, toolClass, standard:"owasp-acs/0.1"}AXIOM GATE DENY <code>: <reason> (<relpath>)
写入工具没有可识别的路径键与拒绝相同拒绝 JSONAXIOM GATE DENY ERR_UNSUPPORTED_OP: …
负载格式错误、标准输入超时(2 s)、内部错误与拒绝相同(失败时默认拒绝)拒绝 JSONAXIOM GATE DENY ERR_INTERNAL: … (fail-closed; pass --fail-open to allow)
同上,使用 --fail-open0—AXIOM GATE WARN: … — failing open (--fail-open)

自 2.4.1 起,拒绝时退出码为 0(D-35):Windows 上的 npm axiom.ps1 shim 会将 2 改写为 1,而 VS Code 会将 1 视为警告。所有能解析 JSON 的 harness 都会遵循退出码为 0 时的文档内容;对于只检查退出码的 harness(Windsurf),请使用 --deny-exit 2。只读工具会在 gate 分块加载前得到响应。若目标位于同一仓库的相邻工作树中(共用相同的 git common dir),则会根据该工作树的根目录和 gate 配置进行判定,而不是返回 ERR_CONTAINMENT。

根目录 = 负载中的 cwd,向上遍历至最近的 .git / 仓库 .axiom/ 祖先目录(绝不会是主目录;--no-root-discovery 可禁用此行为);否则使用 --root,再否则使用进程的 cwd(hook 是唯一允许使用 cwd 的位置:harness 会在项目目录中启动 hook,并负责提供该值)。相对目标路径以 cwd 为基准。 配置 = --profile <file> → <root>/.axiom/gate-profile.json → ~/.axiom/gate-profile.json → 内置配置 { deny: [".git/**", ".axiom/**", "**/*.lock", "pnpm-lock.yaml", ".env", ".env.*", "**/node_modules/**"], noSecrets: true, pii: false }。 Schema:{ deny: string[], allow?: string[], noSecrets: boolean, pii: boolean, maxBytes?: number }(严格)。 pii: true 时还会扫描个人数据(cnp、email、phoneRo、card)——自 S-414 起默认关闭(维护者的电子邮件地址会导致 pyproject.toml 中的真实编辑被拒绝;参见 docs/guides/checks.md)。

gate 是单独的延迟加载分块(dist/gate-lazy.js,不含 MCP SDK):进程内每个负载的 p95 约为 5 ms,端到端耗时约为 150–200 ms(包括 Node 启动时间);check-gate-latency 会将 p95 限制在 ≤ 250 ms。 各 harness 的接入说明见 docs/getting-started/hooks.md。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。