关于 ARNO
ARNO 是面向编码 Agent 的 MCP 服务,提供类似 IDE 的仓库导航与受控编辑。它支持按符号探索代码、基于版本修改、运行构建验证并回滚。
主要功能
- 01按符号导航代码
- 02基于版本编辑并返回诊断
- 03运行仓库构建与测试命令
- 04创建检查点并回滚
- 05支持语言服务器
适用场景
- 01追踪声明及调用方
- 02跨文件重命名符号
- 03修改代码并检查构建
- 04撤销高风险编辑
MCP 相关
ARNO 通过 MCP 向编码 Agent 提供仓库导航、编辑、验证和检查点操作工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
ARNO — Agent 仓库导航与操作
面向 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.38M | 215s |
| 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:测试者指南
- ARNO 的由来
- 安装
- 配置 MCP 客户端
- 在容器中使用
- 工具
- 仓库命令
- 语言支持
- 设计原则
- shell 仍然是合适工具的场景
- ARNO 尚未实现的功能
- 稳定性与版本管理
- 遥测
- 报告问题
- 开发
试用 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 会为你安装这些服务器,也可以手动安装:
| 语言 | 安装 | 备注 |
|---|---|---|
| Go | go install golang.org/x/tools/gopls@latest | 首次响应约需 1.6 秒。 |
| Java | brew install jdtls(需要 JDK 21+),或使用你的发行版提供的软件包 | 索引期间首次响应约需 8.5 秒。check 会运行 mvn 或 gradle;如果只有 Gradle 包装器,让 Agent 声明一次 ./gradlew build(第 4 步)。 |
| Scala | cs 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.38M | 215s |
| 精简后的内置工具:Bash、Read、Edit、Write | 12 个中的 10 个 | 0.90M | 213s |
| 仅使用 ARNO,核心配置 | 12 个中的 12 个 | 0.68M | 163s |
| 两者并用,所有内置工具和 ARNO | 12 个中的 11 个 | 1.50M | 191s |
仅精简内置工具列表,就能节省大部分令牌。在此基础上使用 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_DIR | arno-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。
检查
| 工具 | 功能 |
|---|---|
capabilities | ARNO 在此工作区中的功能:按语言列出语法或文本扫描、语言服务器状态、格式化程序;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 会按上述方式降级,并说明你获得的是哪种答案。
设计原则
- 先看结构,再看源码。 首先返回足够使用的最简表示——先给大纲,再给完整源码;先给摘要,再给原始日志。
- 先用确定性工具,再进行模型推理。 ARNO 会编排 tree-sitter、git、gopls 和项目自己的构建工具。它不会重新实现这些工具,也不会在这些工具能给出答案时自行猜测。
- 每次编辑都有前置条件,并会返回影响。 编辑可以指定预期的修订版本;如果 ARNO 的修订版本已变更,编辑就会被拒绝。编辑会返回修订版本的变更、变更内容和诊断信息,而不是只返回“成功”。ARNO 之外所做的变更暂时不会推动修订版本(发布计划第 5 阶段)。
- 先给结论,再给日志。 先给出判定;原始输出可按需展开。
- 先做语义操作,再做文本操作。 但也保留文本操作的备用途径,因为语义操作并非总是可行。
- 状态明确可见。 修订版本、检查点和变更集都是对象,而非隐含信息。
- 验证默认等待,按需在后台运行。
check、run_tests和run_command会返回判定;长时间运行的任务也可以返回一个供轮询的作业。 - 近似结果必须明确说明。 当 ARNO 退回到文本扫描或基于名称匹配的图时,相关限制会随数据一同出现在响应中,而不是只写在 Agent 永远不会看的文档里。
- ARNO 不依赖特定模型或运行环境。 MCP 是适配层,而非架构本身。
- 衡量 Agent 的任务结果,而非基础设施的复杂程度。 关注每项已完成任务所用的令牌数和轮次;如果成功率随令牌数一同下降,那么减少令牌毫无价值。
- 使用仓库原生方式执行。 构建、测试和 lint 通过仓库自己的命令运行——这些命令会自动发现,或在
.arno/commands.json中声明——并在 ARNO 中执行,因此验证会成为记录的一部分,而不是一次脱离工作流的 Shell 操作。 - 比备用途径更省。 如果 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,以及语言服务器;语言服务器在索引工作区时会执行自身的项目配置(构建脚本、插件)。
- 由 ARNO 本身覆盖: 读取和写入操作都限制在工作区根目录内,包括符号链接;依赖项源文件为只读;仓库无法让 ARNO 启动其自带的二进制文件(已声明的命令会通过你已信任的 shell 运行,而
稳定性与版本管理
工具名称和必需参数已冻结,并由测试强制执行。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-mcp | MCP 标准输入/输出服务——重要的入口。 |
| cmd/arno | 一个用于直接驱动内部 API 的小型 CLI。 |
| cmd/arno-bench | Token 基准测试:比较 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/transport | MCP 适配器,以及与传输无关的内部 API。 |
| internal/protocol | 共享的请求和响应类型。 |
欢迎贡献。唯一的硬性规则是原则 8:如果添加了近似实现的代码路径,响应中必须说明这一点。
许可证
Apache License 2.0——请参阅 LICENSE。版权所有 2026 Julian Amelung。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。