内容
# Comar
**协同档案** — 来自爱尔兰语 *comar*,意为汇聚或交汇处。
一个围绕 [Obsidian](https://obsidian.md) 保险库构建的家庭知识系统。Comar 将您的个人数据 — 日历、电子邮件、提醒、财务、健康、音乐、WhatsApp、天气、咖啡 — 桥接到一个单一的 MCP 端点,通过 Claude Desktop、Claude Code 或任何兼容 MCP 的客户端都可以访问。
## 工作原理
```
Claude Code ── MCP / Streamable HTTP (每个用户 bearer, COMAR_TOKEN) ── comar-server (家庭服务器, Docker)
├── ~13 integrations, ~80 tools
├── Postgres 16 + pgvector (语义搜索)
├── WhatsApp 桥接 (Baileys sidecar)
├── APScheduler (后台同步)
└── Web 仪表盘 (React 19)
comar-client (macOS 守护进程, side-car — 不在 Claude Code MCP 路径上)
├── Vault 监视器: fsevents → POST /api/v1/vault/push
├── Apple 提醒: EventKit (PyObjC), 通过服务器 SSE 回调分派
└── 传统本地 MCP 代理在 localhost:9400 — 仅由 Claude Desktop 使用
通过 mcp-remote (参见下面的“连接 Claude”)
```
Claude Code 直接通过 Streamable HTTP 与服务器的 `/mcp/` 端点通信,使用每个用户的 bearer token (`COMAR_TOKEN`) 进行身份验证 — 这是主要且受支持的路径,不会经过守护进程。守护进程在每个 Mac 上运行两个任务,而服务器无法自行完成这些任务:通过 EventKit 写入 Apple 提醒和监视 vault 文件夹中的更改,以推送到服务器进行重新索引。它还启动了一个传统的本地 MCP 代理,Claude Desktop 通过 `mcp-remote` 连接到该代理(Claude Desktop 尚不支持直接连接到远程 HTTP MCP 服务器)— 该代理与 Claude Code 路径无关,并且处于其自己的弃用轨道上。客户端和服务器之间的传输使用 HTTPS + JSON,服务器到客户端的信号使用 SSE。**没有 gRPC,没有 protobuf。**
音频转录已从 comar-client 移至单独的存储库 (`cograda/scribe`),该存储库将 markdown 放入监视文件夹中。
## 您获得的功能
| 集成 | 功能 | 工具 |
|-------------|-------------|-------|
| **谷歌日历** | 多账户事件(读写) | 4 |
| **Gmail** | 搜索、未读、语义搜索(pgvector) | 8 |
| **Apple 提醒** | 通过 EventKit 读取/写入(本地、即时) | 4 服务器 + 3 本地 |
| **财务** | CSV 导入(AIB、Revolut)、分类、分析 | 12 |
| **Obsidian 保险库** | 读取、写入、编辑、grep、列表、语义搜索、最近、统计 | 8 |
| **WhatsApp** | 消息搜索、联系人、语义搜索 | 7 |
| **天气** | 当前 + 7 天预报(Open-Meteo) | 2 |
| **Last.fm** | 听歌历史、统计、搜索 | 5 |
| **爱尔兰铁路** | 您车站的实时出发信息 | 2 |
| **Apple 健康** | 手动导入(Health Auto Export JSON) | 7 |
| **咖啡** | 冲泡日志 + 豆子拨号顾问 | 13 |
| **附件** | 电子邮件/WhatsApp 附件摄入 | 4 |
| **历史语料库** | 装修文件存档 | 2 |
| **系统** | 跨集成诊断 | 4 |
以及 15 个 MCP 提示,用于编排工作流程(`daily_note`、`lock_in`、`process_meeting`、`weekly_review`、`finalize_week`、`quick_capture`、`add_task`、`create_note`、`search`、`week_ahead`、`listening_report`、`import_finance`、`seed_backlog`、`triage`、`plan_week`)。
## 先决条件
- **macOS** 用于客户端(使用 EventKit + launchd)
- **Python 3.12+**
- **Linux 盒子/虚拟机** 运行 Docker(Proxmox VM、Pi 等)用于服务器
- **Obsidian 保险库** (或任何 markdown 文件夹)
- **谷歌云项目** 启用日历和 Gmail API(用于这些集成)
## 快速入门
### 1. 部署服务器
```bash
cd server
cp .env.example .env
# 编辑 .env — 至少设置 HOME_DB_PASSWORD 和 HOME_UI_TOKEN。
# HOME_MCP_TOKEN 是可选的(仅限旧版/开发使用);client_tokens 表中的每个用户 bearer 是规范的 MCP 身份验证路径。
docker compose up -d
```
这会在端口 8400(HTTP,仅限局域网)上启动 FastAPI 应用程序,以及 Postgres 16 + pgvector。参见 [server/README.md](server/README.md) 了解完整的服务器设置,包括谷歌 OAuth、WhatsApp 桥接和保险库挂载。
### 2. 安装客户端
```bash
# 在每个 Mac 上
pipx install comar-client
# 或用于开发:
cd client && pip install -e .
comar setup
```
设置向导会询问您的姓名、保险库路径、服务器 URL(例如 `http://192.168.1.50:8400` 或 `https://comar.lab`)和每个设备的 bearer token(来自服务器上的 `client_tokens` 表)。
对于自动化/脚本安装:
```bash
comar setup --user alex --server http://192.168.1.50:8400 --token <your-token>
```
### 3. 运行机器设置脚本
```bash
bash scripts/setup-machine.sh
```
这会通过 pipx 安装守护进程,如果 `~/.config/comar/config.toml` 不存在,则运行 `comar setup`,并写入 `~/.config/comar/env.sh` — 然后将 `~/.zshenv` 修正为加载它,以便 `.mcp.json` 可以获取 `COMAR_TOKEN`(每个用户的 bearer token)。
**为什么是 `~/.zshenv` 而不是 `~/.zshrc`**:Claude Code 在启动时从其自己的进程环境中展开 `.mcp.json` 中的 `${COMAR_TOKEN}`。当从 Spotlight、Dock 或 IDE 启动时,zsh 运行 `~/.zshenv` 但不运行 `~/.zshrc` — 因此仅在 `.zshrc` 中导出的令牌对 GUI 启动的应用程序不可见。在运行脚本后退出并重新启动 Claude Code,以便它获取令牌。
### 4. 启动守护进程
```bash
comar install # 作为 launchd 代理安装(在登录时自动启动)
# 或
comar daemon # 前台运行,用于调试
```
守护进程不在 Claude Code 的 MCP 路径上(参见上面的“工作原理”)— 需要它来进行 Apple 提醒(EventKit)的写入和保险库监视器的重新索引。
### 5. 连接 Claude
**Claude Code**(主要、受支持的路径):将您的每个机器的 `.mcp.json`(gitignored,不在存储库中)指向服务器的 `/mcp/` 端点,使用 `${COMAR_TOKEN}`:
```json
{
"mcpServers": {
"comar": {
"type": "http",
"url": "https://comar.lab/mcp/",
"headers": {
"Authorization": "Bearer ${COMAR_TOKEN}"
}
}
}
}
```
**Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`) 尚不支持直接连接到远程 HTTP MCP 服务器,因此它通过守护进程的传统本地 MCP 代理进行:
```json
{
"mcpServers": {
"comar": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://127.0.0.1:9400/mcp"]
}
}
}
```
此 Claude Desktop 路径与上面的 Claude Code 路径是分开的,并且处于其自己的弃用轨道上 — 参见 `client/README.md`。
### 6. 验证
```bash
# Claude Code 路径 — 服务器心跳
curl -H "Authorization: Bearer $COMAR_TOKEN" http://192.168.1.50:8400/api/v1/heartbeat
# Claude Desktop 路径 — 守护进程健康
curl http://localhost:9400/health
```
## 项目结构
```
comar/
├── README.md ← 你在这里
├── CLAUDE.md ← 操作手册(保险库约定、任务系统、斜杠命令)
├── Makefile ← 顶级:make build-client, make test, make deploy
├── .mcp.json ← Claude Code MCP 配置(指向 localhost:9400/mcp)
├── .claude/commands/ ← Claude Code 斜杠命令
│
├── client/ ← comar-client Python 包
│ ├── README.md
│ ├── pyproject.toml
│ └── src/comar/
│ ├── cli.py ← CLI 入口点(setup, daemon, install, status, import-health)
│ ├── daemon.py ← 主守护进程循环(MCP 服务器 + HTTP 客户端 + 监视器)
│ ├── mcp_server.py ← MCP 服务器(Starlette + SSE/HTTP 传输,/health 端点)
│ ├── mcp_https_shim.py ← 工具代理 → 服务器通过 HTTP
│ ├── server_client.py ← HTTP 客户端 → comar-server(替换 grpc_client)
│ ├── eventkit.py ← 通过 PyObjC EventKit 的 Apple 提醒
│ ├── vault_watcher.py ← Watchdog fsevents → POST /api/v1/vault/push
│ ├── remote_logging.py ← 通过 /api/v1/logs/push 发送日志
│ ├── updater.py ← 自动更新(检查服务器的新轮子,安装,重启)
│ ├── launchd.py ← launchd 代理安装/卸载
│ └── default_prompts/ ← 捆绑的 MCP 提示 YAML 文件(15)
│
├── server/ ← comar-server(Docker 部署)
│ ├── README.md
│ ├── CLAUDE.md ← 服务器内部深入解析
│ ├── Dockerfile
│ ├── docker-compose.yml
│ ├── Makefile ← make deploy, make deploy-fast, make deploy-pull
│ ├── .env.example
│ ├── backend/app/
│ │ ├── api/v1.py ← V3 客户端 API:工具、推送、事件、心跳、指令
│ │ ├── mcp/ ← MCP 服务器、指令、注释
│ │ ├── tools/ ← 声明式工具 DSL(ListTool/SearchTool/SemanticSearchTool/StatsTool/CustomTool)
│ │ ├── integrations/ ← 一个包/集成
│ │ ├── models/ ← SQLAlchemy 模型
│ │ └── services/ ← 嵌入、更新检查
│ ├── frontend/ ← React 19 仪表盘(Vite,Tailwind v4)
│ └── whatsapp-bridge/ ← Node.js Baileys sidecar
│
├── .github/workflows/
│ └── deploy.yml ← CI:构建前端 + 客户端轮子 + Docker 镜像 → GHCR
│
└── vault/ ← Obsidian 保险库(GITIGNORED — 通过 Google Drive 同步)
```
## 配置
### 客户端 (`~/.config/comar/config.toml`)
由 `comar setup` 创建。示例:
```toml
user = "alex"
mcp_port = 9400
auto_update = true
[server]
url = "http://192.168.1.50:8400" # 或 https://comar.lab
token = "your-client-token"
[vault]
path = "/Users/you/path/to/vault"
```
### 服务器(`.env`)
参见 `server/.env.example`。关键变量:
| 变量 | 必需 | 目的 |
|----------|----------|---------|
| `HOME_DB_PASSWORD` | 是 | Postgres 密码 |
| `HOME_UI_TOKEN` | 是 | Web 仪表盘访问令牌 |
| `HOME_MCP_TOKEN` | 旧版 | 预多用户 MCP bearer(开发/管理员备用)。每用户 `client_tokens` 是实时身份验证路径。 |
| `HOME_GOOGLE_CLIENT_ID` | 用于 OAuth | 谷歌日历 + Gmail |
| `HOME_GOOGLE_CLIENT_SECRET` | 用于 OAuth | 谷歌日历 + Gmail |
| `HOME_LASTFM_API_KEY` | 用于 Last.fm | Last.fm 播放历史 |
| `HOME_VAULTS_HOST_PATH` | 用于保险库 | 主机路径挂载到容器中。应包含每个用户的子文件夹,例如 `<host-path>/alex/` |
| `HOME_WEATHER_LATITUDE` / `HOME_WEATHER_LONGITUDE` | 否 | 天气预报位置(默认为 Dublin) |
| `HOME_RAIL_STATION_CODE` / `HOME_RAIL_STATION_NAME` | 否 | 爱尔兰铁路家站(默认为 Malahide) |
| `HOME_TRANSFER_MATCH_NAMES` | 否 | 用于内部转账检测的逗号分隔账户持有者姓名 |
## CLI 参考
```
comar setup 交互式首次设置
comar setup --user X --server <url> --token <token>
非交互式设置(用于脚本)
comar daemon 在前台运行守护进程
comar status 显示守护进程和连接状态
comar install 安装 launchd 代理(登录时自动启动)
comar uninstall 删除 launchd 代理
comar import-health <file>
导入 Apple Health Auto Export JSON
```
## Obsidian 保险库
Comar 围绕共享的 Obsidian 保险库构建。保险库结构、任务系统、日常笔记格式和所有约定都在 [CLAUDE.md](CLAUDE.md) 中记录。关键点:
- **两个用户** 具有私有空间(`vault/Alex/`、`vault/Sam/`)和共享区域
- **任务积压** — 三个 markdown 文件(共享 + 一个每人)采用 Obsidian Tasks 插件格式
- **日常笔记** — 每人每天一个,由 `daily_note` MCP 提示创建
- **会议笔记** — 通过 `process_meeting` 提示从转录中构造
- **每周回顾** — 通过 `weekly_review` + `finalize_week` 从日常笔记中合成
- **语义搜索** — 保险库文件嵌入 fastembed(BAAI/bge-small-en-v1.5)并通过 pgvector 搜索
保险库被 gitignore 并单独同步(Google Drive、iCloud、Syncthing)。
## 开发
### 运行测试
```bash
make test # 所有测试(客户端 + 服务器)
make test-client
make test-server
```
### 部署
```bash
make deploy # 默认:从 GHCR 拉取预构建的镜像 + 重启(在 CI 推送后)
make deploy-pull # 别名:make deploy
make deploy-build # 开发 rsync 路径:构建客户端轮子 + 前端 + rsync + docker 构建
make deploy-fast # 开发 rsync 路径,仅后端:rsync + docker 构建(跳过前端)
```
### CI/CD
将 `main` 推送到触发 GitHub Actions(`.github/workflows/deploy.yml`)— 构建 React 前端、客户端轮子(用于自动更新)和 `comar-oss-app` + `comar-oss-whatsapp` 的 Docker 镜像,然后推送到 GHCR。在服务器上运行 `make deploy-pull` 以拉取并重启。
### 自动更新
客户端在每次心跳时检查服务器是否有新版本。如果有新轮子可用,它会下载、安装并自动重启守护进程。服务器从 `server/client-dist/` 提供轮子(不跟踪在 git 中 — 由 CI 或 `make build-client` 填充)。
### 两级提示更新
MCP 提示 YAML 可以在不重建客户端的情况下在服务器上更新。心跳携带一个 `prompt_set_hash` — 当它更改时,客户端获取更新的提示并通知 Claude Desktop 刷新其提示列表。
## 架构决策
**为什么选择 HTTP+SSE?** 服务器运行在没有公共 IP 的家庭网络上,但客户端始终发起连接(不需要入站防火墙规则),而 bearer token 在 LAN 上足够。HTTP 保持表面统一 — 每个工具、推送和事件都使用相同的传输 — 而 SSE 为我们提供了一个干净的服务器→客户端通道,无需 WebSockets。我们以前使用 gRPC;protobuf 开销和双传输复杂性不值得。
**为什么选择 MCP?** Claude Desktop 和 Claude Code 都原生支持 MCP。一种协议,一个端点,~80 个工具 + 15 个提示。客户端抽象哪些工具是本地的(保险库、提醒)以及哪些是远程的。
**为什么选择 Obsidian?** Markdown 文件是个人知识最耐用的格式。Obsidian 添加了链接、搜索和插件生态系统。保险库只是一个文件夹 — 没有锁定。
**为什么选择 EventKit 而不是 osascript?** PyObjC 的 EventKit 绑定为 Apple 提醒提供即时读写访问 — 没有子进程开销,没有 AppleScript 解析。
## 适应您的家庭
Comar 是为特定家庭设计的,但其架构是通用的:
1. **用户**:在 `setup_flow.py` 和保险库文件夹结构中更改名称选择
2. **集成**:每个集成都包含在 `server/backend/app/integrations/<name>/` 中。禁用时,请从 `register_all()` 中删除,或按照 `BaseIntegration` 的方式添加新的集成
3. **提示**:在 `client/src/comar/default_prompts/` 中编辑 YAML
4. **位置特定**:天气坐标(`HOME_WEATHER_LATITUDE`/`HOME_WEATHER_LONGITUDE`)和铁路站(`HOME_RAIL_STATION_CODE`/`HOME_RAIL_STATION_NAME`)通过 `.env` 设置,具有合理的默认值
5. **日历过滤**:`config.py` 中的 `calendar_visibility` 每个谷歌账户 — `"full"`、`"busy"` 或 `"hidden"`
## 法律
这是一个自托管的个人项目,作为 MIT 许可(见下文)共享,不提供任何保证。它未经过多租户或生产环境审计 — 认证模型假设一个受信任的家庭网络,而不是一个公开的服务。
一些需要注意的事情:
- **第三方商标**:Comar 集成来自 Google 日历、Gmail、Apple 提醒/健康、Home Assistant、Last.fm、爱尔兰铁路、WhatsApp 和 Anthropic 的 Claude。这些名称仅用于描述集成连接的内容 — Comar 不隶属于、获得任何这些公司的认可或赞助。
- **WhatsApp 桥接**:`whatsapp-bridge` 服务使用 [Baileys](https://github.com/WhiskeySockets/Baileys),一个 WhatsApp Web 协议的非官方、反向工程客户端。WhatsApp 的服务条款禁止非官方/自动化客户端,使用此桥接存在账户限制或封禁的风险。这是您运行它所承担的风险,而不是 Comar 可以缓解的风险。
- **财务和个人数据**:财务集成分析您自己的银行 CSV 导出(AIB、Revolut 格式)并在您自己的数据库中存储交易。除了您明确配置的 API 外,任何内容都不会被发送。您负责确保您的部署(令牌、网络暴露、备份)的安全 — 请参阅 `server/CLAUDE.md` 中的安全说明,并保持 `HOME_UI_TOKEN`/`HOME_OAUTH_ENCRYPTION_KEY` 设置。
- **依赖项**:依赖树中的所有内容都具有 MIT/BSD/Apache-2.0/ISC 许可,并与在 MIT 许可下分发此项目兼容,其中一个 LGPL-3.0 依赖项(`psycopg2-binary`)以其 API 的标准“通过 API 消费”的方式使用,不会产生任何重新许可义务。
## 贡献
问题和 PR 是欢迎的 — 参见 [CONTRIBUTING.md](CONTRIBUTING.md) 了解预期内容和如何提交。
## 许可
MIT — 参见 [LICENSE](LICENSE)。`server/coglib/` 从单独的私有存储库中获取,但它是同一作者的原始代码,并受此存储库的许可约束。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器