自建 MCP 服务器实现周效率提升
详细分享开发自定义 MCP Server 全过程,展示工具集成如何显著提升开发效率。
详细分享开发自定义 MCP Server 全过程,展示工具集成如何显著提升开发效率。
最近,我一直在美国各地奔波,通过「Accelerate AI with Cloud Run」系列研讨会,帮助工程师学习如何在 Cloud Run 上以 Serverless 方式构建 MCP Server 和 AI Agent。参与者经常会问:如何把学到的知识应用到自己的实际场景中?这篇文章讲述了我如何利用研讨会第一个动手实验中的内容,构建出一个能在日常工作中真正帮我节省时间和精力的工具!
作为 Google Kubernetes Podcast 的联合主持人,我很享受节目中的交流,也喜欢了解各种有趣的技术和应用场景。但和任何内容栏目一样,每一期节目的制作与发布都需要投入大量时间和精力。在本文中,我会解释自己为什么以及如何构建一个 MCP Server,用来简化并加速我们的发布流程。你也可以在 GitHub 上查看我的 podcast-assistant-mcp Server 代码,亲自试用这个解决方案!
运营一档 Podcast 涉及很多环节:挑选嘉宾和话题、安排访谈、剪辑节目,等等。你可能会觉得,发布应该是整个流程中最快的部分——不就是点一下按钮,节目就上线了吗?!唉,亲爱的读者,我多希望事情真有这么简单。
每一期节目大致都要经过下面这套发布流程:
收听节目、检查质量并撰写 show notes。(说实话,这可能是整个流程中最耗时、最需要主动投入精力的一步。)
将最终音频上传到发布平台,并填写所有元数据字段(show notes、标签等)。
在代码仓库中创建 pull request,更新 kubernetespodcast.com(我们的网站使用 Hugo 构建)。
在社交媒体上宣传新一期节目(X、LinkedIn、BlueSky、Reddit 等)。
发布流程中数量庞大的手动操作,占用了我们大量时间。我需要一种更好的方式,而我看到了让 AI 提供帮助的机会。
AI 非常擅长总结和转换内容。我们发布流程中许多最耗时的工作,本质上都是总结任务。因此,我们显然可以利用 AI 来起草 show notes、社交媒体帖子等发布素材。
为了验证 AI 能否在这些总结步骤中帮我节省时间,我编写了一个简单的 Python 脚本,它可以:
接收一个音频文件作为输入。
使用 AI 将音频转换成文字稿。
根据文字稿生成 show notes 和社交媒体帖子的初稿。
仅仅通过一个简单的 Python 脚本,我就大幅减少了为了撰写 show notes 而逐字仔细收听节目的时间。虽然我仍然会审核并编辑所有要发布的内容,但 AI 起草的 show notes 为我提供了一个基础,使我在收听节目并检查质量时,不再需要频繁暂停下来记笔记。此外,社交媒体帖子的初稿也简化了发布前的准备工作。我从 2025 年年初开始定期使用这个脚本,它每期节目都能稳定节省 1.5~2 小时。在过去几个月里,它已经成为我发布流程中不可或缺的一部分。
但这里有一个问题。你看,我并不是 Kubernetes Podcast 唯一的主持人,负责发布节目的人也并不总是我。这个出色的省时脚本存在一个问题:只有我一个人在用!当然,我把脚本分享给了联合主持人,但由于它没有集成进他们现有的发布流程,他们并没有借助它节省宝贵的发布时间。
为了实现一个新的目标——帮联合主持人也节省时间——我开始探索如何更有效地共享这套自动化能力,同时扩展最初的脚本,进一步优化我们的发布流程。
起初,我设想的是一个功能全面、向导式的 Web 应用,由它管理整个流程,并加入「human in the loop」审核环节。这种方式可以将我们的发布工具和流程集中到一起,同时简化新主持人的上手过程。
然后,我不得不面对现实:
我是 Kubernetes/Cloud Infrastructure 专家——我不具备快速构建多步骤 Web 应用所需的前端技能!
发布到所有平台所需的 API,有很多都无法方便地获取。😞
归根结底,我没有足够的时间开发这样一个全面的解决方案。因此,我重新想起了那条古老的智慧:优先保持简单。要解决这个问题,我真正需要的是一套团队能够轻松采用、并立即节省时间的系统。从长期来看,我还希望它采用可扩展的架构,让我可以在时间允许时逐步构建出理想的发布流程。
解决方案就是:创建一个 MCP(Model Context Protocol)Server!这种方式有几个关键优势:
它拥有简单的用户界面,而且大部分功能都通过后端代码实现(不需要学习前端语言或库)。
它可以与 Gemini CLI 集成,而我们的团队本来就在使用 Gemini CLI。这意味着他们不需要学习新工具,也不需要向现有工作流中添加新工具!
它的扩展性非常强!只要有时间,我就可以逐个添加新工具,例如 generate_hugo_post 或 publish_to_platform_x,循序渐进地扩展功能。
可以利用已有成果:为了快速构建这个 MCP Server,我复用了两项现有成果。首先,我复用了「Accelerate AI with Cloud Run」系列研讨会第一个动手实验中的 MCP Server 设计和部署方法,该实验演示了如何在 Cloud Run 上运行安全的 MCP Server。其次,为了让它适配我的实际场景,我将之前开发的 Python 脚本转换成了 MCP Server。这个转换过程简单得令人惊讶——我只需要集成 FastMCP 库,并修改输出机制,确保每个函数都能独立地把输出保存到存储桶中。
我复用了「Accelerate AI with Cloud Run」系列研讨会第一个动手实验中的 MCP Server 设计和部署方法,该实验演示了如何在 Cloud Run 上运行安全的 MCP Server。
为了让它适配我的实际场景,我还将之前开发的 Python 脚本转换成了 MCP Server。这个转换过程简单得令人惊讶——我只需要集成 FastMCP 库,并修改输出机制,确保每个函数都能独立地把输出保存到存储桶中。
我使用 FastMCP 和 Google 的 GenAI 库构建了这个 Server,并将它称为 podcast-assistant-mcp。整个项目通过 Docker 完成容器化,可以直接部署到 Cloud Run。
这个项目非常直观。和实验中一样,我使用命令行工具 uv 管理依赖,因此项目中有一个 pyproject.toml 文件,用来定义以下关键依赖:
FastMCP:用于创建 MCP Server 本身。
google-genai:用于与 Vertex AI 上的 Gemini 2.5 Flash 模型交互。
google-cloud-storage:用于读取音频文件,并将文本输出写入 Google Cloud Storage Bucket。
当我最初以 Python 脚本的形式编写这个项目时,它采用的是顺序执行模式:一个工具的输出会成为下一个工具的输入。而在 MCP Server 中,每个组件都可以被独立调用,因此灵活性更高。例如,如果我们已经手动创建了 show notes 文件——我们偶尔确实会这样做——或者你已经有了一份文字稿,希望用它生成社交媒体帖子和博客文章——我们可能会针对旧节目这样做——那么 AI Podcast Assistant 就可以灵活地协助完成它所支持的发布流程中的任何特定环节。它仍然可以调用自己拥有的所有工具完成全部工作,并且知道如何按照合理的顺序执行!随着我们为这个 Server 开发更多工具,这种灵活性会变得更加有用。
这个项目主要由三个文件组成:定义 MCP Server 本身的 server.py,以及用于部署的 Dockerfile 和 pyproject.toml。
server.py 文件定义了四个主要工具,README 中则包含了通过 Gemini CLI 使用这些工具的操作说明。按照我们的原则,所有生成的内容都只被视为初稿——任何准备发布的内容,我们都会认真审核和编辑。
第一个工具是整个流程的起点。它接收一个 .mp3 或 .wav 文件的 GCS URI,并使用一段详细的 prompt 对音频进行转写。这个 prompt 的要求非常具体,包括标注说话人和时间戳;这对于制作 show notes 至关重要,因为之后我可以亲自检查其质量,也可以使用质量评估工具完成检查。随后,它会将文字稿保存到 GCS,并返回新的 URI。
第二个工具接收文字稿的 GCS URI。在我们的生产环境 Server 中,它使用一段专门针对 Podcast 风格定制的 prompt,生成 Markdown 格式的 show notes 文件。这个文件本质上由一系列相关补充资料的链接组成,方便任何希望进一步了解节目中提到的技术的人继续学习。
在 GitHub 代码仓库的版本中,我采用了一种稍微通用一些的 show notes 方案,主要用于总结本期节目。如果你想亲自试用,随时可以编辑 prompt,让它以不同方式工作!无论是在我们的生产环境中,还是部署代码仓库里的版本,这个函数都会把 Markdown show notes 文件保存到 GCS,并返回该文件的 URI。
第三个函数接收文字稿,并生成一篇完整且有吸引力的 Markdown 格式博客文章,然后将结果保存到 GCS。这里稍微体现出了 MCP Server 的可扩展性,因为 kubernetespodcast.com 目前还没有博客。我们希望未来某个时候能够实现这个功能。等博客页面准备就绪后,这个工具生成的初稿应该可以成为非常方便的起点。我们会以这个函数的输出为基础,将更多时间投入到确保内容准确、链接相关参考资料,以及保证节目中的核心观点能够通过博客文章清晰呈现。
最后,这个 MCP Server 中的第四个工具会根据文字稿,分别生成适用于 X(不超过 280 个字符)和 LinkedIn 的格式化帖子初稿。和这个 MCP Server 的所有其他输出一样,我们也会在发布前对这些内容进行审核和编辑。
将它实现成 MCP Server 的根本目的,就是把它分享给我的联合主持人。这意味着需要将它部署到 Cloud Run,并要求身份验证——也就是说,任何人都能使用它,只要我们告诉他们怎么用!这也应该能够简化新主持人的上手过程,尤其是随着我们把发布流程中的更多环节实现为工具。部署方面,我们使用一个简单的 Dockerfile 完成容器化,并使用 pyproject.toml 管理依赖。
在设计这个项目时,我有意识地做出了几项选择。如果你也在考虑构建自己的 MCP Server,或许可以把下面这些因素纳入考量。
我最初的脚本使用 Gemini 2.5 Pro,这是一款强大的内容生成模型。不过,我遇到了一个问题:Gemini CLI 在等待工具输出时会超时。在尝试修改可能的超时配置但未能解决问题之后,我改用了 Vertex AI 上的 Gemini 2.5 Flash。事实证明,Flash 的速度足够快,可以在客户端的超时限制内完成内容生成以及保存到存储桶的操作,从而保证工作流可靠执行。虽然其他模型也可以胜任,但目前 Gemini 2.5 Flash 是我在这个应用中的首选。
作为一个关键依赖,FastMCP 提供了一项功能,允许开发者注册 prompt,而不必注册完整的 tool。对于这样的工作流,主要操作是接收单一输入(文字稿 URI),然后生成一个无法继续串联的单一输出,例如 show notes、博客文章或社交媒体动态。在这种情况下,经过配置的 prompt 看起来可能是理想的解决方案。既然这些工具已经与 AI Model 集成,从逻辑上讲,自然应该利用 AI 完成所需的内容生成工作。
不过,Podcast Assistant 的主要目标不只是生成内容,还要将内容长期保存在存储桶中。prompt 功能的设计用途是直接向用户输出生成的文本,通常是通过 Gemini CLI 展示。对于这个 Server,生成的文本必须保存到 Google Cloud Storage(GCS)Bucket 中,这样才能在后续步骤中使用,或者方便联合主持人下载。因此,我选择实现完整的 tools——尽管复杂度更高——因为它们可以提供对输出存储所需的明确控制,并能保存 GCS URI,供工作流的下一步使用。
能够与联合主持人共享这个 MCP Server,正是它成为优秀解决方案的原因——但我可不想为全世界所有人的使用费用买单!因此,我希望延续原始 codelab「How to deploy a secure MCP server on Cloud Run」的理念,要求用户通过身份验证后才能使用我的 MCP Server。
我们可以在 MCP Server 层面设置 Auth,但我比较懒,而且那听起来意味着要写更多代码,所以我选择利用 Cloud Run 层面的身份验证。具体做法是在部署时使用 gcloud cli 的 –no-allow-unauthenticated flag。
在 codelab 中,身份验证本质上按 session 处理:最终用户需要配置一个一小时后过期的 ID Token。对于我的 Podcast 场景来说,这种方式也没问题,因为我可以把创建 ID Token 纳入发布工作流,而且实际使用 Server 工具的时间应该不会超过几分钟。不过,考虑到预期用户数量有限,我也希望探索一些更加顺畅的方案。
在 podcast-assistant-mcp Server 的 README 中,我列出了三种不同的身份验证方案:
方案 1:通过 Gemini CLI 使用身份验证 token:这种方法设置起来很快,适合临时访问 MCP Server。token 的有效期为一小时。
方案 2:通过 Gemini CLI 使用 proxy:这种方法更加稳健,建议用于持续开发。proxy 会自动处理身份验证,并将请求转发给 MCP Server。
[示例] 方案 3:使用 service account:方案 1 和方案 2 都是通过 Gemini CLI 以用户身份完成验证。该方法则通过 service account,以 service 或 Agent(而不是用户)的身份进行验证。这个项目不包含这样的 service 或 Agent,因此这个方案仅作为示例供参考,单纯部署本项目后并不能立即使用。
对于我的使用场景,方案 1 或方案 2 都能很好地满足需求。我可能会让联合主持人分别测试这两种方案,看看他们更喜欢哪一种。随着我们继续扩展 MCP Server 的能力,我们的偏好和需求也可能发生变化。
尽管我依然希望构建一个完全集成、功能全面的解决方案,但这个 MCP Server 已经是一款切实可用的工具:它能够正常工作,可以集成到团队日常使用的工作流中,而且具备扩展能力,让我或联合主持人能够根据需要添加更多功能,使每个人都从中受益。
在过去几个月里,这个项目一直在稳定地为我节省大量时间。现在,我的联合主持人也可以直接通过各自的 Gemini CLI 使用它,共同节省宝贵的时间,并将这些时间投入到未来节目的制作中。你也可以查看这个 GitHub 代码仓库中简单直观、仅由三个文件组成的 MCP Server 实现,然后开始构建属于自己的、实用又省时的 MCP Server!