news 2026/10/2 12:11:44

Cursor + Claude Desktop接入MCP Server实战:让AI真正调用你的Python工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cursor + Claude Desktop接入MCP Server实战:让AI真正调用你的Python工具

1. 为什么你的 Python 工具写完了,AI 却还是“看不见”

很多人第一次接触 MCP Server 时,都会经历一个心理落差:代码写完了,python server.py也能跑起来,终端里安安静静没有报错,可一打开 Cursor 或 Claude Desktop,问它“帮我查一下上海天气”,它还是自顾自地编一段回答,完全不碰你写的函数。

问题不在你的 Python 代码,而在于客户端根本不知道这个 Server 存在。MCP(Model Context Protocol)的本质,是给 AI 客户端和本地工具之间定一套“发现—描述—调用”的协议。你的 Server 只是把工具“挂”了出来,但 Cursor 和 Claude Desktop 需要被明确告知:去哪里启动它、用什么命令启动、启动后能拿到哪些工具。

我试过把整个链路拆开看,它其实是这样的:

用户提问 → Claude Desktop / Cursor → MCP Client → MCP Server → Python Tool → 数据库/API/文件 → 返回结果 → AI 组织自然语言

真正执行 Python 代码的是 MCP Server,AI 只负责“决定什么时候调用哪个工具”。所以接入的核心动作只有两个:把 Server 注册进客户端配置,以及验证 AI 确实触发了你的函数。这篇就围绕 FastMCP 写的 Python 工具,把 Cursor 和 Claude Desktop 两条接入路径都走一遍,每一步都给可复制的配置和验证方法。

适合谁看:已经用 FastMCP 写过至少一个@app.tool()的 Python 开发者;想让 Cursor 里的 AI 真正调用本地脚本的人;以及准备把内部系统封装成 MCP 工具、但卡在“接不上客户端”这一步的工程同学。

需要提前说明一点:MCP Server 跑在本地,客户端通过标准输入输出或本地命令与它通信,不涉及任何网络穿透类操作。你只需要保证 Python 环境可用、脚本路径正确即可。

2. 用 FastMCP 把 Python 工具封装成 MCP Server 的完整写法

在接入客户端之前,先把 Server 本身写扎实。FastMCP 的好处是把协议细节都藏起来了,你只需要关心“工具函数长什么样”。但要让 AI 正确选择工具,函数命名、类型标注、docstring 这三样一个都不能省。

先装依赖。FastMCP 现在有独立包,也可以直接用官方mcp包里的 FastMCP:

pip install fastmcp # 或者 pip install mcp

下面是一个可以直接跑的server.py,我放了两个工具:一个做加法,一个查天气(先用假数据,方便验证调用链路):

from mcp.server.fastmcp import FastMCP app = FastMCP("DemoTools") @app.tool() def add(a: int, b: int) -> int: """计算两个整数之和,用于数学运算类请求。""" return a + b @app.tool() def get_weather(city: str) -> str: """查询指定城市的当前天气,输入为城市中文名。""" fake = {"上海": "晴,30℃", "北京": "多云,26℃"} return fake.get(city, f"{city} 暂无数据") if __name__ == "__main__": app.run()

启动它:

python server.py

如果终端没有报错、进程保持运行,说明 Server 已经就绪。这里有个容易被忽略的点:@app.tool()装饰器是工具被发现的唯一入口。如果你写了函数却忘了加装饰器,AI 那边永远看不到它,后面配置再正确也没用。

工具暴露给 AI 的其实是这样一段结构化描述:

{ "name": "get_weather", "description": "查询指定城市的当前天气,输入为城市中文名。", "inputSchema": { "city": "string" } }

AI 就是靠name和description判断“什么时候该调用它”。所以def test():这种命名和空 docstring 是灾难,模型根本不知道它能干什么。反过来,get_weather加上一句清晰描述,命中率会高很多。

再补一个稍微贴近真实业务的工具,把数据库查询封装成固定用途函数,而不是让模型直接执行任意 SQL:

@app.tool() def query_customer(customer_id: int) -> dict: """根据客户 ID 查询客户基本信息,返回姓名与等级。""" # 实际项目里替换为你的 DB 查询 return {"id": customer_id, "name": "张三", "level": "VIP"}

这种写法的好处是权限边界清晰:模型只能调用你允许的固定查询,不能拼 SQL。企业项目里这一点比“功能强大”更重要。

Server 写完后,建议先在命令行确认它能正常启动、不依赖任何客户端。因为后面 90% 的接入失败,根源都在“Server 本身没跑起来”或“路径写错”。

3. Cursor 与 Claude Desktop 的 MCP 配置片段(可直接复制)

这一节是重点,两个客户端的配置文件格式不同,但核心三要素一致:启动命令、脚本路径、Server 名称。任何一处写错,客户端都会静默失败或报 “No MCP Server”。

3.1 Claude Desktop 配置

Claude Desktop 通过一个 JSON 配置文件注册本地 MCP Server。不同系统路径不同:

  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows:%APPDATA%\Claude\claude_desktop_config.json

打开(没有就新建)后写入:

{ "mcpServers": { "demo-tools": { "command": "python", "args": [ "D:/mcp/demo/server.py" ] } } }

三个字段的含义:

字段作用常见错误
demo-toolsServer 名称,客户端内显示用重名会互相覆盖
command启动命令写成python3但系统只有python
args脚本绝对路径用相对路径导致找不到文件

保存后完全退出并重启 Claude Desktop(不是关窗口,是退出进程)。重启时它会自动拉起这个 Server,并发现add、get_weather、query_customer三个工具。

如果 Python 不在系统 PATH 里,command要写绝对路径,比如 Windows 下"C:/Python311/python.exe"。这是新手最常踩的坑之一。

3.2 Cursor 配置

Cursor 的 MCP 配置入口在设置里,不同版本位置略有差异,通常在Settings → MCP或Features → MCP Servers,选择 “Add Server”。它同样支持 JSON 配置,格式与 Claude Desktop 接近:

{ "mcpServers": { "demo-tools": { "command": "python", "args": [ "D:/mcp/demo/server.py" ] } } }

如果你用的是较新版本,Cursor 也支持在项目根目录放.cursor/mcp.json,这样配置可以跟着项目走,团队协作时更方便。写入后重启 Cursor,在 MCP 面板里应该能看到demo-tools处于已连接状态,展开后列出三个工具。

这里要强调一个完整配置的“三件套”概念:无论 Claude Desktop 还是 Cursor,一个可用的 MCP 接入都必须同时具备Base URL(本地场景即启动命令)、Key(本地场景通常不需要,远程 Server 才涉及)、Model ID(客户端里选用的模型)。本地 stdio 模式下,Key 一般留空,但如果你接的是远程 MCP 服务,就需要在配置里补上鉴权信息。很多教程只贴一半配置,导致读者接不上,问题就出在这。

配置完成后,两个客户端的行为是一致的:启动时自动拉起 Server,读取工具列表,之后在对话中按需调用。你不需要手动“连接”,客户端会管理生命周期。

4. 验证 AI 真的调用了你的 Python 函数

配置写完不代表成功,必须做一次可观测的调用验证。否则你无法区分“AI 调用了工具”和“AI 自己编了答案”。

最直接的验证方式,是在工具函数里加一行打印,让调用留下痕迹:

@app.tool() def add(a: int, b: int) -> int: """计算两个整数之和,用于数学运算类请求。""" print(f"[TOOL CALLED] add({a}, {b})") return a + b

然后在 Claude Desktop 或 Cursor 里输入:

帮我计算 12345 加 67890

如果接入成功,你会看到两件事同时发生:客户端返回80235,同时运行 Server 的终端里打印出[TOOL CALLED] add(12345, 67890)。这行打印就是“AI 真正触发了 Python 函数”的铁证。

再验证天气工具:

上海今天多少度?

预期终端打印[TOOL CALLED] get_weather(上海),客户端回答里出现“晴,30℃”。如果 AI 回答的是“我无法获取实时天气”,说明工具没被发现;如果它编了一个温度,说明它没调用工具而是自己生成。

这里有个细节值得注意:AI 内部流程是“理解需求 → 发现可用工具 → 选择get_weather→ 传入city="上海"→ 拿到返回值 → 组织自然语言”。整个过程用户无感知,但后台函数确实执行了。这也是 MCP 相比“让模型直接写代码”的核心价值——执行发生在你可控的 Python 环境里,而不是模型的黑盒里。

验证通过后,你可以把假数据换成真实 API 或数据库查询,链路不用改。工具层、业务层、数据访问层分离,后续维护会轻松很多。

5. 接入失败排查:401、local proxy failed、reading choices、OAuth 对照表

接入阶段最常见的不是代码错,而是配置和环境的错。下面按真实报错逐条对照。

报错一:No MCP Server或工具列表为空

这是最高频的问题。原因通常是三类:Python 路径错误、脚本路径错误、环境变量未生效。排查顺序是先在命令行手动执行python D:/mcp/demo/server.py,确认能启动;再把配置里的command换成 Python 绝对路径;最后确认 JSON 没有多余逗号。JSON 语法错误会导致整个配置被忽略,且客户端往往不报明确错误。

报错二:401 Unauthorized

本地 stdio 模式一般不会出现 401。如果你接的是远程 MCP 服务,401 说明鉴权信息缺失或过期。检查配置里是否带了正确的 Key,以及 Key 是否已失效。远程场景下 Base URL、Key、Model ID 三件套缺一不可。

报错三:local proxy failed

这个报错通常出现在客户端尝试通过本地代理连接 Server 时。检查是否有其他进程占用了同一端口,或配置里误加了代理相关字段。本地 stdio 模式不需要任何代理设置,把多余字段删掉即可。

报错四:reading choices相关错误

这类错误多出现在模型返回结构解析阶段,常见于客户端版本与模型接口不匹配。先升级 Cursor / Claude Desktop 到最新版,再确认所选模型 ID 正确。如果配置里 Model ID 写错,客户端可能拿到非预期响应。

报错五:OAuth 相关报错

部分远程 MCP 服务要求 OAuth 授权。如果报 OAuth 失败,检查回调地址是否与注册时一致,以及授权是否已过期。本地工具不需要 OAuth,遇到这个报错说明你接的是远程服务,按服务方文档重新授权即可。

报错六:AI 始终不调用工具

配置没问题、工具也发现了,但 AI 就是不用。这几乎总是描述问题。把def test():改成def get_weather(city: str):,并补上 docstring。函数名要能自解释,参数类型要标注,描述要说清“什么时候用”。模型选择工具靠的就是这些元信息。

排查时建议养成一个习惯:每改一次配置就重启客户端,并观察 Server 终端输出。有打印就说明链路通了,没打印就往配置和路径上找。这套方法能覆盖绝大多数接入问题。

6. 把工具接上之后,下一步怎么走

走到这里,你的 FastMCP Server 应该已经能在 Cursor 和 Claude Desktop 里被真实调用了。回头看,真正卡住大多数人的从来不是 Python 代码,而是“客户端不知道 Server 在哪”这一层配置。把配置写对、把验证做扎实,AI 就从“会聊天”变成了“能干活”。

如果你还想继续扩展,几个方向比较实用:把数据库查询、文件操作、内部 API 都封装成固定用途的工具,让模型在权限边界内调用;给工具加统一的异常处理和超时,避免一个慢查询拖垮整个对话;敏感信息走环境变量,不要写进代码或配置。

需要提醒的是,MCP 工具应该封装成明确的业务动作,而不是把生产库的任意 SQL 执行权交给模型。工具层做窄、做清晰,权限和审计才好落地。

接入过程中如果卡在配置或鉴权上,可以直接对照官方文档排查,也可以到控制台里管理你的 Key 和接入信息。把本地工具接上 AI 客户端只是第一步,后面把更多业务能力以 MCP 工具的形式暴露出来,AI Agent 能承担的事情会越来越多。

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

Agent开发实战:ADK框架从零搭建到多工具编排的TaoToken配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 12:09:29

全景解读 MCP 协议:从 Cline MCP 到 TaoToken 统一 Key 的接入实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/2 12:09:28

1688商品爬虫实战:Selenium绕过滑块+SQLite入库毕设方案

简介:本资源是一套基于Selenium实现的1688平台商品信息自动化采集系统,专为计算机相关专业学生毕业设计、课程设计及初学者实践打造,解决电商数据抓取中的反爬应对、动态页面渲染与结构化存储等典型问题。压缩包共19个文件,含7个核…

作者头像 李华