开发者分享构建自定义 MCP Server 的实战经验,展示如何整合 AI 工具链自动化发布流程,对 AI 工程师有直接参考价值。
最近我一直在深入 AI 工程准备工作——部署了几个全栈 AI 项目、微调了一个开源权重 LLM,还在为校招准备 DSA。在这些工作的间隙,我对 MCP(Model Context Protocol)产生了好奇,决定真正用它构建一些东西,而不只是阅读相关文章。
这个想法很简单:如果 Claude 可以读取我机器上的粗糙博客草稿、清理它,然后直接发布到 Dev.to——完全不用我碰 Dev.to 的 UI,会怎样?
事实证明,这正是 MCP 的用途。
MCP 是一个协议,让像 Claude 这样的 AI 模型可以调用你定义的工具——读取文件、调用 API、运行脚本——而不仅仅是生成文本。你写一个小的服务器,暴露"工具"(带文档字符串的普通 Python 函数),把它插入 Claude Desktop 的配置中,突然间 Claude 就可以行动,而不仅仅是聊天。
我为此设置了两个服务器:
我用 uv 来管理 Python 包——比纯粹的 pip/venv 快得多。
第一个小坑:PowerShell 在安装后找不到 uv,因为我的终端会话是在安装程序更新 PATH 之前就已经打开的。关闭并重新打开终端立即解决了问题。这是一个小事,但如果不知道为什么会发生,很容易惊慌失措。
第二个小坑更有意思。我创建了一个全新的 venv 并尝试 uv add "mcp[cli]",但它一直在依赖解析上失败——因为我的 pyproject.toml 中还有 requires-python = ">=3.9",这是项目最初基于系统 Python 3.9 的时候留下的,但实际上 MCP SDK 需要 3.10+。我通过显式固定版本修复了它:
uv python pin 3.12
uv venv --python 3.12
然后我在 pyproject.toml 中编辑了 requires-python 为 >=3.10,安装顺利进行。
这是困扰我一段时间的。在一次"成功"的安装之后,导入 fastmcp 一直抛出 ModuleNotFoundError: No module named 'mcp.server.fastmcp'——即使 import mcp 工作正常,文件夹里确实有一个 server 目录。
事实上是 uv pip show mcp 显示安装的包是版本 2.0.0,有像 httpx2、mcp-types、pyjwt 和 pywin32 这样的依赖——这些都不属于真正的 MCP SDK。PyPI 上有一个不相关的包占用了 mcp 这个名字,它被拉取进来了,而不是真正的 modelcontextprotocol SDK。
解决方案是显式固定版本范围:
uv remove mcp
uv add "mcp[cli]>=1.2.0,<2.0.0"
这拉取了合法的 SDK(当时是 1.29.0),from mcp.server.fastmcp import FastMCP 最终工作了。
教训:如果 uv add somepackage "成功"了但之后一切都说不通,检查一下 uv pip show——不要假设 PyPI 上的名字是你认为的项目。
Claude Desktop 从 claude_desktop_config.json 的顶层 mcpServers 键读取其 MCP 服务器列表。这个文件现在有其他无关的应用偏好设置在里面,所以很容易把你的服务器意外地添加为 mcpServers 的兄弟节点而不是嵌套在其内部——这会无声地什么都不做。我吃了这个亏,盯着设置 → 开发者 → 本地 MCP 服务器,想知道为什么只有 filesystem 显示了。
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "C:\\Technical\\mcp-code"]
},
"devto": {
"command": "C:\\Users\\vdine\\.local\\bin\\uv.exe",
"args": ["--directory", "C:\\Technical\\custom-mcp\\devto-mcp-server", "run", "dev-server.py"]
}
}
}
另一个 Windows 特有的坑:Claude Desktop 并不总是继承你 shell 的 PATH,所以 "command": "uv" 单独有时会无法启动。使用 where.exe uv 的完整路径永久解决了这个问题。
在完全退出并重新打开 Claude Desktop(不仅仅是关闭窗口——它在系统托盘里还活着)后,两个服务器都显示为运行状态。
在把任何东西接入 Claude Desktop 之前,我用以下方式独立测试了服务器:
uv run mcp dev src/mcp_server_demo/__init__.py
这启动了 MCP Inspector——一个本地 web UI,你可以在其中直接调用你的工具,看到原始请求/响应有效负载,完全不需要 Claude 参与。这对于早期捕获 bug 真的很有用,而不是通过聊天界面进行调试。
两个服务器都连接后,实际发布步骤几乎令人厌倦——我只是正常和 Claude 聊天:
"我在 [文件夹] 有一个 blog.txt 文件,完善其内容,然后发布到 Dev.to 作为草稿,附加相关标签。"
Claude 自己链接这些工具:
无需复制粘贴到 Dev.to 的编辑器,无需手动格式化。我首先设置 published: false 来在发布前审查草稿——这是防止发布半成品的廉价保险。
这里大部分真正的学习并不是关于 MCP 协议本身——这是标准的环境调试:PATH 问题、Python 版本固定、被占用的包名和 JSON 嵌套错误。MCP 本身,一旦环境是健全的,可能只需要 20 行 Python 代码加一个文档字符串。
这可能是被低估的教训:agent 工具的可靠性只取决于底层无聊的管道。搞定 venv、包版本和配置形状,"AI 做有趣部分"就自动处理好了。
接下来,我计划在同一个服务器中添加几个工具——也许是一个可以拉取我的 GitHub 提交历史来帮助自动草拟"我这周构建了什么"帖子的工具。