内容
#+title: anvil.el — 高效的MCP工具包,适用于AI智能体
#+author: zawatton
*语言:* 简体中文 / [[file:README.ja.org][日语]]
#+begin_quote
*语言说明:* 我是一名非英语母语者。本README的措辞是在LLM的帮助下形成的,但思考和设计决策完全是我自己的。LLM扮演的是翻译员/编辑,而不是作者。如果某些内容读起来很别扭,请带着这种理解去阅读。
#+end_quote
#+html: <a href="https://github.com/zawatton/anvil.el/actions"><img src="https://img.shields.io/github/actions/workflow/status/zawatton/anvil.el/ci.yml?branch=master&style=flat-square" alt="CI"></a>
#+html: <a href="https://github.com/sponsors/zawatton"><img src="https://img.shields.io/badge/Sponsor_%E2%9D%A4_Support_this_project-pink?style=for-the-badge" alt="Sponsor"></a>
* 快速了解
anvil.el 是为AI智能体提供的工作台。可选模块(内存/编排/会话/HTTP/…)在启用时各自添加自己的工具。
Claude Code、Codex CLI、Claude Desktop、GPT、通过Ollama的本地LLM — 任何支持 [[https://modelcontextprotocol.io/][模型上下文协议(MCP)]] 的AI,都可以通过Emacs原生操作(如编辑文件、导航org-mode、运行elisp、查询SQLite等)而不是通用的`sed` / `grep` / `read-whole-file`往返操作。
v1.0(2026-04)发布了第一个稳定版本,以及一个Rust运行时,使您无需安装Emacs即可运行anvil。 2026-05更新添加了AI增强层:
工具注意力用于缩小工具清单,跨AI内存/工作日志桥接,安全的自动研究循环,以及Claude Code监视器。
[[file:STORY.org][STORY.org]] ([[file:STORY.ja.org][日语]]) 讲述了更长的“为什么存在”故事。
* 为什么能节省令牌?
LLM智能体按令牌付费。幼稚的`读取文件 → 编辑文件`循环会将整个文件两次发送到网络上。Anvil的原生操作作用于区域、标题、缓冲区状态 — 只有差异会被传输。
| 场景 | 减少比例 | 发生了什么 |
|---------------------------------------------------------+-----------|----------------------------------------|
| 在大文件中插入/删除一行 | *~90%+* | 无需整个文件读取+写入 |
| 对同一文件进行3次以上编辑 | *~70%* | 一次往返 + 原子写入 |
| 向JSON/配置文件字典中添加N个键值对 | *~73%* | 国际化、功能标志等 |
| 批量向TS/JS ={ ja: "..." }=数据添加翻译 | *~78%* | 映射JSON发送一次 |
| 从大文件中提取重复的结构化记录 | *~50%* | 传统迁移、ETL |
| 跨多个文件进行批量文档字符串更改 | *~60-80%* | 所有文件一次性调用 |
数字是实测的;案例研究在 [[https://github.com/zawatton/anvil.el#efficiency--why-anvil-saves-ai-tokens][效率部分]] 中。一次典型的重构会话可节省 *15,000-25,000* 个令牌。
* 架构
#+begin_example
┌──────────────────────────┐
│ Claude Code / Codex CLI │
│ (任何支持MCP的AI) │
└────────────┬─────────────┘
│ MCP / stdio JSON-RPC
┌────────────▼─────────────┐
│ anvil.el │ ← Emacs原生操作
│ ┌──────┬──────┬──────┐ │ 暴露为MCP工具
│ │ 文件 │ org │ elisp│ │
│ └──────┴──────┴──────┘ │
└────┬─────────────────┬───┘
│ │
┌────────▼─────────┐ ┌─────▼──────────────┐
│ 运行中的Emacs │ │ NeLisp(Rust) │
│ 守护进程 │ │ 无Emacs运行时 │
│ (默认路径) │ │ (--no-emacs标志) │
└──────────────────┘ └────────────────────┘
#+end_example
AI客户端通过MCP与anvil.el通信。anvil.el分派到正在运行的Emacs守护进程(默认 — 完整功能集)或NeLisp Rust运行时(--no-emacs路径 — 较小的表面,无需Emacs安装)。
* 组件
anvil项目分为四个仓库,以便每个部分保持较小且有自己的发布节奏:
| 仓库 | 角色 | 是否必需? |
|------+------+-----------|
| [[https://github.com/zawatton/anvil.el][anvil.el]] | AI核心 — MCP服务器,默认约40种工具(每个可选模块添加自己的工具) | 是 |
| [[https://github.com/zawatton/anvil-ide.el][anvil-ide.el]] | 人类IDE层 — treesit导航、仪表板、信息查找 | 可选,Emacs用户 |
| [[https://github.com/zawatton/anvil-pkg][anvil-pkg]] | Nix支持的包管理器 — 允许AI安装自己的依赖项 | 可选 |
| [[https://github.com/zawatton/nelisp][NeLisp]] | Rust运行时 — 无Emacs运行Elisp | 可选, `--no-emacs`路径 |
* 安装
根据您的需求选择路径。
** 路径A — 无需安装Emacs(NeLisp Rust运行时)
适用于希望在没有Emacs守护进程的情况下使用MCP工具的用户 — CI运行器、短暂容器,或“I不使用Emacs,但希望减少Claude Code / Codex CLI的令牌使用。”
#+begin_src bash
# 1. 克隆NeLisp + 构建Rust运行时
git clone https://github.com/zawatton/nelisp.git
cd nelisp/nelisp-runtime
cargo build --release
cd ../..
# 2. 克隆anvil.el(提供运行时加载的Elisp源代码)
git clone https://github.com/zawatton/anvil.el.git
# 3. 运行MCP服务器(无需启动Emacs守护进程)
ANVIL_EL_DIR="$(pwd)/anvil.el" \
./nelisp/bin/anvil mcp serve --no-emacs
#+end_src
Rust二进制文件直接读取和评估Elisp;无需调用Emacs C核心。当前通过此路径提供的表面:`file-*` / `shell-*` / `data-*` / `anvil-host-*` / `directory-list`(42种工具)。
** 路径B — Emacs集成(推荐Emacs用户)
适用于日常Emacs用户。通过您喜欢的包管理器固定到v1.2.0。
*** 快速安装(一条命令)
#+begin_src bash
# Linux / macOS
curl -fsSL https://raw.githubusercontent.com/zawatton/anvil.el/master/install.sh | bash
#+end_src
#+begin_src powershell
```
# Windows
iwr -useb https://raw.githubusercontent.com/zawatton/anvil.el/master/install.ps1 | iex
#+end_src
安装程序会自动安装Emacs(=apt= / =dnf= / =brew= / =winget=),克隆仓库,启动守护进程,将MCP桥接器放入=~/.emacs.d/=,并在=~/.claude.json=中注册服务器。如果Emacs已经安装,可以添加=--skip-emacs=(或在Windows上使用=-SkipEmacs=)。
*** 手动通过Emacs软件包管理器安装
#+begin_src emacs-lisp
;; 异步安装器
(async-installer-git-add "https://github.com/zawatton/anvil.el.git"
:tag "v1.2.0"
:main "anvil.el")
;; 或者 straight.el
(straight-use-package
'(anvil :type git :host github :repo "zawatton/anvil.el"
:branch "v1.2.0"))
;; 或者 elpaca
(elpaca (anvil :host github :repo "zawatton/anvil.el"
:ref "v1.2.0"))
#+end_src
安装后:
#+begin_src emacs-lisp
(require 'anvil)
(anvil-enable)
(anvil-server-start)
#+end_src
** 路径 C — anvil-pkg Nix 支持的 AI 工具(可选)
允许 AI 安装自己的系统依赖项(=ripgrep=,=fd=,语言服务器,Nixpkgs 中的任何内容)通过一个 Lisp 形式。需要在主机上安装 Nix。
#+begin_src emacs-lisp
(async-installer-git-add "https://github.com/zawatton/anvil-pkg.git"
:main "anvil-pkg.el")
(require 'anvil-pkg)
(require 'anvil-pkg-dsl) ; 用于 `pkg-define' 宏
(anvil-pkg-enable) ; 注册 pkg-* MCP 工具
#+end_src
现在,代理可以调用 =(pkg-install "ripgrep")= 或使用 =(pkg-define ...)= 定义自定义构建。仓库:[[https://github.com/zawatton/anvil-pkg][zawatton/anvil-pkg]]。
** 路径 D — anvil-ide.el 用于 Emacs IDE 层(可选)
添加人类侧的 IDE 功能(treesit 导航,工作仪表盘,=info-lookup-symbol=)。
#+begin_src emacs-lisp
(async-installer-git-add "https://github.com/zawatton/anvil-ide.el.git"
:main "anvil-ide.el")
(require 'anvil-ide)
#+end_src
仓库:[[https://github.com/zawatton/anvil-ide.el][zawatton/anvil-ide.el]]。
* 快速入门
通过路径 B 安装后:
1. 启动守护进程 — ~M-x anvil-enable~ 然后 ~M-x anvil-server-start~
2. 打印 MCP 配置片段 — ~M-x anvil-describe-setup~
3. 将片段粘贴到 =~/.claude.json=(或客户端的 MCP 配置文件中)
4. 重启 AI 客户端;您应该在工具列表中看到 =anvil-*= 工具
完整的演练包括 Claude Code / Claude Desktop 配置:
[[file:docs/QUICKSTART.org][docs/QUICKSTART.org]]。
* 为什么选择 anvil?
- *与 LLM 无关* — 与任何 MCP 兼容的客户端一起工作
- *高效使用令牌* — 原语操作在区域、标题、缓冲区状态上,而不是整个文件
- *多代理协调* — 将一个提示分发给五个 AI CLI 并行,具有共识和元 LLM 评判,全部在 Emacs 中
- *设计安全* — 长期任务分派到后台 Emacs,因此交互式 Emacs 永远不会被阻塞
- *Org 模式原生* — 一流的 Org 读取 / 写入 / 重构
- *大文件安全* — 处理 1.2 MB+ 文件而不会截断
- *跨平台* — Linux,macOS,Windows,WSL
- *模块化* — 只加载需要的模块,并使用自己的模块扩展
* 对于非 Emacs 用户 — 您需要什么样的设置成本
Anvil 在后台作为 MCP 服务器运行。您日常的编辑器(VSCode / Cursor / Neovim / Claude Code / Codex CLI 本身)不会改变。
#+begin_example
AI 客户端 ──MCP──▶ Anvil(Emacs 守护进程,无头) ──▶ 文件操作
(VSCode / Cursor / (仅差异交叉)
Claude Code / Codex CLI 等)
#+end_example
您不需要打开 Emacs 窗口或编写 =init.el=。
*诚实的成本:*
- *首次设置 15-30 分钟* 在路径 B 上(安装 Emacs,克隆 anvil,连接 MCP)— 或在路径 A 上为零(根本不需要 Emacs)
- *驻留内存* — 路径 B 在 ~50-200 MB 空闲时保留 Emacs 守护进程;路径 A 的 Rust 运行时保持在 ~50 MB 以下
- *多一个依赖项需要维护* — Emacs 更新和 OS 迁移包括它(仅限路径 B)
对于每月几次的 30+ 分钟代理会话,一次性设置几乎立即通过上述令牌节省回报。
* 功能亮点
Anvil 的默认安装公开了 *~40 个 MCP 工具*(=anvil.el= 核心模块)。每个可选模块都添加了自己的工具 — anvil-memory ~22,anvil-orchestrator ~23,anvil-http ~9,anvil-defs ~7,anvil-session ~6 等。挑选您实际需要的工具;您不需要加载所有内容(=anvil.el= 核心 + [[https://github.com/zawatton/anvil-ide.el][anvil-ide.el]] 分割 + [[https://github.com/zawatton/anvil-pkg][anvil-pkg]] 姐妹包)。亮点:
| 能力 | 它能做什么 |
| --- | --- |
| =bin/anvil mcp serve --no-emacs= (v1.0) | *独立路径 — 不需要安装 Emacs。* =anvil-runtime= Rust 二进制文件读取并评估 Elisp,并通过 stdio 提供 anvil 的 MCP 工具。现有 Emacs 用户保持 =bin/anvil mcp serve= 不变 |
| =anvil-pkg= (v1.0) | Elisp-DSL 包管理器,由 Nix 存储支持。 =(pkg-install "ripgrep")= 用于 nixpkgs 属性; =(pkg-define …)= 宏用于自定义构建(=stdenv= / =rust= / =python= / =go= / =emacs-package= 构建系统)。与 Guix 在 Scheme 中的理念相同 — 但在 Elisp 中,与 anvil 的 MCP 接口集成,以便 AI 代理可以通过一个 Lisp 形式安装自己的依赖项。位于 [[https://github.com/zawatton/anvil-pkg][zawatton/anvil-pkg]] |
| =anvil-ide.el= 分割(v1.0) | Emacs 独有的 IDE 层(treesit 导航,=worker-ui= 仪表盘,=info-lookup-symbol=)移出到 [[https://github.com/zawatton/anvil-ide.el][zawatton/anvil-ide.el]]。安装两者以获取原始功能集;仅安装 =anvil.el= 如果您想要 AI 端的工作台而无需人类 IDE 界面 |
| Treesit 子进程回退(v1.0) | 文档 38 阶段 F + G — =anvil-ts= / =-js= / =-py= 结构操作在没有 Emacs tree-sitter 的主机上保持工作(例如 NeLisp 独立),通过 Python =ast= / acorn 子进程回退。令牌高效的 AST 查询在 Rust 基板上保留 |
| =anvil-orchestrator= | 将一个提示分发给最多五个 AI CLI(=claude= / =aider= / =gemini= / =ollama= / =codex=)并行。 Jaccard 共识 + 元 LLM 评判 + DAG 依赖 + =anvil-cron= 集成用于夜间 PDCA 环路 |
| =anvil-memory= (v0.4.0 + 2026-05) | 具有贝叶斯 TTL 和 FTS5 全文搜索的自动内存引擎。扫描多提供商 =.md= 内存,支持基于 DB 的 =memory-add= / =memory-get= / =memory-export-md=,WHISPER 会话增量,矛盾扫描,静态 HTML 导出和仅查看内存收获。设计用于每个机器的 SQLite 数据库加上文本导出,而不是二进制数据库合并 |
| =anvil-memory-bridge= (2026-05) | =anvil-memory= 和 =anvil-worklog= 前面的本地 JSON 桥。添加读写内存端点,事件流,读取副本拉取,工作日志搜索/列出/获取端点,配置来源的 CORS,一个用于 Claude.ai / ChatGPT / Gemini 的侧载浏览器扩展和一个具有离线保存队列的静态移动客户端 |
| =anvil-autoresearch= (2026-05) | 安全的自我改进原语:扫描本地 Web/X/YouTube/设计笔记以查找实现候选,排名较弱的 MCP 文档字符串,提出/收获/应用描述,在评估+停留门后路由提供商映射实验,通过编排器路由,搭建 NeLisp 47 阶段代码生成任务,并在表格列表仪表盘中查看进度 |
| =anvil-tools-by-intent= + =anvil-manifest= (v0.4.0 + 2026-05) | 基于意图的工具发现 + =ANVIL_PROFILE= 过滤器。 2026-05 更新添加了工具注意力:基于查询的动态排名,可选的嵌入后端,状态先决条件,模式修剪,温暖 LRU 完整模式保留,恢复建议和 Doc43 桥接,用于文档字符串重写候选 |
| =anvil-worklog= (2026-05) | SQLite 支持的 AI 工作日志索引。旧的 Org 日志可以扫描,新的条目通过 =worklog-add= 基于 DB,桥接端点暴露只读搜索/列表/获取给其他 AI 客户端。数据库句柄在文件替换/取消链接事件后自我恢复,并为 =worklog-add= 使用短写入事务 |
| =anvil-claude-watchdog= (2026-05) | 用于 Claude Code TUI 挂起的 Linux procfs/jsonl 监视器。检测 State=R 停滞和 State=S 旋转器/MCP-子 IO 变体,记录事件,通知桌面,并通过 =claude --resume= 在 tmux 中暂存提供手动恢复 |
| =anvil-sexp= / =sexp-cst= / =py= / =ts= / =js= (v0.4.0) | 语言感知结构编辑。基于读取器的 Elisp 编辑,Python / TypeScript / TSX / JavaScript 的 tree-sitter CST — 无需触摸整个文件的 AST 级重构 |
| =anvil-session= + Claude Code 钩子(v0.4.0) | 会话快照/恢复 + 5 个生命周期钩子(PreCompact / SessionStart / PostToolUse / UserPromptSubmit / SessionEnd)。捕获具有 14 天 TTL 的分支 + 任务摘要,以便会话重启不会重新冷启动 |
| =anvil-shell-filter= (v0.4.0) | Shell 输出压缩 — 20 个捆绑过滤器用于 git / rg / pytest / ert-batch / docker-logs 等。原始输出保留以便调用者需要时仍可恢复完整文本 |
| =file-batch= | 在一次往返中将多个编辑应用于同一文件(最高可达 ~90% 令牌减少) |
| =org-read-outline= / =org-read-headline= | 读取只是标题或单个子树,即使在 13,000 行的 Org 文件上。无需读取整个文件 |
| =anvil-worker= | 将长期任务(OCR,PDF 转换,批量文件扫描)分派到单独的后台 Emacs。交互式 Emacs 永远不会冻结 |
| 大型 Org 文件编辑 | 编辑 1.2 MB 或更大的 Org 文件而不会截断(避免 Windows 文件挂载问题) |
| LLM 客户端不可知 | Claude Code / Codex CLI / Claude Desktop / GPT / 通过 Ollama 的本地 LLM — 所有通过 MCP 通信 |
| =anvil-modes-allow-buffer-modify= | 配置主要模式,其中 Anvil 工具直接修改实时缓冲区,而不是访问文件,保留未保存的更改。 |
有关数值证据和详细案例研究,请参见 [[https://github.com/zawatton/anvil.el#efficiency--why-anvil-saves-ai-tokens][效率 — 为什么 Anvil 为 AI 节省令牌]]。
有关完整模块列表,请参见 [[https://github.com/zawatton/anvil.el#modules][模块]]。
* 架构 α — NeLisp 委托激活
多个 anvil 模块现在在可用时将它们的内核助手委托给 NeLisp(=fboundp= 保护 + 独立使用的回退)。截至 2026-04-25 架构 α 的已移植模块:
- =anvil-http= — 25 个助手(~467 LOC)委托给 =nelisp-http=
- =anvil-state= — 5 个纯助手委托给 =nelisp-state=
- =anvil-defs= — SQLite Elisp 索引委托给 =nelisp-defs-index=(文档 25)
- =anvil-org-index= — 2 个函数委托给 =nelisp-org-index=(文档 26)
总共 ≈ 37 个助手 / ~573 LOC 委托。行为在 NeLisp 消失时保持不变(测试覆盖两种路径)。
* 效率 — 为什么 Anvil 为 AI 节省令牌
LLM 代理按令牌支付,每个读写往返都会产生费用。Anvil 的工具旨在让代理的上下文预算保持自由,以便推理,而不是记账。
** 调度器测量(v0.3.0,2026-04-19)
来自 [[file:benchmarks/][=benchmarks/=]] 的第一个可发布数字 — 一个生产守护进程在 Debian 13 上,n=1 每单元格,场景 S1(通过 =claude-haiku-4-5= / =codex-gpt-5.4= / =ollama-llama3.2:3b= 递归斐波那契)。使用已检查的测试框架重现。
| 条件 | 墙上时间 | 费用 |
| --- | --- | --- |
| 独立 =claude-haiku= | 14.2 秒 | $0.030 |
| 3× =claude-haiku= 并行 | 15.1 秒 | $0.087 |
| 3 路共识(claude + codex + ollama) | 12.5 秒 | $0.029 |
| 3 路共识 + 元 LLM 评判 | 34.6 秒 | $0.041 |
三个并行的 Claude 任务在 *1.07×* 单任务时间完成 — 调度器的池以接近零的开销并发分派它们。具有共识的三提供商分发比单独的 Claude 快 *又快又便宜*:codex(ChatGPT Plus OAuth)和 ollama(本地)调用没有每令牌成本,而池重叠了最慢的。
Codex 在 Plus 上扩展到 *八个并发* 请求而没有 429 个,吞吐量斜坡(级别 1 / 3 / 6 / 8 @ 5.5 秒 / 6.6 秒 / 9.8 秒 / 6.8 秒墙上时间)与此 CSV 相同。完整的处理方法和注意事项在
[[file:benchmarks/results/report-2026-04-19.org][benchmarks/results/report-2026-04-19.org]]。
** 清单配置文件 — 会话提示的清单成本(v0.4.0)
文档 26 =anvil-manifest= 允许每个客户端在虚拟服务器 ID(=emacs-eval-ultra= / =-nav= / =-core= / =-agent= / =-edit=)下连接,该 ID 过滤 =tools/list= 响应。处理程序保持活动 — 隐藏的工具仍然可以通过显式 =tools/call= 调用,但 Claude Code 在会话开始时解析的清单前奏缩小:
| 配置文件 | 广告工具 | 近似令牌 | 用例 |
| --- | --- | --- | --- |
| =full= | 198 | ~20,400 | 所有功能 |
| =core= | 54 | ~5,800 | 每天编码,无记忆引擎 |
| =lean= | 59 | ~6,620 | 内存引擎关闭 |
| =nav= | 28 | ~3,100 | 只读探索 |
| =ultra= | 17 | ~2,740 | 快速工具 + =ts_extended= 延迟加载 |
| =agent= (v0.4.0) | ≈60(意图过滤) | ~6,500 | 调度器 / 会话 / 内存 / 编辑 |
| =edit= (v0.4.0) | ≈40(意图过滤) | ~4,200 | 纯文件 / Org / 代码 / JSON 编辑器 |
| =dynamic= (2026-05) | 顶部 K + 暖 LRU | 查询相关 | 工具注意力 + 模式修剪 |
在任何时候通过 =manifest-cost= MCP 工具(返回 ={:profile :advertised-count :registered-count :approx-tokens}=)测量您自己的配置文件成本。
2026-05 更新将其扩展为工具注意力层。设置 =ANVIL_PROFILE=dynamic= 和可选的 =ANVIL_ATTENTION_QUERY= 以根据当前意图对工具进行排名;不满足 =ANVIL_STATE_TAGS= 的工具将被过滤。启用模式修剪后,仅顶部 K 关注的工具、清单自我工具和最近的暖 LRU 工具保留完整的模式;其余工具宣传紧凑的名称/类型模式。=manifest-recovery-suggest= 解释为什么工具被隐藏或不关注,而 =manifest-docstring-candidates= 向 Doc43 自动研究提供薄弱的描述。
*调度器子会话*(文档 26 阶段 1b,文档 34 阶段 B 中扩展)自动注入 =--mcp-config= 指向 =emacs-eval-PROFILE= 当设置 =anvil-orchestrator-manifest-profile= 时。典型的好处:一个 20 个提供商的共识运行,带有 200 个总子会话的 =full= 在 *87%* 清单上花费 ~4M 令牌;相同的运行在 =ultra= 上花费 ~550k — **在清单上减少 ~87%**,在代理说出一个词之前。
** 操作于区域而非整个文件
通用文件工具强制执行“读取-然后-编辑”的模式,该模式会发送整个文件每次。Anvil 公开了有针对性的操作,只发送增量:
| 任务 | 常规流程 | Anvil 流程 |
| --- | --- | --- |
| 在 1.2 MB 的 Org 文件中替换一个字符串 | 读取 1.2 MB → 编辑(发送旧值 + 新值) | =anvil-file-replace-string=(仅模式 + 替换) |
| 从 30k 行的 =init.org= 读取一个标题 | 读取和分页 | =anvil-org-read-headline=(仅子树) |
| 插入到大文件的末尾 | 读取整个文件 → 重写 | =anvil-file-insert-at-line=(仅增量) |
对于 Org 模式的重构,MCP 支持的操作(章节移动,重新归档,拆分)比其读取 + 写入等价操作 *便宜 10-20 倍*。
** 将批量编辑合并为一次往返
当代理对同一文件进行多次编辑时,每个编辑都会成为具有自己的请求/模式/响应开销的单独工具调用。=anvil-file-batch= 在单个事务中应用一系列编辑 — *高达 ~90% 的令牌减少*,而不是一次发出编辑。
** 网络获取缓存(anvil-http + anvil-browser)
=anvil-http-get= 和 =anvil-browser= 配备了基于 URL + 身份验证预设的进程内 TTL 缓存。测量
[[file:benchmarks/results/http-browser-report-2026-04-19.org][=http-browser-report-2026-04-19.org=]]:
在默认 TTL 内,*第二次及后续获取成本为 0–2 毫秒墙上时间和零字节网络传输* — 响应属性的 =:from-cache= 为 =t=。在会话期间获取相同文档页面/ GitHub PR/维基百科文章两次的代理仅需支付一次。
=anvil-browser= 返回可访问性树快照而不是原始 HTML,这缩小了渲染页面的有效载荷。测量四个 URL:
| 网址 | HTTP 字节 | 浏览器字节 | 减少 |
| --- | ---: | ---: | ---: |
| =en.wikipedia.org/wiki/Emacs= | 276,082 | 25,122 | *11.0×* |
| =news.ycombinator.com/= | 35,098 | 13,597 | *2.6×* |
| =example.com/= | 528 | 73 | *7.2×* |
原始文本端点(例如 =raw.githubusercontent.com/…/README=)退化为占位符快照;使用 =anvil-http-get= 而不是浏览器。对于这些,字节数更小意味着提示更小,当代理引用获取内容回 LLM 时。
** 繁重工作在带外运行
缓慢操作(大型缠结,完整树扫描,字节编译)被调度到工作守护进程池中,因此代理的主要连接保持响应。
测量影响:~1 MB 的 =init.org= *30 秒* 进程内运行,但 *2 秒* 分派工作后 — *~15× 更快* 完成端到端,代理的主要会话从未被阻塞。
** 支持大型 Org 数据库
Anvil 可以高效地处理大型 Org 数据库。
* 支持的平台
Anvil 可以在多个平台上运行,包括 Linux、macOS、Windows 和 WSL。
3. 部分
### 简单方法存在的问题
遍历临时缓冲区处理 org 文件,当文件大小超过 ~50 KB 时,MCP 请求超时。Anvil 的 org 工具使用流式正则表达式扫描器,因此在多兆字节的 org 树中,标题查找和大纲读取速度仍然很快(例如:`init.org` 或日记文件)。
### 独立运行时 - 无Emacs 守护进程启动成本(v1.0)
NeLisp 文档 44 附带 `bin/anvil mcp serve --no-emacs=`,它会启动 Anvil Rust 二进制文件,而不是 Emacs 守护进程。对于短暂的 MCP 会话(CI 运行、一次性代理调度、短暂容器),这完全跳过了 Emacs 守护进程的冷启动,并保持驻留进程比完全加载的 Emacs 守护进程小得多。
### 架构
α 架构(`anvil-http` / `anvil-state` / `anvil-defs` / `anvil-org-index` 将其核心帮助程序委托给 NeLisp,通过 `fboundp` 保护 + 回退)使得相同的 MCP 工具表面可以从任一基质访问:
| 部署方式 | 工具表面 |
|---------------+--------------------------------------------------|
| 捆绑 Emacs | 完整的 `anvil.el` + `anvil-ide.el` |
| 仅限 Rust | 完整的 `anvil.el`(通过子进程回退的 IDE) |
现有 Emacs 用户继续使用 `bin/anvil mcp serve=`。容器 / 短暂运行器 / “我只想要 AI 工作台,而不想要学习 Emacs” 的用户可以通过 Rust 路径获得相同的 MCP 工具,无需 `apt install emacs=` 步骤。
### 案例研究:在大规模 TypeScript 重构
Anvil 不仅仅是理论,它也不仅限于 org-mode。它在大型 TypeScript 迁移项目中得到了验证 - [newDTW](https://github.com/zawatton/newDTW.github.io) 仓库,它将反编译的 HSP 应用程序移植到 TypeScript:
- *16,000+* 行 TypeScript 代码,跨越 *1,400+* 个模块
- 大型类型定义文件(数千行)与实现文件紧密耦合
- 相同文件中多点编辑的高频率
与 org-mode 相同的 Anvil 工具在这里也带来了可衡量的胜利。
### `anvil-file-batch` - 对单个文件进行多次编辑
TypeScript 重构通常意味着对单个文件进行多个同时编辑:添加导入、修改类型定义、替换实现、重命名方法。
测量:在 130 行源文件中进行 6 次编辑。
| 方法 | 标记 | 往返次数 |
|-----------------------+----------+-------------|
| 常规 `Edit` ×6 | ~4,800 | 6 |
| `anvil-file-batch` | ~1,500 | 1 |
| 减少 | *~70%* | *83%* |
### `anvil-file-replace-regexp` - 批量类型/标识符重命名
诸如在整个代码库中更改 `Promise<T>` → `AsyncResult<T>`,或重命名全局使用的变量等任务,只需一个命令即可完成。传统流程(grep 搜索数百个文件,读取每个文件,单独编辑)是相同的机械工作的多次往返。
### `anvil-file-insert-at-line` / `delete-lines` - 大型文件上的本地操作
用例:在 4,000+ 行类型定义文件或全局状态接口中添加单个字段。
| 方法 | 标记 |
|------------------------------+------------|
| 读取整个文件 + 编辑 | 数千 |
| `anvil-file-insert-at-line` | 十几 |
| 减少 | *~90%+* |
### `anvil-json-object-add` - JSON 对象添加
对于将许多键值对追加到 JSON 对象(语言字典、功能标志、配置映射)的流程,通用 `Edit` 工具需要在每次往返中输入很长的锚字符串。
测量:以 40 为一批,添加约 200 个 i18n 键。
| 方法 | 标记 | 调用次数 |
|------------------------------+----------+-------|
| 常规 `Edit` ×5 | ~30,000 | 5 |
| `anvil-json-object-add` ×5 | ~8,000 | 5 |
| 减少 | *~73%* | 0 |
自动处理尾随逗号、闭括号位置、缩进检测和重复键策略。
### `anvil-file-ensure-import` - 幂等导入插入
在许多源文件中添加 `import` 行是最重复的编辑模式之一。`file-ensure-import` 检查该行是否已存在,并且仅在需要时插入到最后一个匹配的头部行之后。适用于任何 `:after-regex`,因此它同样适用于 Emacs `(require ...)` 块。
### `anvil-file-batch-across` - 协调多文件编辑
对于涉及类似方式的 N 个文件的重构(文档字符串更新、重命名、导入添加),将此功能与 `file-batch` 的每个文件操作列表配对,以一个 MCP 调用完成整个重构。
### `anvil-code-extract-pattern` - 从巨大文件中提取结构化数据(只读)
对于遗留数据提取和 ETL,通常的流程是“读取整个文件,然后使用正则表达式组装”。此工具通过单个 MCP 调用替换它。`:block-start` 匹配每个块头,`:block-end` 选择关闭策略brace-balance` 跳过字符串中的括号),`:fields` 正则表达式捕获每个字段值;结果作为纯数据记录列表返回。
测量:在 newDTW 中从 `func492.ts` 中提取了 347 个项目定义(3,407 行遗留 if-blocks)。
| 方法 | 标记 |
|-------------------------------------+----------------|
| 整个文件读取 + 提取脚本 | ~8,000 + α |
| `anvil-code-extract-pattern` ×1 | ~3,000-5,000 |
| 减少 | *~50%* |
在重复出现结构化文本的任何地方都很有用:遗留迁移、数据迁移、i18n 库存。
### `anvil-code-add-field-by-map` - 批量为 TS/JS 对象字面量添加字段
对于 i18n 样式的工作 - “将 `add-key: "..."` 添加到同一个文件中的每个 `lookup-key: "..."` 中” - 这将整个循环折叠为一个调用,该调用仅接受一个映射 JSON。默认情况下是干运行(`:apply` 默认值为 nil),因此典型的流程是:先预览,然后再次调用 `apply t` 以写入 - 具有额外管道的安全性保证。
测量:在 newDTW 中为 8 个数据文件(每个文件 25-100 个条目)添加 `en` 翻译。
| 方法 | 标记 |
|---------------------------------------------------+----------|
| 每个文件读取 + 完整重写写入 | ~16,000 |
| `anvil-code-add-field-by-map`(仅映射) | ~3,200 |
| 减少 | *~78%* |
现有的添加键处理由 `:on-existing`(默认为 `error` 以防止出错)控制,防止无声覆盖。
### 为什么 TypeScript 特别受益
| TypeScript 特性 | Anvil 有帮助 |
-+--------------------------------------------------|
| 类型定义 + 实现共存于一个文件许多文件编辑 → `file-batch` 效果显著 |
| 大型类型定义文件 | 本地操作避免整个文件读取 |
| 频繁的导入添加 | `file-insert-at-line` 处理例行插入 |
| 全局状态接口 | 字段添加遵循模式,易于脚本化 |
| 遗留 if-block / switch 提取 | `code-pattern` 删除整个 |
| 对象字面量的批量 i18n译 | `code-add-field-by-map` 将叠为一个映射 |
在 newDT,每次重构累计节省 *15,000 到 25,000 个标记*(在 `code-extract-pattern`code-add-field-by-map` 落地后)- 代理随后将时间花在实际推理上,而不是文件传输上。
### 何时选择 Anvil
| 场景 | Anvil 优势 |
|-----------------------------------------------+-------------------------------------|
| 相同文件中的 3+ 编辑 | ◎ 显著减少标记 |
| 对大文件的本地添加 | ◎ 避免整个文件读取 |
| 批量重命名(类型,标识符) | ◎ 一条命令完成 |
| 添加导入 / 类型字段 | ○ 减少往返次数 |
| 代理工作期间繁重的 Emacs 操作 | ◎ 工作线程调度(~15 倍更快) |
| 从头开始创建新文件 | △ 通用 `Write` 尚可 |
| 文件或仓库探索 | × Glob / Grep 更适合 |
### 实践中的效果
一个典型的代理会话,涉及一个大配置文件,重构几个 org 标题,并运行一个 tang流程,否则将受到文件传输开销的支配。有了 Anvil:
- 每次编辑只发送 *已更改的字节*,而不是文件。
- 多步骤重构折叠为 *一次* 批量- 慢速 Emacs 操作在 *工作线程* 中执行,而不是代理线程。
结果是每标记更多的有用工作 - 代理的上下文预算用于推理代码,而不是重新读取它。
### 模块
| 模块 | 工具 | 外部依赖 |
|--------------+------------------------------------------------|
| ` | 隔离的子 Emacs 守护进程池用于 AI 调用 | |
| `eval | 同步/isp 评估 — |
| `org` | 读取 org 标题、轮廓、TODO 状态 | org-mode |
| `file` | 安全的文件操作、批量编辑、替换/正则表达式 | |
| `host` | CPU、RAM、磁盘、GPU、网络、OS 信息 | — |
| ` | 状态、差异统计,带有 路径安全性 | |
| `proc` | 和检查 | — |
| `net` | 端口和 | — `fs` | 目录树、磁盘最近的文件 | — |
| `emacs | 缓冲区状态和磁盘同步诊断 | — |
|` | URL 提取、链接解析 | — |
| `clipboard` | OS 剪贴板读取 | — |
| `data`/CSV 读取/写入,强制 UTF- | — |
| `xlsx` | Excel 读取/写入( | Python, openpyxl |
| `pdf` | PDF 文(可选) | Python, pymupdf |
| `ide` (拆分) |到 [[https://github.com/zawatton/anvil-ide.el][zawatton/anvil-ide.el]] in 2026-04 (Doc 38). `anvil.el` 现在是 NeLisp 可运行的;`anvil-ide.el` 捆绑了仅限 Emacs 的 IDE 层(xref / 诊断 / imenu / tree-sitter / info-look / 工作线程 UI 仪表盘)。 安装两者以获取原始功能集 | anvil-ide.el 仓库 |
| `cron` | 带工作线程调度的定时任务运行 | — |
| `elisp` | 代理 Elisp 开发工具(可选) | — |
| `browser` | 通过 agent-browser 的 Web 获取/交互/捕获/截图(可选) | agent-browser CLI |
| `state` | 持久的 SQLite 支持的 KV 存储(命名空间/TTL,可选) | Emacs 29+ |
| `http` | 使用 `url-retrieve` 的 GET/HEAD,带有 ETag/TTL 缓存(可选) | Emacs 29+ (state) |
| `orchestrator` | 并行 AI CLI 分发器(claude / aider / gemini / ollama / codex),带有 DAG,共识,元 LLM 评判,实时流媒体,cron + 工作树隔离(可选) | AI CLI,Emacs 29+ |
| `orchestrator-routing` | 用于 `orchestrator-routing-select` 的每个提供商延迟路由(v0.4.0) | orchestrator |
| `orchestrator-presets` | 命名提供商组合(v0.4.0) | orchestrator |
| `pty-broker` | 节点 pty TCP 代理,用于启动需要真正 TTY 的进程(可选) | Node.js, node-pty |
| `memory` (v0.4.0 + 2026-05) | 自动内存索引 + TTL 审计 + 访问跟踪器,DB 主添加/获取/导出,WHISPER 会话增量,矛盾扫描,静态 HTML 导出和仅查看收获候选者(可选) | Emacs 29+ |
| `memory-bridge` (2026-05) | 内存和工作日志的本地 HTTP/JSON API,写入身份验证,事件流,读取副本拉取,CORS,浏览器扩展,移动客户端(可选) | `memory=`,`worklog=` |
| `worklog` (2026-05) | AI 工作日志 org 扫描 + DB 主 `worklog-add` + 搜索/列表/获取/导出工具;适用于长时间运行的守护进程的陈旧 SQLite 处理恢复(可选) | Emacs 29+ |
|oresearch` (2026-05) | 候选者扫描,MCP 文档字符串提案/应用/收获门,路由实验,NeLisp 代码生成任务脚手架,选项卡列表仪表盘(可选) | `orchestrator=`,可选 `memory=` |
| `-watchdog` (2026-05) | Linux Claude 代码挂起检测 + 桌面通知 + 基于确认的 tmux 恢复暂存(可选) | Linux procfs,tmux 用于恢复 |
| `session` (v0.4.0) | 会话快照/恢复 + 5 个 Claude Code 生命周期钩子(可选) | `state=`discovery` (v0.4.0) | 基于意图的 MCP 工具发现(=anvil-tools-by-intent=)+ 每个工具使用计数器(可选) | `state=` |
| `manifest` (v0.4.0 + 2026-05) | 每个会话的 `tools/list=` 过滤器,由 `ANVIL_PROFILE=` 驱动;动态工具注意力添加查询排名,状态过滤,模式修剪,温暖 LRU 和恢复提示(可选) | — |
| `disclosure` (v0.4.0) | 3 层读取合约 + 引用 URI 方案 + `disclosure-help=`(可选) | `org-index=` |
| `shell-filter` (v0.4.0) | 带有 20 个捆绑过滤器的 Shell 输出压缩 + tee + 增益统计(可选) | `state=` |
| `data` (v0.4.0) | 基于 JSON 路径的编辑,默认预览:data-get-path / data-set-path / data-delete-path / data-list-keys (可选) | — |
| `sexp` (v0.4.0) | 基于读取器的 Elisp 结构编辑:rename-symbol / replace-defun / wrap-form / macroexpand (可选) | — |
| `sexp-cst` (v0.4.0) | Tree-sitter-elisp CST + 运行时 `inspect-object` + `sexp-cst-read` /edit=` / `=repair=`(可选) | Emacs 29+,tree-sitter-elisp 语法 |
| `defs` (v0.4.0) | SQLite 支持的 Elisp 符号索引:defs-search / defs-references / defs-signature / defs-who-requires (可选) | Emacs 29+ |
| `treesit` (v0.4.0) | Tree-sitter 共享核心用于每个语言的结构模块(可选) | Emacs 29+ |
| `py` (v0.4.0) | 通过 treesit 的 Python 结构定位器 + 编辑:py-list-* / py-find-definition / py-add-import 等(可选) | `treesit=`,python 语法 |
| `ts` (v0.4.0) | 通过 treesit 的 TypeScript/TSX 结构定位器(可选) | `treesit=`,tree-sitter-typescript 语法 |
| `js` (v0.4.0) | 通过 treesit 的 JavaScript/JSX 结构定位器(可选) | `treesit=`,tree-sitter-javascript 语法 |
| `bench` (v0.4.0) | bench-compare / bench-profile-expr / bench-last (可选) | — |
### 配置
```elisp
;; 选择要加载的模块(显示默认值)
(setq anvil-modules '(worker eval org file host git proc fs emacs text clipboard data net))
;; 启用可选模块
(setq anvil-optional-modules '(xlsx pdf ide cron browser))
;; 启动 anvil
(anvil-enable)
(anvil-server-start)
```
### 缓存优先编辑 - `anvil-modes-allow-buffer-modify`
默认情况下,Anvil 的 org 修改工具(`update-todo-state`、`add-todo`、`rename-headline`、`edit-body`)使用**磁盘优先**策略:它们将文件读取到临时缓冲区,应用编辑,然后将结果写入磁盘,并刷新任何访问缓冲区的缓冲区。如果任何缓冲区有未保存的修改,则操作将被拒绝 - Anvil 不会覆盖您正在进行的编辑。
当 `anvil-modes-allow-buffer-modify` 设置为**主要模式**列表时,Anvil 切换到**缓冲区优先**策略,对于文件打开缓冲区与其中一个模式匹配的文件:
1. 定位访问该文件的第一个缓冲区(跟随间接缓冲区到其基础缓冲区)。
2. 检查缓冲区是否已经有未保存的修改。
3. 直接在实时缓冲区中进行编辑。
4. 仅在缓冲区**没有**事先具有未保存的修改的情况下保存缓冲区 - 保存任何正在进行的用戶工作。
这意味着 AI 代理和人类可以协作处理同一个文件,而无需代理强制保存可能提交的半成品编辑。
```elisp
;; 仅为 org 文件启用缓冲区优先编辑
(setq anvil-modes-allow-buffer-modify '(org-mode))
;; 或者为每个打开的缓冲区启用(`fundamental-mode` 是一个特殊情况,匹配任何主要模式)
(setq anvil-modes-allow-buffer-modify '(fundamental-mode))
```
### 用户配置 - Emacs 与 NeLisp 独立
两种入口路径,两种配置位置:
| 入口路径 | 配置源 |
|-------------------------------------------+------------------------------|
| Emacs(~emacs --daemon~ + ~emacsclient~) | 现有 `init.el` |
| NeLisp 独立(~bin/anvil mcp serve~) | `$ANVIL_CONFIG_DIR/config.el` |
在常规 Emacs 中,没有变化 - 将您的 `setq` 覆盖放在 `init.el` 中。在 NeLisp 独立路径下(由 Rust `anvil-runtime` 二进制文件启动,`bin/anvil` 启动,没有 `init.el` 读取),Anvil 从以下 env 变量按顺序解析配置文件:
1. `$ANVIL_CONFIG_DIR=`
2. `$XDG_CONFIG_HOME/anvil=` (XDG 默认值)
3. `~/.config/anvil=` (POSIX 回退)
该目录中的文件始终为 `config.el`。 缺失文件是沉默的(即**可选**)。 解析/评估失败通过 `display-warning` 引发,但从不中止 MCP 服务器 - 损坏的用户配置不得卡住引导。
示例 `~/.config/anvil/config.el`:
#+begin_src emacs-lisp
;; 代码任务需要写入访问权限才能进行非琐碎调度。
(setq anvil-orchestrator-codex-sandbox "workspace-write")
;; 积极截断增益摘要行。
(setq anvil-shell-filter-default-truncate-lines-at 200)
#+end_src
分支上的路径处于完全自动状态 — Anvil 通过 =(featurep 'nelisp)= 检测它,该值仅在 NeLisp 解释器启动后为真。有关实现,请参见 =anvil-config.el=。
** 浏览器模块(可选)
=浏览器= 模块封装了 [[https://agent-browser.dev/][agent-browser]] CLI,以便 MCP 客户端可以获取页面的可访问性树快照,单次工具调用(通常比原始 DOM 转储少 25 倍)。
#+begin_src shell
npm install -g agent-browser
agent-browser install # 如有需要,下载 Chrome for Testing
#+end_src
然后将 =browser= 添加到 =anvil-optional-modules=,如上所示。已注册的工具包括 =browser-fetch=、=browser-interact=、=browser-capture=、=browser-screenshot= 和 =browser-close=。捕获的页面进入 =anvil-browser-capture-dir=(defcustom)。在 =anvil-browser-cache-ttl-sec= 秒(默认为 300)内,相同 URL 的获取请求将从内存缓存中提供。
在 Windows 上,agent-browser Rust 二进制文件偶尔会被 Defender 标记为可疑;如果遇到这种情况,请将 %=APPDATA%\npm\node_modules\agent-browser\bin\=% 添加到白名单。
** 调度器模块(可选)
=调度器= 模块并行启动多个智能 AI CLI 子进程,并公开一个简洁的提交/状态/收集 API,以便父 Claude 会话仅在任务 ID 和最终摘要上花费上下文,而不是在每个子任务进行的中间工具调用上。
将 =orchestrator= 添加到 =anvil-optional-modules=。已注册的工具包括:
- =orchestrator-submit= — 队列一批任务(JSON 数组);每个任务都是一个 plist,包含 =name=、=provider=、=prompt=(以及可选的 =model=、=budget_usd=、=timeout_sec=等)。返回一个批次 ID 而不阻塞。
- =orchestrator-status= — 返回一个批次(或单个任务)的计数 + 精简的每任务 plist。
- =orchestrator-collect= — 返回一个批次的精简任务结果列表;如果 =wait="t"= 则阻塞直到所有任务都达到终端状态。
- =orchestrator-cancel= — 向正在运行或排队的任务发送 SIGTERM / SIGKILL。
- =orchestrator-retry= — 在新的 ID 下重新提交一个任务。
第 1a 阶段提供了 =claude= 提供程序(硬依赖于 =exec-path= 上的 =claude= CLI)。第 2 阶段添加了 =aider= 提供程序 — 使用 =:provider 'aider= 和 =:model "<vendor>/<model>"=(例如 =openai/gpt-4o-mini=、=anthropic/claude-3-5-sonnet-latest=、=gemini/gemini-2.0-flash=、=ollama/llama3=)将单个 =aider --message= 调用路由到多供应商 aider CLI。 Gemini / Ollama 本地适配器在第 3 阶段及以后版本中提供。并发上限(=anvil-orchestrator-concurrency=、=anvil-orchestrator-per-provider-concurrency=)保护措施防止耗尽 Claude MAX 计划的 5 小时窗口;默认并发数为 3 个全局和 3 个每提供程序。
=M-x anvil-orchestrator-dashboard= 打开一个 =tabulated-list= 视图,显示所有任务:按键 =g= 刷新,=RET= 打开 stdout 文件,=k= 取消,=r= 重试。
任务状态持久保存到 =anvil-state=(ns=orchestrator),因此队列在守护进程重启后仍然存在。运行中的任务在关闭时被标记为 =failed=,并带有清晰的错误提示,因为 OS pid 不再属于 Emacs。
第 1b 阶段新增:
- *Git 工作树隔离*。当任务的 =:cwd= 位于 git 仓库内且 =anvil-orchestrator-worktree-auto= 开启(默认)时,claude 提供程序接收 =--worktree NAME=,因此 N 个并行任务永远不会踩踏同一个工作树。没有原生工作树支持的提供程序会回退到 =anvil-git worktree add= 下的 =anvil-orchestrator-work-dir/worktrees/=; =:cwd= 在 spawn 之前被重写为该路径。每个任务选择退出 =:no-worktree t=。
- *DAG 调度*。任务可以通过 =:depends-on ("other-name" …)= 命名批次中的兄弟依赖。仅当每个依赖达到 =done= 时,池才会启动任务;如果任何依赖 =failed= 或 =cancelled=,则依赖项被标记为 =failed=,并带有“依赖 X 未成功”的错误。批次级循环和未知名称检测在提交时发生。
- *stdout / stderr 溢出*。每个任务的输出文件超过 =anvil-orchestrator-output-size-cap=(默认为 1 MB)时,会重写为 =head 256 KB= + 截断标记 + =tail 256 KB=;原始字节数在任务记录中保存为 =:stdout-bytes-original=,以便仪表板和父会话可以查看日志被精简。
第 2 阶段新增:
- *aider 提供程序*。 =:provider 'aider= 将提示信息通过 =aider --message --yes-always --no-stream --no-check-update= 路由到目标模型,选定的模型由 =:model= 指定。可选任务字段包括 =:files=(位置参数 aider 允许编辑)、=read-only-files=(变为 =--read FILE= 对)、=subtree-only=、=no-auto-commits=。解析器提取最后的 =Commit <sha>= 行到 =:commit-sha=,并将尾随的非 diff 段落提取到 =:summary=。由于 aider 没有原生的工作树标志,Anvil 创建一个 =git worktree add= 在 =anvil-orchestrator-work-dir/worktrees/= 下,并重写 =:cwd= 后再 spawn(与第 1b 阶段对每个非 claude 提供程序使用的后备路径相同)。持久化额外标志存储在 =anvil-orchestrator-aider-extra-args= 中。
- *通过 anvil-cron 调度批次*。注册一个调度函数,调用 =anvil-orchestrator-submit=,然后使用 =anvil-cron-register :time "02:00"= 进行调度,实现自主的夜间运行。有关四种端到端模式(调度仅、调度后收集、基于钩子的批次 ID 日志、多提供程序混合)的示例,请参阅 =examples/nightly-orchestrator.org= 和 worker-vs-main-daemon 权衡取舍。
需要 Emacs 29+(通过 =anvil-state=)。
** 自动搜索模块(可选)
=anvil-autoresearch= 是“智能体自我改进”循环的安全、需审查的版本。它不会自行运行无边界实验。相反,它提供了小型 MCP 原语,使每个步骤都可检查:
- =autoresearch-scan= — 从本地 Web/X/YouTube 摘要和 =docs/design= 中排名实现候选。
- =autoresearch-docstrings= /=plan= /=patch= — 查找弱 MCP 工具描述并生成干运行重写候选。
- =autoresearch-docstring-apply= /=run= /=harvest= — 在评估和保持门控下应用审查候选,失败时恢复。
- =autoresearch-routing-*= — 评估、提出、收获和审查调度器提供程序路由改进。
- =autoresearch-nelisp-codegen-*= — 在不编辑 NeLisp 仓库的情况下,为 MCP 工具本身提供 NeLisp 第 47 阶段代码生成实现任务。
=M-x anvil-autoresearch-dashboard= 打开一个 =tabulated-list= 视图,显示当前的 =autoresearch-*= 调度器任务。仪表板是观察性的:=g= 刷新,=RET= 打开任务 plist;收获、应用和内存提升仍然是显式工具调用。
** Claude 代码监视器(可选,Linux)
=anvil-claude-watchdog= 在 TUI 之外监视 Claude Code 会话,使用 Linux =/proc= 计数器和 jsonl mtime。它检测到经典的“流仍然存活但 UI/jsonl 停止”卡顿,以及跟踪的 MCP 子进程未推进 =rchar= 和 =wchar= 的 State=S 旋转器变体。事件通过 =anvil-state= 记录,可以触发桌面通知。
恢复设计为手动。 =M-x anvil-claude-watchdog-recover= 请求确认,向选定的卡顿进程发送 =SIGKILL=,从 jsonl 基础名称派生 =claude --resume <session-id>=,并在匹配的 tmux 窗格中准备该命令,而无需按 Enter。
** 内存模块(可选)— 跨 AI CLI 索引自动内存
=内存= 模块是跨提供程序的索引,涵盖每个磁盘上的 =.md= 自动内存文件,因此任何 MCP 客户端(Claude Code、Codex CLI、Gemini CLI、Continue、Aider、Cline、Cursor 等)都可以共享相同的长期上下文。
启用它:
#+begin_src emacs-lisp
(add-to-list 'anvil-optional-modules 'memory)
(anvil-enable) ; 重新加载模块集
#+end_src
然后索引当前磁盘上的所有内容:
#+begin_src text
;; 从 Emacs:
M-x anvil-memory-scan
;; 从 MCP 客户端:
调用 `memory-scan' 工具(无参数)
#+end_src
=memory-scan= 遍历 =anvil-memory-provider-paths=(默认如下)匹配的每个目录,插入每个 =.md= 的一行(跳过 =MEMORY.md= 索引文件),并刷新 FTS5 正文索引。它是幂等的 — 冲突时保留现有的 =access_count= / =validity_prior= 行,因此您可以随时重新运行。
默认提供程序映射(编辑以添加您自己的):
#+begin_src emacs-lisp
(setq anvil-memory-provider-paths
'((claude . "~/.claude/projects/*/memory")
(codex . "~/.codex/memories")
(gemini . "~/.gemini/memories")
(continue . "~/.continue/memories")
(aider . "~/.aider/memories")
(cline . "~/.cline/memories")
(cursor . "~/.cursor/memories")
(windsurf . "~/.windsurf/memories")
(zed . "~/.config/zed/memories")))
#+end_src
模式可能包含 =*= 通配符。非存在的扩展名将被静默丢弃,因此添加您尚未安装的提供程序不会产生任何影响。 如果要完全覆盖自动检测,请将 =anvil-memory-roots= 设置为固定列表(测试/沙盒使用此功能)。
一旦索引,所有常规工具都在单个 SQLite DB (=~/.emacs.d/anvil-memory-index.db=) 中跨提供程序运行:
- =memory-search QUERY= — 跨每个提供程序的内存正文的 FTS5 全文搜索(支持 =:limit=、=:type= 关键字过滤器)。
- =memory-audit= — TTL 检查; =:with_urls t= 通过 =anvil-http-head= 探测引用 URL。
- =memory-list= — 所有行,可选 =:with-decay t 按衰减排名。
- =memory-save-check SUBJECT BODY= — 在写入新内存之前,计算 Jaccard Top-N 重复候选。
- =memory-duplicates= — 跨提供程序的近似重复对。
- =memory-promote OLD NEW-TYPE= — 重命名并重新索引,有助于将行从 =project_= 成熟为 =user_=。
- =memory-regenerate-index= — 发出一个仅限读取的 =MEMORY.md= 正文排序的衰减分数(调用者决定是否写入)。
- =memory-add= / =memory-get= / =memory-export-md= — DB 主写/读/导出路径。新内存可以直接插入 SQLite,从 =.md= 文件中获取,无需读取,然后在另一个 AI 需要基于文件的交换时渲染回 Markdown 文件。
- =memory-session-delta= / =memory-stop-sync= — WHISPER 会话上下文。第一个调用返回完整的按衰减排名的索引;后续调用仅返回添加/更改/删除的内存行,直到增量太大。
- =memory-harvest-candidates= — 从会话文本或转录中仅提取持久的内存候选。它本身永远不会持久保存;调用者决定保存哪些候选。
非 Claude 客户端通过连接到相同的 Anvil MCP 服务器访问这些功能。普通的扫描/搜索/列表/审计路径针对提供者管理的 =.md= 文件是只读的;变异操作是显式(=memory-promote= 重命名,=memory-add= DB 插入,或 =memory-export-md= 调用者驱动的 Markdown 导出)。
*** 数据库位置和跨机器共享
元数据 DB 默认存储在 =<user-emacs-directory>/anvil-memory-index.db=。您可以通过以下方式将机器重定向到笔记存储库本地 DB 而无需符号链接:
#+begin_src emacs-lisp
(setq anvil-memory-shared-db-roots
'("~/Cowork/Notes"))
#+end_src
当 =anvil-memory-db-path= 保留其默认值时,打开路径通过检查以下内容进行解析:
1. =ANVIL_MEMORY_DB= 环境变量
2. =anvil-memory-db-path=(显式自定义时)
3. =anvil-memory-shared-db-roots= 的第一个条目包含 =.anvil-memory/anvil-memory-index.db=
4. 默认 <user-emacs-directory>/anvil-memory-index.db=
使用 =(anvil-memory-effective-db-path)= 确认模块正在使用的路径。
不要通过 git 合并多个机器的 =.anvil-memory/*.db= 文件。当前操作模型是:
- 保留 =.anvil-memory/*.db= 文件每个机器并 gitignore;
- 使用 =memory-export-md= 当 DB 直接内存应该成为其他 AI 的文件基质时;
- 让 =memory-scan= 在另一台机器上重新索引那些导出的文件。
这避免了二进制合并冲突和长-lived Emacs 守护进程中的打开 SQLite 文件句柄。
*** 内存桥 — 跨 AI 和移动访问
=memory-bridge= 可选模块在 =anvil-memory= 和 =anvil-worklog= 前面提供了一个小 localhost JSON API。这适用于无法直接与 Emacs MCP 服务器通信的客户端:浏览器聊天 UI、移动端薄客户端、另一台机器上的 Tailscale 读取副本。
#+begin_src emacs-lisp
(add-to-list 'anvil-optional-modules 'memory)
(add-to-list 'anvil-optional-modules 'worklog)
(add-to-list 'anvil-optional-modules 'memory-bridge)
(anvil-enable)
(anvil-memory-bridge-start)
#+end_src
默认绑定为 =127.0.0.1:8730=, 读取端点包括 =/memory/search=、=/memory/list=、=/memory/get/<name>=、=/memory/events=、=/worklog/search= 和 =/worklog/get=。变异内存端点需要 =Authorization: Bearer <token>=;使用 =M-x anvil-memory-bridge-rotate-token= 轮换令牌。
两个薄客户端位于 =extensions/= 下:
- =extensions/memory-bridge/= — 为 Claude.ai、ChatGPT 和 Gemini 提供了 Manifest V3 浏览器扩展。 =Ctrl+Alt+M= 搜索/注入内存; =Ctrl+Alt+S= 保存选定的文本。
- =extensions/mobile-bridge/= — 无依赖的静态移动应用。它在 =localStorage= 中存储桥接 URL/令牌,并在重新上线时对失败的保存进行重放。
读取副本模式故意为单写入者设计:副本可以拉取主 =memory_event= 行,但本地变异端点返回 =409=,因此两个机器不会静默分离。
** 工作日志模块(可选)
=worklog= 模块将 AI 工作日志与长期内存分开索引。它可以扫描旧的 =capture/ai-logs-*.org= 存档,但新条目通过 =worklog-add= 而非手动组织追加。搜索/列表/获取功能通过 MCP 工具和 =memory-bridge= 公开,供非 Emacs 客户端使用。
与 =memory= 一样,=worklog= 旨在使用每个机器的 SQLite DB。 当您想要人类可读的 org 快照以用于 git 或跨机器交换时,请使用 =worklog-export-org=。 2026-05 开发分支还教导长寿命守护进程在 SQLite 文件被替换或取消链接后重新打开它,然后在下一次 DB 操作之前。
典型用法:
```text
worklog-add(title, body)
worklog-search("Doc43 autoresearch")
worklog-get("anvil-worklog:db:linux-debian:2026", 1779295660)
worklog-export-org(machine, year)
```
** Git 帮助程序
=git= 模块是默认 =anvil-modules= 列表的一部分。它在共享的 =emacs-eval= 服务器 ID 下公开只读 Git 检视工具:
- =git-repo-root= — 顶级目录,对于目录路径为 nil,在仓库外。
- =git-head-sha= — 完整或缩写的 HEAD 提交。
- =git-branch-current= — 当前分支名称,在分离时为 nil。
- =git-log= — 最近的提交作为 =(hash, date, author, subject)= 对象,最高可达 =anvil-git-log-default-count=。
- =git-diff-names= — 之间更改的路径 FROM 和 TO。
- =git-diff-stats= — 结构化 =(files, insertions, deletions)= 计数。
- =git-status= — 分支 / 上游 / 前方 / 后方 + 分段 / 修改 / 未跟踪 / 未合并路径的桶。
- =git-worktree-list= — 附加的工作树,包含 =(path, head, branch, bare, detached)=。
Elisp API 添加了 =anvil-git-worktree-add= 和 =anvil-git-worktree-remove=(写操作,故意不通过 MCP 公开 — =anvil-orchestrator= 使用它们来隔离并行任务)。每个调用都会运行 =git --no-pager -c core.quotepath=false ...= 以便 Japanese 路径可以正确轮询,配置了终端转义的存储库不会泄漏。
** HTTP 模块(可选)
= http = 模块是 Emacs 内置 =url-retrieve-synchronously= 的薄封装,添加了一个 SQLite 支持的 ETag/TTL 缓存(通过 =anvil-state=)。对于完整的浏览器会话来说,它是浪费资源的静态 HTTP/JSON 资源、REST API、 JavaScript 挑战 Chrome 的 =.json= 端点、RSS 源、公共文档轮询等工具的正确选择。
将 =http= 添加到 =anvil-optional-modules=。已注册的工具包括:
- =http-fetch= — 带有缓存意识的 GET 请求。在 =anvil-http-cache-ttl-sec=(默认为 300 秒)内,响应无需网络调用即可提供;否则,将发出带有 =If-None-Match= / =If-Modified-Since= 的条件 GET 请求,并且 304 将刷新缓存条目而无需正文传输。重试 =5xx= / =408= / =429=,指数退避(=Retry-After= 在 829 上受尊崇)。
- =http-head= — 廉价的元数据检查的 HEAD 探测;从不缓存。
- =http-cache-clear= — 丢弃单个 URL 或刷新整个 HTTP 命名空间。
方案保护:只接受 =http= / =https=(=anvil-http-allowed-schemes=),因此拒绝 =file://= / =javascript:=。=url-max-redirections= 被限制为每次调用 5 个,低于 Emacs 的默认 30 个。
需要 Emacs 29+(用于 =anvil-state= 所使用的内置 =sqlite-*=)。
* 客户端设置 — 将您的 AI 连接到 Anvil
在 Emacs 内运行 Anvil 后,您需要将其注册为您的 AI 客户端(Claude Desktop、Claude Code CLI、Codex CLI 或任何其他 MCP 兼容客户端)中的 MCP 服务器。
桥梁是一个小的 shell 脚本(=anvil-stdio.sh=),它在标准输入输出上讲 JSON-RPC,并通过 =emacsclient= 将调用转发到正在运行的 Emacs 守护进程。
安装它:
```elisp
M-x anvil-server-install
```
默认情况下,这将 =anvil-stdio.sh= 放在您的 =user-emacs-directory=(通常是 ~/.emacs.d/)。您可以使用 =M-x customize-variable RET anvil-server-install-directory= 更改目标位置。
** 必备条件:**Emacs 必须作为守护进程运行(=server-start= 或 =emacs --daemon=)。Anvil 通过 =emacsclient= 连接到它。
** 克劳德桌面
配置文件位置:
## 5. 配置
### 5.1. 配置文件路径
| 操作系统 | 路径 |
|-------------------+---------------------------------------------------------------------------------------------|
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Linux | `~/.config/Claude/claude_desktop_config.json` |
| Windows (普通版) | `%APPDATA%\Claude\claude_desktop_config.json` |
| Windows (UWP 版) | `%LOCALAPPDATA%\Packages\Claude_<id>\LocalCache\Roaming\Claude\claude_desktop_config.json` |
### 5.2. Anvil 目前注册了两个 MCP 服务器 ID
Anvil 目前在内部注册了两个 MCP 服务器 ID - `anvil`(eval / IDE)和 `emacs-eval`(文件,组织,缓冲区,工作线程...)。大多数客户端为每个 `mcpServers` 条目显示一个工具列表,因此您需要两个条目指向同一个脚本,但具有不同的 `--server-id` 值,以公开所有工具。(未来版本将把这些合并为一个服务器 ID;目前,两个条目是支持的设置。)
### 5.3. macOS / Linux 配置示例
```json
{
"mcpServers": {
"anvil": {
"command": "/path/to/.emacs.d/anvil-stdio.sh",
"args": [
"--server-id=anvil",
"--init-function=anvil-enable",
"--stop-function=anvil-disable"
]
},
"anvil-emacs-eval": {
"command": "/path/to/.emacs.d/anvil-stdio.sh",
"args": [
"--server-id=emacs-eval"
]
}
}
}
```
### 5.4. Windows 配置示例
Windows 需要 Git Bash 来执行 shell 脚本:
```json
{
"mcpServers": {
"anvil": {
"command": "C:\\Program Files\\Git\\bin\\bash.exe",
"args": [
"C:/Users/<you>/.emacs.d/anvil-stdio.sh",
"--server-id=anvil",
"--init-function=anvil-enable",
"--stop-function=anvil-disable"
]
},
"anvil-emacs-eval": {
"command": "C:\\Program Files\\Git\\bin\\bash.exe",
"args": [
"C:/Users/<you>/.emacs.d/anvil-stdio.sh",
"--server-id=emacs-eval"
]
}
}
}
```
### 5.5. 重启 Claude Desktop
编辑配置后,请重启 Claude Desktop。
### 5.6. Claude Code (CLI)
CLI 将其配置存储在 `~/.claude.json` 中,与聊天记录和其他状态混合 - **请勿覆盖整个文件**。使用 `claude mcp add` 命令添加服务器条目。运行 **两个** 命令以公开所有工具:
```sh
claude mcp add -s user -t stdio anvil -- \
~/.emacs.d/anvil-stdio.sh \
--server-id=anvil \
--init-function=anvil-enable \
--stop-function=anvil-disable
claude mcp add -s user -t stdio anvil-emacs-eval -- \
~/.emacs.d/anvil-stdio.sh \
--server-id=emacs-eval
```
在 Windows 上,请将脚本路径替换为上述 Git Bash 调用(`command` = `bash.exe`,第一个 `arg` = 脚本路径)。
### 5.7. 可选:注册工作线程池
对于需要异步执行的工作负载(大型 tangles,多 MB org 扫描,字节编译),Anvil 的工作线程模块运行子 Emacs 守护进程。您可以将其中一个注册为单独的 MCP 服务器,以便 AI 客户端可以直接访问它:
```json
{
"mcpServers": {
"anvil": { ... 主守护进程 ... },
"anvil-worker": {
"command": "/path/to/.emacs.d/anvil-stdio.sh",
"args": [
"--socket=/path/to/.emacs.d/server/anvil-worker",
"--server-id=anvil-worker"
]
}
}
}
```
大多数用户不需要此功能 - Anvil 的 `worker` 模块自动调度重操作。
### 5.8. 验证连接
在 Emacs 中:
| 命令 | 显示内容 |
|-------------------------------+------------------------------------------------|
| `M-x anvil-describe-setup` | 工具、资源和示例客户端配置 |
| `(anvil-server-status)` | 主 MCP 服务器状态(运行 / 停止) |
| `(anvil-worker-status)` | 工作线程池状态 |
在您的 AI 客户端中:要求代理列出其工具或调用类似 `anvil-host-info` 的只读工具。如果调用返回,则桥接器正在工作。
### 5.9. 教导您的 AI 使用 Anvil - CLAUDE.md 指南
连接 Anvil 只公开工具 - 您的 AI 代理仍然需要 **优先** 使用它们而不是内置的 `Read` / `Edit` / `Write` 以实现上述令牌节省。大多数 LLM 客户端读取项目级指令文件(Claude Code 使用 `CLAUDE.md`,Cursor 使用 `.cursorrules` 等)。将以下代码段放入您的文件中。
### 5.10. 推荐的代码段(Claude Code `CLAUDE.md`)
```markdown
## 文件编辑
在适用时,优先使用 Anvil MCP 工具而不是内置的 Read/Edit/Write。它们只发送增量,批量处理多个编辑,并在一次往返中避免读取整个文件。
- `anvil-file-batch` — 对同一文件的 3+ 编辑(合并为一个调用)
- `anvil-file-replace-string` / `anvil-file-replace-regexp` —
精确定位替换;无需事先读取整个文件
- `anvil-file-insert-at-line` / `anvil-file-delete-lines` /
`anvil-file-append` — 局部行级操作
仅在小的一次性更改时使用内置的 `Edit`。对于同一文件的 3 或更多编辑,请始终使用 `anvil-file-batch`。
## org-mode
对于章节移动、重新归档、拆分或从大型 org 文件中读取单个标题,请使用 `anvil-org-*` 工具而不是 Read+Write。它们在令牌上便宜 10-20 倍。
- `anvil-org-read-headline` — 读取单个子树
- `anvil-org-read-outline` — 大纲视图,无正文
- `anvil-org-edit-body` / `anvil-org-rename-headline` /
`anvil-org-update-todo-state` — 目标 org 编辑
## 重操作 - 工作线程调度
长时间运行的 Emacs 操作(大型 tangles,字节编译,多 MB org 扫描,完整树搜索)不得在主守护进程上运行 -
它们会阻塞其他所有工具调用。通过工作线程池调度它们。
- 从 Anvil 内部调用 Elisp:对于可能超过 ~1 秒的任何操作,请优先使用 `anvil-worker-call` 而不是原始 `eval`。
- 如果工作线程已注册为其自己的 MCP 服务器(参见自述文件中的“可选:注册工作线程池”),
则重型 `eval` 调用应直接以 `mcp__anvil-worker__eval` 为目标,以便保持主会话的响应性。
您应该使用工作线程的症状:主 MCP 会话停止接受工具调用数秒钟。
## 调度任务(cron)
如果配置了 `anvil-cron` 任务(lint,健康检查,批量索引器等),请勿重复实施它们的工作。
通过 cron MCP 工具检查和触发它们:
- `anvil-cron-list` — 存在哪些任务及其计划
- `anvil-cron-status` — 最后运行时间,状态,近期故障
- `anvil-cron-run` — 按需触发已注册的任务
在编写新的临时脚本之前,请检查 `anvil-cron-list` —
该作业可能已经定义。
### 5.11. 自我强化规则(可选)
为了在长时间会话中保持代理在轨道上,请添加自我纠正触发器:
```markdown
## MCP 工具自我强化
如果在任务中您注意到以下任何情况,请切换到适当的 Anvil 工具继续:
- 相同的 elisp 模式在一次会话中被写入两次
- 为一个逻辑编辑发出三个或更多 `anvil-eval` 调用
(一个 `anvil-file-batch` 就足够了)
- 重复读取同一个大文件的整个文件
- 重型 elisp 操作阻塞了主会话 - 应该通过 `anvil-worker-call` / `mcp__anvil-worker__eval`
路由
在任务中纠正 - 不要等到最后。
```
### 5.12. 为什么这很重要
没有明确的指导,代理将默认为最低公约工具(`Read`,`Edit`,`Write`),无论连接了哪些 MCP 服务器。
自述文件顶部的节省表假设代理实际上 **选择** Anvil 工具 -
而这一决定是由您的指令文件驱动的,而不是 Anvil 本身。
### 5.13. FAQ - 它与...相比如何?
#### 5.13.1. ...claude-code-ide?
它们解决不同的问题,并且可以很好地共存。`claude-code-ide` 将 Claude Code 的交互式 UI 带入 Emacs 中,通过 eat;其 MCP 界面主要是 IDE 导向的(xref / 诊断 / 缓冲区元数据)。对于文件编辑,它依赖于 Claude Code 的内置 Read / Edit / Write 针对文件系统。
Anvil 朝相反的方向发展:它是一个独立的 MCP 服务器,公开 **Emacs 本身** -
文件操作,原语,工作线程调度,elisp 反射 -
给任何 MCP 客户端。实际上,我运行两者:
用于 Emacs 中的内联 Claude 会话的 claude-code-ide,以及作为单独的 MCP 服务器,
两者都可以由 claude-code-ide 和独立的 `claude` CLI 调用。
#### 5.13.2. ...任意 elisp eval 的 MCP?
单个 eval MCP(例如 [[https://github.com/steveyegge/efrit][efrit]])在哲学上是纯粹的:零客户端智能,代理为每个任务编写 elisp。
权衡取舍是 **权限粒度** - 单个 eval 工具不能标记为 `:read-only`,因此您不能自动批准读取同时限制写入。
Anvil 的默认安装公开了约 40 个命名原语。可选模块在启用时添加它们自己的模块(最大上限取决于您加载哪些模块)。
每个模块都注册了明确的 `:read-only` 提示,在适用情况下。
在 Claude Code 中,这映射到 `/permissions/`:自动批准 `org-read-outline`,`file-read`,
`elisp-describe-function`;强制提示 `file-batch`,
`org-edit-body`,`file-replace-string`。Anvil 仍然提供 `emacs-eval` 和 `emacs-eval-async` 作为逃生阀 -
但它们并不是 80% 的路径。
#### 5.13.3. ...从 bash 调用 `emacsclient`?
那也是我的起点。 我之所以放弃它,有以下几个原因:
- **没有权限粒度**。每个 `emacsclient -e '...'` 对 ` /permissions/` 都是不透明的 - 这都是“Bash”。
使用 MCP,每个命名工具注册一个 `:read-only` 提示,以便客户端可以自动批准读取并提示写入。
- **没有模式**。代理必须从提示中记住 elisp 表面 -
MCP 在系统模式中发布工具列表,以便选择正确的工具而无需每次提醒。
- **逃避地狱**。通过 bash 引用的多行 elisp 非常脆弱,
特别是对于日语路径或正则表达式。
- **结构化返回**。MCP 工具返回类型化的 JSON;
`emacsclient` 返回一个打印的 sexp,您必须解析。
相同的 Emacs 底层;MCP 层只是一个类型化的,权限的 facade。
#### 5.13.4. ...org-mcp?
[[https://github.com/laurynas-biveinis/org-mcp][Org-mcp]] 紧密关注 org 编辑原语的 MCP。
Anvil 捆绑了这些原语(以及扩展和错误修复)并添加了文件 / 子进程 / 重型操作 / 工作线程池层,
因此单个 MCP 服务器涵盖整个工作流程,而不是仅仅 org。
如果您已经对 org-mcp 自身感到满意,那么 anvil 不是替代品 -
它是一个更大的外套。
#### 5.13.5. ...我以前从未接触过 Emacs。可以吗?
是的。Anvil 是一个 MCP 服务器,作为后台守护进程运行 -
您永远不需要打开 Emacs 窗口。继续使用您已经使用的编辑器(VSCode / Cursor / Neovim / Claude Code / Codex CLI 本身)。
您实际需要的是:
- 安装 Emacs 一次并确认 `emacs --version` 工作
- 以 `--fg-daemon` 运行它(存储库中附带启动脚本)
- 在您的 AI 客户端的 MCP 配置中添加一个块
完整的演练位于 [[https://github.com/zawatton/anvil.el#for-non-emacs-users--what-setup-costs-you][For non-Emacs users]]。
不需要 Emacs Lisp 知识即可捕获 AI 令牌节省。
### 5.14. 内部 - 桥接 + 工作线程池
```example
Claude / Codex / GPT / 本地 LLM
|
MCP(JSON-RPC via stdio)
|
anvil-stdio.sh(桥接)
|
emacsclient → Emacs 守护进程
|
anvil-server(调度器)
|
+---------+---------+
| 主 | 工作线程 | (工作线程池:重型操作
| 守护进程 | 守护进程 | 在隔离的子 Emacs 中运行)
+---------+---------+
```
### 5.15. 平台支持
| 平台 | 状态 |
|----------------------+-----------|
| Linux(原生 Emacs) | 支持 |
| macOS(原生 Emacs) | 支持 |
| Windows(原生) | 支持 |
| WSL | 支持 |
### 5.16. 如何帮助塑造接下来发生的事情
如果自述文件中的某些内容与您产生共鸣,最有用的信号是这四个:
- 资源库上的 **星标** - 它让我看到什么样的上下文落地。
- 描述您具体的 org / MCP 工作流的 **问题** - 这决定了下一个添加哪些原语。
- 与 [[https://github.com/laurynas-biveinis/org-mcp][org-mcp]] 或我可能无意中重新发明的任何现有 MCP 垫片的诚实比较。
- 工具命名和粒度反馈 - 这里“太多小操作”或“刚好合适”吗?您的直觉帮助很大。
### 5.17. 贡献
欢迎在 [[https://github.com/zawatton/anvil.el]] 上提出问题,功能请求和拉取请求。
如果您发现 Anvil 有用,请考虑 [[https://github.com/sponsors/zawatton][赞助该项目]]。
### 5.18. 相关软件包
这些软件包也是由同一作者开发的:
| 软件包 | 描述 | 仓库 |
|---------|-------------+------|
| [[https://github.com/zawatton/async-installer][async-installer]] | 非阻塞 GitHub 包安装程序,带有提交固定 | [[https://github.com/zawatton/async-installer][GitHub]] |
| [[https://github.com/zawatton/eat-windows-pty][eat-windows-pty]] | native Windows 的 emacs-eat ConPTY 支持 | [[https://github.com/zawatton/eat-windows-pty][GitHub]] |
| [[https://github.com/zawatton/org-draw][org-draw]] | org-mode 的 Excalidraw 和 tldraw 集成 | [[https://github.com/zawatton/org-draw][GitHub]] |
| [[https://github.com/zawatton/catchall-box][catchall-box]] | org-mode 的基于 UUID 的文件管理 | [[https://github.com/zawatton/catchall-box][GitHub]] |
| [[https://github.com/zawatton/emacs-skkserv][emacs-skkserv]] | 纯 Elisp skkserv,用于日语输入(ddskk,Google IME,MeCab) | [[https://github.com/zawatton/emacs-skkserv][GitHub]] |
| [[https://github.com/zawatton/my-locate-library][my-locate-library]] | 加速 require/load 的快速 load-path 索引 | [[https://github.com/zawatton/my-locate-library][GitHub]] |
### 5.19. 许可证
GPL-3.0。参见 [[file:LICENSE][LICENSE]]。
### 5.20. 致谢
- [[https://github.com/laurynas-biveinis/mcp-server-lib.el][mcp-server-lib.el]] 由 Laurynas Biveinis - MCP 协议基础
- [[https://github.com/laurynas-biveinis/org-mcp][org-mcp]] 由 Laurynas Biveinis - org 原语扩展和集成到 `anvil-org`
- [[https://github.com/manzaltu/claude-code-ide.el][claude-code-ide.el]] 由 Manzaltu - IDE 集成灵感
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器