mcpField
J
Jade

Jade

本地服务
github.com开发工具14 周前更新

关于 Jade

Jade 是 ARNO 的早期名称;ARNO 是为编码 Agent 提供 IDE 式仓库操作的 MCP 服务。README 介绍按符号导航、基于版本编辑、构建检查和回滚,并说明 0.0.14 起使用 ARNO 名称。

主要功能

  1. 01按符号导航代码
  2. 02基于版本编辑并返回诊断
  3. 03运行仓库构建与测试命令
  4. 04创建检查点并回滚
  5. 05支持语言服务器

适用场景

  1. 01追踪声明及调用方
  2. 02跨文件重命名符号
  3. 03修改代码并检查构建
  4. 04撤销高风险编辑

MCP 相关

README 将 ARNO 描述为面向编码 Agent、提供仓库导航、编辑、验证和检查点操作工具的 MCP 服务;Jade 是其早期名称。

配置

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

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
ocighcr.io/julianbei/jade-mcp:v0.0.11
mcpbjade-mcp_v0.0.11.mcpb

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

ARNO — Agent 仓库导航与操作

ARNO — Agent 仓库导航与操作

ARNO MCP server – quality and maintenance score on Glama

面向 Agent 的 IDE

ARNO 通过 MCP,为编码 Agent 提供 IDE 所具备的能力。按符号读取、基于已知版本进行编辑、获取编译器针对编辑返回的诊断信息、使用仓库自身的命令进行验证、查看改动内容,并回退到检查点——每一步只需调用一个工具,全程无需通过 shell。

ARNO 通过理解符号来查找代码;而事务处理才是它的用途。shell 仍然是更好的工具时,就用 shell——ARNO 要回答的问题是,与不使用它相比,Agent 是否能借助它完成更多工作,且成本在可接受范围内(docs/benchmark.md)。

Token 用量减半,修复的问题更多。 使用 Claude Code 处理 cobra(Go)、ky(TypeScript)、requests(Python)和 ripgrep(Rust)中的 12 个真实已关闭问题,并通过各上游修复自己的隐藏测试来评估:

Claude Code 使用……修复的问题每项任务的 Token 用量每项任务耗时
内置工具12 个中修复了 10 个1.38M215s
ARNO 替代内置工具12 个中修复了 12 个0.68M(−51%)163s(−24%)

这不仅仅是缩短了工具列表:与仅使用 Bash、Read、Edit 和 Write 的精简 shell 相比,在两次独立运行中,ARNO 仍减少了 18–25% 的 Token 用量和工具调用轮数。Sonnet 5,每项任务运行一次,覆盖四种语言—— 结果与注意事项 · 设置方法。

**状态:**0.0.14 已发布,这是首个不再使用 Jade 名称的版本;0.0.11 及更早版本使用 Jade——目前处于早期阶段,已可使用,欢迎反馈。想测试一下? 请从测试者指南开始。

curl -fsSL https://raw.githubusercontent.com/julianbei/arno/main/install.sh | sh

适用于 macOS 和 Linux——不支持 Windows(原因及支持投票链接)。 再次运行即可更新。其他安装方式。


目录


试用 ARNO:测试者指南

感谢参与测试。花半小时就能完成设置;真正有价值的是在日常工作中启用它一两周,然后告诉我们使用体验——包括你决定关闭它的情况。

1. 安装 ARNO 和语言服务器

macOS 和 Linux:

curl -fsSL https://raw.githubusercontent.com/julianbei/arno/main/install.sh | sh

抱歉,Windows 暂不受支持!如果你希望支持 Windows,请为 issue #2 点个 👍,或告诉我们它对你有何重要意义。(WSL 2 运行的是 Linux,因此 Linux 版本可能可以在那里运行,但我们不会对此进行测试,也不受理相关错误报告。)

脚本会为你的操作系统和 CPU 选择相应的构建版本,根据发布版本的校验和进行验证,并将其安装到 /usr/local/bin;如果该目录不可写,则安装到 ~/.local/bin —— 无需 sudo,也无需 Go 工具链。如果该目录不在 PATH 中,脚本会提供将其添加到 shell 配置文件的选项,并打印 MCP 客户端配置中要用作 command 的绝对路径。首次安装后,脚本会打开 arno-mcp install,这是一个用于安装所选语言服务器的菜单,也会介绍手动安装方法;按 Enter 跳过即可,也可以随时再次运行。再次运行同一条命令即可 更新 —— 有新版本发布时,ARNO 会通知你(参见 更新检查)。(更喜欢 Go?也可以运行 go install github.com/julianbei/arno/cmd/arno-mcp@latest。)ARNO 无需安装其他组件,即可读取所有语言的代码结构;要获取准确的引用、跨文件重命名和编辑时的类型错误,则需要相应语言的服务器 — arno-mcp install 会为你安装这些服务器,也可以手动安装:

语言安装备注
Gogo install golang.org/x/tools/gopls@latest首次响应约需 1.6 秒。
Javabrew install jdtls(需要 JDK 21+),或使用你的发行版提供的软件包索引期间首次响应约需 8.5 秒。check 会运行 mvn 或 gradle;如果只有 Gradle 包装器,让 Agent 声明一次 ./gradlew build(第 4 步)。
Scalacs install metals(coursier)设置 ARNO_METALS_IMPORT=1,以便 metals 导入 sbt 构建(这会创建 .bloop/ 和 .metals/)。首次响应约需 22 秒。
Kotlin—暂无语法解析器或服务器:只能进行文本搜索。如果你需要,请告诉我们。

缺少服务器绝不会导致错误:ARNO 会说明哪些结果只是近似值。

2. 将 Agent 指向一个真实的仓库

对于 Claude Code,请将以下内容放入你正在处理的仓库根目录下的 .mcp.json(其他主机:Codex CLI、goose、OpenCode):

{
  "mcpServers": {
    "arno": {
      "type": "stdio",
      "command": "arno-mcp",
      "args": ["--root", "/absolute/path/to/the/repo", "--tools", "core"],
      "alwaysLoad": true
    }
  }
}

这样也会保留 Claude Code 自带的工具。为了获得最清晰的信号,可以在一些会话中用 ARNO 代替这些工具:使用相同配置运行 claude --tools ""(原因及取舍)。 安装或升级 ARNO 后,重启客户端或重新连接(/mcp)。

3. 检查它是否已启动

向 Agent 提问:"call arno.capabilities"。你应该能看到所用语言,以及每种语言对应的 server … (not started) 或 no server (… not installed),还有 ARNO 找到的构建和测试命令(mvn、gradle、sbt、go test)。如果你安装的服务器显示为未安装,请提交错误报告。

4. 可以尝试的操作

像平常一样工作。如果你想为前几次会话准备一份清单:

  • 查找并跟踪代码:“X 在哪里声明,哪些地方调用了它?”——使用 find、 references。
  • **跨文件重命名:**在多个文件中使用的方法或类——使用 rename (运行 gopls、jdtls 或 metals 时可获得准确结果)。
  • 同时修改多个位置:“更改签名并更新调用方,然后检查是否能构建”——使用带 check 的 apply。
  • **运行相关测试:**使用文件名或测试名运行 run_tests,或使用 apply 并设置 check: "impact"。
  • **重复执行的命令:**让 Agent 使用 declare_command 声明你经常运行的命令(./gradlew :core:test、sbt "testOnly *ParserSpec");后续会话会从 .arno/commands.json 中重复使用这些命令。
  • **撤销:**在执行有风险的操作前使用 checkpoint,出错时使用 revert。
5. 告诉我们使用体验
时间提交此类反馈
使用一两周后——或关闭 ARNO 时反馈
已有 ARNO 工具,但 Agent 仍使用了 shell使用阻碍
工具给出了错误答案或运行失败错误
希望 ARNO 能实现的功能功能建议

模板会要求提供 arno.capabilities 的输出,以及可选的 arno.telemetry 输出。两者都不包含源代码;遥测数据 仅保存在本地,且不记录任何参数或响应文本,因此从私有仓库粘贴这两项内容都是安全的。

JVM 上已知的不足: Java 或 Scala 文件不会运行格式化程序; 大型 Gradle 构建会让 jdtls 的首次回答耗时远超 8.5s;暂不支持 Kotlin。


ARNO 的由来

如果 Agent 退而使用 grep、sed 和 cat,就意味着它在你无法掌控的工具链之外运行。没有版本跟踪,没有防护措施,没有遥测,也无从得知它做了什么,或为何选择那样做。每一次 shell 回退,都是你观测范围中的一个盲点。

仅仅告诉模型不要使用 shell,并不能解决问题。模型之所以使用 shell,是因为 shell 更省——所需 token 更少,往返次数更少,也更灵活。因此,唯一持久的解决办法,就是让结构化工具成为更省的选项,然后衡量是否达到了目标。

这就是全部的设想,而且可以验证。在本仓库自己的基准测试中,ARNO 用相当于 shell 命令 0.85x 的 token 数,回答了 7 个真实的工程问题。在响应从 JSON 改为纯文本之前,这个数值是 5.63x——变更内容及原因见 docs/response-style.md。

反向测试同样重要。在一个无关仓库中测试一个问题,结果是 1.36x——比 shell 更差,因为一个含义模糊的符号名称导致额外调用了一次来消除歧义。在熟悉的仓库中测了 7 个场景,在其他仓库中测了 1 个,结果并不一致,但都是真实的;而第二个结果更能预测实际使用表现。在 4 个外部仓库中进行的 0.0.4 试点提供了更大规模的答案:以 ARNO 替代 Claude Code 内置工具后,它解决了 12 个实际问题,token 数减少了 51%;与精简至 4 个工具的 shell 相比,token 数也减少了 18–25% (docs/benchmark-results.md)。ARNO 尚未完成。

ARNO 自身的开发日志(docs/feedback.md)记录了作者每次转而使用 bash 的情况及原因。日志发现的规律很直接:持续时间最长的那些回退方式,在被写入日志后的两个任务内就得到了改进——而不是等到工具发布后才改进。


安装

使用安装脚本
curl -fsSL https://raw.githubusercontent.com/julianbei/arno/main/install.sh | sh

下载适用于你的操作系统和 CPU 的最新发布二进制文件,根据 checksums.txt 验证文件,并将其安装到 /usr/local/bin 或 ~/.local/bin,无需 sudo。再次运行即可更新:如果 PATH 中已有 arno-mcp,脚本会在原位置替换它;如果已经是最新版本,则不会下载任何内容。如果该目录不在 PATH 中,脚本会提供将其添加到 shell 配置文件的选项(ARNO_ADD_TO_PATH=1 可在不询问的情况下执行),并打印 MCP 客户端配置中要使用的绝对路径。ARNO_VERSION 用于指定发布标签;ARNO_INSTALL_DIR 用于指定目录。你也可以先阅读脚本: install.sh。

不支持 Windows——请参阅 issue #2,如果你希望改变这一点,请点个 👍。

语言服务器:arno-mcp install
arno-mcp install                           # menu: pick what to install
arno-mcp install --list                    # what is installed, and how the rest would be
arno-mcp install --servers go,java,scala   # install these, no questions
arno-mcp install --all                     # every missing server this machine can install

菜单会列出 ARNO 可使用的每个语言服务器、是否已安装,以及它将运行的确切命令——gopls 使用 go install,jdtls 使用 brew install jdtls,metals 使用 cs install metals,TypeScript 和 Pyright 使用 npm install -g,rust-analyzer 使用 rustup component add rust-analyzer,ruby-lsp 使用 gem install ruby-lsp——并在执行任何操作前征求确认。对于机器上没有安装程序的服务器,菜单会提供手动安装说明。首次安装后,安装脚本会打开菜单;设置 ARNO_SKIP_SETUP=1 可跳过该步骤。

供 Agent 或任何脚本使用——没有可供回答菜单的终端,因此相同的步骤会直接执行,不会询问:

# install ARNO and chosen servers in one go
curl -fsSL https://raw.githubusercontent.com/julianbei/arno/main/install.sh | ARNO_SERVERS=go,java sh

arno-mcp install --list --json                   # state of every server, as JSON
arno-mcp install --servers java,scala --dry-run  # the commands, not run
arno-mcp install --servers java,scala            # run them

--list --json 会提供每个服务器的 key、是否已安装及其位置、在本机上用于安装它的 command,以及没有安装程序时的 manual 步骤。arno.capabilities 会在缺少服务器的那一行末尾附上安装该服务器的命令。安装操作刻意不做成 MCP 工具:全局软件包安装通过 Agent 的 shell 执行,由你批准。

其他安装方式

上面的安装脚本是最简单的方式。也可以使用以下方式。

从 Go 安装
go install github.com/julianbei/arno/cmd/arno-mcp@latest    # newest
go install github.com/julianbei/arno/cmd/[email protected]   # pinned to a tag

程序会安装到 $GOBIN;如果该变量未设置,则安装到 $(go env GOPATH)/bin——通常是 ~/go/bin,而且默认情况下不在 PATH 中。如果该目录不在 PATH 中,请将其添加进去,然后确认:

export PATH="$PATH:$(go env GOPATH)/bin"
arno-mcp --version

如果你不想修改 PATH,可以在 MCP 客户端配置中使用绝对路径,而不是下面所示的裸命令 arno-mcp。

从发布的二进制文件安装

每个 GitHub 发布版本都附带适用于 linux 和 darwin 的 amd64 与 arm64 预编译二进制文件,旁边还有一个 checksums.txt。每个二进制文件都在对应平台上原生构建——ARNO 通过 cgo 链接 tree-sitter,因此 linux 构建需要较新的 glibc。对于较旧的发行版,请从源码构建,或使用容器镜像;该镜像静态链接 musl。

VERSION=$(curl -fsSL https://api.github.com/repos/julianbei/arno/releases/latest | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' | head -n 1)
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
curl -fsSL "https://github.com/julianbei/arno/releases/download/${VERSION}/arno-mcp_${VERSION}_${OS}_${ARCH}.tar.gz" \
  | tar xz
sudo mv "arno-mcp_${VERSION}_${OS}_${ARCH}" /usr/local/bin/arno-mcp
作为 MCP bundle 安装,供 Claude Desktop 使用

从 0.0.11 版本起,每个 GitHub 发布版本还会附带 arno-mcp_<version>.mcpb,这是一个包含适用于 Intel 和 ARM 架构 macOS 与 Linux 的二进制文件的 bundle。使用 Claude Desktop 打开它,选择 ARNO 要操作的仓库,然后即可使用核心工具;无需终端,也无需 Docker。语言服务器仍需通过 arno-mcp install 安装,也可以不安装它们,仅使用 tree-sitter。

从源码安装
git clone https://github.com/julianbei/arno.git
cd arno
make binary          # bin/arno-mcp, version stamped from git describe
make install         # or straight onto your PATH
可选:gopls

references 和 rename 使用 gopls 获取精确且经编译器解析的结果。没有它也能正常工作——references 会降级为文本近似结果,并在响应中说明这一点;rename 则会拒绝执行,而不会猜测。

arno-mcp install --servers go      # or: go install golang.org/x/tools/gopls@latest

以下所有语言也一样:arno-mcp install 会显示哪些服务器已安装,并安装其余服务器(语言服务器)。


配置 MCP 客户端

ARNO 是一个 stdio MCP 服务。将客户端指向该二进制文件:

{
  "mcpServers": {
    "arno": {
      "type": "stdio",
      "command": "arno-mcp",
      "alwaysLoad": true,
      "env": {
        "ARNO_WORKSPACE_ROOT": "/absolute/path/to/the/repo/arno/should/work/on"
      }
    }
  }
}

ARNO_WORKSPACE_ROOT 是 ARNO 检查和编辑的仓库。它不必是 ARNO 的检出目录——这正是允许将其指向其他位置的原因。--root /path/to/repo 标志的优先级高于环境变量;启动时,ARNO 会打印它使用的三个来源之一(标志、环境变量、工作目录),因此 Agent 绝不会悄悄操作错误的仓库。

ARNO 可在非 git 目录以及尚无提交的仓库中运行。这两种情况下,它都会说明哪些功能受限——changes、diff、history 和 checkpoint 需要 git——其余功能仍可正常工作。

让 ARNO 替代内置工具

ARNO 在替代 Agent 自带工具时可以节省令牌,而不是与这些工具并列添加时。每轮都会重新发送完整的工具列表;在 Claude Code 中,内置工具约占其中 38k 个令牌。在 ARNO 的试点基准测试中(针对 cobra、ky、requests 和 ripgrep 的 12 个真实问题,每个问题运行一次):

工具已解决任务数每次运行的令牌数每次运行耗时
Claude Code 的内置工具12 个中的 10 个1.38M215s
精简后的内置工具:Bash、Read、Edit、Write12 个中的 10 个0.90M213s
仅使用 ARNO,核心配置12 个中的 12 个0.68M163s
两者并用,所有内置工具和 ARNO12 个中的 11 个1.50M191s

仅精简内置工具列表,就能节省大部分令牌。在此基础上使用 ARNO,与精简后的 Shell 配置相比,令牌数减少了 25%,耗时减少了 24%,并解决了两种 Shell 配置都未能解决的两个任务。如果同时提供 ARNO 和所有内置工具,Agent 有五分之四的调用会使用 Bash,并且要为两份列表付费。如需使用 ARNO 替代内置工具:

claude --tools "" --mcp-config arno.json

通过 arno.json 传入核心配置,其中列出了 12 个工具——读取、编辑、验证,以及运行仓库声明的命令——并保留其他工具供调用:

{
  "mcpServers": {
    "arno": {
      "type": "stdio",
      "command": "arno-mcp",
      "args": ["--root", "/absolute/path/to/the/repo", "--tools", "core"],
      "alwaysLoad": true
    }
  }
}

这确实存在取舍:没有 Bash,Agent 就无法运行任意命令。run_tests、check 和通过 declare_command 声明的仓库命令,可以用于构建、测试和运行可重复执行的脚本——声明保存在 .arno/commands.json 中,后续会话可以重复使用;需要执行 git 操作、访问网络或运行临时脚本的任务,则仍需要 Shell。以上数据是每个任务运行一次的结果——请参阅 docs/benchmark-results.md,了解测试结果、在修复试点问题后重新运行的结果,以及相关注意事项。

其他宿主

已通过实时会话验证——找到一处声明,在其旁边插入配置,然后运行 check——仅使用 ARNO 的工具:

Codex CLI(0.154),配置文件为 ~/.codex/config.toml:

[mcp_servers.arno]
command = "arno-mcp"
args = ["--root", "/absolute/path/to/the/repo", "--tools", "core"]

Codex 每次调用 MCP 工具前都会询问。设置 approval_policy = "never" 后,它会直接拒绝调用;请运行 codex exec --approve-for-me,或在交互过程中批准 ARNO 的工具。

goose(1.50),运行一次时:

goose run --with-extension "arno:arno-mcp --root /absolute/path/to/the/repo --tools core" -t "…"

也可以通过 goose configure → Add Extension → Command-line Extension 永久配置,命令为 arno-mcp --root /absolute/path/to/the/repo --tools core。已通过 goose 的 claude-code 提供程序验证。

OpenCode(1.18),配置文件为仓库根目录下的 opencode.json,或 ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "arno": {
      "type": "local",
      "command": ["arno-mcp", "--root", "/absolute/path/to/the/repo", "--tools", "core"],
      "enabled": true
    }
  }
}

OpenCode 会在工具名称前加上服务名称前缀,因此工具会显示为 arno_arno_find 等。已通过 github-copilot 提供程序(Claude Sonnet 5)验证。

Cline 和 Gemini CLI 尚未验证。

有三件事会让你一开始感到困惑

如果没有 "alwaysLoad": true,Claude Code 可能永远不会使用 ARNO。 Claude Code 默认会通过工具搜索来隐藏 MCP 工具:Agent 能看到工具名称,却看不到其定义,必须先搜索才能调用工具。由于它手边就有自己的 shell 和文件工具,因此通常不会搜索。在 ARNO 的基准测试中,同时提供 ARNO 和 shell 的 Agent 在三次运行中一次也没有调用 ARNO;相同设置下,使用 alwaysLoad 时则会直接调用 ARNO。其他宿主也可能有自己的对应设置——请确认 ARNO 的工具确实被调用。

一个服务对应一个代码库,但可以服务其所有工作树。 ARNO 会固定在其启动时所在的目录,你 shell 中的 cd 无法影响它——MCP 不会为每次调用传递工作目录。在同一代码库的另一个 git worktree 中工作的会话,只需通过 arno.workspace path=<worktree> 指定一次;其子 Agent 会继承此设置。在不同工作树中的子 Agent,则需在自己的调用中传入 root=<path>。对于多会话场景,可设置 ARNO_REQUIRE_WORKSPACE=1,这样从未说明自己在哪个工作树中工作的会话发起写入时,系统会拒绝操作,而不是将更改写入共享的检出目录。请参阅 docs/worktrees.md。

MCP 工具目录在连接时固定。 新增的工具不会立即出现,客户端必须重新连接。如果你在会话中途升级了 ARNO,却发现某个工具似乎缺失,请先重新连接,再进行排查。

请使用二进制文件,不要使用 go run ./cmd/arno-mcp。 go run 配置会在每次进程启动时重新编译:在此测得,即使使用预热过的构建缓存,完成首次握手也需要 284–584ms,而二进制文件只需 14ms。冷缓存则需要几秒钟。此外,源代码每次变动都会让服务静默地发生变化——开发 ARNO 本身时很有用,在其他情况下却会令人困惑。出于这个原因,本代码库自己的 .mcp.json 仍特意使用 go run。

环境变量
变量作用
ARNO_WORKSPACE_ROOT要操作的代码库。可被 --root 覆盖。
ARNO_JSON=1输出机器可读的 JSON,而不是纯文本。
ARNO_TELEMETRY=0完全禁用本地用量记录。
ARNO_STATE_DIR将遥测日志保存在工作区之外,每个工作区对应一个子目录。
ARNO_METALS_IMPORT=1让 metals 导入 sbt 构建,以便为 Scala 编辑提供诊断信息。会运行 sbt;并创建 .bloop/ 和 .metals/。
ARNO_UPDATE_CHECK=0关闭每日新版检查(更新检查)。
ARNO_REQUIRE_WORKSPACE=1在包含多个工作树的代码库中,拒绝写入,直到会话通过 arno.workspace(或在调用中通过 root=)指定其工作树。适用于共享同一检出目录的多会话场景。请参阅 docs/worktrees.md。
ARNO_MAX_WORKSPACES一个服务同时保持打开的 git 工作树数量(默认值为 3,最久未使用的工作树会先被逐出)。请参阅 docs/worktrees.md。

安装脚本还会读取以下变量:

变量作用
ARNO_VERSION要安装的版本,例如 v0.0.12。默认:最新版本。
ARNO_INSTALL_DIRarno-mcp 的安装位置。默认:PATH 中已有的 arno-mcp 所在目录;若无,则为可写时的 /usr/local/bin;否则为 ~/.local/bin。
ARNO_SERVERS无需菜单即可随后安装的语言服务:go,java,scala,typescript,python,rust,ruby,或 all。
ARNO_SKIP_SETUP=1跳过语言服务安装步骤。
ARNO_ADD_TO_PATH=1无需询问,即将安装目录添加到 shell 配置文件中。
ARNO_RELEASE_URL发行版的基础 URL,可用于指定镜像。

在容器中使用

ARNO 是一个子进程,而不是服务,因此实用的做法是将二进制文件复制到你自己的镜像中,而不是运行 ARNO 的镜像:

FROM ghcr.io/julianbei/arno-mcp:latest AS arno

FROM your-project-base
COPY --from=arno /arno-mcp /usr/local/bin/arno-mcp
ENV ARNO_WORKSPACE_ROOT=/workspace

或者,使用随附的 Dockerfile 自行构建。

发布的镜像是 distroless/static,因此不包含 git、gopls 或语言工具链。ARNO 会在运行时检测这些组件;如果缺少,就会显示明确提示并降级运行,而不是直接失败,因此仍然可以使用——你会获得文本形式的 references 回退功能,而 changes/diff/history/checkpoint 则不可用。如果想使用完整功能,请在你自己的镜像中安装 git 和 gopls;ARNO 会找到它们。


工具

共 31 个工具,分为四组。每个响应都是纯文本,并采用便于快速获取关键信息的格式——先给出答案,再提供支持细节,只有在你要求时才提供原始输出。

通过 MCP,每个工具都会注册为 arno.<name>——例如 arno.outline、arno.replace_symbol 等。为便于阅读,下表使用不带前缀的名称。大多数 MCP 客户端会直接显示带前缀的名称,通常还会改写其中的点号(Claude Code 显示为 mcp__arno__arno_find)。在传输过程中,ARNO 同时接受 arno.find 和 arno_find。

检查
工具功能
capabilitiesARNO 在此工作区中的功能:按语言列出语法或文本扫描、语言服务器状态、格式化程序;git、验证命令和已声明的命令。请先调用此工具。
outline文件结构——按类型分组的声明,不读取正文。
read_range原样读取指定行,或整个文件。lines: "280-400" 用于指定范围;ranges 可在一次调用中读取多个文件或范围;如果结束行超出文件长度,则读取到文件末尾。dep:<name>/<path> 以只读方式读取依赖项在锁定版本中的源代码——使用 grep 和 find 搜索时,可通过 dependency 指定依赖项。
find一次调用即可定位声明并获取其正文。queries 可同时查找多个名称。
grep使用路径 glob 进行字面文本或正则表达式搜索。可替代 grep -rn。
references查找用法。安装了语言服务器时,结果精确;否则会按名称匹配并给出近似结果,同时说明由哪种方式提供了结果。
retrieve根据查询提取一组工作所需的内容。
context汇总某个符号周围的上下文。
workspace_tree目录结构。

符号可通过 path::Name 指定;名称不唯一时,可使用 path::Name@line。如果读取的名称不唯一,工具会返回候选项及其签名,而不是自行猜测。

修改
工具功能
replace_symbol替换整个声明。使用完整的 path::Name@line ID;如果名称在文件中唯一,也可以只用 path::Name。
replace_text替换精确且唯一的文本。以内容为锚点,而不是以行号为锚点。与所有文本编辑操作一样,完成后会返回编辑区域的当前内容。
replace_file替换整个文件的内容。
create_file创建新文件。
delete_file删除一个文件;不允许删除目录。
delete_symbol删除一个声明。
rename通过语言服务器跨文件重命名;如果无法确保精确,则拒绝操作,而不是猜测。
insert添加文本,不替换任何内容——例如新增函数、新章节或额外分支。不使用锚点时追加内容;使用唯一锚点时,则在其前面或后面插入。
apply将多项编辑作为一个原子单元执行——预先验证锚点,要么全部应用,要么全部不应用;只提升一次修订版本,并在最后进行一次验证。

每次编辑都会返回后续影响,而不只是“成功”:修订版本的变化、发生变动的符号、即时诊断,以及启动的后台验证 ID。编辑操作接受 expectedRevision 前置条件;提供此参数后,过期编辑会明确失败,而不会悄悄覆盖并发更改。

验证
工具功能
check构建、类型检查或测试——根据清单文件发现仓库自身的命令,而不是想当然地指定命令:依次查找 Makefile 目标、npm 脚本、cargo、Maven、Gradle、sbt、pytest/mypy 或 bundler。无法识别的项目会明确报告,而不会使用错误的工具链运行。每条结果都会列出实际运行的命令;dryRun 会列出命令但不运行。
run_tests针对某个文件、测试名称或已更改文件运行测试。
run_command按名称运行仓库中声明的命令之一。
declare_command添加或移除已声明的命令。
job_status轮询后台任务。
job_output按需获取任务的原始输出。

退出状态具有决定性。命令即使打印出看似成功的内容,只要以非零状态退出,就算失败。

状态
工具功能
changes查看哪些内容发生了变化——按文件和符号列出,而不只是按路径。
diff查看补丁,包括未跟踪文件。since 可接受任意 git 修订版本。
history通过 git log -L 查看哪些提交修改过某个符号。
checkpoint标记一个可还原的时间点:为 ARNO 编辑过的文件创建快照,并记录 git 的 HEAD。这不是提交。
revert将这些文件还原到某个检查点。不会移动 git;如果检查点之后有提交,则会拒绝还原。
events工作区事件流。
telemetry查看 ARNO 自身的工具在此工作区中的使用情况。
workspace列出此仓库的 git 工作树,并更改会话默认服务的工作树。

除 workspace、events、telemetry、job_status 和 job_output 外,上述每个工具还接受可选参数 root=<path>:指定此仓库的某个 git 工作树,以便仅在本次调用中操作。参见 docs/worktrees.md。


项目配置

发现机制会根据清单文件推测如何构建和测试仓库,但有时会猜错:Makefile 中的 python -m pytest 会选用系统解释器;npm run test 会在单文件检查时运行 lint 和浏览器测试套件;而旁边有 TypeScript 应用的 Go 模块,对于“构建”也有两个答案。提交 .arno/project.json 文件即可一次性指定答案,就像编辑器将设置保存在 .vscode/ 中一样:

{
  "areas": [
    { "path": ".", "language": "go",
      "build": "go build ./...", "test": "go test ./...",
      "testName": "go test -run {name} ./..." },
    { "path": "web", "language": "typescript",
      "typecheck": "node_modules/.bin/tsc --noEmit",
      "test": "node_modules/.bin/vitest run",
      "testFile": "node_modules/.bin/vitest run {file}",
      "testName": "node_modules/.bin/vitest run {file} -t {name}" }
  ],
  "env": { "python": ".venv/bin/python", "vars": { "CI": "1" } },
  "generated": ["web/dist", "*.pb.go"],
  "notes": "Browser tests need Playwright; run unit tests by file."
}
  • 区域是仓库中使用各自语言和命令的部分,每条命令都在对应路径下运行。check 会在每个声明了相应类型的区域中运行该类型的检查;run_tests 使用文件时,会选取包含该文件的最深层区域,其中 {file} 相对于该区域,{name} 为测试名称。
  • 空字段会回退到发现机制,因此配置只需写明发现机制无法正确判断的内容。无法解析、包含未知字段或指定了工作区之外路径的配置会导致检查失败,而不会被忽略。
  • env 会将解释器目录放在 PATH 最前面,并将其中的变量添加到每条命令中。generated 路径会从 grep、find 和工作区目录树中排除。会连同区域列表一起发送给 Agent 的 notes 会在会话开始时提供给 Agent。
  • 使用 dryRun 执行 check 时,如果命令来自 .arno/project.json,会明确指出。

arno-mcp init --root /path/to/repo 会根据发现结果为你生成文件草稿,包含一个区域,供你审核并提交;它绝不会覆盖已有文件。

仓库命令

除了构建和测试,每个仓库都有自己的命令——lint、代码生成、迁移、发布门禁——不了解这些命令的 Agent 就会转而使用 shell。因此,ARNO 允许它记录这些命令:

declare_command(name: "lint", run: "golangci-lint run ./...")
run_command(name: "lint")

这些命令保存在 .arno/commands.json 中,建议将此文件提交到仓库。它会成为仓库声明的命令词汇表——由弄清楚具体调用方式的人(或工具)记录一次,此后就能始终按名称调用。调用不带名称的 run_command 会列出仓库声明的命令;使用未知名称调用时,则会返回实际存在的命令,让错误猜测带来提示,而不是直接失败。

这两种回答也会列出检测到的候选项:ARNO 能从仓库自身清单中发现、但尚未有人声明的 npm 脚本和 Makefile 目标。检测只读——只有 declare_command 明确声明后才会写入内容——而且,如果某个脚本 check 已经用于构建、类型检查或测试,就不会列出,因为这并不构成缺漏。capabilities 也会在现有报告内容旁显示这些候选项。这解决了 2026-09-16 基准测试直接测出的一个失败场景:在什么命令都没声明的仓库中,Agent 猜测 run_command 的名称(test-unit、model_formsets_tests),每次猜测都浪费一次调用,而清单其实早已给出了答案。

验证链

仓库规则——Semgrep、自定义 linter、许可证检查——应归入验证流程,且无需与 ARNO 集成。只需声明一个按顺序运行各步骤的命令,并用 && 连接:

{
  "validate": {
    "run": "go test ./... && semgrep scan --config .semgrep.yml --error",
    "description": "tests, then repository rules"
  }
}

或者不编辑文件,直接调用 declare_command(name: "validate", run: "…")。

run_command(name: "validate") 会在 ARNO 内运行该命令,因此运行情况会记录在会话记录中。运行结果由退出状态决定:任何规则失败,整个运行就会失败;后续步骤不会执行,摘要也会首先显示失败输出。请使用 semgrep scan --error 或工具的等效标记——如果工具只打印发现项并以 0 退出,就会被视为通过。


语言支持

结构信息来自编译到二进制文件中的 tree-sitter 语法,因此无需安装任何内容即可使用。语义信息来自真实的语言服务器,需要由你提供——arno-mcp install 会为你安装——ARNO 会在首次使用时启动它,在本次会话中重复使用,并在退出时关闭它。

语言结构信息安装后可用的语义信息
Go✅ 内置gopls
TypeScript / TSX✅ 内置typescript-language-server
JavaScript✅ 内置typescript-language-server
Rust✅ 内置rust-analyzer
Python✅ 内置pyright-langserver,或 pylsp / jedi-language-server
Ruby✅ 内置ruby-lsp,或 solargraph
Java✅ 内置jdtls
Scala✅ 内置metals
其他所有语言文本扫描,并会说明—

make conformance 会对每一行进行端到端验证:它会构建一个包含全部 8 个服务器的镜像,并针对每种语言的真实代码库运行 ARNO。

语义请求会等待服务器完成索引(其 $/progress 令牌),因为索引中的服务器会给出错误答案,而不只是响应较慢。当首选服务器拒绝重命名时,ARNO 会询问该语言已安装的备用服务器:ruby-lsp 可以重命名类,但不能重命名方法,因此要重命名 Ruby 方法,需要同时安装 solargraph。 如果只安装了 ruby-lsp,方法重命名会被拒绝,并重复显示服务器给出的原因。

每个编辑响应都会说明文件由什么检查(checked: pyright-langserver),或者说明未检查的原因(not checked: app.py: pyright-langserver is not installed)。

Scala 需要显式选择启用。 metals 只有在导入 sbt 构建后才会报告错误,而且会先征求许可,因为导入会运行 sbt,并在代码库中创建 .bloop/ 和 .metals/。除非设置了 ARNO_METALS_IMPORT=1,否则 ARNO 会拒绝导入,并在编辑响应中说明这一点。已被编辑器导入过的代码库无需设置。

“结构信息”包括大纲、符号读取、按符号编辑、grep 和搜索。“语义信息”包括精确的 references、跨文件 rename,以及编辑时的类型级诊断。

ARNO 会在 PATH 和工具链实际安装服务器的位置中查找它们——~/go/bin、~/.cargo/bin、~/.local/bin、~/.coursier/bin——因为 go install 会把 gopls 安装到默认不在 PATH 中的位置;只检查 PATH 的客户端会在装有可用 gopls 的机器上错误地报告 Go 不受支持。

缺少服务器不会导致错误。ARNO 会按上述方式降级,并说明你获得的是哪种答案。

设计原则

  1. 先看结构,再看源码。 首先返回足够使用的最简表示——先给大纲,再给完整源码;先给摘要,再给原始日志。
  2. 先用确定性工具,再进行模型推理。 ARNO 会编排 tree-sitter、git、gopls 和项目自己的构建工具。它不会重新实现这些工具,也不会在这些工具能给出答案时自行猜测。
  3. 每次编辑都有前置条件,并会返回影响。 编辑可以指定预期的修订版本;如果 ARNO 的修订版本已变更,编辑就会被拒绝。编辑会返回修订版本的变更、变更内容和诊断信息,而不是只返回“成功”。ARNO 之外所做的变更暂时不会推动修订版本(发布计划第 5 阶段)。
  4. 先给结论,再给日志。 先给出判定;原始输出可按需展开。
  5. 先做语义操作,再做文本操作。 但也保留文本操作的备用途径,因为语义操作并非总是可行。
  6. 状态明确可见。 修订版本、检查点和变更集都是对象,而非隐含信息。
  7. 验证默认等待,按需在后台运行。 check、run_tests 和 run_command 会返回判定;长时间运行的任务也可以返回一个供轮询的作业。
  8. 近似结果必须明确说明。 当 ARNO 退回到文本扫描或基于名称匹配的图时,相关限制会随数据一同出现在响应中,而不是只写在 Agent 永远不会看的文档里。
  9. ARNO 不依赖特定模型或运行环境。 MCP 是适配层,而非架构本身。
  10. 衡量 Agent 的任务结果,而非基础设施的复杂程度。 关注每项已完成任务所用的令牌数和轮次;如果成功率随令牌数一同下降,那么减少令牌毫无价值。
  11. 使用仓库原生方式执行。 构建、测试和 lint 通过仓库自己的命令运行——这些命令会自动发现,或在 .arno/commands.json 中声明——并在 ARNO 中执行,因此验证会成为记录的一部分,而不是一次脱离工作流的 Shell 操作。
  12. 比备用途径更省。 如果 Shell 对某个工作流来说更简单、更快、更省,ARNO 就没能满足该工作流。以基准测试而非主观意见为准(docs/benchmark.md)。

更完整的设计文档见 docs/scope.md。


什么时候 Shell 仍是合适的工具

ARNO 并不试图匹配 Shell 的可组合性。在以下情况下,使用 Shell 是有意为之,而非遗漏:

  • Git 操作:提交、分支、变基、推送、blame。ARNO 会读取 git 状态(changes、diff、history),但不会更改这些状态。
  • 一次性探查:用 curl 访问本地服务、检查进程、检查端口、读取环境变量。
  • 调试脚本或构建系统本身,此时要解决的问题是 Shell 命令的行为,而非代码所表达的内容。
  • 安装依赖和工具链:npm install、go install、pip install。
  • 任何形式的网络访问。

以下工作仍由 ARNO 负责,即使 Shell 也能完成:

  • 构建、类型检查、测试、lint 和代码生成。 使用 check、run_tests 或已声明的命令(先用 declare_command 声明,再用 run_command 运行)。从 Shell 运行的验证不在变更事务的可见范围内:编辑记录中没有判定,没有范围限定的测试运行器,也没有失败摘要。
  • 读取和搜索代码,以及编辑代码。ARNO 的修订版本、诊断信息和溯源信息在这些操作中发挥作用。

如果你一直从 Shell 运行某个验证命令,就应将它加入 .arno/commands.json,或在 .arno/project.json 中将其声明为某个区域的构建或测试命令。


ARNO 目前尚不能做什么

Windows。 ARNO 仅针对 macOS 和 Linux 构建和测试,我们宁愿把这两个平台做好,也不愿在三个平台上都只做到一半。在另行通知之前,我们不会为 Windows 构建、测试或查看问题。如果你希望 ARNO 支持 Windows,请 👍 issue #2 — 如果你认为这个决定不妥,也请在那里说明;欢迎坦诚反馈。WSL 2 运行的是 Linux,因此 Linux 版本可能可以在那里运行,但未经测试。

这份列表比功能列表更有用——它会告诉你哪些问题值得报告,以及哪些问题已为人所知。计划中的内容见 ROADMAP.md。

  • 九种语言使用真正的语法解析;其余语言则退回文本扫描。 Go、TypeScript、TSX、JavaScript、Python、Ruby、Java、Scala 和 Rust 都会被正确解析。其他语言(Kotlin、Swift、C/C++、C#、PHP 等)则使用启发式方法查找部分声明,遗漏其他声明;不同语言的遗漏程度差异很大,因此应将这些大纲视为提示,而非完整清单。ARNO 始终会说明使用的是哪种方式(! no kotlin grammar — …)。
  • 语义功能需要安装相应语言的语言服务器。 ARNO 会通过 LSP 与机器上已有的语言服务器通信(参见 语言支持)。使用语言服务器时,references 和 rename 的结果与编译器完全一致,并支持跨文件操作。没有语言服务器时,references 会降级为文本近似结果,并明确说明这一点;rename 则会拒绝操作,而不是猜测——近似的引用列表仍可供读者参考,但近似的编辑会造成内容损坏。
  • 不支持补全、悬停或代码操作。 ARNO 的 LSP 客户端只实现工具所需的功能——引用、重命名、诊断——并非完整的协议。
  • 不支持 blame、跨仓库操作或远程执行。
  • 格式化遵循项目自身的规则,且仅针对你编辑过的文件。 gofmt 和 rustfmt 始终会运行。prettier(TypeScript/JavaScript)、black 或 ruff(Python)以及 scalafmt 仅在仓库声明使用时才会运行——通过 prettier 配置或 package.json 键、[tool.black]、[tool.ruff.format] 或 ruff.toml 中的 [format] 区段、.scalafmt.conf 声明;对于 Node 和 Python,会使用项目自身的二进制文件,因为项目未选择的格式化工具会把一行编辑变成整个文件的差异。rustfmt 会读取最近的 rustfmt.toml,并从 Cargo.toml(或工作区)读取 edition,然后只格式化单个文件:它不会跟随 mod 声明格式化你未修改的文件。Ruby、Java、JSON 和 Markdown 会保持编辑后的样子;ARNO 不会解析 .editorconfig。
  • 修订跟踪使用 ARNO 自己的计数器,而非 git 的计数器。 它会检测会话内的并发编辑,但它不是 VCS。检查点会为 ARNO 已编辑的文件创建快照,并记录 git 的 HEAD;revert 会还原这些文件,不涉及其他内容,也绝不会移动 git;如果检查点之后已有提交落盘,它会拒绝还原——撤销已提交的工作应由 git 负责。服务器重启后,检查点不会保留。
  • 尚未针对不可信输入进行加固。 它会运行你声明的 shell 命令,并编辑你指定的文件。请将其视为开发工具,不要让它处理你不愿运行 make 的仓库。在沙盒或容器中运行 ARNO 能覆盖和不能覆盖的内容如下:
    • 由 ARNO 本身覆盖: 读取和写入操作都限制在工作区根目录内,包括符号链接;依赖项源文件为只读;仓库无法让 ARNO 启动其自带的二进制文件(已声明的命令会通过你已信任的 shell 运行,而 .arno/project.json 中的解释器路径也会显示在差异中,供你审查)。
    • 仅由沙盒覆盖: check、run_tests 或 run_command 运行已声明命令、Makefile 目标、npm 脚本或测试套件时的行为,包括网络访问、工作区外的文件以及环境中的凭据。ARNO 会使用你的环境运行仓库自身的命令;恶意仓库的 make test 在 ARNO 中运行,与在你的 shell 中运行同样危险。
    • 完全不覆盖: 被要求声明有害命令的 Agent,以及语言服务器;语言服务器在索引工作区时会执行自身的项目配置(构建脚本、插件)。

稳定性与版本管理

工具名称和必需参数已冻结,并由测试强制执行。0.0.3 未添加任何工具,并将两个参数设为可选(find 的 query 和 read_range 的 path),两者均向后兼容。架构和服务端说明仍只会在连接时读取一次,因此升级后请重新连接。 docs/tool-contract.md 列出了完整接口以及对哪些变更算作破坏性变更的政策。

未冻结的内容:响应的措辞、.arno/* 文件格式、符号 ID 的具体拼写,以及 internal/ 下的所有内容。请将响应视为供模型阅读的文本,而非可解析的格式。如果需要解析内容,请使用 ARNO_JSON=1 获取机器可读的输出。


遥测

ARNO 会记录自身工具的使用情况——调用次数、响应大小、耗时,以及最常导致调用方放弃并改用 shell 的失败类别。

记录写入工作区中的 .arno/telemetry.jsonl,并且绝不会传输到任何地方。记录中不包含参数、响应正文或错误文本——只包含每次调用目标(路径、符号或查询)的 10 位哈希值,以便混淆报告识别出第二个工具询问的是同一内容。设置 ARNO_TELEMETRY=0 可关闭遥测;telemetry(reset: true) 可清除记录。

ARNO 会尽量避免在仅被要求处理的仓库中留下文件:

  • 在 git 仓库中,创建日志前,ARNO 会将其添加到 .git/info/exclude——这是仅对本地克隆生效、不会提交的忽略文件——除非 git 已经忽略该文件。.gitignore 不会被修改。日志不会显示为未跟踪文件,因此会提交所有未跟踪文件的测试框架不会将其提交。
  • ARNO_STATE_DIR=/some/dir 会将日志移出工作区,放入按工作区划分的子目录中。如果 ARNO 的根目录是某个会被其他程序整体提交或审查的检出目录,请使用此设置。
  • ARNO 直接拒绝的调用(工具名称未知)不会创建日志。

.arno/commands.json 则不同:它是仓库声明的命令词汇表,旨在提交到仓库中,并且只有在你声明命令时才会创建。

更新检查

与遥测分开,ARNO 会查询 GitHub 上最新的发布标签——发送一次未经身份验证的 releases/latest 请求,不包含任何关于工作区或你如何使用 ARNO 的信息——每天最多一次,在后台执行,超时时间为 3 秒。检查失败或处于离线状态时,也会等待一天。存在较新版本时,只有在你询问当前运行版本时才会提示:

$ arno-mcp --version
arno-mcp v0.0.12
update available: v0.0.13 (running v0.0.12) · curl -fsSL https://raw.githubusercontent.com/julianbei/arno/main/install.sh | sh, then reconnect your MCP client

并且会显示为 arno.capabilities 的第二行。它绝不会出现在服务端说明或其他工具响应中。设置 ARNO_UPDATE_CHECK=0 可关闭此功能;在 CI(设置了 CI)和开发构建中,此功能也会关闭。

设置此功能的原因是,阅读响应的人无法直观看到响应的成本。首次在实际使用中检查时,发现某个工具在一次常规调用中用时 704ms,返回了 4.6KB 内容——此前十六项手写笔记都未能发现这一点。


问题反馈

docs/reporting.md 说明了什么样的报告有帮助。这里有四种问题模板:

  • 反馈——实际使用后的感受,或你关闭它的原因。
  • 缺陷——它做错了事。
  • 使用阻碍——“我改用 shell 了。” 这是最有价值的一类。
  • 功能愿望——它应该能够做到 X。

如果不确定选哪种,就选使用阻碍。它最容易撰写,也最容易采取行动,而且**“只是习惯而已”也是有效答案**——我们欢迎这样的反馈。每次改用 shell 都说明 ARNO 不值得被调用,而这正是唯一能可靠帮助改进它的信号。

提交缺陷报告前,请确认版本变更后客户端是否重新连接过。工具目录过期,可以解释相当一部分“这个工具不存在”和“我的修复没有生效”的问题。


开发

make build      # go build ./...
make test       # go test ./...
make fmt        # gofmt -w ./cmd ./internal
make binary     # bin/arno-mcp, version-stamped
make install    # onto your PATH

仓库在 .arno/commands.json 中声明了自己的命令,包括 release-gate——构建、vet、测试和 gofmt 检查,这是标签必须通过的门槛。 像 Agent 那样运行它:run_command(name: "release-gate")。

目录结构:

路径内容
cmd/arno-mcpMCP 标准输入/输出服务——重要的入口。
cmd/arno一个用于直接驱动内部 API 的小型 CLI。
cmd/arno-benchToken 基准测试:比较 ARNO 与等效的 shell 命令。
internal/workspace修订、变更集、检查点、git。
internal/code符号索引、大纲、搜索、grep、引用。
internal/edit修改、原子应用、格式化。
internal/diagnostics对编辑即时反馈;gopls。
internal/jobs异步任务运行器、命令发现。
internal/languages按语言划分的适配器(Go、TypeScript、Rust)。
internal/commands已声明命令的注册表。
internal/telemetry本地使用情况记录。
internal/transportMCP 适配器,以及与传输无关的内部 API。
internal/protocol共享的请求和响应类型。

欢迎贡献。唯一的硬性规则是原则 8:如果添加了近似实现的代码路径,响应中必须说明这一点。


许可证

Apache License 2.0——请参阅 LICENSE。版权所有 2026 Julian Amelung。

评论

支持 Markdown

第一次接触 MCP?

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

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