关于 Easy Notion Mcp
Easy Notion Mcp 是连接 AI Agent 与 Notion 的 MCP 服务,以 Markdown 作为内容格式,并支持 Notion 内容的读写转换。它提供多种块类型、工具及 CLI 配置档,并支持 stdio 或 HTTP 传输。
主要功能
- 01Markdown 与 Notion 块双向转换
- 02支持 24 种块类型
- 03提供 43 个独立命名工具
- 04支持 API Token 和 OAuth
- 05CLI 配置档及读写权限模式
适用场景
- 01通过 AI Agent 读取和编辑 Notion 页面
- 02以 Markdown 格式写入包含复杂块的内容
- 03按不同权限配置多个 Notion 访问配置档
- 04通过 HTTP 为共享部署提供 Notion 访问
MCP 相关
作为 MCP 服务向兼容客户端提供 Notion 页面与数据库操作。支持使用 API Token 的 stdio 传输,以及 OAuth 或 API Token 的 HTTP 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
42收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 是 | 页面标题 |
| markdown | string | 是 | 页面正文的 Markdown 内容 |
| parent_page_id | string | 否 | 父页面 ID。省略時的解析顺序:NOTION_ROOT_PAGE_ID 环境变量 → 本会话中上次使用的父页面 → 工作区级别的私有页面(OAuth 模式)。在 stdio 模式下,如果未设置 NOTION_ROOT_PAGE_ID,则首次使用时必须提供此参数。 |
| icon | string | 否 | 可选的 emoji 图标 |
| cover | string | 否 | 可选的封面图片 URL |
详细介绍
Easy Notion MCP
以 Markdown 为先的 MCP 服务,可将 AI Agent 连接到 Notion。
Agent 使用 Markdown 编写内容 — easy-notion-mcp 会将其转换为 Notion 的块 API,并可反向转换。
43 个工具 · 24 种块类型 · 与官方 Notion MCP 相比,响应 token 减少约 6–7 倍 · 支持文档化的往返转换
npx easy-notion-mcp
查看实际效果 → 这个 Notion 页面完全通过 easy-notion-mcp 创建和管理。

目录: 对比 · 设置 · CLI 配置文件 · 配置 · 为何以 Markdown 为先 · 工作原理 · 工具 · MCP 资源 · 块类型 · 往返转换 · 数据库 · 操作指南 · 安全 · 稳定性 · 常见问题 · 社区
easy-notion-mcp 与其他 Notion MCP 服务相比如何?
| 功能 | easy-notion-mcp | 官方 Notion MCP(npm) | better-notion-mcp |
|---|---|---|---|
| 内容格式 | ✅ 标准 GFM Markdown | ❌ 原始 Notion API JSON | ⚠️ Markdown(块类型有限) |
| 块类型 | ✅ 24 种(切换列表、分栏、标注、公式、嵌入、表格、文件上传、任务列表) | ⚠️ 全部(以原始 JSON 提供) | ⚠️ 约 7 种(标题、段落、列表、代码、引用、分隔线) |
| 往返转换支持 | ✅ 24 种块类型,并记录了注意事项 | ❌ 原始 JSON 需要重建块 | ⚠️ 不支持的块会被静默丢弃 |
| 工具 | 43 个各自命名的工具 | 18 个根据 OpenAPI 自动生成的工具 | 9 个组合工具(39 项操作) |
| 文件上传 | ✅ 在 Markdown 中使用 file:///path | ❌ 尚未实现的功能请求 | ✅ 5 步生命周期 |
| 提示词注入防护 | ✅ 内容提示前缀 + URL 清理 | ❌ | ❌ |
| 数据库条目格式 | 简单的 {"Status": "Done"} 键值对 | 简化的键值对 | 简化的键值对 |
| 身份验证选项 | API 令牌或 OAuth | API 令牌或 OAuth | API 令牌或 OAuth |
easy-notion-mcp 能节省多少 token?
读取页面内容所需的响应 token 约比官方 Notion MCP 服务少 6–7 倍,因为 Notion 的原始区块 JSON 带有逐区块元数据(区块 ID、时间戳、作者对象),只读取内容的 Agent 根本用不到这些信息。通常可减少约 5–7 倍,代码较多的页面约为 3 倍,内容丰富的页面最高可达 15 倍,同时保留页面中 ≥94% 的内容。该结果是与官方原始 JSON 服务对比得出的;与其他基于 Markdown 的服务大致相当。
节省来自省略元数据,而非编码效率。在信息量相同的情况下,两种格式的成本大致相同(对于完整呈现的页面结构,常见的中间表示比例约为 1.0–1.06 倍;对于典型的散文内容为 1.32 倍),因此节省来自原始 JSON 携带、而读取内容时用不到的逐区块元数据(区块 UUID、时间戳、作者对象、注释包装)。数据库查询在内容完整度相同的情况下也有类似的约 7 倍优势。
方法、各类别结果和所有注意事项:.meta/research/token-bench-results-2026-06-13.md(通过 scripts/bench/lib/recompute-tiers.ts 重新运行)。
如何设置 easy-notion-mcp?
使用 API token
创建一个 Notion 集成,复制 token,并将页面共享给该集成。
Claude Code:
claude mcp add notion -s user \
-e NOTION_TOKEN=ntn_your_integration_token \
-- npx -y easy-notion-mcp
这会将服务注册到 Claude Code 的用户级配置(-s user),并通过 -e 将 NOTION_TOKEN 直接传递给 MCP 子进程。不会修改 shell 环境或 rcfiles——token 保存在 Claude Code 的配置文件中,仅作用于此服务,其他进程无法访问。若要为 create_page 设置默认父页面,请在同一命令中添加 -e NOTION_ROOT_PAGE_ID=<page-id>。
OpenClaw:
openclaw config set mcpServers.notion.command "npx"
openclaw config set mcpServers.notion.args '["-y","easy-notion-mcp"]'
然后在启动 OpenClaw 之前,通过父 shell 环境提供 token:
export NOTION_TOKEN=ntn_your_integration_token
这种 export 写法是适用于任何继承父 shell 环境的 MCP 客户端的通用备用方案。请注意:除非将其添加到 shell rcfile,否则只会在当前 shell 会话中生效;而此举也有其安全影响——专门使用 Claude Code 时,建议优先采用上面的 -e 写法。
Claude Desktop / Cursor / Windsurf — 添加到 MCP 配置文件中:
{
"mcpServers": {
"notion": {
"command": "npx",
"args": ["-y", "easy-notion-mcp"],
"env": {
"NOTION_TOKEN": "ntn_your_integration_token"
}
}
}
}
配置文件位置:Claude Desktop → claude_desktop_config.json · Cursor → .cursor/mcp.json · Windsurf → ~/.windsurf/mcp.json
VS Code Copilot — 添加到 .vscode/mcp.json(使用 servers,而非 mcpServers)
{
"servers": {
"notion": {
"command": "npx",
"args": ["-y", "easy-notion-mcp"],
"env": {
"NOTION_TOKEN": "ntn_your_integration_token"
}
}
}
}
用于低上下文 Notion 访问的 CLI 配置档
当 Agent 需要访问 Notion,但不想加载完整的 MCP 工具集,或希望为不同权限模式使用单独的 Notion 集成时,请使用 easy-notion CLI。配置档默认存放在 ~/.config/easy-notion-mcp/profiles.json,其中引用的是环境变量名称,而非原始 token。
export NOTION_WORK_READONLY=ntn_readonly_token
export NOTION_WORK_WRITE=ntn_readwrite_token
npx -y --package easy-notion-mcp easy-notion profile add work-ro \
--token-env NOTION_WORK_READONLY \
--mode readonly \
--default
npx -y --package easy-notion-mcp easy-notion profile add work-rw \
--token-env NOTION_WORK_WRITE \
--mode readwrite \
--root-page-id your_root_page_id
只读命令可使用只读配置档:
npx -y --package easy-notion-mcp easy-notion --profile work-ro search "roadmap" --filter pages
npx -y --package easy-notion-mcp easy-notion --profile work-ro page read PAGE_ID --include-metadata
npx -y --package easy-notion-mcp easy-notion --profile work-ro content search-in-page PAGE_ID --query "launch" --within-toggle "Script"
修改命令需要使用读写配置档:
npx -y --package easy-notion-mcp easy-notion --profile work-rw content append PAGE_ID --markdown "## Update"
npx -y --package easy-notion-mcp easy-notion --profile work-rw content update-toggle PAGE_ID --title "Script" --markdown-file ./script.md
npx -y --package easy-notion-mcp easy-notion --profile work-rw content archive-toggle PAGE_ID --title "Done"
npx -y --package easy-notion-mcp easy-notion --profile work-rw content restore-toggle ARCHIVED_BLOCK_ID
CLI 的破坏性命令支持通过 --dry-run 进行只读预检。它会在可行时执行相同的查找和 Markdown 验证,返回 would_delete_block_ids、would_update、would_archive 或 would_restore 等计划字段,且不会修改 Notion。
用于 Agent 路由的轻量技能发布在本仓库的 skills/easy-notion-cli/。它会指导 Agent 优先使用 CLI 进行基于配置档的 Notion 访问,而不是注册多个 MCP 服务。
使用 OAuth
API 令牌 + stdio 是门槛较低的默认方案。如果你运行的是共享部署,或希望按用户控制访问权限,OAuth 可以处理身份验证,无需复制粘贴令牌。
启动服务:
npx -p easy-notion-mcp easy-notion-mcp-http
需要设置 NOTION_OAUTH_CLIENT_ID 和 NOTION_OAUTH_CLIENT_SECRET 环境变量。请参阅下文的 OAuth 设置。
Claude Code:
claude mcp add notion --transport http http://localhost:3333/mcp
OpenClaw:
openclaw config set mcpServers.notion.transport "http"
openclaw config set mcpServers.notion.url "http://localhost:3333/mcp"
Claude Desktop:
前往 Settings → Connectors → Add custom connector,输入 http://localhost:3333/mcp。
浏览器将打开 Notion 的授权页面。选择要共享的页面,点击 Allow,即可完成。
手动安装并限定项目范围(高级) — 在项目根目录放置 .mcp.json,按项目注册 easy-notion-mcp
如果你希望按项目注册 easy-notion-mcp,而不是对所有用户生效,请将以下内容粘贴到你的项目根目录中的 .mcp.json 文件:
{
"mcpServers": {
"easy-notion-mcp": {
"command": "npx",
"args": ["-y", "easy-notion-mcp"],
"env": {
"NOTION_TOKEN": "ntn_your_integration_token",
"NOTION_ROOT_PAGE_ID": "your_root_page_id"
}
}
}
}
将占位值替换为你实际的 Notion 集成令牌和(可选)根页面 ID。请注意,此文件应放在你的项目中,而不是此仓库中 — Claude Code 会自动注册在项目范围的 .mcp.json 中找到的任何服务并尝试启动它,因此,如果提交了带有占位凭据的文件,打开仓库时将导致“Failed to connect”。
Dify / n8n / FlowiseAI(基于 Docker 的平台):
在主机上运行 HTTP 服务:
export NOTION_MCP_BEARER=$(openssl rand -hex 32)
NOTION_TOKEN=ntn_your_integration_token \
NOTION_MCP_BIND_HOST=0.0.0.0 \
NOTION_MCP_BEARER=$NOTION_MCP_BEARER \
npx -p easy-notion-mcp easy-notion-mcp-http
在平台的 MCP 服务设置中,使用 host.docker.internal 替代 localhost,并在请求标头中添加 bearer 令牌:
http://host.docker.internal:3333/mcp
Authorization: Bearer <your NOTION_MCP_BEARER value>
为什么不能用 localhost? 这些平台通常在 Docker 中运行。容器内的
localhost指向容器本身,而非主机。host.docker.internal可以连接两者。HTTP 主机和 bearer 令牌: HTTP 服务默认绑定到
127.0.0.1,静态令牌模式需要设置NOTION_MCP_BEARER。host.docker.internal会连接到主机的桥接 IP,因此请在主机上设置NOTION_MCP_BIND_HOST=0.0.0.0,并在每个客户端请求中发送 bearer 标头。OAuth 模式会为每位用户签发 bearer 令牌,可作为共享 Docker 部署的替代方案。
easy-notion-mcp 适用于任何兼容 MCP 的客户端。服务通过 stdio(API 令牌模式)或 HTTP(OAuth 或 API 令牌模式)运行。
如果你在设置过程中有疑问,Discord 社区是提问的好地方。#easy-notion-mcp 频道讨论设置和设计相关问题。Bug 请提交到 GitHub issues。
配置
Stdio 模式(API 令牌)
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
NOTION_TOKEN | 是 | — | Notion API 集成令牌 |
NOTION_ROOT_PAGE_ID | 否 | — | 默认父页面 ID |
NOTION_TRUST_CONTENT | 否 | false | 读取 Markdown 的响应时跳过内容提示(read_page、read_section、read_block、read_toggle) |
关于
.env文件(仅限贡献者): easy-notion-mcp 通过dotenv从当前工作目录加载.env文件。实际上,只有在克隆的仓库副本中运行服务时(执行npm install && npm run build后运行node dist/index.js),.env才会“直接生效”,因为仓库根目录就是当前工作目录。通过npx easy-notion-mcp调用软件包,或从任意目录进行全局安装时,不会加载该文件 — 这是标准的 npm CLI 行为。对于npx方式,请通过上文 Claude Code 设置中的-e标志传递NOTION_TOKEN,或通过 MCP 客户端配置的env块传递。
OAuth / HTTP 传输
运行 npx -p easy-notion-mcp easy-notion-mcp-http,启动支持 OAuth 的 HTTP 服务。
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
NOTION_OAUTH_CLIENT_ID | 是(OAuth 模式) | — | Notion 公共集成的 OAuth 客户端 ID |
NOTION_OAUTH_CLIENT_SECRET | 是(OAuth 模式) | — | Notion 公共集成的 OAuth 客户端密钥 |
PORT | 否 | 3333 | HTTP 服务端口 |
OAUTH_REDIRECT_URI | 否 | http://localhost:{PORT}/callback | OAuth 回调 URL |
NOTION_MCP_BIND_HOST | 否 | 127.0.0.1 | 绑定地址。默认仅绑定环回地址;设为 0.0.0.0 可供网络访问,也可设置为特定接口,例如 192.168.1.5。 |
NOTION_MCP_BEARER | 是(静态令牌模式) | — | 静态令牌 HTTP 模式下,客户端必须提供的共享密钥 Bearer。未设置时,服务拒绝启动。OAuth 模式下不需要。 |
要获取 OAuth 凭据,请在 notion.so/profile/integrations 创建一个公共集成,并将 http://localhost:3333/callback 配置为重定向 URI。
在 OAuth 模式下,无需设置 NOTION_ROOT_PAGE_ID 即可使用 create_page——默认会在用户的私人工作区分区中创建页面。
HTTP 模式的安全状况
HTTP 传输面向可信网络:使用 Bearer 密钥进行单人自托管,或通过 OAuth 进行共享部署。它并未针对直接暴露到开放互联网的情况进行加固;如果需要远程访问,请在前面部署支持 TLS 的反向代理。
静态令牌模式必须设置 Bearer。 如果仅设置 NOTION_TOKEN,运行 npx -p easy-notion-mcp easy-notion-mcp-http 时服务将拒绝启动。请在服务的环境中设置共享密钥 Bearer,然后配置 MCP 客户端在每个 /mcp 请求中通过 Authorization: Bearer <secret> 发送该密钥:
export NOTION_MCP_BEARER=$(openssl rand -hex 32)
NOTION_TOKEN=ntn_your_integration_token npx -p easy-notion-mcp easy-notion-mcp-http
Bearer 会使用 crypto.timingSafeEqual 进行比较。缺少 Bearer 或 Bearer 不正确时,会返回 401 { "error": "invalid_token" }。如需轮换密钥,请使用新值重启服务。
默认绑定地址为环回地址。 服务默认绑定到 127.0.0.1——仅本地进程可访问。设置 NOTION_MCP_BIND_HOST=0.0.0.0 可暴露所有接口,也可设置为特定 IP,例如 192.168.1.5,以仅暴露一个接口。无论绑定地址如何,都必须设置 Bearer。
始终要求 Bearer 是信任边界。 /mcp 端点未启用 DNS 重绑定保护,OAuth 注册和令牌端点(/register、/token、/revoke)的 CORS 策略也较宽松。请将 Bearer(或 OAuth 的用户专属 Bearer)视为网络与 Notion 工作区之间唯一的防线。即使仅绑定环回地址,也请始终设置 Bearer。如果需要将此服务暴露到可信网络之外,请将它置于能够处理 TLS 和来源检查的反向代理之后。
多用户/远程场景使用 OAuth。 OAuth 会强制执行用户专属的 Bearer 验证;OAuth 模式下无需设置 NOTION_MCP_BEARER。对于共享部署,OAuth 的用户专属身份模型更合适——静态令牌 + Bearer 适用于单人自托管。
file:// 上传仅支持 stdio。 通过 HTTP 传入的 Markdown 中,如果 create_page、append_content、replace_content、update_section 或 update_page.cover 使用了 file:// URL,请求将被拒绝。本地文件工作流请使用 stdio 模式(create_page_from_file 也仅支持 stdio),或者将文件托管在 HTTPS URL 上,并在 Markdown 中使用该 URL。

为什么采用 Markdown 优先?
官方 Notion MCP npm 包会返回原始 API JSON——深度嵌套的区块对象,每个区块约包含 120 个令牌的元数据。其他服务会转换为 Markdown,但只支持少数几种区块类型,且会静默丢弃提示框、折叠内容、表格、公式等。
easy-notion-mcp 使用 Agent 已经熟悉的标准 GFM Markdown。无需学习新内容,也没有自定义标签语法或需要构造的区块对象。Agent 编写 Markdown,easy-notion-mcp 负责将其转换为 Notion 的区块 API,也能反向转换,并保留 24 种区块类型。
这意味着 Agent 可以编辑现有内容。读取页面,获取 Markdown,修改字符串,再写回去。此服务所表示的区块类型,其支持的格式和结构都会得到保留;已知的缺失和降级情况则在下文说明。Agent 像编辑代码一样,以文本形式编辑 Notion 页面。
easy-notion-mcp 如何工作?
页面——读写 Markdown:
create_page({
title: "Sprint Review",
markdown: "## Decisions\n\n- Ship v2 by Friday\n- [ ] Update deploy scripts\n\n> [!WARNING]\n> Deploy window is Saturday 2–4am only"
})
读回内容——得到相同的 Markdown:
read_page({ page_id: "..." })
{ "markdown": "## Decisions\n\n- Ship v2 by Friday\n- [ ] Update deploy scripts\n\n> [!WARNING]\n> Deploy window is Saturday 2–4am only" }
修改字符串后调用 replace_content 即可。也可以通过标题名称使用 update_section 定位单个章节,或使用 find_replace 精准替换内容,而不影响页面的其他部分。还可以通过 create_page 或 update_page 为页面设置表情符号图标和封面图片。
数据库——写入简单的键值对:
add_database_entry({
database_id: "...",
properties: { "Status": "Done", "Priority": "High", "Due": "2026-05-15", "Tags": ["v2", "launch"] }
})
无需属性类型对象,也无需嵌套的 { select: { name: "Done" } } 包装结构。easy-notion-mcp 会在运行时获取数据库架构并自动转换。Agent 只需传入 { "Status": "Done" },其余工作由 easy-notion-mcp 完成。
错误信息会告诉你如何修复。 标题名称错误时,会返回可用标题。找不到页面时,会建议将页面共享给集成。筛选条件错误时,会提示你先调用 get_database。Agent 无需向用户求助即可自行纠正。
复杂内容也能正常处理。 嵌套折叠内容、包含混合内容类型的列(列表 + 代码块 + 引用块)、深层列表嵌套,以及完整的 Unicode 字符集(日语、中文、阿拉伯语、表情符号)均通过了往返转换测试。update_section 的标题搜索不区分大小写,找不到标题时会返回可用标题。add_database_entries 会处理部分失败,并分别返回成功和失败的条目,方便 Agent 只重试失败项。

easy-notion-mcp 提供哪些工具?
easy-notion-mcp 提供 7 个类别的 43 个独立命名工具(HTTP 方式提供 42 个,不包括仅限 stdio 的 create_page_from_file)。工具描述会在正文中保留安全关键行为,并指向 MCP 资源,以查阅更详细的参考资料,例如 Markdown 语法、警告格式、属性分页和 update_data_source 示例。
页面(20 个工具)
| 工具 | 描述 |
|---|---|
create_page | 根据 markdown 创建页面 |
create_page_from_file | 根据本地 markdown 文件创建页面(仅 stdio) |
read_page | 以 markdown 格式读取页面 |
read_section | 根据标题名称读取一个章节 |
read_block | 根据 ID 读取一个区块,包括容器中的嵌套子项 |
read_toggle | 根据标题读取一个折叠项或可折叠标题 |
search_in_page | 在页面或一个折叠项中搜索原始区块文本 |
append_content | 向页面追加 markdown |
replace_content | 原子性地替换页面的所有内容(保留匹配区块的 ID) |
update_section | 根据标题名称更新章节;可选择保留标题并替换正文(具有破坏性;对于不可替代的内容,请先使用 duplicate_page) |
update_toggle | 根据标题更新一个折叠项的正文(具有破坏性;保留折叠容器 ID) |
archive_toggle | 归档一个折叠项或可折叠标题 |
restore_toggle | 根据已归档的区块 ID 恢复折叠项或可折叠标题 |
find_replace | 查找并替换文本,同时保留文件 |
update_block | 根据 ID 更新单个区块(保留区块身份,以供深层链接和评论使用) |
update_page | 更新标题、图标或封面 |
duplicate_page | 复制页面及其内容 |
archive_page | 将页面移至垃圾箱 |
move_page | 将页面移至新的父级 |
restore_page | 恢复已归档的页面 |
具有破坏性的工具支持将 dry_run: true 用作预检。试运行不会上传或验证本地 file:// markdown 上传内容,因为这会创建 Notion 上传项;对于本地文件,请使用 HTTPS URL,或在不试运行的情况下执行。
replace_content 试运行会转换 markdown 并返回转换器警告,但由于它不会调用 Notion 的更新端点,因此无法显示 Notion 端的 unmatched_blocks 或 truncated 字段。
restore_toggle 特意采用基于 ID 的方式:请传入 archive_toggle 返回的已归档区块 ID。Notion 不会提供已归档子项的枚举功能来进行标题搜索,也不支持 read_page include_archived 工作流,因此无法按标题恢复。
导航(3 个工具)
| 工具 | 描述 |
|---|---|
list_pages | 列出父级下的子页面,每行包含 created_time 和 last_edited_time |
search | 搜索页面和数据库 |
share_page | 获取可分享的 URL |
每个 list_pages 行都会返回 id、title、created_time 和 last_edited_time,因此 Agent 无需逐页查询,就能区分活跃页面和过时页面。时间戳直接来自 Notion,精确到分钟;页面内容和属性的编辑都会更新 last_edited_time。请注意,它与 search 有意采用不同的格式:search 返回的 last_edited 仅包含日期,而 list_pages 返回的 last_edited_time 是完整的 ISO-8601 时间戳。
数据库(9 个工具)
| 工具 | 描述 |
|---|---|
create_database | 创建具有类型化架构的数据库 |
update_data_source | 更新数据库架构(添加、重命名或移除属性;更改标题;移至废纸篓或恢复) |
get_database | 获取数据库架构、属性名称和选项 |
list_databases | 列出集成可访问的所有数据库 |
query_database | 使用筛选条件、排序或文本搜索进行查询 |
add_database_entry | 使用简单的键值对添加一行 |
add_database_entries | 一次调用添加多行 |
update_database_entry | 使用简单的键值对更新一行 |
delete_database_entry | 删除(归档)数据库条目 |
数据库写入工具遇到未知属性名称和不支持的属性类型时,会返回明确错误,而不会静默丢弃。 请先调用
get_database确认属性名称和类型。支持写入的属性类型:title、rich_text、number、select、multi_select、date、checkbox、url、phone、status、relation、people。对于people,请传入单个用户 ID 字符串或用户 ID 数组。计算类型(formula、rollup、unique_id、created_time、last_edited_time、created_by、last_edited_by)由 Notion 填充,无法通过 API 设置。对于files、verification、place、location和button,写入值也会被拒绝。对于关系写入,请传入单个页面 ID 字符串("Projects": "page-id")或数组("Projects": ["id-a", "id-b"]);空数组会清除关系。
easy-notion-mcp 会获取数据库架构,将值映射为 Notion 的属性格式,并在 Agent 传入 { "Status": "Done" } 这样的简单键值对时自动处理类型转换。架构会缓存 5 分钟,以避免批量操作期间重复调用 API。
视图(6 个工具)
| 工具 | 描述 |
|---|---|
list_views | 列出数据库或数据源的已保存视图 |
get_view | 获取一个已保存视图的原始配置 |
query_view | 通过已保存视图查询条目 |
create_view | 创建表格、列表、看板、日历、图库或时间线视图 |
update_view | 重命名已保存视图,或更新其原始筛选、排序和配置字段 |
delete_view | 在明确确认后删除已保存视图 |
评论(2 个工具)
| 工具 | 描述 |
|---|---|
list_comments | 列出页面上的评论 |
add_comment | 向页面添加评论 |
用户(2 个工具)
| 工具 | 描述 |
|---|---|
list_users | 列出工作区用户 |
get_me | 获取当前机器人用户 |
服务(1 个工具)
| 工具 | 描述 |
|---|---|
get_config | 报告服务自身的设置:版本、传输方式、工作区根目录和可见工具数量 |
当文件路径或配置错误让你无从判断时,可以调用 get_config。create_page_from_file 只接受工作区根目录内的路径;如果路径超出该范围,现在的拒绝消息会指出解析后的根目录。get_config 可让你直接读取该根目录,无须推断。在 HTTP 模式下,工作区根目录不适用,因此路径字段为 null,状态为 not_applicable;服务绝不会向 HTTP 调用方报告主机路径。
有哪些 MCP 资源可用?
支持 MCP Resources 的客户端可按需读取这些文档,无须将所有参考资料都加载到每个工具描述中:
| 资源 URI | 内容 |
|---|---|
easy-notion://docs/markdown | 页面写入和读取支持的 Markdown 语法 |
easy-notion://docs/warnings | 警告代码和响应结构 |
easy-notion://docs/property-pagination | 长属性的 max_property_items 行为 |
easy-notion://docs/update-data-source | update_data_source 的负载模式、示例和架构安全说明 |
easy-notion-mcp 支持哪些块类型?
easy-notion-mcp 通过标准 Markdown 语法支持 24 种 Notion 块类型,并扩展了适用于切换块、分栏和标注块等 Notion 专属块的约定。Agent 可以编写熟悉的 Markdown,easy-notion-mcp 会负责与 Notion 块格式之间的转换。
标准 Markdown
| 语法 | Markdown |
|---|---|
| 标题 | # H1 ## H2 ### H3 |
| 粗体、斜体、删除线 | **bold** *italic* ~~strike~~ |
| 行内代码 | `code` |
| 链接 | [text](url) |
| 图片 |  |
| 项目符号列表 | - item |
| 编号列表 | 1. item |
| 任务列表 | - [ ] todo / - [x] done |
| 引用块 | > text |
| 代码块 | ```language |
| 表格 | 标准管道符表格语法 |
| 分隔线 | --- |
Notion 专属语法
| 块 | 语法 |
|---|---|
| 切换块 | +++ Title ... +++ |
| 分栏 | ::: columns / ::: column ... ::: |
| 标注块(注释) | > [!NOTE] |
| 标注块(提示) | > [!TIP] |
| 标注块(警告) | > [!WARNING] |
| 标注块(重要) | > [!IMPORTANT] |
| 标注块(信息) | > [!INFO] |
| 标注块(成功) | > [!SUCCESS] |
| 标注块(错误) | > [!ERROR] |
| 公式 | $$expression$$ |
| 目录 | [toc] |
| 嵌入 | [embed](url) |
| 书签 | 单独一行的裸 URL |
| 文件上传(图片) |  |
| 文件上传(文件) | [name](file:///path/to/file.pdf) |
换行与 collapse_soft_wraps
默认情况下,段落中的单个换行会原样写入。因此,按固定列宽硬换行的 Markdown(大多数代码库采用的惯例)会带着这些换行进入 Notion。此默认行为没有改变。
每个 Markdown 写入工具都接受可选参数 collapse_soft_wraps: true,它会改用 CommonMark 软换行语义:段落中的单个换行会变为空格,因此硬换行的文件会以连贯段落的形式进入 Notion。空行仍会分隔块,围栏代码块在两种模式下都不受影响。
easy-notion page create-from-file --title "Design notes" --file ./NOTES.md --collapse-soft-wraps
重新上传从 Notion 读回的内容时,不要使用此参数,否则有意保留的换行会丢失。
显式硬换行(行尾反斜杠或两个行尾空格)无论是否设置此参数,行为都相同,但不同写入路径的处理方式有所不同:
| 写入路径 | 硬换行行为 |
|---|---|
create_page、create_page_from_file、append_content、update_section、update_toggle、update_block | 保留在块内 |
replace_content | Notion 的 Enhanced Markdown 导入会将段落内的换行渲染为单独的段落,因此硬换行会变成段落分隔 |
这种差异是导入路径造成的,与 collapse_soft_wraps 无关。
标题与开头 H1 重复
create_page 和 create_page_from_file 接受可选参数 strip_leading_h1: true,用于移除文档开头的 H1,避免以与传入 title 相同标题开头的文件在页面中重复显示该标题。仅当转换后的第一个顶层块是普通(不可切换的)heading_1 时,此参数才会生效;默认值为 false。
easy-notion page create-from-file --title "Design notes" --file ./NOTES.md --strip-leading-h1
create_page、create_page_from_file、append_content、replace_content、update_section 和 update_toggle 接受 return_block_map: false,以便在不需要时省略 block_map;默认值仍为 true,未发生变化。
我可以在保留格式的情况下读取和重写页面吗?
可以,适用于此服务支持的 Markdown 约定。往返支持涵盖 24 种块类型。已记录已知的遗漏和格式降级,其中许多会通过明确的警告报告。
read_page 返回 create_page 接受的 Markdown 约定:标题、列表、表格、提示框、折叠块、分栏、公式和页面提及。
当页面包含此服务尚未表示的 Notion 块类型(例如 synced_block、child_database、child_page 或 link_to_page)时,read_page 会在 warnings 字段中包含代码为 omitted_block_types 的警告,列出被省略的块 ID 和类型。通过 replace_content 将该 Markdown 写回会删除这些块,因此此警告可帮助 Agent 避免不安全的重写。对于行内页面提及,请使用 @[Title](notion-url),它与 link_to_page 块类型是不同的结构。
Notion AI 会议记录块(以及已弃用的 transcription 块)会渲染为合成折叠块,其中包含标题、可选的录制时间戳,以及 ## Summary / ## Notes 部分;只有在设置 read_page include_transcript: true 时才会包含转录文本。这类渲染读取会发出 read_only_block_rendered 警告,提示将 Markdown 写回会把原生会议块替换为普通块。
有些格式降级不会通过警告报告。在 replace_content 路径中,书签和嵌入内容会以裸 URL 写入(会发出警告),而 file、audio 和 video 块会被静默简化为 URL。Markdown 无法表示下划线和文本颜色注释,因此读取和写入时都会静默丢弃这些注释。
easy-notion-mcp 让 Agent 能够读取页面、修改 Markdown 字符串,再将其写回,同时保留受支持的格式、结构和内容。无需格式转换,也无需重建块。Agent 编辑 Notion 页面时,就像编辑代码一样,以文本形式进行操作。
find_replace 和 replace_content 有什么区别?
easy-notion-mcp 提供了三种适用于不同场景的编辑策略:
replace_content— 将页面上的全部内容替换为新的 Markdown。最适合完整重写。update_section— 替换通过标题名称指定的单个部分。默认情况下,替换 Markdown 包含该标题,并替换整个部分。传入preserve_heading: true(或 CLI--preserve-heading)可保留现有标题块的 ID、文本、类型、评论和可折叠状态,同时仅破坏性地替换该部分的正文。find_replace— 在页面任意位置查找并替换特定文本,同时保留所有其他内容和附件。最适合精细修改。
如果需要先获取预检响应,而不是直接执行修改,请在 MCP 工具中传入 dry_run: true,或在 CLI 中传入 --dry-run,再进行破坏性编辑。
easy-notion-mcp 如何处理数据库?
easy-notion-mcp 提供 9 种数据库工具,可抽象处理 Notion 复杂的属性格式。Agent 只需传入简单的键值对,例如 { "Status": "Done", "Priority": "High" };easy-notion-mcp 会在运行时获取数据库架构,将其缓存 5 分钟,并自动转换为 Notion 的属性格式。
easy-notion-mcp 支持使用类型化架构创建和更新数据库、通过筛选条件和排序进行查询,以及通过 add_database_entries 执行批量操作(一次调用添加多行)。
食谱:为你的 Agent 准备的实用方案
这些实用方案可让你的 Agent 使用 Notion。智能由 Agent 负责;easy-notion-mcp 通过现有 MCP 工具提供确定性的连接支持,因此这些方案可按需运行,无需额外安装。它们免费且自主:使用你自己的 Agent 和令牌,无需 OAuth 的 API 令牌设置,以及免费套餐数据库查询。
这些步骤可通过 MCP 工具或 claude.ai 连接器运行,前提是已启用相应工具。方案 2 也可通过 skills/easy-notion-cli/ 中的 easy-notion CLI 技能运行;方案 1 需要 create_database、通过 search_in_page 查找源区块,以及结构化去重筛选,而当前 CLI 功能尚未提供完整工作流。Claude Code Agent 可以使用 skills/notion-recipes/ 中的操作技能。
方案 1:将会议记录转为行动事项
此方案可将会议记录页面或粘贴的记录转为「行动事项」数据库中去重后的行。工具调用顺序为:先运行一次 create_database,之后每次运行时,如果来源是页面,则调用 read_page;调用 search_in_page 解析每个事项的源区块 ID;针对每个候选事项,使用精确的 Item Key 筛选条件调用 query_database;为新行调用 add_database_entry 或 add_database_entries;最后调用 query_database 验证。
一次已验证的实际运行从规划会议记录中生成了 5 行。缺失的负责人和截止日期存储在 Flags 多选属性中,而非 Source 中;query_database 筛选条件 {"property":"Item Key","rich_text":{"equals":"38bbe876-242f-81f1-97b7-df935d050a24:38bbe876-242f-81c9-86c6-d9a792fc70b7"}} 恰好返回了 1 行。对同一份记录运行两次后,行数仍为 5,且没有重复项。由于自由文本搜索也会扫描 Source,搜索共享的会议名称会返回所有行,因此此方案使用精确的 Item Key 筛选条件进行去重。
安全边界:方案 1 可安全重复运行且具有幂等性,因为 Item Key 存储的是源行稳定的 Notion 标识(<pageId>:<blockId>),而非行动事项的措辞。
claude.ai 连接器用户的复制粘贴内容,方案 1
Use the enabled easy-notion or Notion connector tools to turn my meeting notes into an Action Items database.
Note: the simple {"Property":"Value"} write format below assumes the easy-notion tools. If only the official Notion connector is enabled, wrap each value in its Notion property-type object instead.
Inputs I will provide:
- Meeting notes page or pasted meeting notes: <MEETING_NOTES_PAGE_OR_TEXT>
- Parent page for the database, if a new database is needed: <PARENT_PAGE>
- Existing Action Items database, if one already exists: <DATABASE_NAME_OR_ID>
If an Action Items database does not already exist, create one with these properties:
- Name: title
- Item Key: rich_text
- Owner: rich_text
- Due: date
- Status: status
- Flags: multi_select
- Source: rich_text
Read the meeting notes or use the pasted notes. Extract only discrete action items. For each item, derive:
- Name: the action text
- Owner: the named assignee, or blank
- Due: the stated date as ISO YYYY-MM-DD, or blank
- Item Key: the source line's stable identity, formatted as <sourcePageId>:<sourceBlockId>
- Source: the meeting title plus date, with no flags stashed here
- Status: Not started
- Flags: add needs-owner if no owner, and needs-due if no due date
Resolve sourceBlockId with search_in_page. read_page returns markdown without block IDs. For a Notion-page source, call read_page to extract items, then for each item call search_in_page with a verbatim, distinctive substring of that item's original source line. Use the matches[].block_id whose text is that source line. If several blocks match, use a longer verbatim substring to isolate one block. For pasted notes, first save them as a Notion page with create_page, then proceed through search_in_page. Do not rely on block IDs from create_page, which returns only {id,title,url}. If one source line contains multiple distinct actions, append a stable ordinal suffix in source order, such as :1 or :2, to keep keys unique.
Before inserting each item, dedupe with an exact Item Key filter:
{"property":"Item Key","rich_text":{"equals":"<that item's key>"}}
If the query returns no results, insert the row with simple key-value properties. If it returns a result, skip that item. Do not dedupe with free-text database search, because text search also scans Source and can false-match every row from the same meeting.
After inserting, query the database and summarize the rows created and skipped.
Re-running is safe and idempotent because the exact Item Key filter uses the source line's stable Notion identity, not the action wording.
方案 2:批量编辑、查找替换和修复
此方案涵盖两种 Agent 可以迭代处理、突破 Notion 原生限制的场景:数据库属性修复和页面正文查找替换。数据库修复的调用顺序为:get_database、遍历所有行调用 query_database、构建规范化映射、对需要修复的行调用 update_database_entry,然后重新查询。页面文本的调用顺序为:使用 dry_run: true 调用 find_replace,使用 replace_all: true 调用 find_replace,然后调用 read_page 验证。
一次已验证的实际数据库修复将 4 行中混用的 Eng 和 engineering 值统一为同一个选项,同时未更改其他无关行。一次已验证的实际页面编辑替换了段落和标题正文中的 4 处内容。注意:select 和 status 选项匹配不区分大小写,写入时会采用最早创建的选项所用的大小写形式。如果已存在小写形式,写入首字母大写的版本时会复用已有的小写选项。若要强制使用特定大小写,请在 Notion 界面中重命名选项,而不要写入新的大小写形式。
claude.ai 连接器用户的复制粘贴内容,方案 2
Use the enabled easy-notion or Notion connector tools to repair Notion database rows or replace repeated text in a Notion page.
Note: the simple {"Property":"Value"} write format below assumes the easy-notion tools. If only the official Notion connector is enabled, wrap each value in its Notion property-type object instead.
Inputs I will provide:
- Target database for property repair: <DATABASE_NAME_OR_ID>
- Property to normalize: <PROPERTY_NAME>
- Normalization map, for example {"Eng":"Engineering","engineering":"Engineering"}
- Target page for find-replace, if needed: <PAGE_NAME_OR_ID>
- Find text and replacement text, if needed: <FIND_TEXT> -> <REPLACE_TEXT>
For database property repair:
1. Get the database schema so you know the exact property names. If select or status options are missing from the schema, query live rows and read the current values from the results.
2. Query the database rows. If the database is large, page through all results in a loop.
3. Build or use the normalization map I provide.
4. For each row whose property value needs fixing, update that row with a simple key-value map such as {"<PROPERTY_NAME>":"<CANONICAL_VALUE>"}.
5. Re-query the database and summarize how many rows changed and which values remain.
Important caveat: select and status option matching is case-insensitive, and writes snap to the earliest-existing option's casing. If a lowercase variant already exists, writing a capitalized version may reuse the lowercase option. To force specific casing, I need to rename the option in Notion's UI.
For page-body find-replace:
1. Run a dry-run find-replace with replace_all enabled and report the match count before changing anything.
2. If the match count is expected, run find-replace with replace_all enabled.
3. Read the page afterward and verify the replacement.
安全性和提示词注入怎么办?
easy-notion-mcp 为生产部署提供了两层安全防护:
提示词注入加固: Markdown 读取响应(read_page、read_section、read_block 和 read_toggle)包含内容提示前缀,指示 Agent 将 Notion 数据视为内容,而非指令。search_in_page 返回原始片段/文本,也应以同样方式处理。这可以降低页面内容左右 Agent 行为的风险;最终行为取决于模型和客户端。如果你控制该工作区,可设置 NOTION_TRUST_CONTENT=true 来停用 Markdown 提示。
URL 清理: javascript:、data: 和其他不安全的 URL 协议会被剥除,并以纯文本形式呈现。仅允许使用 http:、https: 和 mailto:。

稳定性和版本控制
easy-notion-mcp 遵循语义化版本控制。自 1.0.0 起,公开契约已冻结,仅允许增量变更:工具名称、工具输入 架构、工具返回结构、自定义 Markdown 约定以及 警告代码词汇,在未来发布 2.0 版本之前都不会发生破坏性变更。 增量变更(新增工具、新的可选参数、新的可选响应字段、新的警告代码)不属于破坏性变更,可以在次要版本中发布。
有两个方面不在此冻结范围内:OAuth / HTTP 身份验证契约仍属实验性功能,可能会随着安全机制的完善而发生变化;easy-notion CLI 尚未达到 1.0 版本,因此也不在此范围内。完整的契约声明和各版本历史请参见
CHANGELOG。
常见问题
easy-notion-mcp 与官方 Notion MCP 服务有何不同?
官方 Notion MCP npm 包(@notionhq/notion-mcp-server)是一个原始 API 代理,会返回未经修改的 Notion JSON,因此读取页面所需的响应令牌大约是 easy-notion-mcp 返回 Markdown 的 6–7 倍。easy-notion-mcp 会将所有内容转换为 Agent 已熟悉的标准 GFM Markdown,支持 24 种块类型并记录往返转换的注意事项,还包含提示词注入加固。Notion 还提供了单独托管的远程 MCP 服务(基于 OAuth),使用基于自定义 HTML 标签的 Markdown 格式;而 easy-notion-mcp 使用标准 Markdown 语法。
easy-notion-mcp 适用于哪些 MCP 客户端?
easy-notion-mcp 适用于任何兼容 MCP 的客户端,包括 Claude Desktop、Claude Code、Cursor、VS Code Copilot、Windsurf 和 OpenClaw。它同时支持 stdio 传输(API 令牌)和 HTTP 传输(OAuth)。请参阅设置说明,其中提供了各客户端可直接复制粘贴的配置。
easy-notion-mcp 支持上传文件吗?
支持。easy-notion-mcp 使用 Markdown 语法中的 file:/// 协议上传文件。使用  上传图片,使用 [name](file:///path/to/file.pdf) 上传文件。
easy-notion-mcp 能处理嵌套和复杂内容吗?
能。针对以下受支持的结构进行了往返测试:嵌套在其他切换块中的切换块、包含混合内容类型的分栏(不同栏中有列表、引用块和代码块)、嵌套的项目符号列表和编号列表,以及对包括日语、中文、俄语、阿拉伯语和表情符号在内的完整 Unicode 字符集的支持。
easy-notion-mcp 能处理批量操作中的部分失败吗?
能。add_database_entries 会分别返回 succeeded 和 failed 数组。如果某条目未通过验证,其他条目仍会创建。Agent 可以只重试失败的条目,而不必重新发送整个批次。
社区
我们有一个社区 Discord,地址为 discord.gg/S8cghJSVBU。#easy-notion-mcp 频道用于讨论设置问题和设计方案,服务器的其他部分则开放给大家展示分享或进行一般交流。如需反馈 Bug 或提交具体的功能请求,GitHub issues 仍是首选渠道。
贡献
欢迎通过 GitHub 提交问题和 PR。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。