Zellij MCP守护进程

用于通过in-repo后端安全地与Zellij窗格进行代理交互的Rust MCP守护进程。

  • by LumenYoung
  • Rust
  • 本地部署
  • 更新于
在 GitHub 查看 LumenYoung/zellij_mcp

使用说明

MCP 细胞

Rust MCP守护进程,用于通过回购后端与Zellij窗格进行安全的代理交互。

当前发布线: 0.1.0

它提供了什么

守护程序公开了以下MCP工具:

  • zellij_spawn
  • zellij_attach
  • zellij_discover
  • zellij_send
  • zellij_wait
  • zellij_capture
  • zellij_close
  • zellij_list

它保持面向代理的句柄稳定,保持轻量级状态,并添加捕获语义(full, delta, current)在原始窗格访问之上。

最近的生成硬化:

  • zellij_spawn(wait_ready=true) 可能返回 status="busy" 当窗格是真实的,但渲染的屏幕空闲检测未在有界等待窗口内解决时
  • 守护进程现在会在启动后探测之前保留生成的句柄,这样真正的启动就不会因为后续准备或捕获工作降低而丢失
  • 默认交互式 spawn_target="new_tab" 现在绑定新选项卡的默认终端窗格,而不是隐式创建第二个shell窗格
  • 默认计划器行为更喜欢在请求的选项卡中重用明显的单shell终端窗格,现在拒绝模糊的多窗格选项卡,而不是默默地选择一个

打包命令演示文稿:

  • 鱼背包裹提交流使用干净 __zellij_mcp_run_b64 <interaction-id> <payload> 入口点,而不是将完整的内联交互脚本打印到窗格中
  • 守护进程将规范的fish包装器实现嵌入二进制文件中,并在需要时将其延迟引导到fish窗格中,因此运行时不依赖于存在的repo签出或点文件
  • scripts/__zellij_mcp_run_b64.fish 仍然是包装器契约的回购拥有的源工件,并且仍然支持 -p 预览模式,用户可以在不执行解码命令的情况下检查它
  • 如果运行时包装器验证、引导或干净调用仍然失败,守护进程将回退到旧的内联包装器,因此命令仍然运行

需求

  • 防锈工具链
  • Zellij会话,所需插件已批准用于守护进程RPC

正常的守护进程操作直接使用仓库内后端。您不需要安装或调用外部 zjctl 本地MCP流的包装器。

构建

cargo build --release
cargo build-plugin

二进制路径:

target/release/zellij_mcp

插件工件路径:

target/wasm32-wasip1/release/zrpc.wasm

手动运行

守护程序通过stdio为MCP提供服务。

ZELLIJ_MCP_STATE_DIR=/home/yang/.local/state/zellij-mcp-opencode \
./target/release/zellij_mcp

手动烟雾测试

mcp2cli 是可选的。它对于手动本地验证很有用,但OpenCode在正常使用时不需要它。

例子:

mcp2cli --mcp-stdio "./target/release/zellij_mcp" --list

此计算机上的OpenCode设置

OpenCode配置如下:

/home/yang/dotfiles/opencode/opencode.json

此计算机现在使用名为的本地MCP条目 zellij 按需启动守护进程。

重要后果:

  • 在OpenCode中使用代理之前,您不需要预先生成守护进程
  • 当需要MCP工具时,OpenCode会启动它
  • mcp2cli 仅用于手动测试,不需要使用OpenCode代理

通过SSH远程

当前模型保留一个本地MCP守护进程,并允许选择工具选择远程目标。

  • 省略 target 使用本地后端
  • 集 target 上 zellij_spawn, zellij_attach, zellij_discover,或 zellij_list 选择SSH目标别名,例如 aws
  • 目标值可以是一个简单的别名,如 aws,守护进程将其规范地解析为 ssh:aws
  • 后续工具,如 zellij_send, zellij_wait, zellij_capture,以及 zellij_close 不需要 target;守护进程通过持久句柄绑定路由它们
  • 远程后端命令和 zellij 由本地守护进程通过SSH执行

运行时配置是通过守护进程端进行的 ZELLIJ_MCP_TARGETS.

当前形状是分层的,共享 defaults 每个别名可选部分 overrides:

例子:

ZELLIJ_MCP_TARGETS='{"defaults":{"remote_zjctl_bin":"zjctl","remote_zellij_bin":"zellij","remote_env":{"ZELLIJ_SESSION_NAME":"remote"},"ssh_options":["-o","BatchMode=yes"]},"overrides":{"aws":{"host":"aws","remote_env":{"ZELLIJ_SESSION_NAME":"aws"}},"a100":{"host":"a100","remote_env":{"ZELLIJ_SESSION_NAME":"a100"}}}}' \
./target/release/zellij_mcp

在这种分层形式中,每个别名都从 defaults,则只有其覆盖下存在的字段会替换或扩展它们。守护进程还继续接受旧的遗留映射形状以实现向后兼容性,但分层 defaults 加 overrides 表单是预期的仅别名设置。

准备和补救:

  • 守护进程在尝试使用远程SSH目标之前检查它们,然后将目标分类为 Ready, AutoFixable,或 ManualActionRequired
  • AutoFixable 意味着守护进程可以安全地应用有界修复,例如复制构建的仓库 zrpc.wasm 进入标准插件目录,启动一个分离的辅助客户端,并重试一次准备就绪
  • AutoFixable 专门用于丢失二进制文件、辅助客户端缺失和RPC未就绪漂移,这些漂移仍然可以通过确定性用户空间设置进行恢复
  • 丢失的插件工件与可重试的状态截然不同,因为启动插件无法修复不符合预期的主机 zrpc.wasm 尚未安装
  • 当远程命令路径尚未包含它时,守护进程会在前面添加 $HOME/.local/bin 用于非交互式SSH探测和执行,因此普通主机不需要每个主机的二进制路径
  • ManualActionRequired 涵盖了其余不可自动修复的情况,包括非托管插件审批提示和守护进程/插件协议版本偏差,这些情况需要在重试前匹配工件
  • 准备就绪并不意味着每个主机都能零接触成功,它只会自动修复安全、有界的情况

新鲜度和可诊断性:

  • startup现在将守护进程实例id、包版本、构建戳、pid和启动时间戳记录到stderr
  • 现在,每个成功的MCP工具响应都包括 _daemon 元数据具有相同的标识字段,因此每个请求都可以看到过时的本地进程
  • MCP错误数据现在也包括守护进程标识,这使得混合本地/远程故障更容易归因于正确运行的二进制文件

实用设置说明:

  • 如果本地复制的Linux二进制文件在远程主机上出现glibc版本错误而失败,请在用户空间中的远程主机上本地构建它,并将其安装到远程 ~/.local/bin
  • 守护进程将远程HOME和PATH标准化,以便进行非交互式SSH探测和执行,因此安装在中的远程工具 ~/.local/bin 发现没有每个主机的路径覆盖
  • 插件RPC路径仍然需要一个附加的Zellij客户端,因此无头远程主机可能仍然需要用户空间助手,例如分离的 tmux 会话正在运行 zellij attach <session>

Bootstrap助手:

./scripts/zellij-mcp-bootstrap-ssh a100 --session a100

引导助手完全留在用户空间中。如果需要,它会安装Rust,同步此仓库,克隆或更新兼容性助手仓库,构建 zellij_mcp,可选兼容性 zjctl 后端层使用的二进制文件,以及所拥有的仓库 zrpc.wasm 在远程主机上,将插件工件复制到标准的Zellij插件目录中,启动一个分离的辅助客户端,并通过运行当前的准备状态检查来完成。

最终的引导输出是回购拥有的,并且是有意压缩的:

  • readiness_state=READY 表示远程主机已完成当前引导路径,并且仓库拥有的RPC探测成功
  • readiness_state=AUTO_FIXABLE 意味着主机仍然需要有界修复,如帮助客户端或RPC恢复,并且面向MCP的类仍然 PLUGIN_NOT_READY
  • readiness_state=MANUAL_ACTION_REQUIRED 意味着主机在重试之前需要人工操作或匹配工件; readiness_reason 区分缺失的插件、插件批准和协议/版本偏差
  • mcp_error_code 镜像接下来应该遇到的面向守护进程的错误系列: PLUGIN_NOT_READY, PROTOCOL_VERSION_MISMATCH,或 ZJCTL_UNAVAILABLE

脚本不再处理原始内容 zjctl doctor 文本是真理的最终来源。它以有界回购拥有的准备就绪调查结束(zjctl panes ls --json 加上此仓库的就绪分类规则),因此引导输出与守护进程的实际错误模型相匹配。

操作辅助说明:

  • scripts/zellij-mcp-ssh 对于烟雾测试或回退操作仍然有用
  • 它不再是主要的远程架构或推荐的OpenCode MCP形状

路径注释:

  • 首选绝对远程路径或已在远程非交互式上解析的纯可执行文件名 PATH
  • 不要依赖 ~ 辅助脚本参数的扩展;包装器在将远程令牌传递给SSH之前故意引用它们

重要约束:

  • 这不会在远程主机上创建分离的网络守护进程;本地守护进程仍然会根据需要通过SSH启动远程操作
  • 如果以后希望远程守护进程在没有任何SSH传输的情况下保持可访问性,则这将成为一个单独的传输功能
  • 这也不会消除Zellij在使用远程插件RPC路径时对连接客户端的要求
  • zellij_discover 现在将预览失败降级为仅元数据候选,而不是整个调用失败,但在非常繁忙的实时窗格中,仅元数据发现仍然是更干净的选择

目标和句柄语义:

  • 存储在响应和绑定中的规范目标id是 ssh:<alias>
  • 选择工具接受用户的别名表单,而后续调用继续使用持久句柄绑定
  • 这种分离保持了单个本地MCP架构的完整性,并避免了嵌套的远程守护进程

此计算机上配置的运行时值:

  • ZELLIJ_MCP_STATE_DIR=/home/yang/.local/state/zellij-mcp-opencode

推荐药剂流量

对于现有用户窗格:

  1. zellij_discover
  2. zellij_attach
  3. zellij_wait
  4. zellij_capture
  5. zellij_send

对于新代理拥有的窗格:

  1. zellij_spawn
  2. 如果spawn返回 status="busy",保留退回的手柄并继续 zellij_wait 或 zellij_capture
  3. zellij_capture
  4. zellij_send
  5. zellij_close

笔记:

  • wait_ready=true 是一种方便的空闲探测,而不是进程启动或应用程序就绪的保证
  • 稍后的 zellij_list 重新验证可以从以下位置升级生成的句柄 busy 到 ready 一旦窗格选择器再次可访问;使用 zellij_capture 当你需要一个新的输出基线时

远程故障排除快速图

  • TARGET_NOT_FOUND:所选别名未知或远程窗格选择器不再解析;验证 ZELLIJ_MCP_TARGETS、会话名称以及窗格是否仍然存在
  • CAPTURE_FAILED:句柄存在,但捕获路径降级;使用相同的句柄重试,然后使用 zellij_list 在假设窗格已消失之前重新验证所有权
  • PLUGIN_NOT_READY:主机可访问,但缺少插件/运行时先决条件;在重试之前,区分丢失的插件工件、手动插件批准、辅助客户端缺失和RPC未就绪漂移
  • PROTOCOL_VERSION_MISMATCH:守护进程并已加载 zrpc 插件不同意 PROTOCOL_VERSION;在重试之前重建或重新加载匹配的工件,因为仅重新启动助手/插件无法修复偏斜
  • ZJCTL_UNAVAILABLE:传输或远程二进制路径有问题;验证SSH可达性、本机远程安装以及所需的远程二进制文件是否在非交互式远程PATH中解析

当你使用 scripts/zellij-mcp-bootstrap-ssh,这些准备就绪的家庭被明确地表现为 readiness_state, readiness_reason,以及 mcp_error_code,因此shell引导和MCP运行时诊断使用相同的仓库拥有的词汇表。

更多细节

  • docs/architecture.md
  • docs/mcp-contract.md
  • docs/ssh-remote-design.md zellij_discover 返回实时窗格元数据和附加就绪 selector 价值观。 zellij_attach 然后需要一个精确的选择器,以便守护进程可以绑定一个特定的窗格并返回一个稳定的 handle 供以后使用 send, wait, capture,以及 close 电话。