Skip to content

系统总览

核心模型

Coffer 是一个本地优先的 AI agent 仓库:一个长生命周期的本地守护进程,将开发者积累的 AI 资产保存在本机,并让任意 AI agent(Claude Code、Codex、未来的工具)通过一个安全接口读取与贡献。仓库横跨六种资源 kind——mcp_serveragentskillknowledge_basememorychannel——构建于一个与 kind 无关的 Resource 框架之上,外加若干横切特性(进程内与 CLI agent 聊天、消息渠道、多机同步)。MCP 网关只是其中一种 kind:注册一次上游服务器,所有 MCP 客户端就连接同一个守护进程,看到相同的命名空间化工具集,工具名形如 filesystem__read_file。所有状态本地存储于 SQLite(密钥以 Fernet 密文形式存储),唯一的主密钥存于 DB 旁的 0600 文件(操作系统钥匙串为 opt-in)。守护进程仅绑定到 127.0.0.1——外部机器无法访问。

系统拓扑

下图展示了各组件之间的关系。守护进程持有六种资源 kind 的全部仓库状态;对 MCP 网关 kind 而言,客户端不直接连接上游服务器——它们连接到 Coffer 守护进程,由守护进程代为管理上游连接。当某个 SeaTalk 渠道启用时,一个独立的回调监听进程负责处理经过签名校验的渠道 webhook。

组件与接口说明

组件类型职责
coffer-daemon长生命周期进程FastAPI 服务,监听 127.0.0.1:<auto-port>。持有六种资源 kind 以及横切特性(聊天、渠道、同步)的全部状态,是唯一的 SQLite 写入者。
资源 kind守护进程承载的抽象构建于一个与 kind 无关的 Resource 框架之上的六种 kind:mcp_server(网关上游)、agent(已注册的编码 agent)、skill(投递进 agent 的主技能包)、knowledge_basememory(文件即真理 + SQLite 检索底座的两面)、channel(Telegram/SeaTalk 绑定)。
聊天 / 渠道 / 同步守护进程的横切特性进程内 LangGraph 聊天 agent 以及 Claude Code/Codex CLI agent(spec 008);从 IM 应用中转聊天的消息渠道(ADR-014);基于用户自有 git 仓库、opt-in 的多机同步(ADR-016)。它们不是 kind——而是横跨各 kind。
coffer 回调监听守护进程拉起的子进程仅服务经过签名校验的渠道 webhook(POST /seatalk/{channel}),监听一个位于用户自运行隧道之后的 loopback 端口;校验 SeaTalk 签名并将事件转发给守护进程。当某个 SeaTalk 渠道启用时运行(ADR-014)。
coffer-mcp-shim短生命周期进程(每个 MCP 客户端会话一份)桥接 MCP 客户端 stdio ↔ 守护进程 HTTP/SSE。检测已运行的守护进程,或在需要时拉起一个。
coffer CLI短生命周期子进程面向用户的管理命令。通过 loopback HTTP 调用守护进程。
Web UI浏览器进程管理界面。开发时由 http://localhost:5173 的 Vite 开发服务器提供;生产时由 Tauri 桌面 shell 内嵌。调用 REST API。
Desktop 应用原生进程(Tauri 2,Rust + WebView)将 Web UI 内嵌在原生桌面窗口中。通过 REST 与守护进程通信。
REST API(/api/v1守护进程上的 HTTP 接口面管理面:资源 CRUD、审计日志、设置。Token + CORS 鉴权。
MCP 端点(/mcp守护进程上的 HTTP/SSE 接口面MCP JSON-RPC 端点。shim 连接此处。将命名空间化的工具调用转发给上游子进程。
SQLite(~/.coffer/coffer.db持久化存储控制面状态:资源注册、能力偏好、审计日志、保留策略,以及 credentials 表中以 Fernet 密文形式存储的密钥。WAL 模式,单写入者。
master.key / 操作系统钥匙串主密钥存储唯一的 Fernet 主密钥。默认:DB 旁的 0600 ~/.coffer/master.key 文件;操作系统钥匙串为 opt-in。密钥用它解密,并在上游进程拉起时物化进上游 env / header。
~/.coffer/daemon.json发现文件(权限 0600)PID + 端口 + token。守护进程启动时写入;shim 和 CLI 读取此文件以定位运行中的守护进程。

鉴权模型

所有与守护进程通信的接口面都携带 X-Coffer-Token 头。Token 在守护进程启动时生成,写入 ~/.coffer/daemon.json(权限 0600)。因为该文件仅 owner 可读,且守护进程绑定到 loopback,有效的信任边界就是本地用户账号。

全部状态都在 ~/.coffer/

每一份持久化产物都在同一个目录下:

~/.coffer/
├── daemon.json          # 发现信息:PID + 端口 + token(0600)
├── coffer.db            # SQLite:控制面状态 + 可重建的检索索引
├── master.key           # Fernet 主密钥(0600;opt-in 钥匙串会将其移出)
├── knowledge/           # knowledge_base 文件即真理(每个 KB 含 docs/ + raw/)
├── memory/              # memory 文件即真理(global/ + projects/<ulid>/)
├── skills/              # 主技能存储(canonical)
├── sync/                # 多机同步的 git 工作树(opt-in)
├── backups/             # 仓库备份的默认目标目录
├── bin/                 # 同处一地的 coffer 二进制(daemon/shim/CLI)
├── logs/
│   └── daemon.log       # 守护进程的结构化 JSON 日志
└── upstream-pids/       # 上游子进程的 PID 文件(守护进程重启时清理)

这种单目录布局意味着,一条 cp -r ~/.coffer/ backup/ 命令即可完成 Coffer 状态的完整备份。

阅读路线图

后续页面各自深入探讨系统的一个切面:

页面主题
守护进程与进程模型进程模型、detect-or-spawn、上游子进程生命周期
Resource 框架统一身份、生命周期与审计的与 kind 无关的抽象
分层与边界import 规则、各层职责、强制执行
SurfacesREST API、MCP 端点、CLI、Web UI、Desktop
请求全链路工具调用从客户端到上游的端到端追踪
持久化SQLite schema、WAL、Alembic、JSON 字段处理
安全Token 鉴权、加密凭据存储、SSRF 防护、loopback 强制
可观测性结构化日志、trace ID、审计日志、保留策略
分发包结构、安装方式、平台支持

参见: 架构参考