
1. 从零搭一个 MCP Server到底在解决什么问题MCP Server 这个词最近出现频率很高但很多人第一次接触时会把它想复杂。简单说MCPModel Context Protocol就是一套让 AI 客户端和外部工具之间说同一种话的约定。你可以把它理解成 USB 接口不管你是键盘、鼠标还是移动硬盘只要插口标准一致电脑就能识别。MCP Server 就是那个标准插口它对外暴露若干工具方法Cline 这类支持 MCP 的客户端连上来之后就能按统一格式调用这些方法。那为什么要在 Cline 里接自定义 MCP Server因为 Cline 自带的文件读写、终端执行能力覆盖的是通用场景一旦你想让它调用公司内部的工单系统、查询某个私有数据库、或者跑一段你自己写的业务脚本就需要一个自定义工具入口。MCP Server 正好承担这个角色——你把逻辑写在 Server 里Cline 通过配置连过来模型就能在对话中直接触发你的工具。这篇面向的是想在 Cline 中接入自定义工具能力的开发者目标很明确从零写一个最小可用的 MCP Server用 TaoToken 统一 Key 作为模型通道最后在 Cline 的 settings.json 里完成配置并跑通一次真实调用。全程不需要你有多深的协议背景跟着步骤走就能得到一个能用的链路。适合谁适合已经用过 Cline、想扩展它能力边界但还没动手写过 MCP Server 的人。2. 前置准备TaoToken 统一 Key 与运行环境在写 Server 之前先把两件事准备好模型通道和环境依赖。模型通道这块我用 TaoToken 的统一 Key 来打通。原因是 Cline 在调用模型时需要填 API 地址和 Key如果你同时用多个模型来源配置会散落在各处。TaoToken 提供一个统一的 API 入口Key 也是统一的Cline 里只需要填一次后面切换模型不用反复改配置。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基地址是 https://taotoken.net/api 。你需要先去控制台创建一个 API Key。打开 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 登录后在 API Keys 页面新建一个 Key复制出来先存好。这个 Key 后面会同时用在 Cline 的模型配置里。如果你还没决定用哪个模型可以先去模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 试一下确认通道正常再往下走。环境依赖方面MCP Server 用 Python 写最省事。确认本机 Python 版本在 3.10 以上然后装 MCP 官方 SDKpython --version pip install mcp如果你打算用 Node 写也可以但本文以 Python 为例因为 SDK 的异步写法比较直观。装完之后建一个项目目录mkdir mcp-demo cd mcp-demo到这里前置就齐了。注意一点MCP Server 本身不负责调用大模型它只负责暴露工具模型调用是 Cline 那边通过 TaoToken 通道完成的。两者职责分开配置才不会乱。3. 写一个最小可用的 MCP ServerMCP Server 的核心结构就三部分创建 Server 实例、用装饰器注册工具、启动 stdio 传输。下面这个例子暴露两个工具一个是加法计算一个是查询当前时间足够验证链路。新建server.pyimport asyncio from datetime import datetime from mcp.server import Server from mcp.server.stdio import stdio_server from mcp.types import Tool, TextContent app Server(demo-server) app.list_tools() async def list_tools() - list[Tool]: return [ Tool( nameadd_numbers, description计算两个数字之和, inputSchema{ type: object, properties: { a: {type: number, description: 第一个加数}, b: {type: number, description: 第二个加数} }, required: [a, b] } ), Tool( nameget_time, description返回服务器当前时间, inputSchema{type: object, properties: {}} ) ] app.call_tool() async def call_tool(name: str, arguments: dict) - list[TextContent]: if name add_numbers: result arguments[a] arguments[b] return [TextContent(typetext, textf结果: {result})] if name get_time: now datetime.now().strftime(%Y-%m-%d %H:%M:%S) return [TextContent(typetext, textf当前时间: {now})] raise ValueError(f未知工具: {name}) async def main(): async with stdio_server() as (read, write): await app.run(read, write, app.create_initialization_options()) if __name__ __main__: asyncio.run(main())几个关键点解释一下。list_tools返回的是工具清单Cline 连上来之后先读这个清单知道有哪些工具可用、每个工具要什么参数。inputSchema用的是 JSON Schema 格式参数类型和必填项都在这里声明模型会根据这个 schema 生成调用参数。call_tool是实际执行入口按工具名分发逻辑返回值必须是TextContent列表。传输方式这里用的是 stdio也就是标准输入输出。这是本地 MCP Server 最常用的方式Cline 会以子进程形式启动你的 Server通过 stdin/stdout 通信不需要开端口也不需要网络配置。对本地工具来说这是最省心的选择。写完先本地跑一下确认不报错python server.py如果没有任何输出且进程挂起等待输入说明启动正常——stdio 模式下它就在等客户端发消息。按 CtrlC 退出即可。4. 在 Cline 的 settings.json 里接入这一步是把 Server 注册到 Cline。Cline 的 MCP 配置在 settings.json 里找到mcpServers字段按下面骨架填{ mcpServers: { demo-server: { command: python, args: [/absolute/path/to/mcp-demo/server.py], env: { PYTHONUNBUFFERED: 1 } } } }command是启动命令args里必须用绝对路径相对路径在 Cline 启动子进程时容易找不到文件。env里加PYTHONUNBUFFERED是为了让 Python 输出不被缓冲否则 stdio 通信可能卡住。同时Cline 调用模型也需要配置。在 settings.json 的模型配置部分把 API 地址指向 TaoTokenKey 填你前面创建的那个{ apiProvider: openai, openAiBaseUrl: https://taotoken.net/api, openAiApiKey: 你的_TaoToken_Key, openAiModelId: claude-sonnet-4-5 }模型 ID 按你实际要用的填TaoToken 支持的模型可以在文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里查。这样模型通道和 MCP 工具通道就都配好了两者互不干扰。保存 settings.json 后重启 Cline在 MCP 面板里应该能看到demo-server处于已连接状态展开后列出add_numbers和get_time两个工具。如果显示未连接先看第 5 节的排查。5. 验证一次真实调用配置完成后别急着写复杂逻辑先用一句话验证链路。在 Cline 对话框里输入帮我算一下 37 加 58 等于多少用 add_numbers 工具正常情况下 Cline 会识别到需要调用工具弹出工具调用确认执行后返回结果: 95。这一步跑通说明三件事都对了Cline 成功启动了你的 Server、工具清单被正确读取、模型通过 TaoToken 通道完成了工具调用决策。再试一个无参数工具现在服务器时间是多少应该返回类似当前时间: 2025-01-15 14:30:22。两个工具都通最小可用链路就算完整了。如果你想更直接地验证 Server 本身可以绕过 Cline用 MCP 官方提供的调试工具npx modelcontextprotocol/inspector python /absolute/path/to/mcp-demo/server.py这会打开一个网页界面左边列出工具右边可以手动填参数调用适合排查是 Server 的问题还是 Cline 配置的问题。6. 常见报错与排查Server 显示未连接九成是路径问题。args里必须绝对路径且确认该路径下server.py存在。另外确认python命令在系统 PATH 里有些环境要用python3或完整解释器路径。工具调用后无响应多半是 stdio 缓冲导致。检查env里有没有PYTHONUNBUFFERED没有就加上。另外 Server 里任何print输出都会污染 stdio 通道调试信息一律用sys.stderr或 logging 写到文件不要用 print。模型不触发工具先确认 Cline 的模型配置里 API 地址和 Key 正确可以在模型对话页面单独测一下通道是否通。如果模型本身正常但就是不调工具检查工具的description是否写清楚——描述太模糊模型不知道什么时候该用。把计算两个数字之和改成当用户需要做加法运算时调用此工具触发率会明显提升。inputSchema 校验失败JSON Schema 写错会导致模型生成的参数对不上。required数组里的字段名必须和properties里的键完全一致类型也要匹配。改完 schema 记得重启 Cline配置不会热更新。Key 无效或额度问题去控制台 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 确认 Key 状态必要时重新生成一个替换。接入细节如果拿不准文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里有完整的参数说明。7. 把链路用起来下一步怎么扩展最小链路跑通之后真正有价值的是往里加你自己的工具。思路很简单在list_tools里加一条工具定义在call_tool里加对应的处理分支。比如接一个内部查询接口工具描述写清楚查询订单状态需要订单号参数模型就能在对话里自动调用。如果你打算长期在 Cline 里跑编码和 Agent 任务工具调用频率会比较高可以考虑用 Coding Plan 来统一管理额度入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。这样模型通道和工具通道都稳定日常开发不用反复折腾配置。最后提醒一个实际踩过的坑MCP Server 里不要写阻塞式的长任务stdio 是单通道的一个工具调用卡住整个 Server 就没法响应下一个请求。耗时操作要么异步化要么拆成提交任务和查询结果两个工具。这个设计习惯在工具数量变多之后会省很多事。