关于 Apple Notes
Apple Notes 的 MCP 服务,可对个人笔记进行混合检索、连接发现和引用式综合。它直接读取本机 SQLite 与 protobuf;搜索、嵌入和连接分析在设备端运行。
主要功能
- 01语义与 BM25 混合搜索
- 02跨笔记桥接发现
- 03实体与相关笔记检索
- 04引用来源的内容综合
- 05本机索引与增量更新
适用场景
- 01按含义查找旧笔记
- 02发现主题间的间接联系
- 03汇总多篇笔记中的观点
MCP 相关
该服务向 MCP 客户端提供笔记索引、搜索、读取、编辑及连接分析工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
MCP Apple Notes

mcp-apple-notes 是一款 MCP 服务,可对你自己的 Apple Notes 进行语义搜索和关联发现,提供混合搜索、Swanson-ABC 桥接、实体脉络,以及基于你所有笔记并附带引用的综合分析。
它会遍历你积累的大量笔记:语义 + BM25 混合搜索、意想不到的桥接关联、实体脉络、相关笔记,以及基于你在 Apple Notes 中写过的所有内容生成有据可依的综合分析。嵌入、搜索、BM25、聚类和桥接均在设备本地运行;只有综合分析生成会调用大模型(可通过 LM Studio/Ollama 使用本地模型,或通过 OpenAI 使用云端模型,由你选择)。基于 Model Context Protocol (MCP) 构建。
Fork 自 RafalWilinski/mcp-apple-notes——此 fork 直接读取 SQLite 存储和 protobuf,并添加了桥接、实体、信息流和综合分析功能。
安装为 Claude Code 插件
/plugin marketplace add connerkward/ckw-skills
/plugin install apple-notes@connerkward
这会注册 MCP 服务并捆绑 apple-notes-search Agent 技能。也可以手动安装 MCP 服务——参见下方的安装(需要 macOS + bun + 完全磁盘访问权限)。
其他 MCP Notes 服务在规模扩大时会出问题。 它们使用 JXA(AppleScript 自动化)逐条读取笔记——读取 50 条笔记没问题,但 500 条以上就无法使用。读取 1,800 条笔记时,JXA 仅获取内容就要花约 49 分钟。在 macOS Sequoia 上情况更糟:Apple 会静默拒绝向没有 bundle ID 的进程授予自动化权限,因此基于 JXA 的服务会彻底失效。此 fork 直接读取 SQLite 数据库,解码 protobuf 数据块以获取真实笔记文本,并能在 5 秒内为 1,800 条笔记建立索引。

对比
| 功能 | 此 fork | RafalWilinski(基础版本) | disco-trooper | sirmews | dhravya |
|---|---|---|---|---|---|
| 笔记访问方式 | SQLite(直接读取) | JXA | JXA | SQLite | JXA |
| 获取 1800 条笔记 | 约 430ms | 约 49 分钟(估算) | 约 49 分钟(估算) | 快 | 慢 |
| 兼容 Sequoia | ✅ | ⚠️ JXA 被拒绝 | ⚠️ JXA 被拒绝 | ✅ | ⚠️ |
| 内容质量 | 已解码 protobuf | 原始 HTML | 原始 HTML | 部分内容 | 原始内容 |
| 语义搜索 | ✅ | ✅ | ✅ | ❌ | ❌ |
| 搜索时自动重新建立索引 | ✅ | ❌ | ❌ | ❌ | ❌ |
| 按文件夹搜索 | ✅ 完整路径 | ❌ | ✅ | ✅ | ✅ |
| 笔记分块 | ✅ 1500 个字符 | ❌ | ✅ | ❌ | ❌ |
| 重新排序(RRF × 标题 × 新近度) | ✅ | 仅 RRF | 仅 RRF | ❌ | ❌ |
| 非阻塞索引 UI | ✅ 实时进度 | ❌ | ❌ | ❌ | ❌ |
| 增量索引 | ✅ | ❌ | ✅ | ❌ | ❌ |
| 更新现有笔记 | ✅ | ❌ | ✅ | ❌ | ❌ |
| 标签 + wikilinks | ✅ | ❌ | ❌ | ❌ | ❌ |
| 相关笔记 | ✅ 多信号 | ❌ | ❌ | ❌ | ❌ |
macOS Sequoia 上的 JXA:没有 bundle ID 的进程会被静默自动拒绝自动化权限。此 fork 直接读取 SQLite。
功能
- 🔍 使用
all-MiniLM-L6-v2在设备本地生成嵌入,进行语义搜索 - 📝 BM25 全文搜索,并通过 Reciprocal Rank Fusion 进行融合
- 🧠 重新排序:
RRF × title_boost × recency_factor - 📂 完整文件夹层级——可按任意路径片段筛选
- 🕐 自动重新建立索引:每次搜索都会运行约 1ms 的变更检测;如果笔记有变化,就会启动一个后台索引任务(单航班),搜索本身绝不会因索引而阻塞
- ✂️ 将长笔记按 1500 个字符分块
- 🍎 直接读取 SQLite + 解码 protobuf——获取真实笔记文本,而非乱码 HTML
- 🏃♂️ 在设备本地运行——嵌入、搜索、BM25、聚类和桥接均在本地运行,无需 API 密钥;只有可选的综合分析生成会调用大模型(可通过 LM Studio/Ollama 使用本地模型,或通过 OpenAI 使用云端模型,由你选择)
本地 Web 应用——不只是搜索,还有关联与综合
直接运行服务并打开浏览器 UI——无需 MCP 客户端:
bun index.ts # → http://localhost:3741/ (also serves /mcp)
六种模式,从检索逐步迈向理解:
- Feed(默认)——按相关性排序的信息流,以证据为先,混合三类关联:桥接(A ↔ C,通过 B 连接,并从 B 中挖掘连接短语作为纯文本证据)、抽象配对(两条笔记,其由 LLM 整合得到的抽象来自
~/.mcp-apple-notes/consolidated.jsonl,并体现相同的底层思路),以及实体线索(“Y 个文件夹中的 X 条笔记提到了 Z”,来自实体图)。每个条目都会以纯文本展示其证据。对任意条目点 👍/👎 都会调整排序:一个微型在线逻辑回归模型(纯 TS,无依赖)会针对每次投票执行几步 SGD;投票会连同条目的特征向量追加到~/.mcp-apple-notes/votes.jsonl,并在启动时重放,因此重启后排序仍会保留。多样性约束:同一类型的条目连续不超过 2 个;每页 20 条中,同一条笔记最多出现 2 次;“显示更多”会翻页。端点:GET /api/feed?offset=&limit=、POST /api/vote{id, vote: 1|-1}。 - 搜索——混合语义搜索与 BM25 搜索,采用论文主题 UI,支持查询高亮和文件夹筛选。
- 地图——展示所有笔记的主题地图:对嵌入向量进行球面 k-means 聚类(标签使用 TF-IDF),再用 PCA 投影到 2D。将鼠标悬停在笔记上即可查看邻居透镜——连接到语义上最近笔记的线条,这些笔记往往跨越不同聚类(这是发现关联的核心功能)。端点:
GET /api/clusters?k=。 - 综合——“我写过的所有内容中,关于 X 的想法是什么?” 查询扩展 → 相关性门控检索(不受时间新近度影响)→ MMR 多样化 → LLM 撰写有依据的回答,并以内联
[n]引用对应源笔记;之后会再次核查来源。端点:GET /api/synthesize?q=。 - 桥接——在你自己的笔记中发现 Swanson-ABC 关联:找出 (A, C) 这一对笔记,它们彼此并不直接相似,但都与共享的桥接笔记 B 高度相似——这类关联只能通过中间笔记在语料中建立。仅对嵌入向量进行算术运算(得分 = sim(A,B)·sim(B,C)·(1−sim(A,C));跨文件夹,且没有共同标签或维基链接;阈值会自动放宽;选择时会惩罚枢纽节点,避免某条笔记主导列表)。无需 LLM,费用为 0。端点:
GET /api/bridges?limit=40。 - 实体——“我还在哪里谈到了 Mercedes?” 按提及权重排序的实体标签(人物、组织、概念)→ 提及这些实体的笔记。读取可选的 sqlite 图数据库(见下文)。端点:
GET /api/entities?q=&limit=、GET /api/entity-notes?entity=。
预计算磁盘缓存(即时获取桥接结果和地图)
桥接挖掘(嵌入计算约 2 分钟)和聚类只计算一次并持久化,缓存以语料指纹(笔记数量 + 最晚修改日期)为键:
~/.mcp-apple-notes/bridges_cache.json— 完整的桥接挖掘结果~/.mcp-apple-notes/clusters_cache.json— 按k保存的聚类结果
缓存有效时,会立即从磁盘提供(<300ms)。缓存过期(笔记已更改)时,会立即提供过期副本,同时在 UI 中显示“正在重新计算…”提示,并由一个后台任务(单航班)刷新缓存。缓存不存在时,会在请求过程中计算一次。
启用综合功能(需要 LLM)
嵌入、搜索、聚类、桥接和实体功能都完全在本地运行。只有生成综合回答需要 LLM。指定一个本地的 OpenAI 兼容服务端,即可保护笔记隐私:
# LM Studio / Ollama (zero API cost, notes stay local):
SYNTH_BASE_URL=http://localhost:1234/v1 SYNTH_MODEL=<loaded-model> OPENAI_API_KEY=local bun index.ts
# …or real OpenAI: set a funded OPENAI_API_KEY (defaults to gpt-4o-mini).
实体图(可选)
实体层读取 ~/.mcp-apple-notes/layered_graph.db(通过 LAYERED_DB 覆盖)——这是配套的 exp-notes-indexing 基准测试工具(layered_graph.py)生成的纯 sqlite 文件。无需额外依赖(bun 自带 bun:sqlite);如果文件不存在,实体工具和选项卡只会说明如何生成它。
安装
- 克隆并安装:
git clone https://github.com/connerkward/mcp-apple-notes
cd mcp-apple-notes
bun install
-
在系统设置中将 bun(
~/.bun/bin/bun)添加到完全磁盘访问权限。 -
添加到
claude_desktop_config.json:
{
"mcpServers": {
"apple-notes": {
"command": "/Users/<YOUR_USER_NAME>/.bun/bin/bun",
"args": ["/Users/<YOUR_USER_NAME>/mcp-apple-notes/index.ts", "--stdio"]
}
}
}
- 重启 Claude Desktop 并询问:“为我的 Apple Notes 建立索引”。
Claude Code / CLI 注册
// .mcp.json (project) or `claude mcp add apple-notes -- bun /path/to/mcp-apple-notes/index.ts --stdio`
{
"mcpServers": {
"apple-notes": {
"command": "bun",
"args": ["/path/to/mcp-apple-notes/index.ts", "--stdio"]
}
}
}
同一组 bridges/entities 工具也为本地应用的网页 UI 标签页提供支持(bun index.ts → http://localhost:3741/);实体图数据库为可选项,由 exp-notes-indexing 基准测试工具生成。
工具
| 工具 | 描述 |
|---|---|
index-notes | 在后台建立索引,并显示实时进度 UI |
search-notes | 语义 + FTS 搜索;可选参数:folder、modifiedAfter、modifiedBefore |
find-notes | 精确子串搜索(类似 Apple Notes 内置搜索);可选参数:folder、日期范围 |
get-note | 按标题获取完整笔记;无精确匹配时使用模糊匹配 |
list-notes | 按最近更新时间排序笔记;可选参数:folder、日期范围、limit |
list-folders | 列出所有文件夹及笔记数量 |
list-tags | 列出笔记中的所有 #hashtags,按出现频率排序 |
search-by-tag | 搜索包含特定标签的笔记 |
related-notes | 通过共享标签、[[wikilinks]] 和向量相似度查找相关笔记 |
bridge-notes | Swanson-ABC 桥接:通过共享中间笔记连接的非相似笔记对;可选参数:folder、limit |
feed | 以 JSON 格式返回按排名排列、以证据为先的关联 Feed(桥接 + 抽象配对 + 实体线索);可选参数:limit |
entity-notes | 按提及权重查找提及某实体(例如“Mercedes”)的笔记——需要可选的实体图数据库 |
list-entities | 按提及次数排序的实体列表;可选参数:子串 query、limit |
get-tables | 从笔记中提取以竖线或制表符分隔的表格 |
create-note | 创建笔记 |
update-note | 编辑现有笔记 |
check-changes | 检查自上次建立索引以来笔记是否有变更(不会触发重新建立索引) |
index-health | 同步状态、上次建立索引时间、笔记数量 |
搜索与排名
每次搜索都会检测变更(约 1 ms)。如果笔记有变更,就会启动一个后台增量索引任务(单任务运行——重复触发会被丢弃),搜索则立即使用当前索引返回结果;任务完成后,结果会更新。上次建立索引的时间水位会在重启后保留于 ~/.mcp-apple-notes/index_state.json。变更检测会比较每个标题对应的修改日期集合(Apple Notes 的标题并不唯一——例如 10 个“TODO”——而标题→单个日期的映射永远无法处理重复标题)。
score = RRF(vector, BM25) × title_boost × recency_factor
时间查询(recent、latest、today)会自动切换为 1 天的时效半衰期,权重为 70%。普通查询使用 90 天的半衰期,权重为 10%,因此相关性仍是首要因素。
基准测试
1,806 条笔记,Apple Silicon:
| 方式 | 耗时 | 是否包含正文 |
|---|---|---|
| 仅 JXA 元数据 | 4,463 ms | 否 |
| JXA(含正文) | 约 49 分钟 | 是 |
| 直接读取 SQLite | 430 ms | 是 |
故障排除
tail -n 50 -f ~/Library/Logs/Claude/mcp-server-apple-notes.log
权限错误 → 确保 bun(~/.bun/bin/bun)在系统设置 → 隐私与安全性中拥有完全磁盘访问权限。
🧭 ckw-skills — 属于 Conner K. Ward 的 Claude Code 技能与 MCP 服务合集。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。