ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

连接真实宿主:用 MCP Python SDK 将服务器接入 Claude Desktop、Claude Code、Cursor 与 VS Code

连接真实宿主:用 MCP Python SDK 将服务器接入 Claude Desktop、Claude Code、Cursor 与 VS Code 连接真实宿主用 MCP Python SDK 将服务器接入 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-sdkpython-sdkModel Context Protocol 官方 Python SDK开发的 MCP 服务器最终都要跑在一个宿主host应用里——Claude Desktop、Claude Code、IDE 都算宿主用户是在宿主里与你的工具交互的。本文基于官方文档 docs/get-started/real-host.md 讲解接入宿主的完整流程你将掌握统一的服务端启动命令以及把它分别写进 Claude Desktop、Claude Code、Cursor、VS Code 配置的四种方式并学会在服务器不显示时按部就班地定位问题。读完你会发现接入宿主本质上只有一件事——告诉宿主用哪条命令启动你的服务器。宿主的角色进程、管道与 stdio一个宿主host就是你的服务器最终运行在其中的应用Claude Desktop、Claude Code、某款 IDE。宿主是用户直接对话的对象在宿主内部一个 MCP客户端client把你的服务器文件作为子进程启动并通过该进程的 stdin / stdout 两条管道与它通信。这一点决定了连接宿主这个动作的全部含义你只需要告诉宿主启动你服务器的命令。本文接下来的全部内容两条 CLI 命令、三个 JSON 文件本质上是同一个命令的不同存放位置。宿主启动你的文件作为子进程并拥有这两条管道所以你永远不会去选端口也没有任何端口在监听。从源码看MCPServer.run()的默认传输正是 stdioserver.py 中run()不带参数时transport默认为stdio并经由run_stdio_async()使用stdio_server()建立读写流后交给底层服务器循环server.py。宿主侧的客户端则通过Client(StdioServerParameters(...))以子进程方式启动同一文件参见 docs/client/transports.md。一个服务器适配所有宿主文档用同一个示例文件演示所有宿主docs_src/real_host/tutorial001.py 是一个Bookshop书店服务器包含两个工具search_books、get_author和一个资源catalog://titles全部代码只有一个文件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(fNo 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()对这个文件有三个要点关系到后面每一个宿主的接入mcp.run()不带参数即启动 stdio 服务器它会阻塞从 stdin 读取协议消息、向 stdout 写入响应。这正是本文所有宿主使用的传输方式。测试 tests/docs_src/test_real_host.py 也验证了该服务器对外暴露的内容tools/list返回两个工具及其 JSON Schematools/call能完成真实往返如search_books({query: gibson})返回[Neuromancer]资源catalog://titles可被列出并读取。run()必须放在if __name__ __main__:之内下面所有接入方式都是import这个文件而不是直接执行它若没有这层保护任何模块加载都会立刻启动一个服务器。mcp install、mcp run等 CLI 工具正是通过 import 来读取服务器对象见 src/mcp/cli/cli.py 的_import_server。服务器对象是模块级全局变量且必须叫mcp这是mcp run查找的默认名字server和app也兼容。如果你用了其他名字就必须显式指定mcp run server.py:bookshop。CLI 源码 cli.py 中按[mcp, server, app]的顺序探测全局变量并校验其类型必须是MCPServerfile:object语法在_parse_file_path中通过最后一个冒号切分解析Windows 盘符除外。这是本页最后一行 Python从下一节起全是宿主配置。统一的启动命令下面所有宿主接收的都是同一条命令uv run --with mcp[cli] mcp run /absolute/path/to/server.py所有宿主共用一条命令是因为uv run --with会当场把 SDK 解析进一个全新环境它可以从任意目录运行不需要项目、也不需要激活虚拟环境。这一点在这里比其他任何场景都重要——宿主是从它自己的工作目录、用一个近乎空白的环境启动你的服务器而不是从你的 shell。这条命令也正是mcp install替你写入 Claude Desktop 配置的命令见下文所以手动输入与工具生成的结果是一致的唯一的差别是工具额外追加了一个精确的版本锁定。提示宿主找不到uv怎么办宿主以最小化的PATH启动你的服务器uv可能不在其中。此时把裸的uv换成which uvmacOS/Linux或where uvWindows返回的绝对路径即可——这正是mcp install写入的内容。注意本页是本地场景本文所有方式都是在宿主所在机器上运行你的服务器宿主通过 stdio 启动你的文件。这正适合个人工具或单机场景。若要把服务器交付给没有你文件的人你分发的是URL而不是命令同一个mcp对象以 Streamable HTTP 方式对外服务。决策对照表见 docs/run/index.md从那里走向真实主机名的路径见 docs/run/deploy.md。 另外宿主不过是内部含有一个 MCP 客户端的应用所以你自己的 Python 代码也能扮演宿主用Client(StdioServerParameters(...))以子进程方式启动同一个文件docs/client/transports.md或者在 docs/get-started/testing.md 中于内存中连接它完全不开进程。Claude DesktopSDK 唯一能替你配置的宿主Claude Desktop 是 SDK 能自动配置的唯一宿主一条命令即可uv run mcp install server.py仅此而已。mcp install会 import 这个文件以读取服务器名称找到 Claude Desktop 的配置文件并把启动命令写进去过程中它顺手把路径转成绝对路径你无需手动处理。它写入的条目毫无神秘之处就是下面这段 JSON{ 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永不改写附近恰好存在的 lockfile、以及一个对你当前安装的mcp版本的精确锁定。这三处都由源码直接产生get_uv_path()用shutil.which(uv)解析出绝对路径src/mcp/cli/claude.pymcp_requirement()依据已安装的mcp版本生成mcp[cli]X.Y.Z形式的锁定串仅当版本号含.dev或源码构建的本地版本段未发布到 PyPI或包未安装时才退化为不带锁定的形式claude.pyupdate_claude_config()则负责把文件路径解析为绝对路径保留:object后缀并写出配置claude.py。该配置落在claude_desktop_config.json位置为macOS~/Library/Application Support/Claude/claude_desktop_config.jsonWindows%APPDATA%\Claude\claude_desktop_config.jsonLinux 上get_claude_config_path()会读取XDG_CONFIG_HOME或~/.config下的Claude目录见 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_KEYabc123或-f .env会把这些变量记入条目的env字段。--name可覆盖条目名称默认取服务器的name。底层实现中update_claude_config会合并已有env与新增变量新值优先并读取-f指定的.env文件见 cli.py。Claude Code没有文件要编辑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] } } }同样的command与args同样的mcpServers键——与 Claude Desktop 完全一致。配置后服务器会出现在 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且每条目声明了自己的typestdio。确认信任提示后在命令面板执行MCP: List Servers即可看到bookshop正在运行。注意你需要 VS Code 1.99 或更高版本登录GitHub Copilot扩展Copilot Free 即可且 Copilot Chat 必须处于Agent模式——其他模式不会调用工具。服务器不显示按这个顺序排查在你改动任何宿主配置之前先自己运行一遍启动命令uv run --with mcp[cli] mcp run /absolute/path/to/server.py什么都不打印、也不返回——这是正确的表现一个 stdio 服务器正在等待宿主先通过 stdin 开口按Ctrl-C停止。真正的 bug 是立即抛出的 traceback 或立即退出而现在你能直接读懂它不必隔着宿主去猜。一旦这条命令能安静地等待剩下的问题几乎总逃不出三种相对路径。宿主从它自己的工作目录启动服务器而不是你当初注册时所在的目录。该写/absolute/path/to/server.py的地方写了server.py是最常见的一类失败如果宿主连uv都找不到那uv的路径也必须用绝对路径。宿主还在跑旧配置。宿主在启动时读取配置。尤其是 Claude Desktop编辑claude_desktop_config.json后必须彻底退出只关窗口不够再重新打开改动才会生效。有内容在分流窗口之外写到了 stdout。在 stdio 下stdout就是协议本身。SDK 在服务期间会把 flush 过的零散输出分流到 stderr但在此之前的 stdout 输出wrapper 脚本的回显、无缓冲进程在 import 时的print()或者缓冲的print()在解释器退出时才落盘都会把损坏的消息交给宿主宿主随即断开连接。请使用默认logging配置记录日志——其 stderr handler 会对每条记录 flush见 src/mcp/server/mcpserver/utilities/logging.pyRichHandler绑定Console(stderrTrue)自定义 handler 同样必须避开 stdout。完整说明见 docs/handlers/logging.md。Claude Desktop 为每个服务器保留一份日志mcp-server-NAME.log即你服务器的 stderr与连接日志mcp.log并列位于 macOS 的~/Library/Logs/Claude与 Windows 的%APPDATA%\Claude\logs。超出上述三种情况请参阅 docs/troubleshooting.md。小结宿主Claude Desktop、IDE 等运行一个 MCP 客户端通过 stdio 以子进程方式启动你的服务器。连接 给它一条启动命令。那条命令是uv run --with mcp[cli] mcp run /absolute/path/to/server.py无需激活虚拟环境、从任意目录都能运行。Claude Desktop是mcp install唯一能替你配置的宿主。它把同一条命令外加uv的绝对路径、--frozen、对你所装版本的精确锁定写入claude_desktop_config.json让你永远不必手写。Claude Code用claude mcp add bookshop -- launch commandCursor是.cursor/mcp.json下的mcpServersVS Code是.vscode/mcp.json下的servers每条目带type。全程使用绝对路径编辑宿主配置后重启宿主并且绝不让 SDK 之外的任何东西写 stdout。本页所有宿主都用同一条命令连接了同一个文件。这个文件还能暴露什么就是其余文档的事了docs/servers/tools.md、docs/servers/resources.md以及 stdio 之外的全部传输方式见 docs/run/index.md。【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址: https://gitcode.com/gh_mirrors/pythonsd/python-sdk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表