ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MCP 的 add 示例,Codex 走 TaoToken 后能跑通 stdio 调用

MCP 的 add 示例,Codex 走 TaoToken 后能跑通 stdio 调用 1. 为什么 add 跑完却不知道有没有真的成功MCP 的 add 示例代码很短短到很多人复制粘贴完就觉得“应该没问题”。但真正跑起来问题往往不在代码本身而在“我怎么确认 stdio 通道里的调用真的返回了”。stdio 不像 HTTP 那样有状态码、有响应头它把请求和响应都塞进标准输入输出里客户端打印什么、服务器有没有收到、工具有没有被真正调用全靠日志和返回值来判断。我见过最常见的场景是服务器终端一片安静客户端终端只打印了“可用工具: [add]”然后就卡住或者直接退出加法结果那行根本没出现。这时候你分不清是 Codex 没配通、依赖没装对还是 stdio 握手阶段就断了。所以这篇不走“怎么发布到公网”那条路而是走【验证用量】视角先把 Codex 的模型通道配通再让 Codex 辅助你把这个最精简的 add 示例跑出确定性的成功信号——客户端打印出“加法结果: 5 3.5 8.5”。这个信号为什么重要因为它是端到端的证据客户端成功初始化会话、成功列出工具、成功发起 call_tool、服务器成功执行 add 并把结果写回 stdio、客户端成功解析并打印。任何一环断了这行字都不会出现。对刚接触 MCP 的人来说先拿到这个确定性结果比急着改 socket_server 或写 Nginx 配置要实在得多。2. 前置给 Codex 配一条能用的模型通道Codex 本身是编码助手它要帮你补全、解释、排障前提是模型通道是通的。这里用 TaoToken 来做这件事流程不复杂但每一步都要填对。先打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 创建账号并生成 Key。创建完之后在 Codex 的服务地址配置里把 Base URL 填成https://taotoken.net/api然后把刚才生成的 Key 填到对应的 API Key 字段。注意 Base URL 不要带多余路径也不要自己拼/v1之类的后缀按上面这个填就行。填完之后Codex 的模型请求就会走这条通道。如果你后面要长期用 Codex 做编码和 Agent 类任务可以顺手看一下 Coding Plan 的说明地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。它更适合高频、长会话的编码场景。只是想先把 add 示例跑通的话当前这条通道已经够用。配好之后你可以先在 Codex 里问一句“帮我解释一下 MCP 的 stdio_server 是怎么工作的”如果它能正常回你说明模型通道已经通了。这一步别跳过因为后面排障时你要靠 Codex 帮你读报错。3. 可复制配置两个文件加依赖3.1 安装 mcp 依赖先建一个干净的目录避免和已有环境冲突mkdir mcp-add-demo cd mcp-add-demo python3 -m venv .venv source .venv/bin/activate pip install mcp装完之后可以用pip show mcp确认版本记下这个版本号后面如果报导入错误多半是版本差异导致的。3.2 服务器 mcp_server.py#!/usr/bin/env python3 import asyncio from mcp.server import Server from mcp.server.stdio import stdio_server server Server(math-server) server.tool() async def add(a: float, b: float) - str: 将两个数字相加 result a b return f{a} {b} {result} async def main(): async with stdio_server() as (read_stream, write_stream): await server.run(read_stream, write_stream) if __name__ __main__: asyncio.run(main())这里的关键点是stdio_server()把读写流交给server.run服务器不会主动打印任何东西它只在收到 stdio 上的请求时才响应。所以服务器终端“安静”是正常的不代表它没在工作。3.3 客户端 mcp_client.py#!/usr/bin/env python3 import asyncio from mcp.client import ClientSession from mcp.client.stdio import stdio_client async def main(): async with stdio_client() as (read, write): session ClientSession(read, write) await session.initialize() tools await session.list_tools() print(可用工具:, [t.name for t in tools.tools]) result await session.call_tool( add, arguments{a: 5, b: 3.5} ) print(加法结果:, result.content[0].text) await session.close() if __name__ __main__: asyncio.run(main())注意stdio_client()默认会去拉起一个子进程来跑服务器所以很多示例里你其实不需要手动开两个终端。但为了看清 stdio 通道的行为下面还是按“两个终端”的方式跑一遍这样你能明确区分服务器侧和客户端侧的输出。4. 验证请求跑出那行 8.54.1 先单独确认服务器能启动在第一个终端里source .venv/bin/activate python mcp_server.py如果它没有立刻报错退出而是停在那里等待输入说明服务器进程正常。你可以按 CtrlC 先停掉因为接下来用客户端拉起它更直观。4.2 运行客户端并观察输出在第二个终端里source .venv/bin/activate python mcp_client.py预期输出是两行可用工具: [add] 加法结果: 5 3.5 8.5第二行就是本篇要的验证信号。它证明 stdio 通道完成了完整的请求-响应闭环。如果只出现第一行说明list_tools成功了但call_tool没走通如果两行都没有说明会话初始化阶段就断了。4.3 用 Codex 辅助确认调用链拿到 8.5 之后你可以把两个文件贴给 Codex让它帮你确认调用链。比如问它“session.call_tool的返回值结构里content[0].text对应的是服务器里哪一行”它会指向return f{a} {b} {result}。这一步看起来多余但它能帮你建立“客户端打印的内容 服务器 return 的内容”这个映射关系后面改工具时不容易搞混。如果你还想验证模型侧对 MCP 工具描述的理解可以打开模型对话页面 https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 把 add 工具的描述贴进去问它“如果用户说 5 加 3.5你会怎么调用这个工具”。这能帮你确认工具描述写得够不够清楚。5. 本篇常见错排查5.1 报 ModuleNotFoundError: No module named mcp九成是虚拟环境没激活或者你在系统 Python 里装了但跑的时候用了另一个解释器。先which python确认路径在.venv里再pip show mcp确认装上了。如果用的是 Codex 帮你生成的运行命令注意它有时会写成python3而你的环境里可能只有python。5.2 客户端卡在 initialize 不动stdio 握手阶段卡住常见原因是服务器进程启动失败但客户端没拿到错误。可以先把stdio_client()换成手动启动服务器的方式一个终端跑python mcp_server.py另一个终端用能连已有进程的方式调试。更简单的做法是把服务器里的add函数先改成同步返回一个固定字符串排除计算逻辑的干扰。5.3 打印出“可用工具: []”工具列表为空说明server.tool()装饰器没生效。检查两点一是add函数是否在server Server(...)之后定义二是mcp版本是否支持这种装饰器写法。可以pip install -U mcp升级后再试。5.4 加法结果那行是 None 或报 IndexErrorresult.content[0].text取不到值通常是call_tool返回结构和你预期的不一样。先在客户端加一行print(result)看完整结构再决定取哪个字段。不同 mcp 版本里 content 的类型可能有差异以实际打印为准。5.5 Codex 给的命令跑不通Codex 生成的命令有时会带上它假设的路径或参数。遇到这种情况把完整报错贴回给 Codex让它基于你的实际环境重写。如果模型通道本身不稳先去 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 确认 Key 状态再对照接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 检查 Base URL 有没有填错。6. 把验证习惯带进后面的 MCP 开发add 示例的价值不在于加法本身而在于它给了你一个最小可验证单元。后面你写文件读取、数据库查询、HTTP 请求这类工具时都可以先用同样的方式固定输入、固定预期输出、在客户端打印出来。只要那行预期结果出现就说明 stdio 通道和工具注册都是好的剩下的才是业务逻辑问题。如果你打算把 Codex 长期用在 MCP 工具开发上建议把 Coding Plan 那条通道也配好地址还是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 这样长会话里让它帮你读日志、改工具描述会更顺。先把 8.5 跑出来再往下加功能节奏会稳很多。
返回列表