关于 zsh-tool
zsh-tool 是面向 Claude Code 的原生 zsh 执行 MCP 服务,适合需要交互式终端和可靠长命令管理的开发者。它结合增量轮询、超时熔断和短期命令模式学习。
主要功能
- 01原生 zsh 命令执行
- 02PTY 交互与输入发送
- 03增量输出轮询及任务管理
- 04NEVERHANG 超时熔断
- 05A.L.A.N. 重试与命令模式洞察
- 06失败时提示手册选项
适用场景
- 01运行需要输入密码的交互命令
- 02持续查看构建或安装任务输出
- 03排查重复失败或超时的命令
- 04通过 SSH 执行并区分连接与命令错误
MCP 相关
MCP 服务向 Claude Code 提供 zsh 执行、轮询、输入发送、终止任务及状态查询等工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
zsh-tool
为 Claude Code 提供 zsh 执行工具,具备完整的 Bash 功能对等、基于让出控制权的监督、PTY 模式、NEVERHANG 熔断机制,以及 A.L.A.N. 短期学习能力。
状态: Beta(v0.7.2)
作者: Claude + Meldrey
许可证: MIT
组织: ArkTechNWA
以近乎执着的态度打造,确保可靠性。
为什么?
最主要的原因: 如果你使用 zsh,Claude Code 的 Bash 工具会导致引号不匹配和 shell 混乱。每次调试循环都会消耗令牌。zsh-tool 可立即、永久地解决这个问题。
令牌计算: 避免一次调试循环,就能节省 30+ 秒,保留数百个令牌。
zsh-tool 是智能 shell 执行工具:
| 问题 | zsh-tool 解决方案 |
|---|---|
| Bash/zsh 引号混淆 | 原生 zsh — 无 shell 不匹配,不再反复调试 |
| 命令永远卡住 | 基于让出控制权的执行 — 始终能重新取得控制权 |
| 无法查看正在运行的命令 | zsh_poll — 增量收集输出 |
| 无法与提示交互 | PTY 模式 + zsh_send — 完整支持交互 |
| 无法输入密码 | PTY 模式 — 让 Claude Code 自行输入密码 |
| 超时不断连锁 | NEVERHANG 熔断机制 — 快速失败,自动恢复 |
| 调用之间没有记忆 | A.L.A.N. 2.0 — 重试检测、连续次数跟踪、主动洞察 |
| 轮询浪费令牌 | 智能轮询 — 2s 监听窗口、自适应建议、时长估算 |
| 盲目终止,不会学习 | 具备终止感知的 A.L.A.N. — 区分不耐烦与真正卡住 |
| 使用错误标志重试 | manopt — 多次失败时自动显示命令选项 |
| 没有任务管理 | zsh_tasks、zsh_kill — 全面掌控 |
这就是“运行命令”和“智能 shell 集成”之间的区别。
功能
基于让出控制权的执行
如果命令仍在运行,会在 yield_after 秒后返回部分输出:
- 不再卡住 — 始终能重新取得控制权
- 增量输出 — 使用
zsh_poll收集 - 交互式输入 — 使用
zsh_send发送 - 任务管理 — 使用
zsh_kill和zsh_tasks
PTY 模式
为交互式程序提供完整的伪终端模拟:
# Enable with pty: true
zsh(command="pass insert mypass", pty=true)
# See prompts, send input with zsh_send
- 正确处理交互式提示
- 运行需要 TTY 的程序
- 彩色输出和终端转义序列
- 合并标准输入/标准输出/标准错误
NEVERHANG 熔断机制
防止卡住的命令阻塞会话:
- 按命令哈希跟踪超时模式
- 在滚动 1 小时窗口内发生 3 次超时后打开熔断器
- 5 分钟后自动恢复
- 状态:
CLOSED(正常)→OPEN(阻止)→HALF_OPEN(测试中)
A.L.A.N. 2.0(只要有必要就持续)
智能短期学习 — “也许你他妈的搞砸了,也许你做得没错。”
- 重试检测 — 重复执行失败命令时发出警告
- 连续次数跟踪 — 连续成功时给予肯定,连续失败时发出警告
- 模糊匹配 —
git push origin feature-1→git push origin * - 主动洞察 — 执行命令前提供上下文反馈
- 会话记忆 — 通过 15 分钟滚动窗口跟踪近期活动
- 时间衰减 — 指数衰减(半衰期为 24 小时),自动清理
- SSH 智能分析 — 区分主机连接状态与远程命令是否成功
- 管道段跟踪 — 当
cat foo | grep -badopts | sort失败时,A.L.A.N. 知道是哪个段出错
带行号的增量输出(v0.6.3)
zsh_poll 只返回自上次轮询以来新增的输出,并添加全局行号前缀。每次轮询不再倾倒 800 行内容。
801: Installing package foo...
802: Compiling module bar...
803: Done.
| 字段 | 说明 |
|---|---|
from_line / to_line | 此增量中的行范围(例如,801-803) |
new_bytes | 自上次轮询以来新增输出的字节数 |
full_output(参数) | 传入 true 可获取带行号的完整缓冲区 |
首次轮询会返回从第 1 行开始的所有输出。后续轮询会从上次结束的位置继续。任务完成后会返回最终增量,再次轮询则返回空内容。
智能轮询
zsh_poll 会先进行2 秒监听窗口,然后再返回。如果 2 秒内有输出,就会立即返回。如果没有,轮询元数据会告知 Agent 当前情况:
| 字段 | 说明 |
|---|---|
polls_since_output | 连续无输出的轮询次数 |
elapsed_since_last_output_s | 自上次输出以来的空闲时间 |
alan_estimate | A.L.A.N. 根据命令历史预测的持续时间 |
suggestion | 自适应建议:拉长轮询间隔、很快再检查,或考虑终止 |
这些建议仅供参考——始终由 Agent 决定。2 分钟的 pip install 不再产生 40 次空轮询往返。
可感知终止的 A.L.A.N.
Agent 终止命令时,A.L.A.N. 会将其记录为 KILLED 结果,并判断终止原因:
| 类别 | 含义 | 示例 |
|---|---|---|
EARLY_KILL | 远早于中位完成时间就被终止 | “运行 30 秒时终止。中位数为 120 秒。还需要更多时间。” |
LATE_KILL | 运行时间远超预期后才被终止 | “运行 180 秒后终止。中位数为 45 秒。出现了问题。” |
PATTERN_PROBLEM | 模板在超过 50% 的情况下被终止 | “此模式可能需要采用完全不同的方法。” |
终止分类会比较 kill_elapsed / median_duration,以区分缺乏耐心和确实卡住。
manopt — 失败时显示 man 页面选项
命令反复失败时,A.L.A.N. 会显示可用选项:
- 第 1 次失败 — 正常反馈,不显示 manopt
- 第 2 次失败 — 在后台异步触发
manopt查询(超时 2 秒) - 第 3 次及以后失败 — 在 A.L.A.N. 洞察中显示缓存的选项表
从本地 man 页面解析。缓存在 SQLite 中。默认启用(ALAN_MANOPT_ENABLED=1)。
SSH 跟踪
A.L.A.N. 会特别处理 SSH 命令,分别记录两项观察结果:
| 观察项 | 跟踪内容 | 洞察示例 |
|---|---|---|
| 主机连通性 | 能否连接到此主机? | “主机 ‘vps’ 的连接失败率为 67%” |
| 远程命令 | 此命令能否在不同主机上正常运行? | “远程命令 ‘git pull’ 在 3 台主机上均可靠” |
退出码分类:
0— 成功(已连接且命令成功)255— 连接失败(SSH 无法连接)1-254— 命令失败(已连接,但远程命令失败)
这意味着,当 ssh host3 'git pull' 以退出码 255 失败时,A.L.A.N. 知道是无法访问主机,而不是 git pull 出了问题。
工具
| 工具 | 用途 |
|---|---|
zsh | 在基于让出执行的监管下执行命令 |
zsh_poll | 获取运行中任务的新输出(增量),附带行号 |
zsh_send | 向任务的 stdin 发送输入 |
zsh_kill | 终止正在运行的任务 |
zsh_tasks | 列出所有活动任务 |
zsh_health | 整体健康状态 |
zsh_alan_stats | A.L.A.N. 数据库统计信息 |
zsh_alan_query | 查询命令的模式洞察 |
zsh_neverhang_status | 熔断器状态 |
zsh_neverhang_reset | 将熔断器重置为 CLOSED |
安装
从 Marketplace 安装(推荐)
将 ArkTechNWA marketplace 添加到 Claude Code:
ArkTechNWA/claude-plugins
然后安装:/plugin install arktechnwa/zsh-tool
就是这样。 插件会在首次运行时自动安装依赖项。
手动安装
git clone https://github.com/ArkTechNWA/zsh-tool.git ~/.claude/plugins/zsh-tool
在 ~/.claude/settings.json 中启用:
{
"enabledPlugins": {
"zsh-tool": true
}
}
首次运行时,随附的 scripts/run-mcp.sh 会构建 Rust 二进制文件并启动 MCP 服务。
本地开发
在本地开发/测试时,如果 CLAUDE_PLUGIN_ROOT 未展开,包装脚本会自动检测到这一情况,并改用计算出的插件根目录。无需更改配置。
或者,创建包含绝对路径的 .mcp.local.json:
{
"mcpServers": {
"zsh-tool": {
"type": "stdio",
"command": "/path/to/zsh-tool/scripts/run-mcp.sh",
"env": {
"NEVERHANG_TIMEOUT_DEFAULT": "120",
"NEVERHANG_TIMEOUT_MAX": "600"
}
}
}
}
如果未显式提供 ALAN_DB_PATH,系统会自动将其设为 {plugin_root}/data/alan.db。
**要求:**必须安装 Rust 工具链(cargo)和 zsh。
架构
zsh-tool/
├── .claude-plugin/
│ ├── plugin.json
│ └── CLAUDE.md
├── .mcp.json
├── zsh-tool-rs/
│ ├── Cargo.toml
│ └── src/
│ ├── main.rs # CLI entry point
│ ├── lib.rs # Module exports
│ ├── executor.rs # Pipe/PTY command execution
│ ├── config.rs # User config (~/.config/zsh-tool/)
│ ├── circuit.rs # NEVERHANG circuit breaker
│ ├── meta.rs # Task metadata (exit code, pipestatus)
│ ├── alan/ # A.L.A.N. 2.0 learning engine
│ │ ├── mod.rs # Recording + insights
│ │ ├── hash.rs # Fuzzy command hashing
│ │ ├── insights.rs # Proactive feedback
│ │ ├── manopt.rs # Man-page option parsing
│ │ ├── ssh.rs # SSH host/command tracking
│ │ ├── streak.rs # Success/failure streaks
│ │ ├── pipeline.rs # Pipeline segment tracking
│ │ ├── prune.rs # Temporal decay + pruning
│ │ └── stats.rs # Database statistics
│ └── serve/ # MCP JSON-RPC server
│ ├── mod.rs # Request dispatch + tool handlers
│ ├── format.rs # Rich output formatting
│ ├── protocol.rs # JSON-RPC framing
│ └── tools.rs # Tool schema definitions
├── scripts/
│ └── run-mcp.sh # Build + launch wrapper
├── data/
│ └── alan.db # A.L.A.N. SQLite database
└── README.md
配置
环境变量(在 .mcp.json 中设置):
ALAN_DB_PATH— A.L.A.N. 数据库位置NEVERHANG_TIMEOUT_DEFAULT— 默认超时时间(120s)NEVERHANG_TIMEOUT_MAX— 最大超时时间(600s)ALAN_MANOPT_ENABLED— 失败时启用 man 页面选项提示(默认:1)ALAN_MANOPT_TIMEOUT— 等待 manopt 解析的最长秒数(默认:2.0)ALAN_MANOPT_FAIL_TRIGGER— 触发异步查询的失败次数(默认:2)ALAN_MANOPT_FAIL_PRESENT— 显示缓存选项的失败次数(默认:3)
禁用 Bash(可选)
若要仅使用 zsh,请添加到 ~/.claude/settings.json:
{
"permissions": {
"deny": ["Bash"]
}
}
更新日志
0.7.2
面向用户的输出 — 让模型展示执行结果
- **修复:**Claude Code 中的 MCP 工具结果对用户不可见(平台限制)。现在,工具描述会指示模型在回复文本中逐字转述命令输出。
- 这是针对 Claude Code 不向用户呈现 MCP 工具结果块问题的变通方案。
0.7.1
修复陈旧二进制文件 — 确保真正交付新格式
- **修复:**源代码变更后,
run-mcp.sh现在会在重新构建前运行cargo clean -p,避免 Cargo 增量构建使用陈旧的二进制文件 - **修复:**重新构建触发条件现在也会检查
Cargo.toml(旧版find -newer检查无法检测版本升级)
0.7.0
丰富输出格式 — 不再输出 JSON 转储
- 结构化输出 — 命令标题、分隔符划分的区段,以及带图标的状态页脚
- 状态图标 — 使用
✔/✘替代[COMPLETED/[FAILED括号 - 整合进度信息 — 将连续的进度行(例如
10%、20%、30%)折叠为仅显示最新一行,避免下载/构建期间屏幕刷屏 - 回显命令 —
$ command标题显示运行的命令,最多截断至 120 个字符 - 彩色退出码 — 绿色=0,红色=非零,黄色=信号(129+)
- 更丰富的通知 — 后台任务完成时使用
┌ notify:,失败通知会着色 - ALAN 洞察图标 — 警告使用
⚠,信息使用ℹ - 新增
format.rs模块 — 将所有格式化逻辑从 mod.rs 提取到独立、可测试的模块中 - 新增 35 项测试(共 121 项),覆盖所有格式化函数
0.6.1
协议修复 — 支持 Claude Code v2.1+ 的裸 JSON-RPC
- **修复:**MCP 服务现在会自动检测裸换行符分隔的 JSON(Claude Code v2.1.42+)与 Content-Length 分帧格式
- **调试日志:**将协议协商、请求/响应生命周期和关闭过程的诊断信息写入 stderr
- 日志文件:
run-mcp.sh将 stderr 重定向到/tmp/zsh-tool-mcp.log,用于 MCP 调试
0.6.0
全面改用 Rust 重写 — 告别 Python,迎接速度
- 完全使用 Rust 重写 — MCP 服务、执行器、A.L.A.N.、NEVERHANG 全部采用原生实现
- 79 项 Rust 测试 — 单元测试 + 完整 MCP 集成测试(JSON-RPC 往返测试)
- 重写 CI 流水线 — 使用
cargo test+cargo clippy替代 pytest + ruff - 移除 Python — 删除 7,600 多行 Python 代码,不再依赖 Python
- CI 速度提升约 2 倍 — 冷构建从 97s 降至缓存构建的 48s(Python 需 60-120s)
- 保留所有功能:yield/poll/send/kill、PTY 模式、A.L.A.N. 2.0、NEVERHANG、manopt、SSH 跟踪、流水线分段
0.5.0
A.L.A.N. v2 升级 — 智能轮询、终止感知、manopt
- 智能轮询:
zsh_poll中的 2s 监听窗口可减少空往返;轮询元数据包含时长估算和自适应建议 - 具备终止感知能力的 A.L.A.N.:新增
KILLED结果类型并跟踪已用时;可对提前终止(缺乏耐心)、延迟终止(确实卡住)和模式问题(方法不当)进行分类 - manopt 集成:命令重复失败时异步解析 man 页选项;缓存在 SQLite 中;同一命令模板第 3 次及之后失败时显示
- 观察记录新增
outcome_type和kill_elapsed_ms列 - 新增
manopt_cache表,用于持久化存储 man 页选项 - 环境变量:
ALAN_MANOPT_ENABLED、ALAN_MANOPT_TIMEOUT、ALAN_MANOPT_FAIL_TRIGGER、ALAN_MANOPT_FAIL_PRESENT
0.4.90
反馈改进 — 信号更清晰,噪声更少
- ALAN 洞察现按信息/警告元组分类
- 命令识别:grep 退出代码 1 =“未匹配”(信息),退出代码 127 =“找不到命令”(警告)
- 执行后洞察:静默检测、管道屏蔽警告、排除 SIGPIPE
- 元数据行添加 ANSI 颜色(绿色=成功,红色=失败,青色=运行中,黄色=超时)
- 根据退出代码显示 COMPLETED/FAILED 状态词
- 使用原始 pipestatus 列表替代格式化的
[cmd:code]字符串 - 分组显示洞察:
[info: A.L.A.N.: ...]和[warning: A.L.A.N.: ...]
0.4.83
支持 Python 3.14 — 面向未来
- 添加 Python 3.14 分类标记和徽章
- 移除已弃用的
asyncio.DefaultEventLoopPolicyfixture(计划在 3.16 中移除) - 全部 331 项测试均在 Python 3.14.2 上通过
0.4.81
Pipestatus 标记泄漏修复 — 数据完整性
- 修复竞态条件,避免
___ZSH_PIPESTATUS_MARKER___泄漏到输出中 - 返回给调用方之前,现会在
_build_task_response()中移除标记 - 防止在执行过程中捕获输出时文件内容损坏
- CI:Runner 已切换为 docker executor,并添加 PEP 668 合规支持
0.4.80
分段退出代码 — 准确了解哪个命令失败
- 退出代码现显示为
[cmd1:0,cmd2:1,cmd3:0]格式,而非单个整数 - 每个管道段都与其在 zsh
$pipestatus中的实际退出状态对应 - A.L.A.N. 学习可获得准确的逐命令结果
- 输出可自我说明,便于人工和 AI 分析
- 修复了无论实际状态如何,所有命令都报告
exit=0的问题
0.4.79
服务模块化重构 — 架构更清晰
- 将 MCP 服务提取到
zsh_tool/server.py模块 - 在
zsh_tool/config.py中集中配置 - 修复 plugin.json 版本与软件包版本不同步的问题
0.4.75
管道智能分析 — 了解管道中的哪个环节出现故障
- A.L.A.N. 现在会为每个管道捕获 zsh 的
$pipestatus数组 - 每个管道段都会作为独立观察记录,并记录自身的退出代码
- 当
cat foo | grep -badopts | sort失败时,你可以知道问题出在 grep - 支持识别引号和转义的管道解析,可正确处理复杂命令
- 向后兼容:仍会同时记录完整管道和各个管道段
- 新增 248 行测试,覆盖管道段跟踪和边界情况
0.4.6
配置与完善 — 用户可配置默认值,覆盖率达 91%
- 用户配置文件(
~/.config/zsh-tool/config.yaml)可用于自定义 yield_after - 测试覆盖率提升:303 项测试,覆盖率达 91%
- 修复任务清理中的空值检查问题
- 整合并修复 Logo 文件
0.4.5
捆绑插件 — 在市场中安装,零繁琐步骤
- 自动安装包装脚本(
scripts/run-mcp.sh)会在首次运行时创建 venv - 使用
${CLAUDE_PLUGIN_ROOT}的可移植.mcp.json - 支持 ArkTechNWA 市场
- 无需手动执行 pip install
0.4.0
测试套件与 CI — 290 项测试,覆盖率 89%
- 全面的测试套件,覆盖所有模块
- 包含测试和 lint 阶段的 CI 流水线
- 动态流水线和覆盖率徽章
- 温和的测试运行器(
run_tests.sh),在文件之间使用 nice 和 sleep - 修复弃用警告和 lint 错误
- 添加 pytest-asyncio 以支持异步测试
0.3.1
SSH 智能分析 — 将主机连接情况与远程命令执行结果分开记录
- SSH 命令现在会记录双重观察结果(主机 + 远程命令)
- 退出代码分类:0=成功,255=连接失败,1-254=命令失败
- 新增用于 SSH 专项跟踪的
ssh_observations表 get_ssh_host_stats()— 每台主机的连接/命令成功率get_ssh_command_stats()— 所有主机上各命令的统计数据- SSH 专项洞察:不稳定的主机、可靠的主机、失败的命令
- 新增 31 项 SSH 跟踪测试
0.3.0
A.L.A.N. 2.0 — “也许你他妈的搞砸了,也许你做对了。”
- 重试检测:重复执行失败命令时发出警告
- 连胜追踪:成功时予以肯定,失败时发出警告
- 模糊模板匹配:将相似命令分组
- 主动洞察:执行前提供上下文反馈
- 会话记忆:15 分钟滚动窗口
- 新增数据库表:
recent_commands、streaks
0.2.0
- 基于 yield 的执行,支持实时监督
- PTY 模式,提供完整的终端模拟
- 通过
zsh_send支持交互式输入 - 任务管理:
zsh_poll、zsh_kill、zsh_tasks - 使用 subprocess.PIPE 修复 stdin 阻塞问题
0.1.0
- 首次发布
- NEVERHANG 断路器
- A.L.A.N. 学习数据库
许可证
MIT 许可证 - 详情请参见 LICENSE。
献给 Johnny5。献给我们。
ArkTechNWA
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。