@mu-cabin/muc-cli
v0.5.6
Published
Terminal client for MUC IM (com.meicloud.im.dh).
Readme
MUC-cli
muc-cli 把 MUC IM(com.meicloud.im.dh)搬进终端。在 shell 里登录、找人、列群、读历史、收发消息和文件,不用打开桌面端 GUI。它同时附带MUC Skill,让你直接对 agent 说"把这个报告发给 张三",Skill 会自动选命令、解析返回值。
快速安装(复制给 Agent)
把下面这段话发给 Agent, 它会帮你完成全部安装:
帮我安装 muc-cli 和 MUC Skill:
1. 运行 `npm install -g @mu-cabin/muc-cli` 安装 CLI
2. 运行 `npx skills add <everything-cli 仓库地址>/packages/muc/skills -y -g` 注册 Skill(全局安装到所有 agent)
3. 运行下面这条 `muc init` 一次性写入租户配置(值见你的 MUC 部署管理员):
muc init --no-interactive \
--app-key <APP_KEY> \
--app-id <APP_ID> \
--sign-secret-rest '<SIGN_SECRET_REST>' \
--sign-secret-secure '<SIGN_SECRET_SECURE>'
4. 运行 `muc login --account <UID大写,如 ALICE> --password '<密码>'` 登录
5. 运行 `muc whoami` 确认登录成功MUC 租户配置
CLI 不把租户密钥编进发布包;首次安装后必须用 muc init 把这四个值写入
~/.muc/config.json(权限 0600)。这些值因部署而异——向你的 MUC 管理员索取,
不要外发。
| 字段 | 值 |
|---|---|
| APP_KEY | <APP_KEY>(8 位小写 hex) |
| APP_ID | <APP_ID>(24 位小写 hex) |
| SIGN_SECRET_REST | <SIGN_SECRET_REST> |
| SIGN_SECRET_SECURE | <SIGN_SECRET_SECURE> |
| PWD_DES_KEY | 留空(自动用 APP_KEY) |
主机/端口(向管理员索取你的部署地址,CLI 内置默认仅适用于特定租户):
| 字段 | 示例 |
|---|---|
| restHost | https://muc.example.com/ |
| ssoHost | https://store.example.com/ |
| imHost / imPort | muc.example.com / 8101 |
| fileHost / filePort | muc.example.com / 6101 |
一行式(非交互,CI/Agent 友好):
muc init --no-interactive \
--app-key <APP_KEY> \
--app-id <APP_ID> \
--sign-secret-rest '<SIGN_SECRET_REST>' \
--sign-secret-secure '<SIGN_SECRET_SECURE>'或交互式:
muc init # 逐项提示,密钥手输,主机/端口按回车采用默认校验:
muc init --check --json # exit 0=ok, 6=missing, 7=invalid
muc init --show # 仅显示打码后的指纹(不会回显原值)这些值是租户级密钥,绝不要复制到 npm 包、Skill 包或任何公开渠道。向你的 MUC 部署管理员索取,并只通过私有渠道传递。
安装 CLI
环境: Node ≥ 18
npm install -g @mu-cabin/muc-cli
muc --version首次配置(一次性)
CLI 没有内置可用的租户密钥,必须先用 muc init 写入。值见上面 "MUC 租户配置" 表:
muc init --no-interactive \
--app-key <APP_KEY> \
--app-id <APP_ID> \
--sign-secret-rest '<SIGN_SECRET_REST>' \
--sign-secret-secure '<SIGN_SECRET_SECURE>'
muc init --check # 应输出 ok首次登录
muc login --account ALICE --password '<你的密码>'
muc whoami登录成功后凭证写入 ~/.muc/credentials.json(权限 600),有效期约 7 天;tokenPwd(30 天)可用于静默续登:
muc login --token-pwd # 无需密码,直接续登安装并使用 Agent Code Skill
Skill 注册之后,你可以直接用自然语言驱动 muc,不用记命令格式。
安装 Skill
npx skills add <everything-cli 仓库地址>/packages/muc/skills -y -g注册后 Agent Code 会自动识别 muc 相关请求并调用对应命令。
对 Agent 说什么
以下这些说法都会触发 muc-cli Skill:
"把今天的周报发给 张三"
"拉一下 王五 本周的聊天记录"
"列一下我在 MUC 的群"
"帮我搜一下 MUC 上叫 李四 的人"
"IT 值班群发个通知:今晚 22:00 有计划性维护"
"把 muc 上刚才发的消息撤回"
"下载一下 <mid> 这条消息里的附件"Skill 的行为规则
- 首次直连 TCP 命令前:Skill 只提醒“同账号 iPad 可能被踢”,不再等待槽位确认,随后直接执行。
- 不确定发给谁:先用
muc search缩小候选名单,通过AskUserQuestion让你选,不会猜。 - 非自身目标:必须经过你显式确认,不会偷偷给真实联系人发消息。
- token 过期:自动用
--token-pwd静默续登,续登失败才要求你手动muc login。
Agent 场景示例
MUC Skill 的价值在于嵌入更大的 agent 工作流——先让 agent 完成主任务,再用 MUC 传递结果或读取上下文。
跑测试 → 失败通知值班群
帮我跑一下单测,如果有失败把结果发到 IT 值班群
Agent 跑完测试、整理失败摘要,再通过 MUC 推送到群里。MUC 是"结果出口"。
Code Review → 通知作者
帮我 review 这个 PR,review 完把结论发给作者
Agent 分析 diff、生成意见,从 git log 拿到作者,搜出对应 MUC 账号后发消息。
读群聊上下文 → 代为回复
IT 值班群今天在讨论什么?帮我接着回复,说为什么要用 Redis 而不是本地缓存
Agent 拉取今日群消息,理解讨论脉络,起草回复并等你确认后发出。MUC 历史是输入上下文。
分析日志 → 发文件给同事
帮我分析 logs/access.log,生成访问量报告发给 王五
Agent 统计 PV/UV、Top 路径、错误率,写成报告文件,搜出收件人后 muc send-file 发出。
读 MUC 需求 → 生成代码骨架
看看 王五 昨天发给我的需求,整理成 TODO 并创建对应的函数骨架
Agent 拉取消息、提取功能点、在项目里生成文件,最后用 MUC 回复确认。MUC 历史是任务来源。
定时周报(配合 /schedule)
/schedule 每周五 17:00 帮我把本周 git 提交整理成周报发给上级
Agent 定时触发,跑 git log、整理自然语言周报、确认收件人、发送。
cli 命令速查
查人 / 查组织
muc search 李四 # 关键字搜员工
muc search-dept "信息技术部" # 按部门搜(含员工数 + 层级路径)
muc search-app "审批" # 搜应用/小程序
muc whois BOB # 单人完整档案
muc groups # 我的星标群 + 部门群
muc search-team "值班" --enrich # 查已加入群(TCP)
muc team-members 9009876543210000 --profiles # 查群成员 + 部门/岗位(TCP + REST)聊天历史
muc history --peer WANGWU --days 7 --limit 200
muc history --team 9009876543210000 --days 30 --json | jq '.data.messages[]'
muc history --to-self --days 1发消息
muc send --to-self "hello from CLI" # 发给自己(安全测试)
muc send --peer BOB "明天上午有空吗?" --yes-not-self
muc send --team 9009876543210000 "值班通知" --yes-not-self发文件 / 图片 / 语音
muc send-file ./dist/release.dmg --peer QA_LEAD --yes-not-self
muc send-image ~/Desktop/screenshot.png --to-self # 自动探测宽高
muc send-voice ./recording.amr --duration 3500 --to-self # duration 单位 ms下载 / 撤回
muc download --mid <mid> --to-self --out ./got.bin # 通过消息 ID 下载附件
muc withdraw --mid <mid> --to-self # 撤回自己发出的消息任何命令加
--json输出稳定的机器可读信封:成功{ok:true, data}/ 失败{ok:false, code, msg}。 退出码:0成功 /2用法错误 /3鉴权 /4未找到 /5远端或网络 /1内部错误。
和桌面端 / 手机端 / iPad 共存
REST 命令(search、history、whois、groups 等)永远可以共存,与桌面端、手机端同时在线互不影响。
聊天通道命令(send*、withdraw、sync、search-team、team-members)进入 MUC 实时通道。每个账号有 PC、Mobile、iPad 三个独立槽位;同槽后登录会把前一个挤下线。CLI 继续沿用 --os 选槽位,其中 iPad 是逻辑值:线上报文实际发送 os:"iOS" 和 browser:"iPad"。
| 算作哪端 | 对应的 --os 取值 |
|---|---|
| PC 端 | Windows / OS X / Mac(Mac 桌面端登录时上报的是 OS X) |
| 移动端 | iOS / Android |
| iPad 端 | iPad(CLI 默认;线上报文为 os:iOS + browser:iPad) |
⚠️ CLI 默认使用 iPad 槽位。PC 桌面端和手机端可以继续在线;如果同账号正登录 iPad,iPad 可能被挤下线,重新打开 App 即可恢复,
accessToken不失效。
- 测试或跑通流程时,先用
muc send --to-self ...发给自己。--os iOS/Android会改占 Mobile 槽位,可能踢手机;--os Windows/OS X/Mac会改占 PC 槽位,可能踢桌面端。- Skill 对默认 iPad 风险只做非阻塞提醒,不再要求预先确认槽位;发送给真实联系人、撤回等业务确认仍保留。
muc tcp-ping 只做 TCP 连接和 NEGOTIATE,不发登录帧,不占任何在线名额,纯连通性测试,可以随时跑。
开发者指南
从源码运行
git clone <repo> everything-cli && cd everything-cli
pnpm install # 工作区依赖装在仓库根
cd packages/muc
pnpm run typecheck # tsc --noEmit,必须先过
./bin/muc <command> # 直接走 tsx 跑 src/,零构建仓库结构
packages/muc/ (everything-cli 工作区中的一个包)
├── src/index.ts 命令分发器
├── src/commands/*.ts 每个子命令一个文件
├── src/lib/ 协议层:wire.ts / chat.ts / sign.ts / …
├── src/assistant/ auto-reply 守护进程 + 各 backend
├── skills/ muc-* Agent Skills(muc-message / muc-chat / muc-shared / …)
├── scripts/build.mjs esbuild 打包脚本(→ dist/muc.mjs)
├── bin/muc tsx 入口(零构建直接跑 src/)
├── README.md 本文件
├── REFERENCE.md 完整命令 / 协议参考
└── NATIVE_API.md MUC 原生协议全景 / CLI 实现状态协议研究文档与抓包脚本保留在内部源码研究仓库,未随本包导入;下文"协议抓包 / 改动后测试 / 协议层参考"小节中对它们的引用均指内部仓库。
协议抓包:通过 Surge.app
不用切系统代理、不用安装额外 CA —— Surge.app 已在本机运行即可。
一次性配置:在 Surge UI 里把你的 MUC 主机(如 *.example.com)加进 MITM hostname,打开 MITM + Capture + HTTP API。
# 抓 60 秒的 muc HTTP/S 流量,输出 NDJSON
python3 surge_capture.py --key <surge-http-api-key> --process MUC --duration 60 > flows.ndjson
# 聚合成 API 地图(人读)
python3 analyze_api.py flows.ndjson
# 机器读
python3 analyze_api.py flows.ndjson --json
# 只看某个主机
python3 analyze_api.py flows.ndjson --host muc.example.com如果 Surge 配置了
http-api-tls = true,用https://127.0.0.1:6171+ 关闭 SSL 验证访问,或直接去掉该配置项。
改动后测试流程
pnpm run typecheck(在packages/muc下)— 先过类型检查。- 按内部
TEST_CASES.md从头到尾跑一遍;实时命令默认走 iPad 槽位,实机验证前确认没有需要保持在线的同账号 iPad。 - 任何一项失败:把
--json原始信封贴给用户,停下来,不要"修一修再跑"。
协议层参考(内部文档)
HANDOFF.md— 当前状态、已验证里程碑、常量(hosts / 密钥 / transport AES key)、关键算法的踩坑笔记。MUC_API.md— REST 端点全图(/muc /imm /msm /contacts /mam /...)+ TCP 8101 帧规范 + 6101 文件通道。API_CLIENT.md— 从解包客户端摘出的全量 API 目录,找 CLI 还没封装的端点去这里翻。
红线
- 绝不入库
accessToken、tokenPwd、明文密码、clientSecret、pfxPass、bsSecretKey、encrypt_key,以及租户密钥(APP_KEY/sign secrets)。 - CLI 默认占用同账号的 iPad 槽位(
--os iPad→os:iOS + browser:iPad),可能顶掉真实 iPad;显式传 Mobile/PC 类--os才会影响手机/桌面端。 - CLI 发的消息所有参与方都可见。 非自身目标必须带
--yes-not-self,先用--to-self测。 - 不要擅自改 Surge 配置文件(
~/Library/Application Support/Surge/Profiles/*.conf)。要加 MITM hostname 让用户在 Surge UI 里加。
