我构建了一个 AI 代理,自动在 Notion 中撰写我的每日站会
发布: (2026年3月16日 GMT+8 11:06)
6 分钟阅读
原文: Dev.to
Source: Dev.to
它每天的工作
- 获取任务 – 读取你的 Notion 任务数据库,查找昨天完成的任务以及今天仍在进行的任务。
- 生成摘要 – 使用 Claude 创建简洁的 Yesterday / Today / Blockers(昨天/今天/阻碍)摘要。
- 写入页面 – 通过 Notion MCP 服务器,自动将精美排版的站立会议页面写回你的 Notion 工作区。
- 通知 – 将摘要发布到 Discord,让团队保持同步。
无需表单。无需复制粘贴。只需打开 Notion,你的站立会议就已经在那里。
架构图
┌─────────────────────────────────────────────────────────────┐
│ Notion of Progress │
│ │
│ 1. Fetch Tasks 2. Generate Summary 3. Write Page │
│ ───────────── ───────────────── ──────────────── │
│ Notion Task DB → Claude API → Notion MCP →│
│ (typed client) (Sonnet 4.6) (Opus 4.6 │
│ Agent SDK)│
│ │
│ 4. Notify ↓ │
│ Discord Webhook │
└─────────────────────────────────────────────────────────────┘Example result in Notion
Block
Content| 📊 | 3 已完成 · 4 正在进行 · 1 阻碍 |
|---|---|
| ✅ Yesterday | 带有直接链接的已完成任务的项目符号 |
| 🔨 Today | 带有直接链接的正在进行任务的项目符号 |
| 🚧 Blockers | 如果存在阻碍则使用红色提示,否则使用灰色提示 |
Repository
GitHub:
该项目使用 TypeScript 构建,采用 ports‑and‑adapters 架构;核心领域对 Notion、Claude 或任何外部系统一无所知。
src/
├── core/
│ ├── domain/types.ts ← TaskSummary, StandupSummary
│ ├── ports/ ← 纯接口,无依赖
│ └── standup.ts ← StandupService 编排器
└── adapters/
├── notion/
│ ├── NotionTaskRepository.ts ← 读取任务数据库
│ └── NotionStandupRepository.ts ← 写入站会页面
├── claude/
│ └── ClaudeSummaryGenerator.ts ← 调用 Claude API
├── mcp/
│ └── McpStandupAgent.ts ← Claude Agent SDK + Notion MCP
└── discord/
└── DiscordNotifier.ts ← 推送至 Discord webhook关键文件 – McpStandupAgent.ts
export async function runMcpStandupAgent({ verbose = false, dryRun = false } = {}) {
// Phase 1: fetch tasks via typed Notion client (reliable)
const { completed, active } = await taskRepo.fetchTasks();
// Phase 2: generate summary with Claude
const summary = await summarizer.generateSummary(completed, active);
// Phase 3: write the page autonomously via Notion MCP
const url = await writeStandupViaMcp(summary, completed, active, verbose);
// Phase 4: notify Discord
await notifyDiscord(summary, url, todayFormatted());
return url;
}Phase 3 是 Claude Opus 4.6 代理接管的地方。它不再使用手写的 Notion API 调用,而是通过 MCP 工具自主在工作区中导航,决定是创建新页面还是更新已有页面,删除陈旧块并追加新内容。
使用 --verbose 运行可实时观察 Claude 的思考过程:
🔧 [MCP] [NOTION API] Post Search
💭 [Claude] A page already exists for today. I'll update it instead of creating a new one.
🔧 [MCP] [NOTION API] Get Block Children
🔧 [MCP] [NOTION API] Patch Page
💭 [Claude] Properties updated. Now deleting 14 old blocks...
🔧 [MCP] [NOTION API] Delete A Block
🔧 [MCP] [NOTION API] Delete A Block
...
🔧 [MCP] [NOTION API] Patch Block Children
💭 [Claude] Done! Here's the standup page: https://notion.so/...为什么 MCP 很重要
传统方法(手写胶水代码)
// Traditional: you write every API call by hand
const existing = await notion.databases.query({ database_id, filter });
if (existing.results.length > 0) {
const blocks = await notion.blocks.children.list({ block_id });
await Promise.all(
blocks.results.map(b => notion.blocks.delete({ block_id: b.id }))
);
await notion.pages.update({ page_id, properties });
await notion.blocks.children.append({ block_id, children });
} else {
await notion.pages.create({ parent, properties, children });
}MCP 方法(Claude 驱动)
// MCP approach: Claude navigates the Notion API autonomously
for await (const message of query({
prompt: `Write today's standup page in the Standup Log DB.
Check if a page exists for ${todayISO()} — update it if so, create it if not.
Use callout blocks with these sections: Yesterday, Today, Blockers.`,
options: {
mcpServers: {
notion: {
command: 'npx',
args: ['-y', '@notionhq/notion-mcp-server'],
env: {
OPENAPI_MCP_HEADERS: JSON.stringify({
Authorization: `Bearer ${NOTION_API_KEY}`,
'Notion-Version': '2022-06-28',
}),
},
},
},
allowedTools: ['mcp__notion__*'],
permissionMode: 'acceptEdits',
},
})) { /* … */ }好处
| 功能 | 传统方式 | MCP |
|---|---|---|
| 幂等性 | 需要手动检查 | Claude 自动检查今天的页面是否存在并自动更新 |
| 对 API 变更的弹性 | 模式变化会导致崩溃 | Claude 在运行时自行适配工具使用 |
| 可读性 / 调试 | 大量样板代码 | 冗余模式会准确显示 Claude 正在做什么以及原因 |
| 干运行 / 冗余 | 需要自定义日志 | 内置 --dryRun 和 --verbose 参数 |
快速入门
# 克隆仓库
git clone https://github.com/elpic/notion-of-progress
cd notion-of-progress
# 安装依赖
npm install
# 设置环境变量
cp .env.example .env
# 编辑 .env 并添加 NOTION_API_KEY 和 ANTHROPIC_API_KEY
# 自动创建 Notion 数据库
npm run setup运行 Stand‑up
mise run standup干运行模式
mise run standup -- --dry-run--dry-run 在不触碰 Notion 的情况下预览摘要——非常适合测试。
MCP 服务器配置
@notionhq/notion-mcp-server 通常在托管版本中需要 OAuth,但你可以通过 stdio 使用内部集成令牌在本地运行——无需 OAuth。
mcpServers: {
notion: {
command: 'npx',
args: ['-y', '@notionhq/notion-mcp-server'],
env: {
OPENAPI_MCP_HEADERS: JSON.stringify({
Authorization: `Bearer ${config.notion.apiKey}`,
'Notion-Version': '2022-06-28',
}),
},
},
},关键洞察: 将 MCP 服务器作为本地子进程启动,并在请求头中携带内部令牌,使整个项目能够无缝运行。