)
1. 为什么你的 AI Agent 总是“接不上”外部工具很多人第一次做 AI Agent卡住的地方不是模型不会写代码而是模型根本“够不着”外部世界。你让它查个天气它只能编你让它读本地文件它只能猜你让它调数据库它连表结构都看不到。于是你开始写一堆胶水代码这个工具用 HTTP那个工具用 SQL再来一个用 Playwright最后整个项目变成接口适配大杂烩。MCPModel Context Protocol模型上下文协议就是来解决这个问题的。你可以把它理解成 AI 应用和外部资源之间的“统一插座”不管外面是文件系统、数据库、浏览器还是某个内部 API只要对方按 MCP 协议暴露能力你的 Agent 就能用同一套方式去发现工具、调用工具、拿回结果。对零基础读者来说最直观的理解是——以前每接一个工具都要重新学一门“方言”现在大家都说普通话了。这篇内容面向的是本地开发环境目标很明确带你从零跑通第一个可用的 MCP AI Agent 原型。你会拿到可复制的 MCP 服务端配置、Agent 调用示例源码以及本地验证步骤。全程不需要你懂复杂的分布式知识只要会装 Python 包、会跑命令行就能跟着做下来。核心检索词就三个MCP、AI Agent、源码。我试过把整套流程拆成最小可运行单元踩过的坑也会在排障章节里标出来。先说清楚 MCP 的架构不然后面配置容易懵。MCP 里有两个关键角色MCP Server 和 MCP Client。MCP Server 不是传统意义上那种集中式服务器它更像一个“服务插件”可以跑在你本机也可以远程部署。它对外提供三类东西Tools工具给 Agent 调用、Resources结构化数据给模型当上下文、Prompts提示词模板给 ChatBot 类应用选用。MCP Client 则是你的 LLM 应用里维护的一个会话负责和 Server 通信比如列出工具有哪些、调用某个工具、拿回结果。本地模式下Client 和 Server 之间通过 stdio标准输入输出做进程间通信。你可以类比成命令行管道cat file.txt | grep error | sort result.txt数据在进程之间流动只不过这里流动的是结构化的 MCP 消息。Server 的启动方式通常是在 Client 配置里写好启动命令Client 一运行Server 作为独立进程被拉起来。不同 Server 的启动命令不一样有的需要先装依赖有的用npx或uvx临时下载运行。编程语言方面TypeScript、Python、Java 都有 SDK这篇用 Python 来演示因为对小白最友好。理解了这些你就知道为什么 Agent 特别需要 MCPAgent 的本质就是“模型 工具 调度”它比普通 ChatBot 更依赖外部资源。没有 MCP 的时候每加一个工具都是一次定制开发有了 MCP加工具变成“插拔”动作。外部接口变了只改对应的 Server所有连它的应用都能跟着适应。这就是统一协议带来的杠杆效应。2. 前置准备TaoToken 接入与本地环境清单在写 Agent 之前先把“模型从哪来”这件事解决掉。本地跑 Agent 需要一个能调用的模型服务这里用 TaoToken 来做接入。它的官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。注意 API 地址后面不加 UTM 参数配置的时候别写错。你需要准备的东西不多我列一下清单照着核对就行Python 3.10 或以上建议用虚拟环境隔离依赖pip 能正常安装包一个可用的 TaoToken API Key本地能访问外网的命令行环境用于拉取依赖一个顺手的编辑器VS Code 就行先装 MCP 的 Python SDK命令很简单pip install mcp如果你用的是虚拟环境先激活再装。装完之后可以验证一下python -c import mcp; print(mcp.__version__)能打印出版本号就说明 SDK 就位了。接下来拿 API Key进入控制台创建即可https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。创建完把 Key 复制出来后面配置里要用。如果你还没想好怎么管理 Key可以先看下 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。这里有个关键点MCP Server 本身不负责“调模型”它只负责暴露工具。真正调模型的是你的 Agent 应用也就是 MCP Client 那一侧。所以模型接入配置要写在 Agent 应用里而不是 Server 里。很多人第一次做会搞混把 API Key 塞进 Server结果 Server 跑起来了但模型根本调不动。模型选择上如果你只是验证流程用模型对话页面先试一下连通性最省事https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。确认模型能正常返回再进到代码环节。如果你打算长期做编码类 Agent可以了解下 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 配置细节以文档为准。环境变量建议这样管理别把 Key 硬编码进源码export TAOTOKEN_API_KEY你的Key export TAOTOKEN_BASE_URLhttps://taotoken.net/apiWindows 下用set或者直接在 IDE 的运行配置里加环境变量。这样做的原因是源码可能被分享出去Key 泄露了很麻烦。后面代码里统一用os.environ读取。再确认一下目录结构建议这样组织后面复制代码不容易乱mcp-agent-demo/ ├── server_demo.py ├── client_demo.py └── requirements.txtrequirements.txt里至少写mcp openai如果你用的模型接口是 OpenAI 兼容格式openai这个包能省很多事。装依赖pip install -r requirements.txt到这里前置就齐了。总结一下SDK 装好、Key 拿到、环境变量设好、目录建好。接下来进入可复制配置环节。3. 可复制配置MCP Server 与 Agent 调用源码这一节是核心直接给可复制的代码和配置。先写 MCP Server它只提供一个计算器工具方便你验证整条链路。文件server_demo.py# server_demo.py from mcp.server.fastmcp import FastMCP mcp FastMCP(演示) mcp.tool() def calculate(expression: str) - float: 计算四则运算表达式 参数: expression: 数学表达式字符串如 1 2 * 3 返回: 计算结果 allowed set(0123456789-*/(). ) if not set(expression) allowed: raise ValueError(表达式包含不允许的字符) return eval(expression, {__builtins__: {}}, {}) if __name__ __main__: mcp.run(transportstdio)注意最后那行mcp.run(transportstdio)必须有否则 Server 不会以 stdio 模式启动。eval这里做了字符白名单避免执行任意代码虽然是个演示但安全习惯要从小例子养起。接下来写 Agent 侧也就是 MCP Client 加模型调度。文件client_demo.py# client_demo.py import asyncio import json import os from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client from openai import OpenAI server_params StdioServerParameters( commandpython, args[./server_demo.py], envNone, ) client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlos.environ[TAOTOKEN_BASE_URL], ) async def main(): async with stdio_client(server_params) as (read, write): async with ClientSession(read, write, sampling_callbackNone) as session: await session.initialize() tools await session.list_tools() tool_specs [] for t in tools.tools: tool_specs.append({ type: function, function: { name: t.name, description: t.description, parameters: t.inputSchema, }, }) messages [ {role: user, content: 帮我算一下 188*23-34 等于多少} ] resp client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstool_specs, ) msg resp.choices[0].message if msg.tool_calls: call msg.tool_calls[0] args json.loads(call.function.arguments) result await session.call_tool(call.function.name, args) print(工具返回:, result.content) else: print(模型直接回答:, msg.content) asyncio.run(main())这段代码做了三件事启动并连接 MCP Server、把 Server 的工具列表转成模型能识别的 function 格式、让模型决定是否调用工具并把结果拿回来。model字段按你实际可用的模型名填这里只是示例。如果你更习惯用配置文件的方式管理 MCP Server可以写一个 JSON 片段很多客户端都认这种格式{ mcpServers: { demo-calculator: { command: python, args: [./server_demo.py], env: {} } } }这个片段可以直接放进支持 MCP 的客户端配置里。注意路径要写对相对路径是相对于客户端工作目录的不确定就用绝对路径。如果你用的是 Claude Code 这类工具配置通常放在settings.json或项目级配置里Base URL、Key、Model ID 三件套要写全{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: 你的Key, ANTHROPIC_MODEL: 你的模型ID } }Claude Code 相关接入可以参考https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 。这里强调一下Base URL、Key、Model ID 缺一不可少一个就会出现 401 或者模型找不到的报错。配置写完后先别急着跑 Agent单独测一下 Server 能不能起来python server_demo.py如果它卡住不动其实是正常的因为 stdio 模式在等输入。按 CtrlC 退出即可。真正验证要靠 Client 或 Inspector。4. 验证请求跑通第一个 Agent 并看到结果现在开始验证。第一步直接运行 Clientpython client_demo.py如果一切正常你会看到类似这样的输出工具返回: [TextContent(typetext, text4290, annotationsNone)]4290 就是 188*23-34 的结果。这说明整条链路通了模型识别出需要调用工具Client 通过 MCP 协议调用 Server 的calculateServer 执行后把结果返回。你刚刚跑通的就是一个最小可用的 MCP AI Agent 原型。如果模型没有调用工具而是直接回答可能是模型本身算对了也可能是工具描述没被正确识别。可以换一个更复杂、模型不容易直接算的表达式比如带括号的(188*23-34)/2再看它是否走工具调用。第二步用 MCP Inspector 做可视化调试。对于 Python 写的 Server运行mcp dev server_demo.py然后浏览器访问 http://localhost:5173 你会看到一个调试界面可以列出工具、填参数、点调用直接看到返回。这个方式特别适合单独开发 Server 的时候用不用每次都跑整个 Agent。第三步验证模型对话链路。如果你不确定模型服务是否正常可以先用模型对话页面发一条消息https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。能正常返回说明 Key 和 Base URL 没问题问题就缩小到 MCP 配置或代码逻辑上。第四步观察日志。MCP 的 stdio 通信是双向的如果 Server 里有print输出可能会干扰协议消息。所以 Server 里尽量不要用print调试改用日志写到文件或者用 Inspector。这一点很多人会踩坑明明工具逻辑没问题但 Client 就是报解析错误原因就是 Server 往 stdout 里打了额外内容。验证通过后你可以试着加第二个工具比如一个返回当前时间的工具from datetime import datetime mcp.tool() def now() - str: 返回当前时间 return datetime.now().isoformat()重启 Client问模型“现在几点”看它是否会调用now。这一步能帮你确认工具注册和调度逻辑是可扩展的不是只能跑一个写死的例子。到这里你已经完成了从环境准备、配置、编码到验证的完整闭环。接下来把常见报错过一遍避免卡在细节上。5. 常见报错排查401、local proxy failed 与 choices 解析排障这一节按真实报错来对照遇到问题直接搜关键词。401 未授权。典型表现是模型调用返回 401或者提示 invalid api key。原因通常是 Key 没设对环境变量、Key 复制时带了空格、或者 Base URL 写错。检查方式echo $TAOTOKEN_API_KEY echo $TAOTOKEN_BASE_URL确认输出正确。Base URL 应该是https://taotoken.net/api不要多加斜杠或路径。如果用的是 Claude Code 类配置检查ANTHROPIC_BASE_URL、ANTHROPIC_API_KEY、ANTHROPIC_MODEL三件套是否齐全。缺 Model ID 有时也会报类似鉴权失败的错误容易误导。local proxy failed。这个报错通常出现在客户端尝试启动本地 MCP Server 时。原因可能是command写错比如python不在 PATH 里或者args里的脚本路径不对。排查步骤先在终端手动执行配置里的命令看能不能起来。比如配置写的是python ./server_demo.py你就手动跑一遍。如果手动能跑、客户端跑不了多半是工作目录不同导致相对路径失效改成绝对路径即可。reading choices 相关报错。典型信息是list index out of range或者读取choices[0]时报错。这通常是因为模型返回结构和你预期不一致比如请求失败但没抛异常返回体里没有choices。排查方式把原始响应打印出来看。print(resp)如果resp.choices为空检查模型名是否正确、请求参数是否合法。另一个常见原因是工具调用返回后你没有把工具结果作为新消息追加回对话导致下一轮请求结构不完整。正确做法是把tool角色的消息加进messages再请求一次。OAuth 相关报错。如果你接的是需要 OAuth 的服务可能会看到 token 过期或 scope 不足。这类问题先确认授权流程是否走完token 是否刷新。MCP 本身不负责 OAuth它只是传输层授权逻辑在对应的 Server 或外部服务里。工具调用参数解析失败。报错类似json.decoder.JSONDecodeError。原因是模型返回的arguments不是合法 JSON或者你直接把它当 dict 用了。正确做法是先json.loads并加异常处理try: args json.loads(call.function.arguments) except json.JSONDecodeError: args {}Server 启动后无响应。检查是否用了transportstdio以及 Server 里是否有阻塞式代码。另外Client 和 Server 必须成对使用单独跑 Server 在终端里看起来“卡住”是正常的。把这几类报错过一遍基本能覆盖 90% 的本地搭建问题。剩下的就是具体业务逻辑的调试了。6. 从原型到可用下一步怎么走跑通计算器这个例子之后你可以按同样的模式扩展真实工具。比如把本地文件读取封装成 MCP 工具让 Agent 能读项目里的配置文件或者把数据库查询封装成工具让 Agent 根据自然语言生成查询并返回结果。核心结构不变Server 暴露工具Client 发现并调度模型决定调哪个。如果你打算长期做编码类 Agent建议了解 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入细节以文档为准https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。Key 管理在控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。最后给一个实用建议把每个 MCP Server 当成独立小项目来维护工具描述写清楚参数 schema 写严谨这样模型调用成功率会高很多。工具描述不是写给人看的是写给模型看的越明确越好。