| name | winkterm-remote |
| version | 10 |
| description | 远程操作 WinkTerm —— 默认用 MCP 或 winkterm CLI(WebSocket 长连接,长任务不被反代超时切断),HTTP 仅在 CLI 不可用时兜底。管理 SSH 连接(增删改查)、新建本地/SSH 终端、发命令并读输出、获取终端快照、SSH 文件传输。当需要远程执行 shell 命令、运维服务器、或在受控终端里跑命令时使用。 |
WinkTerm 远程终端 Skill
远程操作 WinkTerm 后端的终端。后端为每个终端维护一个独立 PTY,
你可以创建本地或 SSH 终端、发命令、读输出、传文件。
如果当前 agent 支持 MCP,优先用 MCP;否则默认用 CLI,几乎不用碰 HTTP:
-
MCP(最省心) —— 配好 winkterm-mcp 后,agent 会看到 winkterm_ssh_run、
winkterm_exec、winkterm_snapshot、winkterm_call 等工具,不需要手写 shell 命令、
JSON 引号或 token。MCP server 内部复用同一套 WebSocket-first transport,长任务仍然靠
15s 心跳保活,连不上 WS 时自动 HTTP fallback。见下方 MCP.
-
winkterm CLI(默认,几乎总是用它) —— 走 WebSocket 长连接,应用层心跳每 15s 一次,
长命令(安装、build、dump)不会被 nginx 等反向代理的默认 60s 空闲超时切断。
覆盖全部操作。注意:CLI/MCP 的 WebSocket 保活只保证连接不断,不保证当前 agent 能看到
stderr 的实时流式过程;agent 需要可控观察长任务时,应启动后台任务后主动用
run_wait / snapshot 查看进度。见下方 CLI.
-
HTTP 接口(兜底,实在没办法才用) —— 原有 REST/SSE 接口全部保留,CLI 连不上时
auto 模式自动 fallback。只有目标机跑不了 Node、或需要 SSE 流式订阅时才手动碰 HTTP。
细节单独放在 HTTP_API.md(远程 agent 用 curl ${WINKTERM_BASE_URL}/api/agent/http.md 取),
确需 HTTP 时再读,平时不占上下文。
配置
- Base URL:
${WINKTERM_BASE_URL}(默认 http://localhost:8000)
- 鉴权: 所有请求带 HTTP 头
Authorization: Bearer ${WINKTERM_AGENT_TOKEN}
- 或在 URL 上加
?token=<token>(SSE/EventSource 不支持自定义 header 时用)。
- token 未配置时接口返回
503;token 错误返回 401。
Token 自动发现(会话开始就做)
会话第一次用本 skill 时,按顺序尝试:
1. 查持久化 memory / 上下文:用户之前可能已经告诉你 token,写到了 memory 文件 / CLAUDE.md / 环境变量。先找一遍:
- env
WINKTERM_AGENT_TOKEN
- agent memory 系统(Claude Code 等:
~/.claude/projects/<...>/memory/)
- 项目级
CLAUDE.md
2. 本地 handshake(只对 WinkTerm 同机的 agent 有效):
curl -s http://localhost:8000/api/agent/handshake
→ {"token":"<bearer-token>","base_url":"http://localhost:8000"}
该端点免鉴权但仅 localhost 可访问(远程 IP 返回 403)。
3. 远程 agent / 全部失败:问用户一次 token,立刻写入 memory(或等价持久化层),后续会话直接复用。
不要每次会话都问用户 —— 一次提供,永久记住。
如果调 API 时收到 401,token 可能已轮换:清掉 memory 里的旧值,重走以上流程。
Skill 自更新(会话开始顺手做)
WinkTerm 后端会持续迭代接口。本 skill 文件顶部 frontmatter 有 version 字段,
和服务端 GET /api/agent/skill.md 第二行的 version: N 比对即可判断是否落后。
会话第一次连上 WinkTerm 时:
curl -s http://localhost:8000/api/agent/skill.md | head -10 | grep '^version:'
head -10 <local-skill-path> | grep '^version:'
如果服务端版本更新:
- 告诉用户:"WinkTerm skill 有更新(v2 → v3),建议覆盖本地副本"
- 用户同意后用
curl -s http://<base>/api/agent/skill.md > <local-skill-path> 拉新版
- 当前会话仍按已载入的旧 skill 行为操作(skill 内容只在下次会话载入时刷新)
- 提示用户下次会话才生效
不要静默覆盖。覆盖前给用户看 diff(curl http://<base>/api/agent/skill.md | diff - <local>)。
服务端版本号 < 本地,或两者相等:跳过,正常工作。
MCP(优先)
如果使用 Codex、Claude Desktop 或其他支持 MCP 的客户端,推荐直接配置 WinkTerm MCP server。
它走 stdio,暴露常用工具,并保留 winkterm_call 覆盖全部后端方法。
先保存一次凭据(或在 MCP 配置里放 env):
npx winkterm login --base-url https://ops.example.com --token <bearer-token>
MCP 配置示例:
{
"mcpServers": {
"winkterm": {
"command": "npx",
"args": ["-y", "winkterm", "mcp"],
"env": {
"WINKTERM_BASE_URL": "https://ops.example.com",
"WINKTERM_AGENT_TOKEN": "<bearer-token>"
}
}
}
}
全局安装后也可以:
{
"mcpServers": {
"winkterm": {
"command": "winkterm-mcp"
}
}
}
常用 MCP tools:
| Tool | 用途 |
|---|
winkterm_call | 通用方法调用,覆盖新接口/少用接口 |
winkterm_list_ssh_connections | 列 SSH 连接 |
winkterm_get_ssh_connection | 查看单个 SSH 连接 |
winkterm_create_ssh_connection / winkterm_update_ssh_connection / winkterm_delete_ssh_connection | 管理 SSH 连接 |
winkterm_import_electerm | 导入 electerm 书签 |
winkterm_ssh_run | 对某个 SSH 连接执行一次性命令 |
winkterm_create_terminal | 创建本地/SSH 终端 |
winkterm_get_terminal | 查看单个终端 |
winkterm_exec | 在已有终端跑短命令并等待结果 |
winkterm_run / winkterm_run_wait / winkterm_run_status / winkterm_run_cancel | 长任务启动、等待新输出、查状态、取消 |
winkterm_input | 发交互输入或控制键 |
winkterm_snapshot | 读取终端输出 |
winkterm_delete_terminal | 关闭终端 |
winkterm_recent_events | 查看近期 agent 事件 |
winkterm_ssh_files_list / winkterm_ssh_files_read / winkterm_ssh_files_write | SSH 远端文件读写 |
winkterm_ssh_upload / winkterm_ssh_download | SSH 文件传输;download 落在 WinkTerm 后端机器 |
winkterm_ssh_mkdir / winkterm_ssh_delete_paths | SSH 远端目录创建和路径删除 |
如果 MCP 工具不可用,再退回 CLI。
长任务观察原则(重要)
不要让 agent 盲等一个长时间阻塞的工具调用。即使任务已经在后台运行,也要主动查看执行过程:
- 短命令可以用
winkterm_exec / winkterm_ssh_run 等待结果。
- 长命令、安装、build、迁移、dump、
tail -f、可能卡交互提示的命令,不要只把 timeout
调很大然后等待。优先使用可观察的后台模式:启动命令后用 winkterm_snapshot
增量读取终端,或直接用 winkterm_run + winkterm_run_wait。
- 长任务优先用
winkterm_run 启动,再循环 winkterm_run_wait;它会阻塞到“有新输出、
状态变化或等待超时”再返回。不要自己写固定 sleep 10。
- 每次观察都检查错误提示、确认提示、密码/yes/no 交互、卡住的进度条和实际 exit/status。
发现卡住时用
winkterm_input 发送所需输入或 ctrl+c,不要让错误 timeout 一直挂着。
记住:WebSocket 保活解决的是“连接不被反代切断”,不是“agent 自动理解长命令当前进展”。
agent 必须主动观察。
CLI(MCP 不可用时)
winkterm CLI 把所有终端/SSH 操作封成一条 WebSocket 长连接上的 JSON 消息。
好处:长任务靠心跳保活,不被反向代理的 60s 空闲超时切断;连不上时自动退回 HTTP。
这是默认且几乎唯一的通道——能用 CLI 就别碰 HTTP。
安装与配置
CLI 已发布到 npm,无需 clone 仓库:
npx winkterm help
(开发场景也可用仓库 cli/ 目录:cd cli && npm install && node bin/winkterm.js help)
推荐:login 存一次凭据,写到 ~/.winkterm/cli.json(权限 0600),后续命令行不再带 token——截图也不会泄露:
winkterm login --base-url https://ops.example.com --token <bearer-token>
winkterm ssh-list
winkterm whoami
winkterm logout
也可走环境变量 / flags(优先级 flags > env > 配置文件 > 默认,与 HTTP 同一套 token):
export WINKTERM_BASE_URL=https://ops.example.com
export WINKTERM_AGENT_TOKEN=<bearer-token>
WebSocket URL 自动从 base_url 推导(http→ws、https→wss,路径 /ws/agent)。
通用调用(覆盖全部方法)
winkterm call <method> '<json-params>'
call 直通后端,新增方法无需升级 CLI。CLI 的结果 JSON 打到 stdout,
实时输出(progress)打到 stderr,出错退出码非 0。MCP 复用同一 WS
长连接,底层会接收 progress,但当前 MCP 工具会先收集 progress,等命令结束后
把 {result, progress} 一次性返回给调用方;不要假设 MCP 客户端会边跑边显示
远端终端输出。需要实时肉眼监控时用 CLI,或订阅 terminal.stream。
可用方法(call 直通后端)
每个后端端点都有等价 WS 方法,参数同名(路径参数如 terminal_id / conn_id
放进 params)。完整 HTTP 端点映射见 HTTP_API.md。
| WS method | 用途 | params 关键字段 |
|---|
terminal.create | 新建终端 | type, connection_id, name, ttl_seconds |
terminal.list | 列终端 | — |
terminal.get | 终端信息 | terminal_id |
terminal.delete | 关闭终端 | terminal_id |
terminal.exec | 跑短命令(带退出码,阻塞等待) | terminal_id, command/command_b64, timeout, cwd, env |
terminal.run | 启动长任务并立即返回 run_id | terminal_id, command/command_b64, timeout, cancel_on_timeout |
terminal.run_wait | 等待长任务新输出/状态变化 | run_id, since, timeout |
terminal.run_status | 查询长任务状态/增量输出 | run_id, since |
terminal.run_cancel | 取消长任务 | run_id, mode |
terminal.input | 发输入/控制键 | terminal_id, data/keys, enter, wait |
terminal.snapshot | 读终端内容 | terminal_id, since, pattern |
ssh.connections.list/get/create/update/delete | SSH 连接增删改查 | conn_id, host, username, … |
ssh.import_electerm | 导入 electerm 书签 | bookmarks |
ssh.run | 一次性 SSH 短命令执行 | conn_id, command, timeout |
events.recent | 操作事件流 | since_id, limit |
ssh.files.list/read/write | SSH 文件读写 | conn_id, path, content |
ssh.upload / ssh.download | SSH 文件传输;CLI 上传读取调用机 local_path | conn_id, local_path, remote_path |
ssh.mkdir | 建远端目录 | conn_id, path |
ssh.delete_paths | 批量删远端路径 | conn_id, paths |
terminal.exec / ssh.run 在 WS 上会发 progress。CLI 可能实时打印 progress,
但 agent shell 工具不一定能在进程退出前看到 stderr;MCP 会把 progress 收集后随最终结果返回。
agent 长任务优先用 terminal.run / terminal.run_wait。terminal.stream / events.stream
可用于持续订阅,HTTP 侧也提供同名 SSE 端点,详见 HTTP_API.md。
便捷子命令
winkterm list
winkterm create --type ssh --connection-id ab12cd34 --name fix
winkterm exec <terminal_id> "uptime"
winkterm run <terminal_id> "sleep 300 && echo done"
winkterm run-wait <run_id> --since <size> --timeout 30
winkterm input <terminal_id> ":q!" --no-enter
winkterm snapshot <terminal_id> --since 1024 --pattern ERROR
winkterm delete <terminal_id>
winkterm ssh-list
winkterm ssh-run <conn_id> "uptime; df -h" --timeout 120
长任务怎么办
- 不要把 CLI stderr streaming 当成 agent 协议保证。 有些 agent 的 shell 工具只在进程退出后
才返回 stdout/stderr;即使 CLI 内部实时收到 progress,agent 也可能看不到中间过程。
- 短命令可直接
winkterm exec / winkterm ssh-run。长命令应采用“启动后主动观察”的模式:
用 winkterm input <terminal_id> "<cmd>" 或后续非阻塞 run 接口启动,再用
winkterm run-wait <run_id> --since <size> 等待增量输出;也可用
winkterm snapshot <terminal_id> --since <size> 查看终端。
- 把
--timeout 调到够大只能避免客户端提前返回 timeout,不能替代观察过程;当前 exec
timeout 只是等待超时,不等于一定终止远端命令。
- 只有 CLI 彻底连不上(旧后端无
/ws/agent、WS 被网络阻断)才退回 HTTP;
那种情况下仍可用 HTTP 的 /run + /wait 路径躲网关超时。
选 input 还是 exec
| 场景 | 用哪个 |
|---|
| 跑一条命令,要 stdout 和退出码 | /exec(POSIX shell only,bash/zsh/sh/dash) |
| 发控制键(Ctrl+C、方向键、Tab 补全) | /input + keys 字段 |
| 交互式程序(vim/top/分页器) | /input + snapshot 轮询 |
| Windows 本地 cmd.exe | /input |
| 想要"零回显、零 prompt 干扰" | /exec |
工作流程
winkterm ssh-list 查看可用 SSH 连接,拿到 id。
- 简单一次性命令:
winkterm ssh-run <conn_id> "<cmd>" 一步搞定(自动建临时终端→执行→关闭)。
- 要复用 shell 状态(cd、环境变量)或多步操作:
winkterm create --type ssh --connection-id <id> 新建终端,拿终端 id。
winkterm exec <terminal_id> "<cmd>" 跑命令(带退出码,首选)。
winkterm input <terminal_id> ... 发原始输入 / 控制键(交互程序、Ctrl+C 等)。
winkterm snapshot <terminal_id> 查看终端当前内容。
- 用完
winkterm delete <terminal_id> 关闭。
HTTP 接口(兜底,平时别碰)
默认全部走上面的 CLI。 只有 CLI 真的用不了才退回 HTTP:
- 目标机装不了 Node / 跑不了
winkterm,手头只有 curl;
- 需要 SSE 实时流(
/stream 长命令监控、tail -f);
- CLI 自动 fallback(
auto 模式)连不上 WS 时内部已替你走 HTTP。
完整 HTTP/SSE 端点、异步 job、curl 示例都在 HTTP_API.md——
远程 agent 用 curl ${WINKTERM_BASE_URL}/api/agent/http.md 取。
只在确需 HTTP 时读它,平时不加载、不占上下文。
使用建议
- 优先
exec(winkterm exec / winkterm ssh-run):拿退出码 + 干净 stdout,省去自己 strip 回显和 prompt。
- 复杂引号嵌套命令一律走
command_b64 / data_b64,省一层转义就少一层翻车
(winkterm call terminal.exec '{"terminal_id":"t","command_b64":"<base64>"}')。
- 交互式命令(分页器、确认提示)先发命令再
snapshot 查看,再用 call terminal.input 带 keys 字段发对应按键。
- 命令运行慢时把
--timeout 调大;WS 全程保活,不用怕断。
- 长任务和后台任务都要主动查看过程:用
run-wait 或 snapshot --since。
不要只等待一个超长 timeout;发现错误提示或交互卡住时及时处理。
- SSH 终端启动后首屏可能是登录横幅;发命令前可先
snapshot 确认 shell 就绪。
- 终端是有状态的:
cd、环境变量在同一终端内保持,跨命令复用同一终端 id。
exec 会在 shell 历史里留下 sentinel 包装的命令;若要避免,先 exec "export HISTFILE=/dev/null"。
示例(CLI)
winkterm login --base-url https://ops.example.com --token <bearer-token>
winkterm ssh-run ab12cd34 "uptime; df -h"
TID=$(winkterm create --type ssh --connection-id ab12cd34 | jq -r .id)
winkterm exec "$TID" "cd /var/log && ls -la"
winkterm exec "$TID" "tail -n 50 syslog"
CMD=$(echo -n "ps aux | awk '\$3>0 {print \$2}'" | base64 -w0)
winkterm call terminal.exec "{\"terminal_id\":\"$TID\",\"command_b64\":\"$CMD\"}"
winkterm exec "$TID" "apt-get install -y nginx && systemctl restart nginx" --timeout 600
winkterm snapshot "$TID" --since 0 --pattern "error|failed|waiting|confirm"
winkterm call terminal.input "{\"terminal_id\":\"$TID\",\"keys\":[\"ctrl+c\"],\"enter\":false}"
winkterm delete "$TID"