搞不懂 MCP?从 Function Call 到 MCP Server 手搓一个最小实现

发布时间:2026/10/9 12:22:01
搞不懂 MCP?从 Function Call 到 MCP Server 手搓一个最小实现 1. 从 Function Call 到 MCP为什么你的 LLM 还是“干啥啥不行”如果你最近在折腾 AI Agent大概率被 MCP 这个词刷过屏。MCP 全称 Model Context Protocol模型上下文协议简单说就是给大模型接外部工具定了一套统一插口。它能让你的 LLM 从“只会聊天”变成“能查天气、能读文件、能调数据库”的干活助手适合刚接触 MCP、写过 Function Call 但被多模型适配折磨过的开发者。我最早做微信 AI 机器人时走的就是 Function Call 路线在提示词里写死一堆意图标签用户说“查天气”就调高德 API说“算个数”就调计算器。问题是意图识别不是 100% 准换个模型 tools 参数结构又变了一顿操作写了个接口换 LLM 居然理解不了。Function Call 的硬伤在于它必须由 LLM 本身支持而且不同厂商的输入输出结构、触发结构都不一样你为 GPT 写的 tools搬到通义千问上可能直接报错。MCP 解决的正是这个痛点。它把“工具怎么描述、怎么调用、怎么返回”抽成一套标准协议LLM 不再直接面对五花八门的 API而是通过 MCP Client 去和 MCP Server 通信。Server 可以是本地进程也可以是远程服务Client 负责把工具列表转成 LLM 能理解的格式再把 LLM 的调用请求转发给对应 Server。这样一来你写一次 Server所有支持 MCP 的宿主都能用。这篇文章不堆概念直接带你手搓一个最小 MCP Server从配置到启动再到 Cline MCP 里接入验证把整条请求链路跑通。你会看到 stdio 和 SSE 两种传输方式的区别也会拿到可复制的 JSON 配置和排错清单。读完你至少能自己写一个计算器 Server并让 LLM 成功调用它。2. TaoToken 前置给 MCP Client 准备一个稳定的模型入口MCP Client 本身不产生智能它只是中间人真正决定“要不要调工具、调哪个工具”的还是背后的 LLM。所以在你动手写 Server 之前得先有一个能正常响应 Function Call 的模型接口。我实测下来TaoToken 的 API 兼容 OpenAI 格式base_url 填https://taotoken.net/api就能直接用省去自己折腾多模型适配的麻烦。为什么强调“稳定入口”因为 MCP 的调试过程里你会反复让 LLM 判断工具调用如果模型接口时不时超时或者返回格式错乱你根本分不清是 Server 写错了还是网络抖了。TaoToken 的好处是它把模型对话、Coding Plan、API Keys 管理都放在一个控制台里你注册后先拿 Key再选模型最后把 base_url 和 Key 填进 MCP Client 的配置就行。具体操作路径打开官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content进控制台创建 API Key。如果你只是验证 MCP 链路用按量计费的模型对话就够如果你打算长期跑编码 Agent可以看看 Coding Plan额度更划算。Key 拿到后先别急着写代码用 curl 测一下连通性curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的Key \ -d { model: gpt-4o-mini, messages: [{role: user, content: 只回复ok}] }如果返回 JSON 里有choices字段说明入口通了。这一步很重要因为后面 MCP Client 调模型时如果报reading choices错误你就能快速定位是 Key 问题还是 Client 代码问题。另外TaoToken 的模型对话页面可以直接测试模型是否支持 tools 参数你可以在那里先手动发一个带 tools 的请求确认模型能返回tool_calls再进入下一步。需要留意的是MCP Client 里配置的模型名必须和 TaoToken 支持的模型 ID 一致。比如你填gpt-4o-mini能通填gpt-4o也能通但填一个不存在的名字就会返回 404。我建议把 base_url、Key、Model ID 这三件套先记在便签上后面写配置文件直接复制避免手打出错。3. 可复制配置手搓一个最小 MCP Server 并写进 Cline MCP现在进入动手环节。我们写一个最简计算器 MCP Server基于 Python 的 FastMCP 框架代码不到 20 行。先装依赖pip install mcp然后新建calculator_server.pyfrom mcp.server.fastmcp import FastMCP mcp FastMCP(Calculator) mcp.tool() def calculator(python_expression: str) - dict: For mathematical calculation, always use this tool to calculate the result of a python expression. math and random are available. import math import random result eval(python_expression, {math: math, random: random}) return {success: True, result: result} if __name__ __main__: mcp.run(transportstdio)这段代码做了三件事创建名为 Calculator 的 Server 实例、注册一个 calculator 工具、用 stdio 传输启动。mcp.tool()装饰器会自动把函数签名和 docstring 转成 MCP 协议里的工具描述LLM 就是靠这段描述判断什么时候该调它。接下来配置 Cline MCP。Cline 是 VS Code 里的 AI 编码插件支持 MCP 接入。打开 Cline 的 MCP 配置文件路径通常在~/.cline/mcp_settings.json或者 VS Code 设置里的 Cline MCP Servers。填入以下 JSON{ mcpServers: { calculator: { command: python, args: [/绝对路径/calculator_server.py], env: {} } } }注意args里必须写绝对路径相对路径在 Cline 启动子进程时容易找不到文件。如果你用虚拟环境command要换成虚拟环境里的 python 路径比如/Users/you/venv/bin/python。保存后重启 Cline在 MCP Servers 面板里应该能看到 calculator 处于 connected 状态。如果你还想接入远程 SSE Server配置格式不同{ mcpServers: { amap-maps: { url: https://mcp.api-inference.modelscope.cn/sse/你的token } } }这里url指向 SSE 端点Cline 会自动用 HTTP POST 建立会话。stdio 和 SSE 的区别在于stdio 是本地进程通信适合自己写的工具SSE 是远程 HTTP 通信适合别人托管好的服务。两种可以混用Cline 会分别管理连接。配置完成后Cline 会把所有 Server 的工具列表汇总转成 OpenAI 格式的 tools 参数发给模型。模型返回tool_calls后Cline 根据工具名找到对应 Server通过 stdio 或 SSE 发送调用请求拿到结果再塞回对话。整条链路你不需要手写转发逻辑Cline 已经帮你做了 MCP Client 的活。4. 验证请求在 Cline 里跑通一次完整工具调用配置好之后打开 Cline 对话框输入“半径是 8计算圆的面积”。如果一切正常你会看到 Cline 先显示“正在调用 calculator”然后返回结果201.06192982974676最后模型用自然语言总结“圆的面积约为 201.06 平方单位”。这个过程背后发生了这些事Cline 把 calculator 的工具描述发给 TaoToken 的模型接口模型判断需要调用 calculator参数是{python_expression: math.pi * 8**2}。Cline 收到tool_calls后通过 stdio 把请求发给本地 Python 进程Server 执行 eval 返回结果Cline 再把结果作为role: tool的消息追加到对话模型最终生成总结。如果你想看原始请求日志可以在 Cline 的输出面板里切换到 MCP 频道能看到类似这样的记录{ role: assistant, content: null, tool_calls: [ { id: call_abc123, type: function, function: { name: calculator, arguments: {\python_expression\: \math.pi * 8**2\} } } ] }以及工具返回{ role: tool, tool_call_id: call_abc123, content: {\success\: true, \result\: 201.06192982974676} }看到这两条说明链路完全通了。再试一个多工具场景如果你同时配了 time Server 和 calculator输入“现在几点顺便算一下 15 的平方”Cline 会先调 time 拿时间再调 calculator 算平方最后合并回答。这就是 MCP 相比单次 Function Call 的优势Client 可以串行或并行调度多个 Server模型只需要决定“调什么”不需要关心“怎么连”。验证阶段如果模型没有触发工具调用先检查 docstring 是否清晰。MCP 协议把 docstring 作为工具描述发给模型描述太模糊模型就不知道什么时候用。比如把计算表达式改成For mathematical calculation, always use this tool to calculate the result of a python expression.触发率会明显提升。5. 本篇常见错排查401、local proxy failed 与 reading choices调试 MCP 时踩的坑基本集中在三类认证失败、连接失败、响应解析失败。下面按真实报错逐个拆。401 Unauthorized这个最常见说明 TaoToken 的 API Key 没填对或者过期了。检查 Cline 配置里如果用了环境变量OPENAI_API_KEY确认变量值没有多余空格。另外注意 base_url 要写https://taotoken.net/api不要漏掉/api也不要多加/v1之外的路径。如果 Key 没错但还是 401去控制台看看额度是否用完。local proxy failed / connection refused这个报错通常出现在 stdio Server 启动失败时。Cline 尝试启动python calculator_server.py但进程没起来。原因可能是python 路径不对、脚本里有语法错误、依赖没装。手动在终端跑一遍python /绝对路径/calculator_server.py如果报ModuleNotFoundError: No module named mcp就回到第 3 步装依赖。如果脚本正常挂起等待输入说明 Server 没问题问题在 Cline 的 command 路径。reading choices 报错这个错误说明模型接口返回的 JSON 里没有choices字段。常见原因是 base_url 填成了https://taotoken.net而不是https://taotoken.net/api请求打到了网页端而不是 API 端。另一个原因是模型名写错比如填了gpt-4但实际可用的是gpt-4o。用第 2 步的 curl 命令再测一次确认返回结构。OAuth 相关报错如果你接入的是需要 OAuth 的远程 ServerCline 会弹出授权窗口。如果窗口没弹出或者回调失败检查本地端口是否被占用。这类 Server 通常需要你在浏览器登录后复制 token 到配置里不要直接填账号密码。工具调用不触发模型返回了文本但没有tool_calls。先确认模型本身支持 Function Call有些小模型不支持 tools 参数。其次检查工具描述是否被正确加载在 Cline MCP 面板里点开 calculator 应该能看到calculator工具和它的描述。如果描述为空说明 docstring 没被解析检查装饰器是否写对。Codex auth.json 配置问题如果你用 Codex 类工具接入auth.json 里需要填base_url、api_key、model三件套。格式如下{ base_url: https://taotoken.net/api, api_key: sk-你的Key, model: gpt-4o-mini }少任何一个字段都会导致初始化失败。改完 auth.json 记得重启工具有些工具只在启动时读一次配置。6. 继续往下走把 MCP 接进你自己的 LLM 应用跑通 Cline 里的验证后你可能会想能不能在自己的 Python 项目里也接 MCP答案是可以官方提供了 Python SDK核心流程和 Cline 内部做的差不多。你需要用stdio_client或sse_client建立连接用ClientSession初始化会话调list_tools拿工具列表再把工具转成 OpenAI 的 tools 格式发给模型。模型返回tool_calls后用session.call_tool执行把结果追加到消息列表循环直到模型不再调工具。如果你打算长期跑编码 Agent建议把模型入口固定下来避免每次调试都换 Key。TaoToken 的 Coding Plan 适合这种场景额度稳定不用反复充值。需要看模型对话效果的可以直接进模型对话页面手动发带 tools 的请求观察返回结构。API Keys 管理页面可以创建多个 Key方便区分测试和生产。接入文档里有完整的 SDK 示例和传输协议说明遇到 stdio 和 SSE 混用的场景可以对照查。记住一个原则Server 负责“能做什么”Client 负责“怎么连”LLM 负责“要不要做”。三者解耦之后你换模型不用改 Server换 Server 不用改模型这才是 MCP 真正省心的地方。最后留一个实用技巧写 Server 时把工具函数拆细一个函数只做一件事。比如计算器就只做计算不要在里面顺便查天气。工具描述越单一模型判断越准调试也越容易定位。等你手搓过三四个 Server再回头看 Function Call 的 tools 参数会发现 MCP 的配置结构其实更清晰。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询