基于MCP协议构建本地AI知识库:Affine笔记与智能体集成实践
1. 项目概述:当开源笔记工具遇上AI智能体
最近在折腾AI智能体(Agent)的本地化部署和工具扩展,发现了一个挺有意思的项目:DAWNCR0W/affine-mcp-server。简单来说,这是一个为开源笔记软件Affine打造的MCP(Model Context Protocol)服务器。如果你对Affine不熟,可以把它理解为一个集成了Notion式块编辑、白板协作和本地优先特性的新一代知识管理工具。而MCP,则是Anthropic提出的一套协议,旨在让大语言模型(LLM)能够安全、结构化地访问外部工具、数据和计算资源。
这个项目的核心价值在于,它在用户本地的Affine笔记数据和AI智能体之间,架起了一座安全、可控的桥梁。想象一下,你不再需要手动复制粘贴笔记内容去问AI,而是可以直接让你的AI助手(比如Claude Desktop、Cursor里的AI Agent)基于你整个Affine知识库的上下文,来帮你总结文档、查找关联信息、甚至基于现有笔记草拟新内容。这一切都发生在你的本地环境,数据无需上传到云端,既保护了隐私,又提升了知识工作的效率流。
我之所以花时间深入研究并部署了这个服务器,是因为在信息过载的当下,我的笔记库越来越像一座“沉睡的金矿”。里面有项目复盘、学习心得、临时灵感、会议纪要,但真要用的时候,靠大脑回忆和手动搜索效率太低。affine-mcp-server正是为了解决这个痛点而生——它让AI成为了你个人知识库的“活索引”和“思考伙伴”。这个项目适合所有使用Affine作为主力笔记工具,并且希望探索AI增强工作流的开发者、知识工作者和效率爱好者。即使你对MCP协议不熟,跟着这篇从零开始的踩坑实录走一遍,也能顺利搭起来。
2. 核心架构与MCP协议解析
2.1 MCP协议:AI的“标准外设接口”
要理解affine-mcp-server在做什么,首先得搞懂MCP是什么。你可以把大语言模型想象成一台功能强大但“与世隔绝”的电脑主机。它擅长处理输入的文字信息,但对于主机外部的世界——你电脑里的文件、数据库、API服务——它原本是感知和操作不到的。
MCP就像为这台“主机”定义了一套标准的USB接口协议。任何遵循MCP协议开发的“外设”(即MCP Server),比如文件管理器、数据库连接器、日历服务,甚至是这个Affine笔记服务器,都能通过这套标准接口被“主机”(即支持MCP的AI客户端)识别和使用。协议规定了“外设”必须告诉“主机”自己有哪些功能(Tools)、能提供哪些只读数据(Resources),以及“主机”如何调用这些功能。
这样做有几个关键好处:
- 安全性:AI客户端通过标准协议与Server通信,Server控制着对真实资源的访问权限,避免了AI直接操作系统带来的风险。
- 模块化:笔记、日历、代码库等不同服务可以由独立的、专注的Server提供,AI客户端无需为每个工具做定制化开发。
- 本地化:Server可以完全运行在本地,所有数据流转都在你自己的机器上完成,满足了隐私保护的核心需求。
affine-mcp-server就是这样一个专为Affine设计的“MCP外设”。它启动后,会作为一个本地服务运行,等待支持MCP的AI客户端(如Claude Desktop)来连接。一旦连接建立,它就会向AI客户端“汇报”:“嗨,我这里有这些工具可以用:search_affine_blocks(搜索笔记块)、get_affine_doc_content(获取文档内容)、create_affine_page(创建新页面)等等。”
2.2 项目架构与数据流拆解
这个项目的代码结构清晰,体现了典型的MCP Server设计模式。我们来看一下核心的数据流和组件:
用户提问 ↓ AI客户端 (如 Claude Desktop) 解析用户意图 ↓ AI客户端通过MCP协议调用 `affine-mcp-server` 提供的对应工具(Tool) ↓ affine-mcp-server 收到请求,携带参数(如搜索关键词) ↓ Server 通过 Affine 本地数据库接口(访问 `affine.db` 或 `affine.sqlite`)执行查询 ↓ Server 将查询结果(笔记块、文档内容)格式化为MCP协议规定的JSON结构 ↓ 结果通过MCP协议返回给AI客户端 ↓ AI客户端将结果融入上下文,生成最终回答给用户整个过程中,AI模型本身从未直接接触你的Affine数据库文件。它只是向MCP Server发送了一个结构化的请求(比如{“tool”: “search_affine_blocks”, “arguments”: {“query”: “项目复盘”}}),然后接收结构化的结果。所有的数据访问逻辑、权限控制和错误处理,都封装在affine-mcp-server这个你信任的本地程序中。
项目的核心文件通常包括:
src/server.ts或index.ts:主服务器文件,定义MCP Server的启动、工具注册和请求处理逻辑。src/tools/目录:存放各个具体工具的实现,如搜索工具、创建页面工具等。src/utils/目录:包含数据库连接、Affine数据模型解析等辅助函数。- 配置文件(如
config.json或环境变量):用于指定Affine本地数据文件的路径。
这种架构意味着,只要你Affine笔记的数据文件在本地,这个Server就能工作,完全不需要Affine官方提供云端API,实现了真正的去中心化和用户主权。
注意:Affine目前默认使用IndexedDB(在浏览器中)存储数据,但其桌面版(或某些同步配置下)会在本地生成一个SQLite数据库文件(如
affine.sqlite)。affine-mcp-server需要访问这个本地数据库文件。因此,确保你知道Affine数据存储在电脑的哪个位置,是部署的第一步,也是最重要的一步。
3. 从零开始的本地部署与配置实战
理论讲完了,我们动手把它跑起来。这里我以macOS/Linux环境为例,Windows用户只需注意路径的差异。
3.1 前期准备:定位你的Affine数据仓库
首先,找到Affine在本地的数据库文件。这是整个流程的钥匙。
Affine桌面版(推荐):如果你使用Affine的桌面客户端,数据通常存储在用户的应用数据目录下。
- macOS:
~/Library/Application Support/affine-desktop/ - Linux:
~/.config/affine-desktop/或~/.var/app/app.affine.desktop/data/affine-desktop/(Flatpak安装) - Windows:
%APPDATA%\affine-desktop\进入该目录,寻找名为affine.db或affine.sqlite的文件。我的是affine.sqlite。
- macOS:
Affine Web版 + 本地同步:如果你通过浏览器使用Web版,但开启了本地同步功能,数据也可能以SQLite形式保存在某个指定文件夹。你需要在Affine的设置中查看本地同步路径。
实操心得: 在开始部署前,我强烈建议先用一个轻量级的SQLite查看工具(比如DB Browser for SQLite或 VSCode的SQLite扩展)打开这个数据库文件,确认你能看到类似blocks、pages这样的表。这不仅能验证文件路径正确,还能让你对Affine的数据结构有个直观感受,后续排查问题时心里有底。务必先备份这个数据库文件,任何直接操作原始数据的行为都有风险(尽管MCP Server主要是只读)。
3.2 环境搭建与服务器启动
这个项目通常是Node.js项目,我们需要克隆代码并安装依赖。
# 1. 克隆仓库(请确认DAWNCR0W/affine-mcp-server是公开仓库) git clone https://github.com/DAWNCR0W/affine-mcp-server.git cd affine-mcp-server # 2. 安装依赖(假设项目使用npm) npm install # 3. 配置环境变量 # 通常项目会通过环境变量或配置文件指定数据库路径 # 创建一个 .env 文件在项目根目录 echo "AFFINE_DB_PATH=/绝对/路径/到/你的/affine.sqlite" > .env # 例如:echo "AFFINE_DB_PATH=/Users/yourname/Library/Application Support/affine-desktop/affine.sqlite" > .env # 4. 构建项目(如果是TypeScript项目) npm run build # 5. 启动MCP服务器 # 启动方式可能因项目设计而异,常见的有: # 方式A: 直接运行编译后的JS node dist/index.js # 方式B: 使用npm脚本 npm start # 方式C: 开发模式热重载 npm run dev启动成功后,终端应该会输出类似MCP Server running on stdio或监听某个端口(如localhost:3000)的信息。这表示你的Affine MCP服务器已经就绪,正在等待AI客户端连接。
常见踩坑点:
- 依赖安装失败:确保你的Node.js版本符合项目要求(查看
package.json中的engines字段)。遇到node-gyp编译错误,可能需要安装Python和构建工具链(如macOS的Xcode Command Line Tools)。 - 数据库路径错误:这是最可能出错的地方。
.env文件中的路径必须是绝对路径,并且确保运行Server的用户有该文件的读取权限。如果路径包含空格或特殊字符,可能需要用引号包裹。 - 数据库锁或损坏:如果Affine桌面应用正在运行,它可能会独占数据库连接,导致Server无法访问。启动Server前,请先完全关闭Affine桌面客户端。如果数据库损坏,可能需要从备份恢复。
3.3 配置AI客户端连接MCP Server
服务器跑起来了,现在需要让AI客户端知道它的存在。这里以目前对MCP支持最完善的Claude Desktop为例。
找到Claude Desktop的配置目录:
- macOS:
~/Library/Application Support/Claude/ - Windows:
%APPDATA%\Claude\
- macOS:
编辑或创建MCP配置文件: 在该目录下,找到或创建一个名为
claude_desktop_config.json的文件。其核心结构是定义一个mcpServers对象。配置 affine-mcp-server: 将以下配置添加到
claude_desktop_config.json中。配置方式取决于你的Server启动方式:如果Server通过stdio通信(最常见):
{ "mcpServers": { "affine-notes": { "command": "node", "args": [ "/绝对/路径/到/affine-mcp-server/dist/index.js" // 替换为你的实际路径 ], "env": { "AFFINE_DB_PATH": "/绝对/路径/到/你的/affine.sqlite" } } } }这种方式是最高效的,Claude Desktop会直接启动这个Node进程并与之通信。
如果Server通过HTTP运行在某个端口:
{ "mcpServers": { "affine-notes": { "url": "http://localhost:3000" } } }这种方式需要你先在终端手动启动Server(
npm start),并确保端口一致。重启Claude Desktop: 保存配置文件后,完全退出并重新启动Claude Desktop应用。
验证连接: 重启后,在Claude Desktop的聊天界面,你应该能看到一个微小的变化,比如输入框附近出现新的图标,或者你可以直接问Claude:“你现在可以使用哪些工具?” 或 “你能访问我的Affine笔记吗?”。Claude应该会回复它已连接到一个提供Affine相关工具的MCP服务器,并列出可用的工具列表(如
search_affine_blocks,get_affine_doc_content)。
提示:如果连接失败,首先检查Claude Desktop的日志。在macOS上,可以通过在终端运行
tail -f ~/Library/Logs/Claude/ClaudeDesktop.log来查看实时日志,其中通常会包含加载MCP配置和连接Server的错误信息,是排查问题的第一手资料。
4. 核心功能工具详解与使用场景
成功连接后,你的AI助手就获得了“翻阅”你Affine笔记的能力。我们来看看affine-mcp-server通常提供了哪些工具,以及如何在对话中巧妙地使用它们。
4.1 工具列表与调用范式
根据项目实现,工具可能包括但不限于:
| 工具名 | 功能描述 | 典型使用场景 | 调用示例(用户对AI说) |
|---|---|---|---|
search_affine_blocks | 在全库笔记块中搜索关键词 | 查找分散在不同页面中的相关信息 | “在我的笔记里搜索‘季度目标’和‘OKR’相关的所有内容。” |
get_affine_doc_content | 获取指定页面/文档的完整内容 | 需要基于某篇完整笔记进行分析或总结 | “把我写的《产品需求文档 - XX项目》这篇笔记的全部内容找出来给我看看。” |
get_affine_workspaces | 列出所有工作区 | 了解笔记库的整体结构 | “我的Affine里有哪些工作区?” |
create_affine_page | 创建一个新的页面 | 让AI协助起草新文档 | “帮我在‘项目记录’工作区创建一个名为‘本周会议纪要’的新页面。” |
append_to_affine_page | 在指定页面追加内容 | 让AI将对话产出直接保存到笔记 | “把刚才我们讨论的行动方案,追加到‘项目复盘’页面的末尾。” |
调用范式: 你不需要记住这些工具的具体命令。你只需要用自然语言向AI描述你的需求。例如:
- 模糊查找:“我好像在哪篇笔记里记过关于‘用户画像’的定义,帮我找找。”
- 内容分析:“请阅读我‘学习笔记’工作区里关于‘React Hooks’的那篇文档,然后给我总结出三个最重要的使用要点。”
- 内容创作与保存:“基于我们刚才讨论的API设计原则,帮我起草一份简要的‘微服务接口规范’,并保存到我的‘技术文档’工作区。”
AI在背后会进行意图识别,选择合适的MCP工具,调用Server获取数据,再将结果融入它的回答中。
4.2 实战场景演练
场景一:跨笔记研究辅助我正在准备一个关于“时间管理方法”的分享,但相关笔记散落在各处:有读书笔记《深度工作》的摘录、有自己写的《番茄工作法实践心得》、还有一篇收藏的《GTD系统搭建》网络文章。
- 我对AI说:“我要做一个时间管理的分享,请帮我找出所有笔记中提到的不同时间管理方法,并对比它们的优缺点。”
- AI背后操作:
- 调用
search_affine_blocks,关键词可能包括“时间管理”、“番茄”、“GTD”、“深度工作”、“Pomodoro”等。 - 从返回的多个笔记块中,提取方法名称、描述、优点、缺点等信息。
- 组织语言,生成一个对比表格或总结段落回复给我。
- 调用
- 我的收获:几分钟内,我就得到了一个基于我个人知识库的、个性化的内容聚合,无需手动翻遍所有笔记。
场景二:会议纪要自动化刚开完一个项目同步会,我在Affine里快速记录了零散的要点。
- 我对AI说:“我刚在‘项目A’页面下记了一些零散的会议要点,请帮我将它们整理成结构清晰的会议纪要,包括时间、参会人、讨论议题、决议和待办事项。”
- AI背后操作:
- 调用
get_affine_doc_content获取“项目A”页面的最新内容。 - 理解文本内容,识别出参会人、议题点、决策和行动项。
- 按照标准的会议纪要格式重新组织内容,并回复给我。
- (可选)我可以说:“把这个整理好的纪要,追加到原页面的下方。” AI便会调用
append_to_affine_page工具。
- 调用
场景三:灵感延伸与写作我在笔记里记录了一个新产品的初步构想。
- 我对AI说:“阅读我‘创意’工作区里名为‘智能家居健康助手’的页面,然后基于这个构想,帮我扩展一份可能面临的‘技术挑战与解决方案’列表。”
- AI背后操作:
- 调用
get_affine_doc_content获取原始构想文档。 - 结合其自身的知识(注意:这里AI会结合你的笔记内容和它的训练知识),分析一个智能家居健康产品可能遇到的技术难题(如传感器精度、数据隐私、设备互联等)。
- 为每个挑战提出一两个潜在的解决思路,生成列表。
- 调用
- 我的收获:AI充当了一个“思维拓展伙伴”,基于我的种子想法,激发出了更全面的思考维度。
实操心得: 刚开始使用时,容易陷入“工具思维”,总想直接命令AI“用XX工具搜索YY”。其实最有效的方式是忘记工具的存在,直接用日常语言描述你的任务和上下文。优秀的AI客户端和MCP Server配合,应该能很好地理解你的意图。如果AI没能正确调用工具,你可以稍微调整表述,或者明确说“请在我的Affine笔记中查找……”。
5. 高级配置、问题排查与安全考量
5.1 性能调优与高级配置
对于笔记数量巨大(超过数千页)的用户,简单的全文本搜索可能会变慢。此时可以考虑以下优化方向:
- 启用索引(如果项目支持):查看
affine-mcp-server项目是否支持或预留了数据库索引功能。为blocks表的text字段添加FTS(全文搜索)索引可以极大提升搜索速度。但这通常需要修改Server代码或初始化脚本,属于高级操作。 - 限制搜索范围:向AI提出更精确的请求。与其说“搜索所有关于AI的内容”,不如说“在‘2024年学习’这个工作区里,搜索关于‘Transformer模型’的内容”。更精确的指令能减少Server需要扫描的数据量。
- Server运行参数:如果Server是Node.js进程,确保它运行在合适的Node环境下。对于大型数据库,可以尝试为Node进程分配更多内存(例如使用
NODE_OPTIONS=--max-old-space-size=4096)。
5.2 常见问题排查清单
遇到连接失败或功能异常,可以按以下清单自查:
| 问题现象 | 可能原因 | 排查步骤 |
|---|---|---|
| Claude Desktop 启动后无新工具提示 | 1. 配置文件路径错误 2. 配置文件格式错误(JSON语法) 3. Server启动命令失败 | 1. 确认claude_desktop_config.json在正确目录且名称无误。2. 使用 JSON 验证器检查配置文件语法。 3. 手动在终端运行配置中的 command和args,看Server能否独立启动并输出日志。 |
| AI客户端报告“无法连接到MCP服务器” | 1. Server进程崩溃 2. 数据库路径权限问题 3. 端口冲突(HTTP模式) | 1. 查看终端或Server的日志输出,通常会有错误堆栈。 2. 检查 AFFINE_DB_PATH指向的文件是否存在,且当前用户有读权限。3. 检查指定端口是否被其他程序占用。 |
| 搜索工具返回空结果 | 1. 搜索关键词不匹配 2. 数据库路径指向了错误或空的Affine数据文件 3. Server连接了错误的数据库(如测试库) | 1. 尝试用非常简单的关键词(如“test”)搜索。 2. 用SQLite工具直接打开 AFFINE_DB_PATH指定的文件,执行SELECT COUNT(*) FROM blocks;查看是否有数据。3. 确认关闭了Affine桌面端,避免连接锁死。 |
| 创建或追加内容失败 | 1. 数据库只读模式打开 2. 目标页面ID不存在或错误 3. 磁盘空间不足 | 1. 检查Server是否有对数据库文件的写权限。 2. 通过 get_affine_workspaces等只读工具先确认页面信息。3. 检查磁盘空间。 |
一个典型的调试流程:
- 隔离测试Server:在终端直接运行
node /path/to/server/index.js,观察启动日志,看是否有明显的错误(如“Cannot find database file”)。 - 检查客户端日志:查看Claude Desktop的日志文件,搜索“MCP”、“affine”等关键词,看是否有加载或连接错误。
- 简化配置:暂时将MCP配置改为一个已知可用的简单Server(比如一个简单的echo server)进行测试,以确认Claude Desktop的MCP功能本身是正常的。
- 查阅项目Issue:前往
DAWNCR0W/affine-mcp-server的GitHub仓库,查看已有的Issues和讨论,很可能你遇到的问题别人已经遇到过并提供了解决方案。
5.3 安全与隐私考量
将个人笔记库开放给AI访问,安全是重中之重。affine-mcp-server的本地化设计在架构上提供了很好的基础,但仍需注意:
- 数据不出本地:这是最大的优势。整个数据流:AI客户端 -> MCP Server -> 本地SQLite文件 -> 返回结果,都在你的计算机上完成。只要AI客户端(如Claude Desktop)本身是可信的本地应用,你的笔记内容就不会被发送到远程服务器。
- 权限最小化:MCP Server理论上只应被赋予访问特定数据库文件的权限。它不应该有执行任意系统命令或访问其他无关文件的能力。确保你从可信来源(如官方GitHub仓库)获取代码。
- 注意AI客户端的上下文:当你通过AI客户端与笔记交互时,相关的笔记内容会被纳入与AI对话的上下文中。这意味着,如果你之后将对话记录分享给他人,或者某些AI客户端有对话记录同步到云端的选项(需仔细检查设置),那么这些笔记内容可能会间接泄露。务必了解你所用的AI客户端的隐私政策和数据处理方式。
- Server代码审计:如果你有技术能力,可以粗略浏览一下
affine-mcp-server的源代码,特别是工具的实现部分,确认它没有进行任何网络传输或记录日志到本地的敏感操作。开源项目的好处就在于透明。
个人建议:初期可以在一个测试用的Affine工作区进行操作,里面放一些非敏感的数据。待完全熟悉整个工作流并建立信任后,再应用到主笔记库。
6. 生态展望与个性化扩展可能
目前affine-mcp-server项目可能还处于早期阶段,功能集中在基础的读写搜索。但MCP协议的开放性为我们指明了未来更广阔的想象空间。
- 更智能的笔记检索:未来的工具可以超越关键词搜索,集成语义搜索(通过本地运行的嵌入模型),实现“帮我找和这个概念相似的所有笔记”,即使它们没有相同的关键词。
- 知识图谱查询:如果Server能解析笔记块之间的链接关系(双向链接),就可以提供类似“找出所有引用到这篇笔记的页面”或“展示这个概念的知识网络”这样的工具。
- 自动化工作流触发:结合其他MCP Server(如日历Server、邮件Server),可以实现“将这篇笔记中的待办事项,创建为日历事件并设置提醒”或“将这篇总结通过邮件发送给项目组成员”。
- 自定义工具开发:MCP协议并不复杂。你可以基于现有的Server代码,为自己量身定制工具。例如,开发一个
export_affine_to_markdown工具,让AI帮你将某个页面导出为Markdown文件;或者一个analyze_writing_style工具,让AI分析你过去一个月的写作习惯并提出建议。
部署affine-mcp-server不仅仅是连接了一个工具,更是亲手搭建了一个属于你自己的、以个人知识库为核心的AI增强工作台的起点。它代表了从“人适应工具”到“工具围绕人的知识体系服务”的范式转变。在这个过程中,你可能会遇到配置的麻烦,需要阅读日志排查问题,但一旦跑通,你会发现这种深度整合带来的流畅感和能力提升是值得的。我的体会是,最好的工具永远是那些能够无缝融入你既有工作流、并放大你核心资产(比如多年的笔记积累)价值的工具。这个项目正是这样一个有趣的尝试,它很“极客”,但解决的是一个非常实际的知识工作者痛点。
