AFFiNE MCP服务器
与AFFiNE(自托管或云)集成的模型上下文协议(MCP)服务器。它通过stdio(默认)或HTTP向AI助手公开AFFiNE工作区和文档(/mcp).
概述
- 目的:通过MCP管理AFFiNE工作区和文档
- 传输:stdio(默认)和可选HTTP(
/mcp)用于远程MCP部署 - 身份验证:令牌、Cookie或电子邮件/密码(优先级顺序)
- 工具:76个基于WebSocket的文档编辑工具
- 状态:活动
v1.12.0中的新功能:在数据库行上添加链接文档,为AFFiNE UI中创建的行恢复MCP CRUD,修复自托管表导出,并记录GHCR Docker版本。
特性
- 工作区:创建(带初始文档)、读取、更新、删除
- 文档:列表/获取/读取/发布/撤销+创建/附加/替换/删除+标记导入/导出+标签(基于WebSocket)
- 侧栏数据:AFFiNE工作空间树的集合、文件夹和组织链接
- 数据库工作流:创建数据库块、检查模式、添加/更新/删除行,以及通过MCP工具读取或更新单元格值
- 评论:完整的CRUD和解析
- 版本历史:列表
- 用户和令牌:当前用户、登录、个人资料/设置和个人访问令牌
- 通知:列出并标记为已读
- Blob存储:上传/删除/清理
需求
- Node.js 18+
- AFFiNE实例(自托管或云)
- 有效的AFFiNE凭据或访问令牌
安装
BASH``` 1 2 3 4# Global install (recommended) npm i -g affine-mcp-server
Or run ad‑hoc via npx (no install)
npx -y -p affine-mcp-server affine-mcp — —version
该软件包安装了一个名为的CLI `affine-mcp` 它通过stdio运行MCP服务器。
注意:从v1.2.2+开始,CLI包装器(`bin/affine-mcp`)确保Node运行ESM入口点,防止shell误解JS。
## 配置
### 交互式登录(推荐)
配置凭据的最简单方法:
BASH```
1
2npm i -g affine-mcp-server
affine-mcp login
此操作将凭据存储在 ~/.config/affine-mcp/config (模式600)。MCP服务器自动读取它们,不需要环境变量。
AFFiNE云 (app.affine.pro):系统将提示您从“设置”粘贴API令牌→ 集成→ MCP服务器。
自托管实例:您可以在电子邮件/密码(推荐-自动生成API令牌)或手动粘贴令牌之间进行选择。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$ affine-mcp login
Affine MCP Server — Login
Affine URL [https://app.affine.pro]: https://my-affine.example.com
Auth method — [1] Email/password (recommended) [2] Paste API token: 1
Email: user@example.com
Password: ****
Signing in...
✓ Signed in as: User Name <user@example.com>
Generating API token...
✓ Created token: ut_abc123... (name: affine-mcp-2026-02-18)
Detecting workspaces...
Found 1 workspace: abc-def-123 (by User Name, 1 member, 2/10/2026)
Auto-selected.
✓ Saved to /home/user/.config/affine-mcp/config (mode 600)
The MCP server will use these credentials automatically.
其他CLI命令:
affine-mcp --help/-h/help—显示命令帮助affine-mcp status—显示当前配置和测试连接affine-mcp status --json—机器可读状态输出affine-mcp doctor—运行配置和连接诊断affine-mcp show-config—打印已编辑机密的有效配置affine-mcp config-path—打印配置文件路径affine-mcp snippet <claude|cursor|codex|all> [--env]—打印即粘贴客户端配置代码段affine-mcp logout—删除存储的凭据affine-mcp --version/-v/version—打印已安装的CLI版本并退出
非交互式登录助手:
affine-mcp login --url <url> --token <token> --workspace-id <id> --force
环境变量
您还可以通过环境变量进行配置(它们覆盖配置文件):
- 必修的:
AFFINE_BASE_URL - 身份验证(选择一个):
AFFINE_API_TOKEN|AFFINE_COOKIE|AFFINE_EMAIL+AFFINE_PASSWORD - 可选:
AFFINE_GRAPHQL_PATH(默认值/graphql),AFFINE_WORKSPACE_ID,AFFINE_LOGIN_AT_START(套sync仅当您必须阻止启动时) - 工具筛选:
AFFINE_DISABLED_GROUPS,AFFINE_DISABLED_TOOLS(参见 过滤暴露的工具)
身份验证优先级:
AFFINE_API_TOKEN→ 2)AFFINE_COOKIE→ 3)AFFINE_EMAIL+AFFINE_PASSWORD
Cloudflare说明:
AFFINE_EMAIL/AFFINE_PASSWORDauth需要编程访问/api/auth/sign-in.AFFiNE云(app.affine.pro)Cloudflare阻止了这些请求。使用AFFINE_API_TOKEN用于云,或使用affine-mcp login它自动处理这个问题。电子邮件/密码适用于没有Cloudflare的自托管实例。
快速开始
克劳德代码
运行后 affine-mcp login,添加到您的项目 .mcp.json:
JSON``` 1 2 3 4 5 6 7{ “mcpServers”: { “affine”: { “command”: “affine-mcp” } } }
不 `env` 需要块–服务器读取 `~/.config/affine-mcp/config` 自动。
如果你更喜欢显式的env-vars而不是配置文件:
JSON```
1
2
3
4
5
6
7
8
9
10
11{
"mcpServers": {
"affine": {
"command": "affine-mcp",
"env": {
"AFFINE_BASE_URL": "https://app.affine.pro",
"AFFINE_API_TOKEN": "ut_xxx"
}
}
}
}
克劳德桌面版
添加到您的Claude Desktop配置中:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - 窗户:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
JSON``` 1 2 3 4 5 6 7 8 9 10 11{ “mcpServers”: { “affine”: { “command”: “affine-mcp”, “env”: { “AFFINE_BASE_URL”: “https://app.affine.pro”, “AFFINE_API_TOKEN”: “ut_xxx” } } } }
或者使用自托管实例的电子邮件/密码(AFFiNE Cloud不支持——请参阅上面的Cloudflare注释):
JSON```
1
2
3
4
5
6
7
8
9
10
11
12{
"mcpServers": {
"affine": {
"command": "affine-mcp",
"env": {
"AFFINE_BASE_URL": "https://your-self-hosted-affine.com",
"AFFINE_EMAIL": "you@example.com",
"AFFINE_PASSWORD": "secret!"
}
}
}
}
提示
- 更喜欢
affine-mcp login或AFFINE_API_TOKEN用于零延迟启动。 - 如果您的密码包含
!(zsh历史扩展),在shell中用单引号括起来,或者使用上面的JSON配置。 affine-mcp doctor是确认保存的配置仍然有效的最快方法。affine-mcp snippet claude --env和affine-mcp snippet codex --env可以从当前配置生成即贴式客户端设置。affine-mcp snippet all --env一次性打印Claude、Cursor和Codex设置。
Codex CLI
在Codex注册MCP服务器:
-
配置文件(在
affine-mcp login): -
codex mcp add affine -- affine-mcp -
使用API令牌:
-
codex mcp add affine --env AFFINE_BASE_URL=https://app.affine.pro --env AFFINE_API_TOKEN=ut_xxx -- affine-mcp -
使用电子邮件/密码(仅限自托管):
-
codex mcp add affine --env AFFINE_BASE_URL=https://your-self-hosted-affine.com --env 'AFFINE_EMAIL=you@example.com' --env 'AFFINE_PASSWORD=secret!' -- affine-mcp
光标
Cursor还支持MCP over stdio mcp.json.
项目本地(.cursor/mcp.json)示例:
JSON``` 1 2 3 4 5 6 7 8 9 10 11{ “mcpServers”: { “affine”: { “command”: “affine-mcp”, “env”: { “AFFINE_BASE_URL”: “https://app.affine.pro”, “AFFINE_API_TOKEN”: “ut_xxx” } } } }
如果你喜欢 `npx`:
JSON```
1
2
3
4
5
6
7
8
9
10
11
12{
"mcpServers": {
"affine": {
"command": "npx",
"args": ["-y", "-p", "affine-mcp-server", "affine-mcp"],
"env": {
"AFFINE_BASE_URL": "https://app.affine.pro",
"AFFINE_API_TOKEN": "ut_xxx"
}
}
}
}
码头工人
预构建的多拱形图像(linux/amd64, linux/arm64)在每个发布标签上发布到GitHub容器注册表:
1
2ghcr.io/dawncr0w/affine-mcp-server:latest # latest release
ghcr.io/dawncr0w/affine-mcp-server:1.12.0 # specific version
快速启动:
BASH```
1
2
3
4
5
6docker run -d
-p 3000:3000
-e AFFINE_BASE_URL=https://your-affine-instance.com
-e AFFINE_API_TOKEN=ut_your_token
-e AFFINE_MCP_HTTP_TOKEN=your-strong-secret
ghcr.io/dawncr0w/affine-mcp-server:latest
然后添加到您的MCP客户端配置中:
JSON```
1
2
3
4
5
6
7
8
9{
"mcpServers": {
"affine": {
"type": "http",
"url": "http://localhost:3000/mcp",
"headers": { "Authorization": "Bearer your-strong-secret" }
}
}
}
容器以非root用户身份运行,并公开 /healthz 和 /readyz 用于活性/准备状态探针。
远程服务器
如果你想远程托管服务器(例如,使用Render、Railway、Docker或VPS)并通过HTTP MCP(Streamable HTTP on /mcp)而不是本地 stdio,以HTTP模式运行服务器。
环境变量(HTTP模式)
必修的:
MCP_TRANSPORT=httpAFFINE_BASE_URL(例如:https://app.affine.pro)AFFINE_MCP_AUTH_MODE=bearer(默认)或AFFINE_MCP_AUTH_MODE=oauth
承载模式后端身份验证:
AFFINE_API_TOKEN(推荐),或AFFINE_COOKIE,或AFFINE_EMAIL+AFFINE_PASSWORD
OAuth模式后端身份验证:
AFFINE_API_TOKEN(AFFiNE后端访问所需的服务凭据)
建议用于远程/公共部署:
AFFINE_MCP_HTTP_HOST=0.0.0.0AFFINE_MCP_HTTP_ALLOWED_ORIGINS=<comma-separated-origins>(适用于浏览器客户端)
可选:
PORT(默认为3000;许多像Render这样的平台会自动注入此内容)AFFINE_WORKSPACE_IDAFFINE_GRAPHQL_PATH(默认为/graphql)AFFINE_MCP_HTTP_ALLOW_ALL_ORIGINS=true(仅测试)
仅限承载模式:
AFFINE_MCP_HTTP_TOKEN=<strong-random-token>(保护/mcp,/sse,/messages)
仅限OAuth模式:
AFFINE_MCP_PUBLIC_BASE_URL=https://mcp.yourdomain.comAFFINE_OAUTH_ISSUER_URL=https://auth.yourdomain.comAFFINE_OAUTH_SCOPES=mcp(默认为mcp)
HTTP身份验证模式
AFFINE_MCP_AUTH_MODE=bearer 保持当前静态承载令牌行为。
BASH``` 1 2 3 4 5 6 7export MCP_TRANSPORT=http export AFFINE_MCP_AUTH_MODE=bearer export AFFINE_API_TOKEN=“your_token…” export AFFINE_MCP_HTTP_HOST=“0.0.0.0” export AFFINE_MCP_HTTP_TOKEN=“your-super-secret-token” export PORT=3000 npm run start:http
`AFFINE_MCP_AUTH_MODE=oauth` 将MCP端点转换为web MCP客户端的OAuth保护资源。在此模式下:
- 服务器公开 `/.well-known/oauth-protected-resource`
- 未认证的 `/mcp` 请求返回 `401` 带着一个 `WWW-Authenticate` 挑战
- `AFFINE_MCP_HTTP_TOKEN` 和 `?token=` 已禁用
- `sign_in` 未注册
- `AFFINE_API_TOKEN` 仍然需要,以便服务器可以调用AFFiNE作为服务凭据
BASH```
1
2
3
4
5
6
7
8
9export MCP_TRANSPORT=http
export AFFINE_MCP_AUTH_MODE=oauth
export AFFINE_API_TOKEN="your-affine-service-token"
export AFFINE_MCP_HTTP_HOST="0.0.0.0"
export AFFINE_MCP_PUBLIC_BASE_URL="https://mcp.yourdomain.com"
export AFFINE_OAUTH_ISSUER_URL="https://auth.yourdomain.com"
export AFFINE_OAUTH_SCOPES="mcp"
export PORT=3000
npm run start:http
OAuth模式注意事项:
- 对非本地部署使用HTTPS
AFFINE_MCP_HTTP_ALLOW_ALL_ORIGINS=true在OAuth模式下被拒绝- 令牌根据发行者发现元数据和JWKS进行验证
- 受保护的资源元数据也在以下位置提供
/.well-known/oauth-protected-resource/mcp用于特定路径的发现 GET /healthz和GET /readyz可用于部署诊断
推荐的预设
本地测试(HTTP模式):
MCP_TRANSPORT=httpAFFINE_MCP_AUTH_MODE=bearerAFFINE_MCP_HTTP_HOST=127.0.0.1AFFINE_MCP_HTTP_TOKEN=<token>(即使在当地也推荐)AFFINE_MCP_HTTP_ALLOWED_ORIGINS=http://localhost:3000(如果从浏览器应用程序进行测试)
Docker/容器运行时:
MCP_TRANSPORT=httpAFFINE_MCP_AUTH_MODE=bearerAFFINE_MCP_HTTP_HOST=0.0.0.0PORT=3000(或集装箱/平台港口)AFFINE_MCP_HTTP_TOKEN=<strong-token>AFFINE_MCP_HTTP_ALLOWED_ORIGINS=<your app origin(s)>
渲染/铁路/VPS(公共端点):
MCP_TRANSPORT=httpAFFINE_MCP_AUTH_MODE=bearer或oauthAFFINE_MCP_HTTP_HOST=0.0.0.0AFFINE_MCP_HTTP_TOKEN=<strong-token>(承载模式)AFFINE_MCP_PUBLIC_BASE_URL=<public base URL>(OAuth模式)AFFINE_OAUTH_ISSUER_URL=<issuer URL>(OAuth模式)AFFINE_MCP_HTTP_ALLOWED_ORIGINS=<your client origin(s)>
当前可用的端点:
/mcp-MCP服务器(流式HTTP)/sse-SSE端点(兼容旧协议)/messages-消息端点(兼容旧协议)/healthz-HTTP活性探测/readyz-HTTP就绪性探测
可用工具
工作区
list_workspaces–列出所有工作区get_workspace–获取工作区详细信息create_workspace–使用初始文档创建工作区update_workspace–更新工作区设置delete_workspace–永久删除工作区list_workspace_tree–以树的形式返回工作区文档层次结构get_orphan_docs–查找未从侧边栏树中的任何父文档链接的文档
组织
list_collections–列出工作区集合get_collection–按id获取收藏create_collection–创建收藏update_collection–重命名集合delete_collection–删除收藏add_doc_to_collection–将文档添加到收藏允许列表中remove_doc_from_collection–从收藏允许列表中删除文档list_organize_nodes–实验性组织/文件夹树转储create_folder–实验性创建根文件夹或嵌套文件夹rename_folder–实验文件夹重命名delete_folder–实验递归文件夹删除move_organize_node–实验文件夹/链接移动add_organize_link–文件夹下的实验文档/标签/收藏链接delete_organize_link–实验文档/标签/收藏链接删除
文件
list_docs–列出带分页的文档(包括node.tags)list_tags–列出工作区中的所有标签search_docs–使用子字符串/前缀/精确匹配、可选标签过滤和updatedAt排序进行快速标题搜索list_docs_by_tag–列出包含所请求标签的文档get_docs_by_tag–通过不区分大小写的标签子字符串发现文档并返回availableTags当没有匹配时get_doc–获取文档元数据get_doc_by_title–按标题查找文档并返回其Markdown内容read_doc–读取文档块内容和纯文本快照(WebSocket)export_doc_markdown–将文档内容导出为markdownpublish_doc–公开文档revoke_doc–撤销公共访问权限create_doc–创建新文档(WebSocket)create_doc_from_markdown–从markdown内容创建文档create_doc_from_template–克隆模板文档,替换{{variables}},并可选择将其链接到父文档下duplicate_doc–将文档克隆到新文档中,可选地在父文档下create_tag–创建可重用的工作空间级别标签add_tag_to_doc–在文档上附加标签remove_tag_from_doc–从文档中分离标签update_doc_title–在工作区元数据和内部页面块中重命名文档append_paragraph–附加段落块(WebSocket)append_block–附加规范块类型(文本/列表/代码/媒体/嵌入/数据库/无边框),并进行严格的验证和位置控制(viewMode=kanban启用预设的备份数据视图;data_view默认为看板)move_doc–通过将文档重新链接到不同的父级下,移动侧边栏中的文档batch_create_docs–一次通话最多可创建20个文档add_database_column–向数据库块添加列(rich-text,select,multi-select,number,checkbox,link,date)add_database_row–向数据库块中添加一行,其值按列名/ID映射(title/Title更新内置行标题)delete_database_row–按行块id从数据库块中删除行read_database_columns–读取数据库模式元数据,包括列ID/类型、选择选项和表视图列映射read_database_cells–使用可选的行/列过滤器读取行标题和解码的数据库单元格值update_database_cell–更新单个数据库单元格或内置行标题(createOption默认为true对于选定字段)update_database_row–批量更新数据库行上的多个单元格(createOption默认为true对于选定字段)append_markdown–将markdown内容附加到现有文档中replace_doc_with_markdown–用markdown内容替换主注释内容list_children–列出从文档链接的直接子文档list_backlinks–列出链接到文档的父文档/参考文档cleanup_orphan_embeds–删除指向缺失文档的链接文档嵌入find_and_replace–在文档中预览或应用文本替换delete_doc–删除文档(WebSocket)
评论
list_comments,create_comment,update_comment,delete_comment,resolve_comment
版本历史
list_histories
用户和代币
current_user,sign_in,update_profile,update_settingslist_access_tokens,generate_access_token,revoke_access_token
通知
list_notifications,read_all_notifications
Blob存储
upload_blob,delete_blob,cleanup_blobs
过滤暴露的工具
用于缩小暴露表面的可选环境变量。
集团层面— AFFINE_DISABLED_GROUPS
| 组名 | 包含的工具 |
|---|---|
workspaces | list_workspaces, get_workspace, create_workspace, update_workspace, delete_workspace |
docs | list_docs, read_doc, search_docs, create_doc, create_doc_from_markdown, create_doc_from_template, duplicate_doc, append_paragraph, append_block, append_markdown, replace_doc_with_markdown, delete_doc, publish_doc, revoke_doc, list_tags, list_docs_by_tag, create_tag, add_tag_to_doc, remove_tag_from_doc, list_workspace_tree, get_orphan_docs, list_children, update_doc_title, get_doc_by_title, get_docs_by_tag, list_backlinks, move_doc, batch_create_docs, cleanup_orphan_embeds, find_and_replace, add_database_column, add_database_row, delete_database_row, read_database_columns, read_database_cells, update_database_cell, update_database_row |
comments | list_comments, create_comment, update_comment, delete_comment, resolve_comment |
history | list_histories |
organize | list_collections, get_collection, create_collection, update_collection, delete_collection, add_doc_to_collection, remove_doc_from_collection, list_organize_nodes, create_folder, rename_folder, delete_folder, move_organize_node, add_organize_link, delete_organize_link |
users | current_user, sign_in, update_profile, update_settings |
access_tokens | list_access_tokens, generate_access_token, revoke_access_token |
blobs | upload_blob, delete_blob, cleanup_blobs |
notifications | list_notifications, read_all_notifications |
JSON``` 1 2 3”env”: { “AFFINE_DISABLED_GROUPS”: “comments,history,blobs,users” }
### 工具级别-- `AFFINE_DISABLED_TOOLS`
按确切名称(逗号分隔)禁用单个工具。
JSON```
1
2
3"env": {
"AFFINE_DISABLED_TOOLS": "delete_workspace,delete_doc"
}
本地使用(克隆)
BASH``` 1 2 3 4 5 6 7 8 9git clone https://github.com/dawncr0w/affine-mcp-server.git cd affine-mcp-server npm install npm run build
Run directly
node dist/index.js
Or expose as a global CLI for Codex/Claude without publishing
npm link
Now use affine-mcp like a global binary
## 质量门
BASH```
1
2
3npm run build
npm run test:tool-manifest
npm run pack:check
tool-manifest.json是公开暴露的工具名称的真实来源。- CI验证了这一点
registerTool(...)声明与清单完全匹配。 - 要进行完整的刀具表面验证,请运行
npm run test:comprehensive(自引导本地Docker AFFiNE堆栈)。 - 对于预先配置的环境,请使用
npm run test:comprehensive:raw. - 要进行完整的环境验证,请运行
npm run test:e2e(Docker+MCP+剧作家)。 - 其他专注跑步者:
npm run test:db-create,npm run test:db-cells,npm run test:db-schema,npm run test:supporting-tools,npm run test:organize,npm run test:bearer,npm run test:http-email-password,npm run test:http-bearer,npm run test:oauth-http,npm run test:doc-discovery,npm run test:cli-version,npm run test:cli-commands,npm run test:cli-live,npm run test:tool-filtering,npm run test:markdown-rich-text-import,npm run test:playwright.
故障排除
认证
- Cloudflare(403“请稍等…”):AFFiNE云(
app.affine.pro)使用Cloudflare保护,阻止通过编程登录/api/auth/sign-in.使用AFFINE_API_TOKEN相反,或运行affine-mcp login它会自动引导您完成正确的方法。电子邮件/密码身份验证仅适用于自托管实例。 - 电子邮件/密码:仅适用于没有Cloudflare的自托管实例。确保您的实例允许密码身份验证,并且凭据有效。
- Cookie:复制Cookie(例如。,
affine_session,affine_csrf)登录后从浏览器DevTools - Token:生成个人访问令牌;确认它没有过期。跑
affine-mcp status测试。 - 启动超时:v1.2.2+包含CLI包装修复和默认异步登录,以避免阻止MCP握手。集
AFFINE_LOGIN_AT_START=sync只有在需要的时候。
连接
- 确认
AFFINE_BASE_URL可以联系到 - GraphQL端点默认值为
/graphql - 检查防火墙/代理规则;验证CORS是否为自托管
未找到方法
- MCP工具名称(例如
list_workspaces)不是JSON-RPC顶级方法名。 - 使用MCP客户端(
tools/list,tools/call)而不是像这样直接发送JSON-RPC调用{\"method\":\"list_workspaces\"}. - 从v1.3.0开始,只公开规范工具名称(传统
affine_*别名已删除)。
工作区可见性
- 此MCP服务器只能访问服务器支持的工作区(AFFiNE云/自托管)。
- 浏览器本地存储工作区是客户端数据,因此它们无法通过服务器GraphQL/Webocket API看到。
安全考虑
- 永不承诺
.env有秘密 - 更喜欢生产中的环境变量
- 定期轮换访问令牌
- 使用HTTPS
- 将凭据存储在机密管理器中
发布说明
- 变更日志: 更改日志.md
- 发行说明: 发布_拒绝.md
- GitHub发布: 发布
贡献
欢迎投稿!
- 阅读
CONTRIBUTING.md - 跑
npm run ci在打开PR之前 - 保持工具更改与同步
tool-manifest.json - 在中使用问题/PR模板
.github/
社区卫生
- 行为准则:
CODE_OF_CONDUCT.md - 安全策略:
SECURITY.md - 贡献指南:
CONTRIBUTING.md
许可证
MIT许可证-有关详细信息,请参阅许可证文件
支持
对于问题和疑问:
- 打开一个问题 GitHub
- 查看AFFiNE文档,网址为https://docs.affine.pro
作者
dawncr0w - GitHub
致谢
- 为 AFFiNE 知识库平台
- 使用 模型上下文协议 规格
- 由…驱动 @模型上下文协议/sdk