内容
# Ghostie
**AI 提出建议,您来审批。** 一个更安全的 MCP 消息工具,适用于用户不希望 Claude 在未经人工审核的情况下代表他们发送消息。
Ghostie(前身为 “Messages for AI”)是一个单独的拖拽安装程序,安装路径为 `/Applications/Ghostie.app`。该 `.app` 捆绑了菜单栏 UI、Ghostie(通用 `ghostie-mcp` 接口)、特定于传输的 iMessage 和 WhatsApp MCP,以及它们的后台守护进程。所有内部二进制文件都在一个捆绑标识下签名,并通过菜单栏应用程序在需要时启动,因此 Claude 不需要完全磁盘访问权限。首次启动时, onboarding 向导会询问您要启用的传输。
**v0.3.0 版本提供两个传输:iMessage 和 WhatsApp。** Signal 和 Slack 仍在路线图中。
## 与官方 Anthropic iMessage 插件的区别
Anthropic 提供了官方的 iMessage 插件,允许 Claude 直接发送 iMessage。这是一个很好的选择,如果您想要无缝自动化。但是,本项目是为另一种用户需求而设计的:用户希望 AI 辅助,但需要安全保障。请选择适合您风险承受能力的插件:
以下是 Anthropic 插件与 Ghostie 的比较:
| | Anthropic `imessage` 插件 | Ghostie(本项目) |
|---|---|---|
| **发送模式** | 直接:Claude 立即发送 | 分阶段(默认):`send_draft` 需要 `require_approval` 开关,默认为开启;发送路径通过菜单栏的按住发送按钮。用户可以关闭开关以进行直接纯文本 MCP 发送。媒体始终需要审查和按住发送。 |
| **审批界面** | macOS 自动化 TCC 提示,仅在首次发送时 | 菜单栏审查:按住发送 / 丢弃每个草稿(暂无原位编辑 - 丢弃并重新分阶段) |
| **审计日志** | 链接修订版中不存在 | 每个 **成功** 的 MCP 发送追加到 `~/.messages-mcp/send-audit.log`,包含时间戳、收件人句柄和正文的 SHA-256 哈希值。丢弃和阻止的发送当前不记录。 |
| **UI** | 仅 CLI | 菜单栏界面,带有线程上下文气泡 |
| **联系人解析** | 仅原始句柄 | 通过本地侧车解析为联系人姓名 |
| **传输** | 仅 iMessage | iMessage + WhatsApp(v0.3.0);Signal / Slack 在路线图中 |
| **每日发送上限** | 链接修订版中不存在 | 默认 50/UTC 天,环境可配置 via `IMESSAGE_DAILY_SEND_CAP` |
| **最适合** | “直接发送” 自动化 | “让我看看 Claude 想说什么,然后再发送” - 默认审批门控开启时 |
如果您想要直接发送,请使用 Anthropic 的插件。如果您希望每个外出消息都经过您的审查,请使用本插件。
## 本项目提供的内容
- **通用消息 MCP**:适用于 iMessage 和 WhatsApp 的稳定工具界面:列出/搜索/读取线程,分阶段/列出/获取/丢弃草稿,并管理线程优先级。它故意不公开通用发送工具。
- **iMessage 传输**:读取线程,消息,搜索;分阶段草稿在 `~/.messages-mcp/drafts/` 下;通过 AppleScript 自动化 Messages.app 进行审批门控发送。
- **WhatsApp 传输**(可选):从本地缓存中读取最近的线程;分阶段草稿在 `~/.whatsapp-mcp/drafts/` 下;通过二维码扫描与您的手机配对的后台 Baileys 守护进程进行审批门控发送。守护进程捆绑在 `.app` 中,无需单独安装。请参阅 [SECURITY.md](SECURITY.md) 以了解 WhatsApp 服务条款的注意事项和每个传输的威胁模型。
- **菜单栏界面**:显示来自所有已启用传输的待处理草稿,位于一个弹出窗口中,带有按住发送 / 丢弃按钮和每个传输的平台徽章(WhatsApp 为绿色,iMessage 为系统强调色)。将“草稿”转换为真正的人工审查界面,而不是磁盘上的 JSON 文件。
- **首次运行 onboarding 向导**:询问您要启用的传输,并直接链接到 WhatsApp 二维码配对。
- **设置表**:用于每个传输的配置和配对/取消配对。
- 通过菜单栏应用程序的联系人权限进行联系人姓名解析 - 代理看到并显示真实姓名(“Avery Example”),而不是原始电话号码。
## 安全
此服务器为本地二进制文件提供三个 macOS 级别权限(完全磁盘访问权限,自动化控制 Messages.app,可选的开机启动)。信任配置文件 nontrivial。请在安装前阅读 **[SECURITY.md](SECURITY.md)** - 它涵盖了完整的威胁模型,已实施的缓解措施(提示注入包装,最小暂存年龄,每日发送上限,审计日志,SQL 参数化等),配置旋钮和推荐的用户端实践。
## 为什么存在
调用此服务器的代理在与消息数据相同的 Mac 上运行。本地 stdio MCP 服务器是正确的方式 - 无隧道,无云,无共享密钥。爆炸半径是“进程可以运行的权限”。
## 工具
推荐的默认 MCP 是 Ghostie,通用接口(`ghostie-mcp`)。它公开了诸如 `imessage:123` 和 `whatsapp:<jid>` 之类的传输中立引用:
| 工具 | 用途 |
|---|---|
| `get_message_current_time` | UTC + 系统本地时间戳,用于构建 `since` 过滤器。 |
| `ghostie_health_check` | 诊断接口以及 iMessage 和 WhatsApp 守护进程依赖项。 |
| `list_message_threads` | 跨一个或所有传输的最近线程。需要 `since` 或 `contact_filter`。 |
| `get_message_thread` | 用于通用 `thread_ref` 的消息,分页 via `before`。 |
| `search_message_history` | 跨一个或所有传输的搜索。需要 `query` 加 `since` 或 `contact_filter`。 |
| `stage_message_draft` | 分阶段发送 iMessage 或 WhatsApp 草稿供人工审批。不发送。 |
| `list_message_drafts` | 列出跨一个或所有传输的分阶段草稿。 |
| `get_message_draft` | 通过通用 `draft_ref` 读取分阶段草稿。 |
| `discard_message_draft` | 通过通用 `draft_ref` 删除分阶段草稿。 |
| `set_message_thread_priority` | 在 `thread_ref` 上设置跨传输优先级。 |
| `clear_message_thread_priority` | 清除跨传输优先级。 |
| `list_message_thread_priorities` | 列出跨传输优先级。 |
特定于传输的 MCP 可用于兼容性和故意非通用化的操作:
- `imessage-drafts-mcp` 公开原始 iMessage 工具,包括 `send_draft`,语音/样式助手和自动化提案工具。
- `whatsapp-drafts-mcp` 公开 WhatsApp 特定工具,包括 `send_whatsapp_draft`,完整消息水化,配对/守护进程健康和 WhatsApp 特定优先级工具。
通用接口故意没有 `send_*` 工具。发送仍然是特定于传输的,或者更喜欢从菜单栏的人工审批界面。
硬性防护措施:
- `since` 旧于 2 年 → 拒绝(无深度历史转储)。
- `query` 短于 2 个字符 → 拒绝。
- 所有消息正文截断在 ~8 KB 处,并带有标记。
---
# 产品分析与诊断
产品分析在首次运行 onboarding 中显示,默认开启;用户可以在继续之前关闭它,并且可以在任何时候更改设置。菜单栏应用程序通过允许列出的 Swift 包装器使用 PostHog 手动捕获。它仅捕获粗粒度产品事件,例如看到的应用程序/版本,打开的设置,查看的功能,草稿分阶段/发送,计划的消息创建,实验室扫描启动/完成/失败和诊断导出创建。
现有安装保留其存储的分析设置,不会再次看到首次运行 onboarding,除非设置重置。
分析永远不会包括消息正文,草稿文本,提示,模型响应,联系人姓名,电话号码,电子邮件,Apple ID,WhatsApp ID,原始聊天 ID,收件人标识符,消息 ID,API 密钥,访问令牌或文件路径。
会话重放,屏幕捕获,元素自动捕获和自动屏幕/生命周期捕获已禁用。
发布/开发版本可以提供 `POSTHOG_PROJECT_TOKEN` 和 `POSTHOG_HOST` 以构建应用程序包。没有项目令牌,分析是惰性的,即使启用了切换。`MESSAGES_FOR_AI_ANALYTICS_DISABLED=1` 或 `~/.messages-mcp/analytics.disabled` 禁用运行时捕获。
诊断导出是单独的本地 zip 文件,仅在用户点击导出诊断后创建。设置选择是否包括本地应用程序事件,守护进程日志和相关的崩溃报告。守护进程日志默认关闭,因为本地桥日志可以包括传输标识符;仅当支持请求额外上下文时才启用它们。
---
# 技能
可选的 Claude 技能在此仓库的 [`skills/`](skills/) 下捆绑:
- [`texting-analytics`](skills/texting-analytics/) - 个人“Texting Wrapped”报告(回复延迟,球在你方,群体贡献)渲染为四个图表。只读;通过 MCP 运行在您的 iMessage 历史记录上。需要 Python 和 `matplotlib`。
更多技能(语音克隆草稿,生日短信)正在进行中。
---
# 安装
两种安装方式。选择 A 除非您正在贡献代码。
## 选项 A - 预构建版本(推荐)
发布 zip 文件包含一个签名的,Apple 认可的 `.app`。无需 Xcode,无需 Apple 开发者账户,无需重建或单独的 WhatsApp 安装。拖放,然后执行三个手动权限步骤。
```sh
# 1. 下载最新的发布 zip 文件。
curl -L \
https://github.com/Sunrise-Labs-Dot-AI/messages-for-ai/releases/latest/download/messages-for-ai.zip \
-o /tmp/messages-for-ai.zip
# 2. 解压并运行安装程序。
cd /tmp && unzip -q messages-for-ai.zip
cd messages-for-ai-v* && bash install.sh
```
安装程序将 `Ghostie.app` 复制到 `/Applications/`,刷新 LaunchServices,通过 `initialize` 往返测试捆绑的 MCP 二进制文件,创建 `~/bin/ghostie-mcp` 和 `~/bin/imessage-drafts-mcp` 的符号链接(旧版 v0.1.x 路径),并打印手动下一步骤。
安装后,您需要:
1. **授予完全磁盘访问权限** 给 `Ghostie.app` - 请参阅下面的 [权限](#permissions)。菜单栏应用程序启动执行受保护的本地读取的守护进程,因此 Claude 不需要完全磁盘访问权限。
2. **连接 MCP 客户端** - 请参阅下面的 [MCP 客户端配置](#mcp-client-config)。
3. **启动菜单栏应用程序**:
```sh
open "/Applications/Ghostie.app"
```
首次弹出窗口打开将触发 onboarding 向导。选择要启用的传输(iMessage 默认启用;WhatsApp 可选)。如果您选中 WhatsApp,菜单栏会启动守护进程并直接链接到二维码配对表 - 使用手机上的 WhatsApp 通过设置 → 链接设备 → 链接设备进行扫描。首次弹出窗口还将触发 macOS 联系人同意对话框。
## 选项 B - 从源代码构建
贡献者专用。需要 Bun,Xcode 15+ 和 **Apple 开发者 ID 应用程序证书** 以实现完整的联系人名称解析。如果没有证书,联系人查找会优雅地回落到“原始电话号码”模式 - 其余服务器工作正常。
```sh
git clone https://github.com/Sunrise-Labs-Dot-AI/messages-for-ai.git
cd messages-for-ai
# 步骤 1:构建并安装菜单栏应用程序到 /Applications/。
# 这必须运行在第一个 - 它创建 Ghostie.app 包,
# MCP 二进制文件安装到其中。
cd menubar && bash scripts/dev-install.sh && cd ..
# 步骤 2:构建并安装所有 MCP 二进制文件(通用 MCP,
# iMessage MCP,WhatsApp MCP 和守护进程)到.app 的
# Contents/MacOS/,使用捆绑标识符签名。创建符号链接
# 到 ~/bin/ghostie-mcp 和 ~/bin/imessage-drafts-mcp。
bash scripts/dev-install.sh
```
两个安装脚本自动检测 Keychain 中的开发者 ID 应用程序证书并使用它进行签名。如果未找到证书,它们会回落到 adhoc 签名,并发出明确警告。要强制在 CI / 发布版本中硬失败,请设置 `CONTACTS_REQUIRE_DEVID=1`。
重建 MCP 二进制文件后,**重启任何已经启动旧版的 MCP 客户端**(Claude Desktop,Claude Code,Codex CLI)- 它们持有长久的 stdio 子进程,不会拾取新二进制文件,直到它们重新启动。
### 为什么 Developer ID 很重要
现代 macOS(Sequoia+)对 adhoc 签名应用程序静默阻止 `CNContactStore.requestAccess`。没有 Developer ID 证书,菜单栏应用程序无法通过框架路径读取您的联系人。(FDA 授予也会在每次重建时失效,因为 TCC 关闭二进制哈希。)请参阅 `menubar/scripts/messages-for-ai.entitlements` 了解所需的 Hardened Runtime 授权(`personal-information.addressbook` + `automation.apple-events`)。
---
# 权限
涉及三个 TCC 授权,每个都以不同的方式控制:
## 1. 完全磁盘访问权限(在 `Ghostie.app` 上)
需要读取 `~/Library/Messages/chat.db`。没有程序提示进行 FDA - 您必须手动执行:
1. 打开 **系统设置 → 隐私和安全 → 完全磁盘访问权限**。
2. 点击 **+**。
3. 按 **⌘⇧G**,粘贴 `/Applications`,按 Enter。
4. 选择 **`Ghostie`**(.app 捆绑,而不是内部 Mach-O 或 `~/bin/*-mcp` 符号链接)并点击打开。
5. 确认开关为 **on**。
⚠️ **拖动 .app 捆绑,而不是内部 Mach-O 或符号链接。** macOS 根据捆绑的 `CFBundleIdentifier` 密钥 FDA 授权(`com.sunriselabs.messages-for-ai`)。捆绑的帮助程序共享该标识符进行对等身份验证和捆绑一致性。拖动内部二进制文件或符号链接可能会创建混淆的过时条目,因此目标是 .app 是明确的 Apple 惯例和安装程序打印输出指示的内容。
**故障排除:工具返回 `authorization denied` / `permission_denied`。**
运行 `health_check` 从 Claude Desktop 聊天 - 它将报告哪个子系统失败以及补救措施。常见原因:
- **忘记在授予 FDA 后重启 Claude Desktop** - MCP 子进程是长久的子进程,在 spawn 时间重新检查其 TCC 身份。 `Cmd+Q` Claude Desktop(不是关闭窗口)并重新打开,以便它派生一个全新的子进程。
- **您在以前的尝试中拖动了内部二进制文件到 FDA 列表中** -
结果列表中的行可能是过时的。删除它(`-`
按钮),并通过拖动 `/Applications` 中的 `.app` 重新添加。
- **您从 v0.1.x 升级** - 您的旧授权针对
`~/bin/imessage-mcp`(标识符 `com.sunriselabs.imessage-mcp`)无效。v0.2.0 使用不同的标识符
(`com.sunriselabs.messages-for-ai`)。您必须授予新的 `.app` 捆绑完整的 FDA。
使用 Developer ID 签名(默认的预构建版本和源代码构建具有证书),授权在重建时存活 -
TCC 关闭 `(identifier, team-id)` 元组,这很稳定。
## 2. 联系人(在菜单栏应用程序上)
需要解析收件人句柄为名称。在第一个弹出窗口打开时提示:*“Ghostie 想要访问您的联系人。”*
点击确定。应用程序然后导出 `~/.messages-mcp/contacts-cache.json`
侧车由 MCP 在每个 `stage_draft` 调用时读取。
侧车使用与 Messages.app 使用的相同数据源,包括
iCloud 同步的联系人可能仅限于 CloudKit 且不存在于磁盘上的 AddressBook SQLite 数据库。侧车自动通过
`CNContactStoreDidChangeNotification` 刷新。
## 3. 自动化(在 MCP 客户端 / 菜单栏应用程序上,针对 Messages.app)
实际发送分阶段草稿时提示:<parent app> 想要控制 Messages.app。
点击 **OK**;授权持续。
要稍后撤销:系统设置 → 隐私和安全 → 自动化 →
您的父应用程序 → Messages → 切换关闭。
---
# MCP 客户端配置
> ⚠️ MCP 客户端 `command` 字段根据是否展开 `~` 而有所不同。Claude
> Desktop 和 Codex CLI 执行;而某些终端的 MCP 插件不执行。如果客户端
> 失败启动服务器,请替换 `~/bin/ghostie-mcp` 为
> 绝对路径(`echo $HOME/bin/ghostie-mcp`)。
### 克劳德桌面
* `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"ghostie": {
"command": "~/bin/ghostie-mcp"
}
}
}
```
重启克劳德桌面(Cmd+Q,然后在克劳德菜单上重新打开 - MCP
子进程仅在应用程序启动时生成)。
### 克劳德代码
* 在您的项目中添加以下内容到 `.mcp.json`,或
`~/.claude/mcp.json` 以全局方式:
```json
{
"mcpServers": {
"ghostie": { "command": "~/bin/ghostie-mcp" }
}
}
```
### Codex CLI
* `~/.codex/config.toml`:
```toml
[mcp_servers.ghostie]
command = "~/bin/ghostie-mcp"
```
(请参阅当前 Codex 文档 - 配置形状可能已更改。)
# 快速烟雾测试(无需客户端)
```sh
cat <<'EOF' | ~/bin/ghostie-mcp 2>/tmp/ghostie-mcp.stderr | tail -1
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"ghostie_health_check","arguments":{}}}
EOF
```
健康检查报告了 facade 和守护进程依赖项状态。如果您
更喜欢直接使用旧版 iMessage MCP,请使用
`~/bin/imessage-drafts-mcp` 并调用 `health_check`。
---
# 快速烟雾测试(无需客户端)
# 发送草稿 — 信任模型
概括的MCP可以暂存和丢弃草稿,但它不暴露发送工具。特定于传输的发送工具,例如iMessage的`send_draft({ draft_id })`,使用通过MCP暂存的草稿,并通过本地应用程序/守护进程路径发送。设计有四个信任层:
1. **MCP破坏性注释。** 工具广告`destructiveHint: true`和`idempotentHint: false`,因此MCP客户端应在每次调用前显示确认提示。
2. **仅从草稿发送。** 没有临时发送。每次发送都需要一个`draft_id`,因此在破坏性工具触发之前,草稿文本可以在对话记录中观察到 — 即使代理调用`stage_draft`和`send_draft`在同一回合。
3. **已发送状态锁定。** 一旦草稿设置了`sent_at`,重新调用特定于传输的发送工具将返回一个明确的“拒绝重复发送”错误。代理循环重试时无法重复发送。
4. **macOS TCC自动化。** Messages.app的AppleScript控制由一个单独的TCC服务(“Automation”)与FDA分开。请参阅上面的[权限](#permissions)。
如果您曾经通过网络传输(HTTP / WebSocket /隧道)公开此服务器,**请从公共表面移除发送工具**。信任边界在非本地调用者能够调用它的那一刻崩溃 — 而读取工具本身是有用的。
---
# 菜单栏应用程序
MCP服务器将草稿作为JSON文件暂存。 `/Applications/Ghostie.app`的配套应用程序是一个SwiftUI `MenuBarExtra`,它显示待处理的草稿,并带有按住后发送/丢弃按钮 — 这样您实际上可以在代理发送之前审查它想要发送的内容,而不是仅凭工具调用的草稿UUID。
### 工作原理
- 通过`DispatchSourceFileSystemObject`监视`~/.messages-mcp/drafts`,因此MCP服务器暂存的草稿在约100毫秒内出现在弹出窗口中。
- 通过与MCP服务器相同的AppleScript路径发送(`osascript` + `tell application "Messages"`)。重复是有意的 — 它避免了为stdio MCP服务器创建IPC。
- 发送时,原子性地更新同一个草稿JSON,添加`sent_at` + `send_service`。最近发送的草稿(在过去24小时内)出现在一个淡入的“最近发送”部分,作为确认导航。
- **联系人导出**:启动时,应用程序调用`CNContactStore.enumerateContacts`并写入`~/.messages-mcp/contacts-cache.json`,带有规范化的处理程序 → 显示名称对。MCP在每个`stage_draft`调用时读取此辅助文件以填充`to_handle_name`。辅助文件在`CNContactStoreDidChange`时刷新。
- **默认开机自启动。** 应用程序在第一次运行时的`SMAppService`中自我注册。可以通过弹出窗口底部或系统设置 → 通用 → 登录项目来关闭。
---
# 测试
```sh
bun test
```
104个测试,~100ms — 纯函数 + 内存SQL + 辅助文件读取。覆盖率亮点:
- `decode.test.ts` — 属性正文类型流解码器(短/长长度,UTF-8,损坏输入)。
- `open.test.ts` — Apple-epoch ↔ ISO-8601往返适用于纳秒(High Sierra+)和秒(旧版)表单。
- `schema.test.ts` — Zod输入验证:2年深历史记录拒绝,2字符最小值,处理程序格式,正文长度上限。
- `storage/drafts.test.ts` — 暂存,列表排序,标记发送持久性,符号链接覆盖防御,原子重命名 + 目录修改时间,旧草稿向后兼容规范化。
- `storage/contacts-cache.test.ts` — 辅助文件JSON读取路径,损坏输入容错,模式版本不匹配检测。
- `chatdb/queries.test.ts` — 针对内存`chat.db`装置的端到端SQL,涵盖分页(严格`before`),联系人名称扩展和`attributedBody`在搜索中解码。使用测试缝 `_setChatDbForTesting` + `_setContactsForTesting`注入装置。
- `tools/health.test.ts` — `canonHandlePublic`规范化 + 探测块解析逻辑。
---
# 本项目不具备的功能
- **iOS。** Apple不允许第三方访问iOS上的Messages。除了越狱之外,没有其他解决方法。
- **网络。** 仅限stdio。如果您希望云代理调用此功能,请在隧道 + 承载者密钥后面包装相同的查询 + 草稿代码 — 数据层保持不变。
## 媒体和反应
混合媒体现在与Messages具有读取 + 发送对齐性:代理读取工具(`get_thread`,`search_messages`,Ghostie外观)显示每条消息的附件元数据 — 文件名,本地路径,MIME,粗略`kind`(图像/视频/音频/文档),字节大小,粘贴人标志(iMessage)和标题(WhatsApp) — 以便代理可以查看线程中包含哪些媒体,而不仅仅是包含某些媒体。输出时,`stage_draft` / `stage_whatsapp_draft` / `stage_message_draft`接受一个本地文件路径数组(≤10个文件,每个文件≤100 MB,总计≤250 MB)。在暂存时,Ghostie复制每个常规的非符号链接源到私有草稿所有存储,并记录其SHA-256摘要。原始文件可以移动或删除而不会更改草稿。托管快照在人类批准确切的收件人,文本,引用目标,计划和有序媒体清单后发送(因此文本作为标题读取)。批准卡预览托管媒体;更改或旧版未哈希附件失败并必须重新暂存。 iMessage媒体可以通过MCP暂存,但始终从Ghostie的应用程序界面发送。批准后,应用程序将确切的验证字节复制到一个短暂的托管文件下,该文件在TCC保护的`~/Library/Messages/GhostieSendSpool`下,并保持一个不跟随的描述符打开,使其成为用户不可变的,并为Messages.app提供稳定的macOS文件ID路径。直接MCP媒体发送被阻止,即使直接文本发送已启用。 WhatsApp媒体通过Baileys使用读取和哈希的精确字节通过一个不跟随的文件描述符(图像/视频/音频/文档按MIME)。多部分进度在每个线路操作前后记录,以便在发生模糊故障时进行审查,而不是盲目重放已传递的部分。字节永远不会内联到模型上下文中;只有元数据和提议的源路径会跨越MCP边界。菜单栏记录还显示iMessage Tapbacks/自定义反应表情符号和WhatsApp反应。 WhatsApp反应只能从可见的Messages选项卡发送;MCP/代理工具不公开反应发送方法。实验性的iMessage Tapback发送位于`imessage-ax-tapbacks`功能标志后面:它始终导航到Messages.app到目标对话,验证显示的对话与目标联系人(窗口标题与联系人名称/处理程序)匹配,然后仅在可见,无歧义的气泡内调用Messages.app自己的无障碍操作 — 如果无法积极验证对话,则拒绝而不是猜测。 在记录中,右键单击目标消息气泡以选择反应。
---
# 项目布局
```
src/
index.ts # stdio MCP启动
schema.ts # Zod形状 + 共享验证器
tools/
threads.ts # list_threads, get_thread
search.ts # search_messages
drafts.ts # stage/list/get/discard/send 草稿
time.ts # get_current_time
health.ts # health_check
_result.ts # 共享文本结果信封
chatdb/
open.ts # bun:sqlite 只读句柄,Apple-epoch 助手
decode.ts # attributedBody → 字符串 + 截断
contacts.ts # 处理程序 → 联系人名称(辅助主要,SQLite 备用)
queries.ts # 所有SQL — 参数化
imessage/
send.ts # osascript 消息.app 发送包装器
storage/
drafts.ts # ~/.messages-mcp/drafts CRUD
contacts-cache.ts # ~/.messages-mcp/contacts-cache.json 读取器
menubar/
Package.swift
Sources/MessagesForAIMenu/
App.swift # @main, MenuBarExtra 场景,AppDelegate
DraftStore.swift # ObservableObject + 文件系统监视器
DraftSender.swift # osascript 发送包装器
LoginItemController.swift # SMAppService 开机自启动切换
ContactsExporter.swift # CNContactStore → 辅助文件 JSON
Models/Draft.swift # Codable; 镜像 src/storage/drafts.ts
Views/
DraftListView.swift # 待处理 + 最近发送部分
DraftRowView.swift # 每草稿 发送 / 丢弃
ContactsPermissionBanner.swift # 显示当 NSContacts 未授予时
scripts/
dev-install.sh # 构建 menubar .app → codesign(Developer ID 或 ad hoc)
messages-for-ai.entitlements # 硬化运行时授权
scripts/
dev-install.sh # 重建 MCP 后端 + 启动器 → 安装到 .app → 重新密封
install-release.sh # 最终用户安装程序捆绑到发布 zip 中
build-release.sh # 维护者:构建 + notarize + 打包发布 zip
diagnose-contacts.ts # 独立诊断“联系人未解析”
README.md # 受众矩阵 + .app-wrap 架构解释器
```
---
# 构建发布版本(维护者)
预构建的发布版本由`scripts/build-release.sh`生成,该脚本构建 + 签名 + notarize 应用程序,后端和启动器,并使用Apple的notary服务将它们打包到一个自包含的zip文件中。
### 一次性设置
1. 安装**Developer ID Application**证书(Xcode → 设置 → 账户 → 管理证书 → + → Developer ID Application)。
2. 在https://appleid.apple.com → 登录和安全 → 应用程序特定密码处生成应用程序特定密码。将其标记为`imessage-drafts-mcp-notarytool`。
3. 将其存储在Keychain中:
```sh
xcrun notarytool store-credentials imessage-drafts-mcp-notary \
--apple-id <您的开发者账户电子邮件> \
--team-id <您的团队ID> \
--password <应用程序特定密码>
```
### 构建发布版本
```sh
# 1. 将您要发布的提交标记并推送。
git tag v0.1.0
git push origin v0.1.0
# 2. 构建发布zip。需要 ~5-10 分钟(notarytool 往返)。
bash scripts/build-release.sh v0.2.0
# → 生成 dist/messages-for-ai-v0.2.0.zip
# 3. 通过 gh CLI 发布。
gh release create v0.2.0 dist/messages-for-ai-v0.2.0.zip \
--title 'Ghostie v0.2.0' \
--notes '参见 CHANGELOG / 提交历史记录.'
```
构建脚本如果找不到Developer ID证书或未设置notarytool凭证,则会大声失败 — 无需浪费时间重新构建。生成zip后,它会自动解压到临时目录并运行`spctl --assess`检查解压的`.app`以确保Gatekeeper将在最终用户机器上接受它。如果检查失败,脚本退出1而不是发布损坏的版本。
可以通过`NOTARY_PROFILE=...`覆盖notarytool配置文件名称(例如用于CI)。可以通过`CODESIGN_IDENTITY=...`覆盖签名标识。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器