Skip to content

Repository files navigation

meatshell-custom

简体中文 | English

一个轻量级、低内存占用的 SSH / 终端客户端,灵感来自 FinalShell,但完全由 Rust + Slint 实现。目标是保留 FinalShell 的核心体验 (资源监控侧栏、会话管理、多标签页终端)的同时,把内存占用从 400 MB+ 的 JVM 压到几十 MB 原生级别。

Custom 版本说明

本分支基于原作者的 meatshell 项目,做了一些定制改动,包含功能增强、交互优化和问题修复;README 其余内容尽量保持与上游原版一致。

本分支变更与改进

以下内容均为本分支相对于 upstream/main 的新增功能、交互改进和问题修复:

  • 增加“江南”主题,并完善主题颜色 token;SFTP 斑马纹、悬浮状态、选中状态和危险操作均使用主题配色。
  • 快速连接、运行状态和快捷指令面板统一支持四边停靠;同一边的面板共享停靠区域,通过侧边图标切换或收起,面板宽度和拖拽条保持一致。
  • 快捷指令支持独立侧栏、分组管理、持久化设置和向所有会话广播;欢迎页与运行状态面板也可独立停靠。
  • 增加远程 NVIDIA 多 GPU 显存监控(已用 / 总量)、System Information 窗口和中英文界面;资源面板隐藏时暂停采样。
  • SSH 连接增加 X11 forwarding;本地 PowerShell / CMD 会话使用专用启动逻辑并禁用无效的 SFTP 控件。
  • 增加可选的终端输出高亮(日志 / DevOps 预设和自定义规则)以及 Windows / macOS 渲染器选择。
  • 增加终端 Ctrl+C 复制偏好、拖选自动复制、光标自动颜色、光标不透明度和未聚焦光标显示设置。
  • 优化终端光标:输入或方向键操作后保持亮态并重新开始闪烁;修复拖选、tmux 和不同宽字符场景下的光标位置问题。
  • 会话 Tab 支持同组拖拽排序、横向滚轮浏览、可拖动滚动条、标题宽度上限和始终可用的新标签页。
  • SFTP 文件列表增加键盘操作(方向键、Backspace、Enter、Delete)、路径栏文件打开、确认删除和 Esc 取消;无效路径不会写入历史。
  • SFTP 支持 Windows 风格多选、批量下载 / 移动 / 删除、打包下载、可视化移动目标目录和目录树右键菜单。
  • SFTP 文件列表支持按名称、大小、类型、修改时间、权限和用户/用户组排序,并在进入目录、返回、刷新和重连后保持排序及选中状态。
  • 每个会话保存最多 50 条 SFTP 路径历史,并恢复目录树展开、选中文件和滚动位置;目录列表缓存最多保留 64 个最近目录。
  • SFTP 大目录使用分页、虚拟列表和请求合并,目录树支持加载全部 / 收起,降低大目录打开和连续导航的开销。
  • SFTP 支持“文件 / 端口转发”页签,可创建、停止和清理运行时 -L 本地转发及 -D SOCKS5 动态转发。
  • SFTP 侧面停靠时工具栏会按优先级自适应收缩和裁切,路径栏、上级目录、刷新及收起按钮保持正确位置;所有工具栏按钮提供悬浮提示。
  • SFTP 支持 tmux 中跟随终端 cd 同步路径、会话间上传同步,以及中英文文件类型和界面文案。
  • 新建 / 编辑会话及 SFTP 弹窗支持 Esc 关闭和拖动定位;输入框会自动跟随光标,长路径默认显示末尾。
  • 终端滚动历史和 emoji 图像缓存均设置上限,避免长时间运行或大量输出造成缓存持续增长。

截图

欢迎页 / 会话管理
欢迎页:会话管理 + 左侧本机资源监控

终端 + SFTP
多标签页终端(htop 全屏渲染)+ 底部 SFTP 文件浏览 + 远端资源监控

下载与安装

每次打 v* 标签,GitHub Actions 会自动构建 Windows / Linux / macOS 三平台二进制, 发布到 Releases 页面。

Windows

下载 meatshell-*-windows-x86_64.zip,解压后双击 meatshell.exe

Linux

tar -xzf meatshell-*-linux-x86_64.tar.gz
cd meatshell-*-linux-x86_64
./meatshell                                  # 直接运行
# 可选:装应用图标 + 启动器入口(Dock / 应用列表里显示图标,无需传参)
chmod +x install-linux.sh && ./install-linux.sh

需要 glibc ≥ 2.35(Ubuntu 22.04+ / Debian 12+)。Wayland 下首次装完图标可能要注销重登一次。

从源码 cargo run(Linux Mint / Ubuntu / Debian)需要先安装 Slint/winit/rfd 等用到的系统开发包:

sudo apt update
sudo apt install -y --no-install-recommends \
  build-essential pkg-config cmake \
  libfontconfig1-dev libfreetype6-dev \
  libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
  libxkbcommon-dev libxkbcommon-x11-dev libwayland-dev \
  libgl1-mesa-dev libegl1-mesa-dev libgtk-3-dev \
  libudev-dev

macOS

下载得到的是 .zip,里面是 meatshell.app 应用程序包:

# 解压(aarch64 = Apple 芯片,x86_64 = Intel)
unzip meatshell-*-macos-*.zip
# 移到「应用程序」(可选,留在原地也行)
mv meatshell.app /Applications/
# 去掉「未签名应用」的隔离属性,否则会提示「meatshell 已损坏,无法打开」
xattr -dr com.apple.quarantine /Applications/meatshell.app
# 打开(或在「访达」里双击)
open /Applications/meatshell.app

若未移到 /Applications,把上面两条路径换成 .app 实际所在位置(如 ~/Downloads/meatshell.app)即可。

从源码构建见下方 运行

功能

已实现

  • FinalShell 风格 UI,深色 / 浅色 / 江南主题
  • 本机 + 远端资源监控(CPU / 内存 / 交换 / 网络 / 磁盘)
  • 远端进程监控(按 CPU 排序、PID 复制与权限确认后结束进程)
  • 完整 VT/ANSI 终端模拟(btop / htop / vim 全屏正常渲染)
  • 彩色 emoji(支持肤色、旗帜及 ZWJ 组合序列)
  • 多标签页(欢迎页 + 多个会话)
  • 会话管理:新建 / 编辑 / 删除 / 分组,本地 JSON 持久化,导出 / 导入
    • 配置位置:%APPDATA%/meatshell/sessions.json(Windows) / ~/.config/meatshell/sessions.json(Linux) / ~/Library/Application Support/meatshell/sessions.json(macOS)
  • SSH(russh,纯 Rust):密码 / 私钥 / 加密私钥(密码短语)
  • SFTP 文件浏览 + 上传 / 下载(拖拽)+ 终端内 ZMODEM(sz)接收
  • SSH 端口转发 / 隧道:本地 -L / 远程 -R / 动态 -D(SOCKS5)
  • 快捷命令 + 命令输入框(可群发到所有会话)+ 命令历史
  • 串口 / Telnet 会话
  • 出站代理(SOCKS5 / HTTP)
  • 导入 ~/.ssh/config
  • 会话密码加密存储(ChaCha20-Poly1305)
  • 已知主机(known_hosts)校验 + 首次连接确认
  • 多标签页终端分屏

彩色 emoji 图形来自 Twemoji,按 CC BY 4.0 使用;完整署名见 THIRD_PARTY_NOTICES.md

计划中

  • 会话密码改用 OS 钥匙串存储

技术栈

模块 选型
UI Slint(纯 Rust 编译,无 GC)
异步运行时 tokio
SSH 协议 russh(无 libssh 依赖)
系统指标 sysinfo
序列化 serde + serde_json
日志 tracing + tracing-subscriber

运行

cargo run --release

首次启动会在 %APPDATA%/meatshell/sessions.json 建立空的会话库。点击右上 角 “+ 新建会话” 添加第一台服务器。

CLI 与 MCP 自动化

MeatShell 的 CLI 和 MCP 共用 GUI 中保存的会话及 SSH / SFTP 实现。CLI 适合脚本、 CI 和手动执行明确的命令;MCP 则让支持 MCP 的 AI 客户端通过自然语言完成服务器 巡检、日志分析和文件传输。两者只是调用入口不同,不需要重新维护一份服务器配置。

使用前请先在 GUI 中创建并成功连接一次目标会话,以完成主机密钥确认。密码、私钥等 凭据不会出现在 CLI/MCP 返回结果中,也不要把明文密码写进提示词或 MCP 配置。

CLI

查看所有可用命令:

meatshell cli help

常用示例:

# 列出已保存的会话,第一列是后续命令使用的 session-id
meatshell cli sessions
meatshell cli sessions --json

# 查看单个会话的非敏感信息
meatshell cli session <session-id>

# 执行非交互式 SSH 命令;远端命令必须放在 -- 后面
meatshell cli exec <session-id> -- free -h
meatshell cli exec <session-id> --timeout 60 --json -- journalctl -n 100 --no-pager

# 浏览、读取和传输远端文件
meatshell cli files <session-id> /var/log
meatshell cli read <session-id> /var/log/example.log
meatshell cli upload <session-id> ./local.txt /tmp
meatshell cli download <session-id> /tmp/result.txt ./downloads

CLI 的 <session-id> 可由 meatshell cli sessions 获取。文件下载要求本地目标目录已经 存在,且不会覆盖同名文件。

MCP

先打开 MeatShell 的 设置 → 界面 → MCP

  1. 启用 MCP。
  2. 根据需要允许使用已保存的凭据。
  3. 需要远程诊断时允许执行任意 SSH 命令。
  4. 需要上传或下载文件时允许文件传输。

然后在支持 stdio MCP 的客户端中添加名为 meatshell 的服务:

{
  "mcpServers": {
    "meatshell": {
      "command": "/absolute/path/to/meatshell",
      "args": ["mcp", "serve"]
    }
  }
}

Windows 下 command 可以填写 C:\\path\\to\\meatshell.exe。重启或刷新 MCP 客户端 后,应能看到 meatshell 服务以及会话查询、远程命令、目录浏览、文本读取、上传和下载 等工具。不同 AI 客户端的 MCP 配置文件位置不同,请以对应客户端文档为准。

MCP JSON-RPC 示例

一般情况下由 AI 客户端自动生成这些请求,无需手工输入。调试 stdio 连接时,每个请求 必须是独立的一行 JSON,依次完成初始化和 notifications/initialized 通知:

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"example-client","version":"1.0.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}

查询已保存会话并获取 <session-id>

{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list_sessions","arguments":{}}}
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"get_session","arguments":{"session_id":"<session-id>"}}}

执行 OOM 只读诊断并浏览堆转储目录:

{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"run_command","arguments":{"session_id":"<session-id>","command":"free -h; printf '\\n=== kernel OOM ===\\n'; dmesg 2>/dev/null | grep -iE 'oom|out of memory|killed process' | tail -50 || true; printf '\\n=== Java ===\\n'; ps -ef | grep '[j]ava'","timeout_seconds":30,"max_output_bytes":1048576}}}
{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"list_remote_files","arguments":{"session_id":"<session-id>","path":"/home/jeff/test/heapdumps"}}}

读取日志或下载一个堆文件:

{"jsonrpc":"2.0","id":7,"method":"tools/call","params":{"name":"read_remote_text_file","arguments":{"session_id":"<session-id>","path":"/home/jeff/test/logs/meatshell-log-demo-error.log"}}}
{"jsonrpc":"2.0","id":8,"method":"tools/call","params":{"name":"download_file","arguments":{"session_id":"<session-id>","remote_path":"/home/jeff/test/heapdumps/example.hprof","local_directory":"/existing/local/directory","timeout_seconds":120}}}

read_remote_text_file 只接受有大小和行数限制的 UTF-8 文本;HPROF 等二进制文件应使用 download_file。下载目标目录必须已经存在,且工具不会覆盖同名文件。

配置完成后,可以直接对 AI 客户端说:

meatshell MCP 排查一下:我的 192.168.100.41 服务器出现 OOM,堆转储位于 /home/jeff/test/heapdumps。请检查系统内存、内核 OOM 记录、Java 进程、应用日志和 HPROF 文件,判断根因;先只读排查,不要重启服务或删除文件。

MCP 会先通过 list_sessions 查找匹配的已保存会话,再按已授予的权限调用远程命令或 SFTP 工具。若存在多条同主机会话,可在提示词中补充 GUI 中的会话名称。建议诊断提示词 明确写出目标主机、日志或堆文件路径,以及是否允许重启、修改配置、下载文件等操作边界。

项目布局

meatshell/
├── Cargo.toml
├── build.rs                 # Slint 编译器入口
├── ui/
│   ├── app.slint            # 顶层窗口
│   ├── theme.slint          # 设计 tokens
│   ├── widgets.slint        # 可复用按钮 / 输入框 / sparkline
│   ├── sidebar.slint        # 左侧系统监控面板
│   ├── tabs.slint           # 顶部标签栏
│   ├── welcome.slint        # 欢迎页 / 快速连接
│   ├── session_dialog.slint # 新建 / 编辑会话弹框
│   └── terminal_view.slint  # 终端视图(v0.1 行缓冲)
└── src/
    ├── main.rs
    ├── app.rs               # UI ↔ 后端桥接
    ├── config.rs            # 会话 JSON 持久化
    ├── system.rs            # CPU / 内存 / 网络采样
    └── ssh.rs               # SSH 会话 worker

开发提示

  • Slint 控件有非常严格的布局 DSL,改 .slintcargo check 是最快的 反馈方式。
  • 应用事件循环是单线程(Slint 要求),所有跨线程 UI 更新通过 slint::invoke_from_event_loop 回调。
  • SSH / SFTP 共享 known_hosts 校验逻辑:首次连接会确认并记住主机密钥, 后续密钥变化会再次提示。

发版

不要直接手动修改 Cargo.toml 后再打标签。使用发布脚本,让 Git tag 指向的提交本身就已经包含正确版本号:

.\scripts\release.ps1 v0.6.0 -Push

脚本会更新 Cargo.toml / Cargo.lock,运行 cargo check --locked,验证 meatshell --version,提交 Release v0.6.0,创建 annotated tag,并推送当前分支和 tag。更多细节见 docs/release.md

相关群组

QQ群二维码
扫描二维码加入 QQ 群,与其他用户交流使用经验、反馈问题或获取最新动态

License

MIT OR Apache-2.0(双许可)。

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages