Skip to main content
Glama
zhenyuanfan

xshell-agent-bridge

by zhenyuanfan

Xshell Agent Bridge

Xshell MCP Server for AI Agents — 一个面向 Codex、Claude Code、Kimi Code CLI、Cursor 等 MCP 客户端的本地桥接程序,让 AI Agent 能读取和操作已打开的 Xshell 终端标签页。

v0.4.0 企业安全策略版:在安全确认和文件传输基础上,新增 Agent 危险命令硬拦截。文件删除、资源清理、磁盘格式化、数据库删除、软件卸载和关机重启等操作,以及把编码或下载内容交给 Shell/脚本解释器执行的请求,不能由 Agent 发送;如确有需要,只能由用户在 Xshell 中亲自输入。

它适合需要由 AI 协助完成服务器巡检、部署、排障、离线环境文件中转或重复终端操作的场景。终端功能只能操作你在 Xshell 中已连接并主动接入桥接脚本的标签页;文件下载功能只有在你核对本地弹窗后,才会通过系统 OpenSSH 连接指定服务器。

关键词:Xshell MCP、SFTP MCP、MCP server、AI terminal automation、secure file transfer、Codex、Claude Code、Cursor、Kimi Code CLI、SSH terminal bridge。

能力与边界

能力

说明

读取终端

获取当前可见的 Xshell 屏幕内容。

写入终端

每次先在 Xshell 本地弹窗确认,再发送精确文本、回车或 Ctrl+C

等待输出

等待屏幕出现指定文本,便于确认命令结果。

安全下载

使用 Windows OpenSSH 从服务器下载单个文件;两次本地确认、密码人工输入、.part 临时文件和可选 SHA-256 校验。

安全上传

downloads/ 中的单个文件上传为远程唯一 .part 文件;两次本地确认、密码人工输入、服务器端 SHA-256 校验并禁止覆盖。

企业安全策略

守护核心与 Xshell 脚本双重拦截 Agent 发起的删除、清理、格式化、卸载和关机重启等高破坏性命令。

多 Agent 协作

同一标签页可被多个 Agent 读取;写操作会排队执行。

本机运行

守护进程只监听 127.0.0.1,不对外暴露 HTTP 服务。

它不会扫描 .xsh 会话文件,也不会读取或返回 Xshell 已保存的密码、密钥。下载请求的 MCP 参数不允许包含密码、口令或 Token;认证发生在独立的本地终端窗口中。终端可见内容仍可能包含敏感信息;而且发送文本等同于在当前会话中手动输入命令,权限与该会话完全一致。

工作原理

flowchart LR
  A["Codex / Claude / Kimi / Cursor"] -->|"MCP stdio"| B["src/mcp-stdio.mjs"]
  B --> C["Node 守护进程"]
  C <-->|"本地原子文件信箱"| D["Xshell Python 脚本"]
  D --> F{"用户在 Xshell 确认?"}
  F -->|"是"| E["向当前 Xshell 标签页发送输入"]
  F -->|"否"| G["拒绝执行并回报 Agent"]
  B --> H["安全下载模块"]
  H -->|"无凭据桌面启动请求"| D
  D --> I{"用户核对下载计划?"}
  I -->|"是"| J["独立终端中人工认证"]
  J --> K["下载为 .part 并校验"]
  K --> L{"用户确认最终改名?"}

Xshell 内嵌 Python 的能力有限,因此桥接最后一段使用 data/ipc/ 下的原子 JSON 文件通信:脚本上报屏幕与会话状态,守护进程投递操作申请。脚本领取申请后先调用 Xshell 8 的 MessageBox 显示本地确认框;用户同意后才调用 xsh.Screen.Send。MCP 写请求带幂等键,网络重试不会重复排队;操作也不会自动重试,避免在崩溃或断连后重复执行。

快速开始

1. 准备环境

  • Node.js 20 或更高版本

  • Xshell 8

  • Windows OpenSSH 客户端(Windows 10/11 通常已经包含,可用 ssh -V 检查)

  • 任一支持 MCP stdio 的 Agent 客户端

项目没有 npm 第三方依赖,不需要执行 npm install。仓库已经包含 Codex、Kimi Code CLI 和 Claude Code 的项目级 MCP 配置;在项目目录重新打开 Agent 客户端后,首次调用工具时会自动启动 Node 守护进程。

首次自动启动会创建本机专用的 config/local.json,其中含随机鉴权令牌。该文件已经被 Git 忽略,不能提交或分享。

2. 接入一个 Xshell 标签页

在要让 Agent 操作的 Xshell 标签页中选择:

工具 → 脚本 → 运行

然后打开:

xshell\xshell_agent_bridge.py

每个需要接入的标签页都要运行一次脚本。脚本会持续运行、每隔约 250ms 更新状态;关闭标签页或停止脚本后,该会话会自动离线。

3. 告诉 Agent 你要做什么

例如:“检查 Docker 是否安装,不要执行其他操作。”Agent 可以直接读取屏幕。涉及终端输入时,流程如下:

  1. Agent 先在对话中说明这一步要做什么。

  2. Xshell 弹窗显示目标主机、Agent、风险等级、原因、预期结果和完整输入。

  3. 你检查内容:点击“是”才执行;点击“否”不会向服务器发送任何内容。

  4. Agent 读取执行后的屏幕,再解释结果并提出下一步。

因此,普通使用者日常只需:打开 Xshell → 运行桥接脚本 → 向 Agent 描述任务 → 逐条确认写操作

4. 从服务器下载文件

告诉 Agent 服务器地址、登录用户名、远程文件路径以及希望保存的文件名,例如:“从 10.0.0.8/opt/packages/app.jar 下载到本机,保存为 app.jar。”不要在对话中提供密码。

下载流程如下:

  1. Agent 解释下载目的、目标路径、预期结果和风险,然后调用 sftp_download

  2. 新版 Xshell 桥接脚本在你的真实桌面弹窗,显示服务器、用户名、远程文件、本地文件、临时文件和禁止覆盖策略;默认按钮是“否”。

  3. 你点击“是”后,Xshell 脚本使用 os.startfile 从交互桌面运行本地启动文件,再创建独立 PowerShell 窗口。首次连接的主机指纹确认和密码都由你亲自输入,Agent、MCP 与 Xshell 脚本都不会收到这些输入。

  4. OpenSSH 把内容写入 downloads/ 下唯一的 .part 文件。若提供预期 SHA-256,程序会自动比对。

  5. 下载和校验完成后再次弹窗;只有你再次点击“是”,程序才把 .part 改为正式文件名。

  6. Agent 使用 sftp_transfer_status 查询成功、拒绝或失败结果。

当前版本只下载单个普通文件,不下载目录、不自动覆盖、不自动删除失败的 .part 文件,也不会在失败后自动重试。为了兼容旧版 OpenSSH 并阻止远程路径注入,远程路径必须是绝对路径,首版暂不支持带空格或中文的远程文件名。下载或上传前,程序会确认至少有一个运行新版桥接脚本的 Xshell 标签页可把认证窗口安全地启动到当前 Windows 桌面;目标服务器还必须能从当前电脑通过 SSH/SFTP 访问。

如果直接关闭下载 PowerShell 窗口,后台观察进程会把任务标记为“已取消”;不会连接重试,也不会删除可能已经产生的 .part 文件。

5. 其他 Agent 客户端

仓库已包含 Codex、Kimi Code CLI 与 Claude Code 的项目级 MCP 配置。重新打开项目或在项目目录启动对应客户端后即可使用。

其他 MCP 客户端以以下命令启动服务:

node C:\绝对路径\src\mcp-stdio.mjs

可选环境变量 XSHELL_AGENT_ID 用于在审计日志中区分调用方。各客户端的配置示例见 docs/CLIENTS.md

推荐操作流程

Agent 操作终端时必须遵循以下顺序:

  1. 调用 xshell_health,确认守护进程运行且存在在线会话。

  2. 调用 xshell_list_sessions,多标签页时明确选择目标 session_id

  3. 调用 xshell_read_screen,确认主机、用户、提示符和当前正在运行的命令。

  4. 在对话中向用户说明本阶段的完整目标、预期结果、风险、失败后可能留下的状态和完整命令。同一目标内风险相近、依赖明确的连续命令尽量合并,减少不必要的弹窗;无关操作不得打包。

  5. 调用 xshell_sendxshell_interrupt,等待用户在 Xshell 本地点击“是”或“否”。

  6. 再次读屏,或调用 xshell_wait_for 等待预期输出,确认命令的实际结果。

  7. Agent 必须主动用中文解释本次结果:是否成功、关键输出的含义、实际产生的变化、是否留下临时文件或中间状态,以及是否还需要下一步。

xshell_send 的“完成”只表示用户已批准且 Xshell 已接受输入,不代表远端命令执行成功;最后一步的读屏或等待仍然必要。

如果当前可见输出不足以判断结果,Agent 必须明确说“暂时无法确认”,并建议或执行经过用户许可的核验步骤,不能仅凭命令已经发送就宣称成功。

推荐按“目标阶段”确认,而不是机械地按每条小命令确认。例如部署一个容器通常可分为“环境与冲突检查”和“拉取、创建、启动、验证”两个阶段。后一阶段可以使用 && 在前一步成功后继续,并在确认框中一次展示全部命令。删除文件、覆盖配置、停止服务、修改权限、清理数据等破坏性操作仍须拆开单独确认,不能藏在普通检查或部署命令中。

使用注意事项

屏幕读取不是截图

桥接脚本通过 Xshell 的文本接口读取当前终端窗口,返回的是可见文字而不是图片。当前版本只读取窗口中现有的行和列,不会读取已经滚出窗口的完整回滚历史。

因此:

  • 短命令和少量输出可以直接读屏确认。

  • 输出速度很快时,某些文字可能在两次屏幕采集之间滚出窗口;xshell_wait_for 不应作为高吞吐日志的唯一判断依据。

  • 不要依赖扩大 Xshell 回滚行数来保存部署证据;桥接程序仍然只保证读取当前可见区域。

长任务和大量日志必须落盘

部署 JAR、启动服务、构建项目或运行长任务时,应先把标准输出和错误输出写入服务器日志文件,再使用 tailgrepsedjournalctl 分段检查。例如:

nohup java -jar app.jar > app.log 2>&1 &
tail -n 100 app.log
grep -nEi 'error|exception|failed' app.log | tail -n 100

随后还应检查进程、监听端口或应用健康接口,不能仅凭终端最后几行判断部署成功。同一目标的低风险连续操作可以合并说明和确认;高风险操作必须单独处理,并由用户在 Xshell 判断。

密码和敏感凭据必须由用户亲自输入

Agent 不得请求、代填、传输或保存密码、口令、Passphrase、PIN、OTP、验证码、Token、API Key 等敏感凭据。遇到认证提示时,标准流程是:

  1. Agent 识别到密码或验证码提示后停止发送输入。

  2. Agent 请用户切换到 Xshell,并在终端中亲自输入敏感内容。

  3. 用户输入完成后通知 Agent;Agent只读取后续状态和非敏感输出,再提出下一步。

桥接核心会在两处强制拦截:

  • 当前屏幕末尾出现 Password:、密码、口令、Passphrase、OTP、验证码、PIN、Token 等输入提示时,拒绝 Agent 的文本发送请求。

  • 输入内容疑似使用 sshpasssudo -S、命令行密码参数、URL 内嵌凭据或密码环境变量时,在写入 IPC 文件之前拒绝。

不要把密码发在 Agent 对话中,也不要把密码写入命令行让 Agent 代为执行。自动识别用于防止常见误操作,不能代替用户核对 Xshell 弹窗中的完整命令。

MCP 工具

工具

用途

是否写入终端

xshell_health

检查守护进程与在线会话数量

xshell_list_sessions

列出已接入的标签页

xshell_read_screen

读取最新可见屏幕

xshell_send

提议发送文本;必须提供解释、预期结果和风险,并由用户在 Xshell 确认

xshell_interrupt

提议发送 Ctrl+C;同样需要本地确认

xshell_wait_for

等待屏幕出现目标文本

sftp_download

提议从服务器下载单个文件;两次本地确认,密码由用户在独立终端输入

不写终端;写入本机 downloads/

sftp_upload

提议把 downloads/ 中的单个文件安全上传到服务器;远程校验并禁止覆盖

不写 Xshell;在服务器创建文件

sftp_transfer_status

查询下载或上传阶段、大小、SHA-256 和错误信息

本地验证与排障

不需要 Xshell 也可以验证完整流程:

npm run demo:bridge

常见情况:

现象

处理方式

onlineSessions: 0

在目标 Xshell 标签页重新运行 xshell_agent_bridge.py

会话显示离线

确认标签页仍连接且脚本没有停止;每个新标签页都需要单独接入。

Agent 无法发现工具

重新打开项目或重启 Agent 客户端,确认其 MCP 配置已加载。

提示 APPROVAL_UNAVAILABLE

当前标签页仍在运行旧版脚本;停止脚本并重新运行仓库中的最新脚本。

提示 COMMAND_POLICY_UNAVAILABLE

当前 Xshell 标签页没有声明企业安全策略;停止脚本并重新运行 v0.4.0 的最新脚本。

提示 DESTRUCTIVE_COMMAND_BLOCKED

Agent 请求包含硬拦截的危险操作,程序没有发送。确有需要时由用户在 Xshell 中亲自输入。

提示 DESKTOP_BRIDGE_UNAVAILABLE

文件传输前没有发现可用的新版 Xshell 桌面桥接会话;在任一已打开的 Xshell 标签页重新运行 xshell_agent_bridge.py 后再试。

提示 DAEMON_VERSION_MISMATCH

本机仍有旧版守护进程;先停止旧进程,再重新打开 Agent 客户端,让 v0.4.0 自动启动。

提示 SCP_NOT_FOUND

在 Windows“可选功能”中安装 OpenSSH 客户端,再重新打开 Agent。

提示 LOCAL_FILE_EXISTS

downloads/ 下已有同名文件;程序不会覆盖,请先由你人工核对和改名。

下载停在认证阶段

切换到新打开的 PowerShell 窗口,亲自核对主机指纹并输入密码。

下载失败后留下 .part

这是安全保留的临时文件;程序不会自动删除或重试,请核对后人工处理。

Xshell 弹出安全确认框

核对目标主机、说明、风险和完整输入;同意选“是”,不确定或不同意选“否”。

弹窗中的中文说明变成 ?

正常 Agent 项目配置会直接使用 UTF-8。手动用旧版 Windows PowerShell 管道调试时,应先设置 $OutputEncoding = [System.Text.UTF8Encoding]::new($false),否则中文会在进入 MCP 前丢失。

用户拒绝后工具报错

这是正常的安全结果;没有任何输入发送到服务器。

命令已发送但没有结果

先读屏;长命令需要用 xshell_wait_for 等待标志文本或提示符。

守护进程端口冲突

修改 config/local.json 的本机端口后,重启守护进程和 Agent 客户端。

安全与审计

  • 写操作按 Xshell 标签页串行化,避免多个 Agent 同时输入。

  • v0.4.0 只向同时声明支持 xshell-dialog-v1agent-destructive-block-v1 的新脚本投递写操作;旧脚本默认拒绝。

  • xshell_sendxshell_interrupt 强制要求 Agent 提供解释、预期结果及 low / medium / high / critical 风险等级。

  • 同一目标的低风险连续命令可以合并确认;确认说明必须披露全部动作和中间状态。破坏性或高风险动作必须单独确认。

  • 文件删除或清空、find -delete/-exec、容器与编排资源删除、数据库删除或清空、磁盘格式化或擦除、软件包卸载、Git 强制清理、关机重启和防火墙规则清空会被守护核心硬性拒绝,不进入 Xshell 队列。Xshell 脚本还会对任务文件做第二次检查。

  • 编码或下载内容直接交给 sh / bash,以及 Agent 发起的 Shell、Python、Node、PowerShell 等脚本解释器、evalsource、命令替换也会被拒绝,避免未经审阅的第二阶段命令执行。静态文本策略不能替代服务器最小权限账号、受限 sudoers、文件权限、备份或经审核的命令白名单;企业服务器应继续使用这些系统级保护。

  • 每次命令或文件传输完成后,Agent 必须核验实际输出,并用中文解释成功或失败、关键输出、实际变化及遗留状态;“已批准”或“已发送”不能作为执行成功的依据。

  • 密码提示和常见命令行凭据模式会在桥接核心中被拒绝,敏感内容必须由用户直接在 Xshell 输入。

  • 最终批准发生在 Xshell 本地“是/否”窗口中,不依赖不同 Agent 客户端各自的审批设置。

  • 文件下载参数不提供密码字段;认证输入只发生在独立 OpenSSH 终端。下载先写唯一 .part 文件,默认禁止覆盖,最终改名还需要第二次本地确认。

  • Agent 后台进程不直接创建桌面窗口;它只写无凭据启动请求,由用户主动运行的 Xshell 脚本校验任务 ID 和项目内路径后,在交互桌面启动认证窗口。

  • 下载任务状态位于 data/transfers/,下载结果位于 downloads/;两个目录都被 Git 忽略,不会上传到 GitHub。

  • 默认最大输入长度为 8192 字符;会话超过 5 秒未上报状态会被视为离线,尚未投递的操作会失败而不会留给未来会话;人工确认等待时间至少为 120 秒。完成的任务默认保留 24 小时,离线会话信息默认保留 7 天。

  • 写操作元数据会记录到 data/audit.jsonl,只保存文本长度等元数据,不保存命令原文。

  • data/ 会短暂保存屏幕快照和待执行输入,已被 Git 忽略,并继承当前 Windows 用户的文件权限。守护进程会每小时清理超过 30 天的 IPC、桌面启动和传输状态;它绝不自动删除 downloads/ 内的文件或 .part 文件。

  • Agent 客户端自身的写工具审批建议继续保留,作为 Xshell 本地确认之外的额外保护。

发布与可发现性

README 已使用 Xshell MCP、AI terminal automation 与主流 Agent 的自然语言描述,便于 GitHub、网页搜索和 AI 检索理解项目用途。要让外部用户真正搜到项目,发布到公开 GitHub 仓库时还应:

  1. 使用清晰的仓库名,例如 xshell-agent-bridge

  2. 设置仓库简介:Local MCP server that lets AI agents safely control attached Xshell terminal sessions.

  3. 添加 Topics:xshellmcpmodel-context-protocolai-agentsterminal-automationcodexclaude-code

  4. 保持本 README、版本号和开源许可证完整;公开仓库被搜索引擎收录需要一些时间。

开发命令

npm test          # 运行测试
npm start         # 启动守护进程
npm run mcp       # 以 MCP stdio 方式启动
npm run demo:bridge # 运行模拟 Xshell 演示