前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
返回 AI 情报前线
All News · 全部资讯8629
  • PostgreSQL 的 BM25 全文搜索扩展开源
  • Granite 4.0 3B:企业文档的轻量级多模态模型
  • Claude Code 源码泄露分析:假工具、匹配坑、隐藏模式
  • Claude Code 用户遭遇使用限制提前耗尽
  • Claude Code 源码因 NPM 地图文件泄露
  • 产品思维是 AI 编程工具替不了的能力
  • 通用 Claude.md 秘诀:切减输出 Token
  • TRL 1.0:随行业发展的开源微调库
  • 做中学:Claude Code 实战教程
  • AI 代理审计发现:内容问题逐一报警
  • Zerobox:隔离运行命令的沙箱工具
  • 长链路 Agent 的能力与限制
  • Claude Code 工具 Bug:强制重置代码仓库
  • 谷歌重新想象 AI 时代的鼠标指针
  • LLM 推理优化:KV Cache 压缩方案
  • AI 辅助求解 Knuth 经典问题的进展
  • AI 破译古代亚述泥板的新尝试
  • Notion 创始人不写代码:AI 编程工具成熟见证
  • CLI 成为 AI Agent 接入产品的标准方式
  • 为什么管理层看好 AI,工程师持保留态度?
  • GitHub 活动自动转博客:MCP 工作流自动化
  • .claude/ 文件夹深度解析
  • Cursor 秘用中文 AI 模型未披露,为何程序员应关注
  • OpenClaw 开源项目发布
  • OpenClaw + Pieces 长期记忆一体化配置指南
  • 7 美元 VPS 上跑 AI Agent:IRC 网关新思路
  • 500 美元 GPU 编程性能超越 Claude Sonnet
  • Gemini 3.1 Flash 新增音频模型,延迟更低
  • 两周看透中国 AI 生态:创始人、芯片和泡沫
  • 为 Claude Code 设计纯文本认知架构
  • Claude 生成代码 90% 流向小项目,质量面临考验
  • 为 Agent 提供临时数据库的基础设施
  • Ensu:完全私有的本地 LLM 应用
  • Cursor 自托管 AI Agent:代码隐私的重大升级
  • Apple Silicon 上 LLM 推理的性能优化
  • AI 时代的冷思考:工程能力才是核心
  • 程序员学习 AI 无需过度焦虑
  • LLM 内部机制深度破解:通用语言的蛛丝马迹
  • 给 AI 编码 Agent 加上视觉验证能力
  • RAG 系统从零到一的实战经验与教训
  • 语音 Agent 评估框架 EVA 发布
  • Claude Code 速查表与功能指南
  • Claude Code 实战提效工作流
  • Prompt 工程入门:问法决定质量
  • Cq:AI 编程 Agent 的专属问答社区
  • iPhone 17 成功运行 400B 大模型演示
  • 用 Claude 自动化移动应用 QA 测试
  • 现代 LLM 注意力机制可视化教程
  • OpenTelemetry 统一 LLM 追踪规范
  • OpenCode:开源 AI 编程 Agent 项目
  • 快速构建领域特定嵌入模型
  • 已加载 51 / 8629
6.0
关注
AI SCORE
工具产品2026-03-28 03:07

GitHub 活动自动转博客:MCP 工作流自动化

DEV Community · Yash Kumar Saini#MCP#自动化
Editor brief · 编辑速览

展示用 MCP 连接 GitHub、Notion、DEV.to 自动生成周报和博客,提升开发者工作流效率的实践案例。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

Notion MCP 挑战赛参赛作品 🧠

这是一个 Notion MCP 挑战赛的参赛项目。

每周一站会,总会有人问:“你上周做了什么?”而每到这时,我都会盯着屏幕,努力回忆。我是在周三还是周四合并了那个 PR?那次重构是在 auth 模块里,还是在 pipeline 里?我到底改过多少个仓库?

我受够了这种大脑一片空白的时刻。于是,我构建了 DevNotion——一个由 Mastra 驱动的三 Agent pipeline。它会收集我一整周的 GitHub 活动,用 Gemini 将这些活动讲述成一篇第一人称博客文章,然后发布到 Notion(以带有结构化表格的计划页形式)和 DEV.to(作为文章草稿)。每周日,通过 GitHub Actions 自动运行。

周一再也不会失忆了。博客会自己写好。

它实际做了什么

通过 GraphQL 收集我的 GitHub 活动——commit、PR、issue、代码审查、discussion、语言统计和贡献连续天数。

使用 Gemini 将原始数据讲述成一篇轻松自然的第一人称博客文章(如果 LLM 不可用,则使用确定性的 fallback)。

同时发布到两个平台:Notion——一个计划页,包含统计表格、仓库明细、PR/issue/review 表格、语言明细以及完整博客文章;DEV.to——一篇等待审阅的文章草稿。

Notion——一个计划页,包含统计表格、仓库明细、PR/issue/review 表格、语言明细以及完整博客文章。

DEV.to——一篇等待审阅的文章草稿。

3 个专业化 Agent——每个 Agent 专注做好一件事(收集、讲述、发布)。

仅在真正能创造价值的环节使用 LLM——收集和发布都是确定性的,没有 token 开销。

4 种博客语气配置——casual(默认)、professional、technical、storytelling。

计划式 Notion 页面——不只是一整面文字,而是包含统计、仓库、PR、issue、review 和编程语言等信息的结构化表格。

Notion MCP 集成——通过 Model Context Protocol 使用完整的 Notion API 能力。

Notion Markdown Content API——直接向页面写入富 Markdown 内容(真正改变游戏规则的功能)。

DEV.to 草稿发布——文章会以草稿形式创建,随时可以审阅和发布。

GitHub Actions CI——每周定时任务(周日 08:00 UTC)并支持手动触发。

README 中的博客日志——CI 每次运行后都会自动 commit 一张指标表格。

Fallback 链——即使 Gemini 出现故障,也始终能够生成博客文章。

全方位限流——Notion 和 DEV.to API 都使用 p-queue + p-retry。

整个 pipeline 只在真正能创造价值的地方使用 LLM——也就是内容讲述。收集和发布都是纯函数调用。没有 token 开销,没有幻觉风险,执行速度也更快。

架构深度解析

我本可以构建一个包办一切的超级 Agent。但这样做无异于给自己挖坑:

在确定性工作上浪费 token(获取 GitHub 数据根本不需要 LLM)。

编造 URL 和统计数据(发布步骤绝不能凭空捏造内容)。

制造调试噩梦(单体流程到底是哪一部分失败了?)。

因此,每个 Agent 都各司其职。workflow 将它们串联起来:

export const weeklyDispatchWorkflow = createWorkflow({
  id: 'weekly-dispatch',
  inputSchema: z.object({ weekStart: z.string() }),
  outputSchema: PublishOutputSchema,
})
  .then(harvestStep)
  .then(narrateStep)
  .then(publishStep)
  .commit();

三个步骤通过 .then() 串联,最后作为一个完整 workflow 提交。Mastra 会自动处理步骤之间的数据传递。

Harvest:确定性数据,零 LLM

Harvest 步骤会直接调用 GitHub 的 GraphQL API——不需要 Agent 进行推理:

const harvestStep = createStep({
  id: 'harvest-github',
  inputSchema: z.object({ weekStart: z.string() }),
  outputSchema: WeeklyDataSchema,
  execute: async ({ inputData }) => {
    const data = await fetchWeeklyContributions(inputData.weekStart);
    return WeeklyDataSchema.parse(data);
  },
});

一条 GraphQL 查询就能获取这一周的 commit、PR、issue、review、discussion、语言统计和贡献连续天数。返回结果会通过 Zod schema 进行验证。整个过程没有 LLM 参与——这就是纯粹的数据获取。

Narrate:带有 fallback 链的 LLM

这是 LLM 真正发挥价值的地方。Narrator Agent 会接收原始 JSON,并写出一篇读起来就像是我亲自写的博客文章。system prompt 中包含完整的个性设定——它使用第一人称写作,了解我的技术栈(Python、Rust、TypeScript),会提及我的 OSS 工作,并且能够匹配四种语气配置中的任意一种。

但 LLM 有时并不稳定。因此,Narrate 步骤设置了一条 fallback 链:

const narrateStep = createStep({
  id: 'narrate',
  execute: async ({ inputData, mastra }) => {
    const agent = mastra!.getAgent('narrator-agent');
    let blog;

    try {
      const result = await agent.generate(prompt);
      const parsed = parseFrontmatter(result.text);
      if (parsed.success) {
        blog = parsed.data.blog;
      } else {
        blog = buildFallbackNarration(inputData).blog;
      }
    } catch (err) {
      blog = buildFallbackNarration(inputData).blog;
    }

    return { blog, weeklyData: inputData };
  },
});

Gemini 会生成一篇带有 YAML frontmatter 的 Markdown 博客文章。

如果解析失败 → 确定性 fallback 会根据原始数据构建一篇基础文章。

即使 Gemini 完全不可用,也始终能够生成一篇博客文章。

Publish:Notion 计划页 + DEV.to 草稿

Publish 步骤才是事情真正变得有趣的地方。它并不是简单地把文本一股脑塞进 Notion,而是会构建一个带有结构化表格的计划页:

const publishStep = createStep({
  id: 'publish',
  execute: async ({ inputData }) => {
    const { blog, weeklyData } = inputData;

    // 1. Create Notion page
    const createResult = await createNotionPage(title);

    // 2. Create DEV.to draft (so the link goes into the Notion planner)
    const devtoResult = await createDevtoArticle({
      title: blog.headline,
      body_markdown: buildDevtoMarkdown(blog),
      tags: blog.tags,
      published: false,
    });

    // 3. Write planner markdown to Notion (includes DEV.to link)
    const plannerMd = buildPlannerMarkdown(weeklyData, blog, links);
    await writeNotionMarkdown(notionPageId, plannerMd);
  },
});

执行顺序非常重要:在写入 Notion 页面内容之前,必须先创建 DEV.to 草稿,这样 Notion 计划页中才能包含指向 DEV.to 草稿的链接。这才是跨平台链接的正确做法。

每个 Notion 页面都包含:

Published Links 表格——Notion 页面 URL + DEV.to 草稿编辑链接。

Week at a Glance——commit、PR、issue、review、新增/删除代码行数和贡献连续天数。

Active Repositories——仓库名称、commit、编程语言和代码行变更。

Pull Requests/Issues/Reviews/Discussions——结构化表格。

Languages——按 commit 数量排列的主要编程语言。

完整博客文章——分隔线下方是生成的讲述内容。

在 GitHub 上为 DevNotion 点 Star。

我如何使用 Notion MCP

这是最令我兴奋的部分。DevNotion 通过两种互补方式使用 Notion MCP Server:

1. 通过 @mastra/mcp 使用 Notion MCP Server

Publisher Agent 通过 Mastra 的 MCP client 与官方 @notionhq/notion-mcp-server 集成。这让 Agent 能够通过 Model Context Protocol 使用完整的 Notion API 能力:

import { MCPClient } from '@mastra/mcp';

export const notionMcp = new MCPClient({
  servers: {
    notion: {
      command: 'npx',
      args: ['-y', '@notionhq/notion-mcp-server'],
      env: {
        OPENAPI_MCP_HEADERS: JSON.stringify({
          Authorization: `Bearer ${env.NOTION_TOKEN}`,
          'Notion-Version': '2022-06-28',
        }),
      },
    },
  },
  timeout: 30000,
});

MCP tools 会延迟加载,并提供优雅的 fallback——如果 MCP server 启动失败,直接调用的 tools 仍然可以独立工作:

export async function getNotionMcpTools(): Promise<Record<string, any>> {
  try {
    return await notionMcp.listTools();
  } catch (err) {
    console.warn('MCP: Notion MCP server unavailable, using direct tools only');
    return {};
  }
}

2. 合并直接 tools 与 MCP tools

Publisher Agent 会合并两套 tools——MCP tools 用于提供完整的 Notion API 能力,而直接 tools 则用于实现 MCP 尚未覆盖的功能:

// Direct tools (Markdown Content API + DEV.to — not available via MCP)
const directTools = {
  createNotionPage: createNotionPageTool,
  writeMarkdown: writeMarkdownTool,
  searchNotion: searchNotionTool,
  updateNotionPage: updateNotionPageTool,
};

// Merge: Notion MCP tools + direct tools
const mcpTools = await getNotionMcpTools();
const tools = { ...mcpTools, ...directTools };

这种双轨方案让 Publisher Agent 能够兼得两者之长——在 Mastra playground 中进行交互式操作时,可以使用 MCP 广泛的 API 能力;运行自动化 workflow 时,则可以使用直接 tools。

3. Markdown Content API(改变游戏规则的功能)

正是 Notion 的这项功能,让计划式页面成为可能。无需逐个构造 Notion block(这种方式既痛苦,又很容易触发限流),我只需要通过一次 API 调用,就能将整个页面以 Markdown 形式写入:

const response = await fetch(
  `https://api.notion.com/v1/pages/${pageId}/markdown`,
  {
    method: 'PATCH',
    headers: {
      Authorization: `Bearer ${env.NOTION_TOKEN}`,
      'Content-Type': 'application/json',
      'Notion-Version': '2026-03-11',
    },
    body: JSON.stringify({
      type: 'replace_content',
      replace_content: { new_str: markdown },
    }),
  },
);

只需一个 PATCH 请求,就可以使用富 Markdown 替换整个页面的内容——包括表格、标题、引用块、链接、代码块以及其他所有内容。正是它支撑起了计划式布局:结构化统计表格与完整博客文章,可以通过一次 API 调用全部写入。

Notion API 每秒大约允许发送 3 个请求。每次 Notion 调用(包括 MCP 和直接调用)都会经过一个共享的限流器:

const queue = new PQueue({ concurrency: 1, interval: 334, intervalCap: 1 });

async function rateLimited<T>(fn: () => Promise<T>): Promise<T> {
  return queue.add(() => pRetry(fn, { retries: 3 })) as Promise<T>;
}

p-queue 用于限制并发,p-retry 用于处理暂时性故障。这是我踩坑之后才学到的经验——如果不做限流,当你在短时间内连续创建页面、写入 Markdown 和更新图标时,Notion API 会用铺天盖地的 429 把你彻底淹没。

限流才是真正的 Boss

Notion(3 req/s)、DEV.to(30 req/30s)、GitHub GraphQL(5000 points/hr)——每个 API 都有自己的限流规则。最终,我给所有服务都套上了 p-queue + p-retry wrapper。三个服务中的限流代码几乎完全相同,老实说,它们或许应该被提取成一个共享工具。但与过早抽象相比,保留三段相似的代码更好。

结构化输出比你想象的更慢

一开始,我使用 Gemini 原生的 JSON schema 来获得结构化输出(agent.generate(prompt, { structuredOutput: { schema } }))。它确实可以工作,但每次调用都会额外增加 20~40 秒。改为生成纯文本并解析 YAML frontmatter 后,速度提升到了原来的 3~4 倍,可靠性却丝毫不差。少数解析失败的情况,则由确定性 fallback 兜底。

Gemini 模型的抢椅子游戏

在这个项目中,我已经换过三个 Gemini 模型:gemini-2.5-flash-preview-04-17(已退役)、gemini-2.5-flash(稳定,但生成结构化输出时很慢),以及现在使用的 gemini-3-flash-preview(当前模型)。得到的教训是:始终通过 env vars 配置模型。硬编码模型 ID,迟早会导致部署崩溃。

毁掉一切的 Zod 冲突

Mastra 和我的代码都依赖 Zod,但使用的版本不同。同时存在两个 Zod 实例,意味着一个实例中的 z.string() 无法被另一个实例识别——schema 验证就这样悄无声息地失败了。修复方法是在 package.json 中加入一行配置:

{
  "pnpm": {
    "overrides": {
      "zod": "$zod"
    }
  }
}

这会强制 pnpm 将依赖去重为同一个 Zod 版本。我花了太长时间才找出这个问题。

对于确定性工作,直接调用 API 胜过 Agent 推理

Harvest 和 Publish 步骤最初都是完整的 Agent 调用。但当任务只是“调用这个 GraphQL endpoint 并返回结果”时,LLM 并不能带来任何价值。切换到直接函数调用后,pipeline 变得更快、更便宜,也更可预测。只有在需要创造力或推理能力时才使用 LLM——其他地方,写个函数就够了。

这个项目由 Mastra、Gemini、Notion API,以及大量咖啡共同构建而成。如果你也曾忘记自己上周做过什么,不妨试试 DevNotion。

部分评论可能只有登录后的访客才能看到。请登录以查看全部评论。

如果需要采取进一步行动,你可以考虑屏蔽此人和/或举报滥用行为。

Original source

本文由 AI 翻译整理自 DEV Community · Yash Kumar Saini,原文版权归原作者所有。

阅读英文原文
上一篇
为什么管理层看好 AI,工程师持保留态度?
下一篇
.claude/ 文件夹深度解析