内容
# gmkit
终端和AI代理使用的谷歌消息服务 — 本地优先,带有人工审批队列以确保代理发送的消息安全。
gmkit 提供一个独立的 Go 二进制文件,`gmcli`(CLI,同步守护进程和 MCP 服务器),它与谷歌消息服务配对,并将对话存档到本地 SQLite + FTS5 数据库中。此外,还有一个 Rust 终端 UI,`gmtui`([`gmtui/`](gmtui/))。
```
┌───────────────────────────────┐
│ gmcli serve (Go 守护进程) │
│ libgm 会话 · 同步 · SQLite │
└──────────────┬────────────────┘
│ JSON-RPC 超过 unix 套接字
┌──────────────────┼─────────────────────┐
│ │ │
gmtui (Rust TUI) gmcli mcp gmcli CLI + --json
人机驾驶舱 + MCP 工具适用于 脚本和临时
发送审批 克劳德和代理 代理使用
```
> **状态:** 测试版。配对、会话持久性、同步循环、查询 CLI(`messages`、`contacts`、`chats`)、尽力而为的历史记录回填、发送命令、媒体下载和一个 LLM 技能(`skills/google-messages`)已经连接并涵盖了自动测试套件中。实时设备的行为仍然取决于非官方的谷歌消息服务网页协议,因此请在使用前在您自己的帐户上验证身份验证、同步、历史记录、媒体和发送流程。参见 [`docs/research/phase-1-libgmessages.md`](docs/research/phase-1-libgmessages.md) 以获取设计说明,并参见 [`skills/README.md`](skills/README.md) 以获取技能安装指南。
## 它是什么
- **独立。** 无需 Matrix 服务器,无需 Docker,无需桥接守护进程。只需一个 Go 二进制文件、一个 SQLite 文件和一部运行谷歌消息服务的手机。
- **先读。** 手机修改操作(发送文本和反应)被显式标志阻止。默认情况下为观察,而不是发送。
- **本地。** 消息存储在数据目录(XDG 兼容)下的单个 SQLite 数据库中。没有任何内容被上传到其他地方。
- **AGPL-3.0.** gmcli 导入 `pkg/libgm` 自 [mautrix/gmessages](https://github.com/mautrix/gmessages),其许可证为 AGPL-3.0。这使得 gmcli 成为派生作品,并要求整个程序使用相同的许可证。参见 `LICENSE` 和 `NOTICE`。
## 它是如何工作的
`pkg/libgm` 逆向工程谷歌消息服务的网页客户端协议。在一次性二维码配对握手后,它与配对的手机保持身份验证会话 — 所有消息都通过手机流动,手机将它们代理到谷歌的中继基础设施。gmcli 用事件循环包装该会话,将传入的消息、对话更新和联系人数据写入本地 SQLite 数据库,并通过 CLI 公开数据库。
手机必须在线并安装谷歌消息服务才能使中继工作。配对令牌会自动刷新;大约每 14 天的非活动期(谷歌的政策,而不是我们的)需要完全重新配对。
## 安装
无需工具链 — 安装程序从 GitHub Releases 下载预构建的二进制文件(macOS 和 Linux,arm64 和 x86_64):
```sh
curl -fsSL https://raw.githubusercontent.com/johnlindquist/gmkit/main/install.sh | bash
```
或者从克隆仓库: `./install.sh`。二进制文件位于 `~/.local/bin`(可通过 `GMKIT_BIN_DIR` 重写)。要从源代码构建,请传递 `--source`(需要 Go 1.24+;Rust 可选,用于 gmtui)。手动等效:
```sh
go install github.com/johnlindquist/gmkit/cmd/gmcli@latest
cargo install --git https://github.com/johnlindquist/gmkit gmtui
```
对于源代码构建,其 `gmcli version` 输出包括当前标签或提交,请在链接时注入:
```sh
go build -ldflags "-X github.com/johnlindquist/gmkit/internal/cmd.Version=$(git describe --tags --always --dirty)" -o gmcli ./cmd/gmcli
```
预构建的二进制文件分发和 Homebrew 软件包计划在初始测试版发布后提供。
## 当前限制
- 实时设备覆盖仍然有限。在依赖 gmcli 自动运行之前,请测试 `auth`、`sync`、查询命令、`history backfill`、`media download` 和故意发送您自己的谷歌消息服务帐户。
- 历史记录回填是尽力而为的,取决于配对手机返回的谷歌消息服务内容。
- 手机必须在线才能进行同步、回填、发送和媒体下载。
- SQLite 数据库是本地的但未加密。如果您需要静态保护,请使用文件系统加密。
## 快速开始
```sh
# 1. 一次性配对(在终端中显示二维码 — 使用手机上的谷歌消息服务应用扫描,设置 → 设备配对 → 二维码)。
gmcli auth
# 2. 将手机中的消息同步到本地数据库。 --follow 保持连接打开并写入新消息。
gmcli sync --follow
# 3. 查询本地存档(只读)。
gmcli chats list # 最近的对话
gmcli chats show <conversation-id> # 头部 + 最近的消息
gmcli messages search "dinner" # FTS5 跨所有对话
gmcli messages list --conv <conv-id> # 消息列表,带过滤器
gmcli messages show <message-id> # 单个消息详情
gmcli messages context <message-id> # 周围的消息
gmcli contacts search alice # 名称/号码/别名子字符串匹配
gmcli contacts show <participant-id-or-num> # 联系人详情
# 4. 本地标签。
gmcli contacts alias set --id <pid> --alias "Mom"
gmcli contacts alias list # 列出所有设置的别名
gmcli contacts alias rm --id <pid>
# 5. 尽力而为的历史记录回填,模仿 wacli。
gmcli history backfill --chat <conv-id> --requests 10 --count 50
# JSON 输出分别报告协议记录和聊天消息增量:
# fetched_messages, sync_records_processed, messages_before, messages_after,
# messages_added_for_chat.
# 6. 写入手机(始终需要 --read-only=false)。
gmcli --read-only=false send text --to <conv-id> --message "on my way"
gmcli --read-only=false send react --message <msg-id> --emoji "👍"
gmcli media download --message <msg-id>
# `send text` 仅在谷歌消息服务通过其规范的 message_id 回声消息后报告成功。
```
## 守护进程、TUI 和代理
守护进程保持会话活跃,将事件流式传输到存档,并通过 unix 套接字 (`<store>/gmcli.sock`) 公开 JSON-RPC 接口。 **您通常永远不会自己启动它**:gmtui、`gmcli mcp` 和 `gmcli approvals` 在需要时自动启动它(`serve --auto`),并且它在 10 分钟内无客户端时自动退出。仅在您想要不同行为时手动运行:
```sh
gmcli serve # 始终在线,只读:查询接口
gmcli --read-only=false serve # 始终在线且可发送(审批队列)
gmcli serve --offline # 存档查询,无手机连接
```
自动启动的守护进程为发送使用审批队列 — 默认情况下设计安全,因为如果没有人工审批,代理发送的消息不会到达手机。审批队列是使代理发送安全的功能:默认守护进程策略(`--sends approve`)下,代理的 `send_text` 仅**提议**消息。它进入本地队列,gmtui 弹出警告,人工审批(gmtui 中的 `y` 或 `gmcli approvals approve <id>`)或拒绝它。在审批之前,消息不会触及手机。 `--sends direct` 跳过队列,适用于信任其代理的人员;每次发送仍会留下审计行。
```sh
gmcli approvals list # 无人值守审查队列
gmcli --read-only=false approvals approve <id> # 批准 = 发送
gmcli approvals deny <id> --reason "nope"
```
在 `serve` 运行期间,请优先使用套接字/MCP 接口而不是 `gmcli sync`/`send`/`history` CLI 命令 — 守护进程拥有对手机的唯一允许会话。
## 全局标志
| 标志 | 默认 | 用途 |
| ---------------- | ---------------------------------- | -------------------------------------------------------- |
| `--store DIR` | `$XDG_STATE_HOME/gmcli` | 会话、SQLite 和下载媒体存放的位置。 |
| `--read-only` | `true` | 阻止通过手机发送文本或反应的命令。 |
| `--json` | `false` | 发出机器可读的输出。 |
| `--full` | `false` | 禁用表格输出的截断。 |
| `--log-level` | `info` | 详细程度 (`trace`/`debug`/`info`/`warn`)。 |
## 布局
```
cmd/ Cobra 命令树(auth、sync、serve、mcp、approvals、
version、doctor、messages、contacts、chats、send、media)
internal/
gm/ libgm 包装器 — 配对、会话、事件、发送/反应、
WaitForReady、DownloadMedia
store/ SQLite + FTS5 存储(模式 v3:别名和审批)
sync/ 事件到存储泵
history/ 尽力而为的回填引擎(CLI 和守护进程共享)
rpc/ 守护进程:unix 套接字上的 JSON-RPC、事件流、
审批队列(docs/rpc-protocol.md)
output/ 共享 JSON / 表格对齐渲染器
paths/ XDG 路径解析(XDG_STATE_HOME)
logging/ zerolog 设置
gmtui/ Rust ratatui 终端客户端,用于守护进程
skills/
google-messages/ LLM 技能包 - 存档剧本,用于助手
docs/research/ 第一阶段研究笔记
docs/rpc-protocol.md 守护进程套接字协议参考
```
## LLM 集成
首选集成是 `gmcli mcp`(参见上面的“守护进程、TUI 和代理”)。捆绑的 OpenClaw 技能位于 `skills/google-messages`。它在 ClawHub 上发布为 [Google Messages Local Archive](https://clawhub.ai/fdsouvenir/google-messages-local-archive) (`google-messages-local-archive`),用于从本地 Google Messages SMS/RCS 存档中搜索、总结和回答问题,默认情况下为只读。
## 隐私
- 所有数据都是本地的。gmcli 不会联系服务器。
- 会话令牌存储在 `$XDG_STATE_HOME/gmcli/session.json` 中,模式为 0600。
- 媒体附件在数据库中按 ID 引用;默认情况下不会下载字节。使用 `gmcli media download --message <message-id>` 进行显式下载。
- SQLite 文件未加密。如果您需要静态加密,请使用文件系统加密(FileVault、LUKS 等)。
## 致谢
- **libgm** — 此 CLI 依赖的 Google Messages 协议库 — 由 Tulir Asokan 和 [mautrix](https://github.com/mautrix/gmessages) 贡献者编写。许可证:AGPL-3.0。没有他们的逆向工程工作,gmcli 就不可能实现。
- CLI 动词结构灵感来自 Peter Steinberger 的 [wacli](https://github.com/steipete/wacli),适用于 WhatsApp。
- 存储和 MCP 工具模式借鉴 [openmessage](https://github.com/MaxGhenis/openmessage) by Max Ghenis,在 Unlicense 下发布。
## 许可证
GNU Affero 通用公共许可证,版本 3 或更高版本。有关完整文本,请参见 `LICENSE`;有关上游许可证要求的第三方通知,请参见 `NOTICE`。