news 2026/9/20 21:50:29

连接真实 Host:用 python-sdk 的 `mcp run` 命令将 MCP 服务器接入 Claude Desktop、Claude Code、Cursor 与 VS Code

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
连接真实 Host:用 python-sdk 的 `mcp run` 命令将 MCP 服务器接入 Claude Desktop、Claude Code、Cursor 与 VS Code

连接真实 Host:用 python-sdk 的mcp run命令将 MCP 服务器接入 Claude Desktop、Claude Code、Cursor 与 VS Code

【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk

host是 MCP 服务器最终运行所在的应用程序——Claude Desktop、Claude Code、各类 IDE 都属于 host。用户直接与 host 对话,而 host 内部的 MCP 客户端把你的服务器作为子进程启动,并通过该进程的 stdin/stdout 与之通信。这意味着"连接真实 host"本质上只有一个动作:告诉 host 一个启动你服务器的命令。本页将围绕mcp run这个核心命令,完整演示如何用官方 Python SDK(python-sdk)把同一个服务器文件接入四种主流 host,并给出配置 JSON、命令行参数与故障排查的完整方案。

一个服务器,适配所有 host

先看本页反复出现的服务器文件(完整代码见 docs_src/real_host/tutorial001.py):

from mcp.server import MCPServer from mcp.server.mcpserver.exceptions import ToolError mcp = MCPServer("Bookshop") CATALOG = { "Dune": "Frank Herbert", "Neuromancer": "William Gibson", "The Left Hand of Darkness": "Ursula K. Le Guin", } @mcp.tool() def search_books(query: str) -> list[str]: """Search the catalog by title or author.""" needle = query.lower() return [title for title, author in CATALOG.items() if needle in title.lower() or needle in author.lower()] @mcp.tool() def get_author(title: str) -> str: """Look up the author of a book in the catalog.""" if title not in CATALOG: raise ToolError(f"No book titled {title!r} in the catalog.") return CATALOG[title] @mcp.resource("catalog://titles") def titles() -> str: """Every title in the catalog, one per line.""" return "\n".join(sorted(CATALOG)) if __name__ == "__main__": mcp.run()

两个工具、一个资源,全部装在一个文件里。对于下面所有的 host,这个文件有三个关键点:

  • mcp.run()不带参数启动的是 stdio 服务器:它阻塞运行,从 stdin 读取协议消息,向 stdout 写协议消息。这正是本页所有 host 说的"语言"。host 把你的文件作为子进程启动并持有这两条管道,所以"连接"永远只是"给你一个命令"——你从不选择端口,也没有任何端口在监听。从 SDK 源码看,MCPServer.run()transport参数默认值就是"stdio",并最终通过anyio.run(self.run_stdio_async)进入阻塞的事件循环(见 src/mcp/server/mcpserver/server.py)。
  • run()放在if __name__ == "__main__":之下:下面所有 host 都是导入这个文件而不是执行它,如果没有这层保护,任何代码一旦加载该模块就会立刻启动一个服务器。
  • 服务器对象是模块级全局变量,名为mcp:这是mcp run查找的默认名字(serverapp同样有效)。如果命名为别的,你需要显式指定:mcp run server.py:bookshop。在 CLI 实现中,导入模块后会依次探测mcpserverapp三个候选名,并校验其类型确实是MCPServer(见 src/mcp/cli/cli.py)。

这一页的 Python 代码到此为止,接下来全是 host 配置。配套的测试 tests/docs_src/test_real_host.py 展示了 host 视角下这台服务器暴露的内容:list_tools能列出search_booksget_author两个工具(名称、描述、输入 schema 全部来自代码),catalog://titles是一个可直接列出、可读取的资源。

启动命令:一个命令走遍所有 host

下面每个 host 接收的都是同一个命令:

uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py

所有 host 共用一条命令的原因在于uv run --with:它会在一个全新的临时环境中即时解析安装 SDK,从任何目录都能运行,既不需要项目,也不需要激活虚拟环境。这一点在 host 场景下比在其他地方更重要——因为 host 是从它自己的工作目录、用一个近乎空白的环境启动你的服务器,而不是从你的 shell。

这条命令也正是mcp install自动写进 Claude Desktop 配置的那条命令(见下文),所以手工输入与工具生成的内容一致,唯一差别是工具额外固定的精确版本号。

小贴士:host 找不到uv怎么办

host 用一个极简的PATH启动服务器,uv可能不在其中。此时把裸的uv替换为which uv(macOS/Linux)或where uv(Windows)给出的绝对路径——这正是mcp install写入的内容。源码中get_uv_path()会调用shutil.which("uv")解析出可执行文件完整路径(见 src/mcp/cli/claude.py)。

注意:本页讲的是"本地"故事

本页所有内容都是在你运行 host 的同一台机器上启动服务器:host 通过 stdio 拉起你的文件,这对个人工具或单机工具完全正确。要把服务器交给没有你文件的人,你分发的是URL而不是命令:同一个mcp对象通过 Streamable HTTP 提供服务。运行你的服务器 用一张表帮你做这个决策,部署与扩展 是从那里通向真正主机名的路径。

另外,host 无非是一个内置了 MCP 客户端的应用,所以你自己写的 Python 也能扮演 host:客户端传输 用Client(StdioServerParameters(...))把同一个文件作为子进程启动,而 测试 完全在内存中连接它,不需要任何进程。

Claude Desktop:SDK 唯一能替你配置的 host

Claude Desktop 是 SDK 中唯一能自动配置的 host,一条命令即可:

uv run mcp install server.py

仅此而已。mcp install会导入文件读取服务器名称,找到 Claude Desktop 的配置文件,并把启动命令写进去,同时自动把你的路径转换为绝对路径,你无需手工处理。

这不是什么黑魔法,下面是它写入的配置条目:

{ "mcpServers": { "Bookshop": { "command": "/absolute/path/to/uv", "args": [ "run", "--frozen", "--with", "mcp[cli]==2.0.0", "mcp", "run", "/absolute/path/to/server.py" ] } } }

这是上一节的启动命令,加了三点:uv的绝对路径;--frozen,确保uv永不改写它碰巧旁边的锁文件;以及对当前已安装mcp版本的精确固定。版本固定逻辑在 src/mcp/cli/claude.py 的mcp_requirement()中:它读取当前已安装发行版的版本号,生成mcp[cli]==<version>形式的依赖约束(开发版或本地构建则回退为不加版本号,因为这类版本不会发布到 PyPI)。配置写入claude_desktop_config.json,位置在:

  • macOS~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows%APPDATA%\Claude\claude_desktop_config.json
  • Linux$XDG_CONFIG_HOME/Claude/claude_desktop_config.jsonXDG_CONFIG_HOME缺省为~/.config,见 src/mcp/cli/claude.py)

这个文件完全可以手写。mcp install的存在是为了让你避免手写时最经典的错误——用了相对路径。

写完配置后,彻底退出Claude Desktop(不只是关窗口)再重新打开。

警告

如果 Claude Desktop 的配置目录还不存在,mcp install会以Claude app not found失败。先安装 Claude Desktop 并运行一次——目录就是这时创建的。

小贴士:环境变量与条目命名

Claude Desktop 在自己的进程中启动你的服务器,所以 shell 里的环境变量并不存在。uv run mcp install server.py -v API_KEY=abc123(或-f .env)会把它们写进配置条目的env字段。--name覆盖条目名称,默认取服务器的name。源码层面,update_claude_config保留已有的 env 变量,仅在提供新值时以新值优先合并(见 src/mcp/cli/claude.py),且--env-file需要python-dotenv支持(见 src/mcp/cli/cli.py)。

Claude Code:无需编辑文件,一条 CLI 注册

Claude Code 不需要编辑任何文件。用claudeCLI 注册服务器,--之后的所有内容就是启动命令:

claude mcp add bookshop -- uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py

在 Claude Code 会话中执行/mcp,确认bookshop已连接且其工具出现在列表中。

Cursor:项目根目录下的.cursor/mcp.json

在项目根目录创建.cursor/mcp.json

{ "mcpServers": { "bookshop": { "command": "uv", "args": ["run", "--with", "mcp[cli]", "mcp", "run", "/absolute/path/to/server.py"] } } }

同样的commandargs,置于与 Claude Desktop 相同的mcpServers键下。保存后服务器会出现在 Cursor 的 MCP 设置中,两个工具都会列出。

VS Code:项目根目录下的.vscode/mcp.json

在项目根目录创建.vscode/mcp.json

{ "servers": { "bookshop": { "type": "stdio", "command": "uv", "args": ["run", "--with", "mcp[cli]", "mcp", "run", "/absolute/path/to/server.py"] } } }

与 Cursor 配置文件相比只有两处差异,而且仅此两处:包裹键是servers而非mcpServers;每条目显式声明了type。确认信任提示后,在命令面板执行MCP: List Servers会看到bookshop正在运行。

注意

需要 VS Code 1.99 或更高版本,并已登录GitHub Copilot扩展(Copilot Free 即可),同时 Copilot Chat 必须处于Agent模式——只有该模式会调用工具。

排查:服务器"不出现"怎么办

在动任何 host 配置之前,先自己在终端跑一遍启动命令:

uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py

它什么都不打印、也不会退出——这种"沉默"才是正确的:一个 stdio 服务器正等待 host 先通过 stdin 说话(Ctrl-C停止)。真正的问题是 traceback 或立即退出,此时你能直接读到错误,而不必隔着 host 猜。

一旦这条命令停留在等待状态,剩下的问题几乎总是下面三种之一:

  • 相对路径。host 从它自己的工作目录启动你的服务器,而不是你注册时的目录。该写/absolute/path/to/server.py的地方写了server.py,是所有故障中最常见的一个。如果 host 连uv也找不到,uv的路径同样必须是绝对的。
  • host 仍在运行旧配置。host 在启动时读取配置。特别是 Claude Desktop,编辑claude_desktop_config.json后必须彻底退出(不是只关窗口)再重新打开才能生效。
  • 有东西在转发的窗口之外写到了 stdout。在 stdio 上,stdout 本身就是协议。SDK 会在服务期间把溢出的输出改写到 stderr,但此前已 flush 到 stdout 的输出(包装脚本的 echo、无缓冲进程在导入期的print()),或者解释器退出时被冲刷的缓冲print(),会把损坏的消息交给 host,导致连接被断开。请使用默认logging配置记录日志——它的 stderr handler 会逐条刷新;自定义 handler 也必须避开 stdout。日志 有完整的说明。

Claude Desktop 为每个服务器保留一份日志:mcp-server-<NAME>.log即你服务器的 stderr,与记录连接的mcp.log相邻,位于 macOS 的~/Library/Logs/Claude和 Windows 的%APPDATA%\Claude\logs

超出上述三种情况之外,故障排查 是专门的页面。

小结

  • host(Claude Desktop、IDE 等)运行着一个 MCP 客户端,它通过 stdio 把你的服务器作为子进程启动。"连接"就是给它一条启动命令。
  • 这条命令是uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py:无需激活虚拟环境,从任意目录都能运行。
  • Claude Desktopmcp install唯一能替你配置的 host。它把同一条命令(外加uv绝对路径、--frozen、对已装版本的精确固定)写入claude_desktop_config.json,你永远不用手写。
  • Claude Codeclaude mcp add bookshop -- <启动命令>Cursor.cursor/mcp.json下的mcpServersVS Code.vscode/mcp.json下的servers,且每条目带type
  • 处处使用绝对路径,编辑配置后重启 host,并且永远不要让 SDK 之外的任何东西写 stdout。

本页所有 host 都用同一条命令连接到了同一个文件。这个文件还能暴露什么,就是其余文档的主题:工具、资源,以及 stdio 之外的各种传输方式,见 运行你的服务器。

【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 21:46:05

如何给PicGo贡献代码:本地开发环境搭建到提交第一个PR的完整指南

如何给PicGo贡献代码&#xff1a;本地开发环境搭建到提交第一个PR的完整指南 【免费下载链接】PicGo 高效创作者的最佳图片上传工具。实现图片一键上传并自动获取链接&#xff0c;提升创作效率。它支持主流图床&#xff0c;提供拖拽、剪贴板粘贴等多种上传方式&#xff0c;具备…

作者头像 李华
网站建设 2026/9/20 21:41:13

Sunshine 快速上手 3 步:把 PC 变成 Moonlight 游戏串流服务器

Sunshine 快速上手 3 步&#xff1a;把 PC 变成 Moonlight 游戏串流服务器 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你的游戏装在 PC 上&#xff0c;电视、平板、手机却只能…

作者头像 李华
网站建设 2026/9/20 21:38:47

Lucky反向代理配置指南:单域名接入5个以上后端服务

Lucky反向代理配置指南&#xff1a;单域名接入5个以上后端服务 【免费下载链接】lucky 软硬路由公网神器,ipv6/ipv4 端口转发,反向代理,DDNS,WOL,ipv4 stun内网穿透,cron,acme,rclone,ftp,webdav,filebrowser 项目地址: https://gitcode.com/GitHub_Trending/luc/lucky …

作者头像 李华