news 2026/9/27 17:42:43

编写第一个MCP Client之Hello world:用TaoToken统一Key跑通最小调用链

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
编写第一个MCP Client之Hello world:用TaoToken统一Key跑通最小调用链

1. 从零跑通 MCP Client 到底卡在哪

MCP Client 是 MCP 协议里负责“牵线”的那一层:它把宿主应用(比如 IDE 插件、命令行工具)和 MCP Server 连起来,让工具调用、资源读取、提示词获取这些动作能真正发出去。适合谁?适合刚接触 MCP、已经照着教程写完一个 Hello world Server、但卡在“Client 怎么连上去、怎么把请求发出去”的开发者。我试过把官方 quickstart 直接抄下来跑,结果第一步就卡在传输层配置上——Server 路径写错、命令找不到、JSON-RPC 请求发出去没响应,全是坑。

这篇要解决的核心问题很具体:用最小的代码量,搭一个能跑通的 MCP Client,调用上一篇写好的 echo Server,把callTool这条链路走通。同时把模型调用的 Key 统一收口到 TaoToken,避免在 Client 里散落多家厂商的 Key 和 endpoint。整条链路是:Client 启动子进程 → 通过 stdio 发 JSON-RPC → Server 返回结果 → Client 打印。跑通之后你会看到Tool response里带着 echo 回来的内容,说明协议层、传输层、工具调用三层都通了。

下面按“环境准备 → TaoToken 前置 → 可复制配置 → 验证请求 → 排错 → 下一步”的顺序展开,每一步都给完整命令和文件内容,你可以直接复制改路径。

2. TaoToken 前置:统一 Key 与 endpoint 收口

在写 Client 代码之前,先把模型调用的出口定下来。MCP Client 本身只负责协议通信,但真实场景里 Client 往往还要调模型做推理或工具选择,如果每个 Client 都去配一套 OpenAI/Anthropic 的 Key,维护成本会很高。TaoToken 的做法是提供一个统一的 API 入口,把模型调用收敛到一个 Key 上。

你需要先拿到一个 API Key,入口在控制台的 API Keys 页面:

https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite

拿到 Key 之后,模型调用的 base URL 统一用:

https://taotoken.net/api

注意这个地址不带任何查询参数,直接作为 OpenAI 兼容客户端的base_url使用。Key 的传递方式就是标准的Authorization: Bearer <你的Key>,不需要额外签名或加密。

如果你后面要接 Claude Code 这类编码 Agent,Anthropic 兼容入口的文档在这里:

https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

这一步的意义在于:Client 代码里只出现一个TAOTOKEN_API_KEY环境变量和一个 base URL,换模型、换厂商都不用改 Client 逻辑。对于 Hello world 阶段,你甚至可以先不调模型,只验证 MCP 协议链路;等链路通了,再把模型调用接进来。

3. 可复制配置:项目骨架与 Client 代码

3.1 初始化项目与依赖

先确认 Node 环境,建议 18 以上:

node --version npm --version

然后建目录、初始化、装依赖:

mkdir mcp-hello-client cd mcp-hello-client npm init -y npm install @modelcontextprotocol/sdk zod npm install -D @types/node typescript mkdir src

Windows 下把mkdir换成md,touch换成new-item即可,其余命令一致。

3.2 package.json 关键字段

打开package.json,确保有"type": "module"和构建脚本。下面是一份可直接用的骨架:

{ "name": "mcp-hello-client", "version": "1.0.0", "type": "module", "scripts": { "build": "tsc", "dev": "tsc --watch", "start": "node build/index.js" }, "dependencies": { "@modelcontextprotocol/sdk": "^1.11.1", "zod": "^3.24.4" }, "devDependencies": { "@types/node": "^22.15.17", "typescript": "^5.8.3" } }

"type": "module"必须加,否则 SDK 的 ESM 导入会报Cannot use import statement outside a module。

3.3 tsconfig.json

根目录建tsconfig.json,模块解析用 Node16,输出到build:

{ "compilerOptions": { "target": "ES2022", "module": "Node16", "moduleResolution": "Node16", "outDir": "./build", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules"] }

3.4 Client 主代码

在src/index.ts写入下面内容。核心是StdioClientTransport启动 Server 子进程,Client实例负责发 JSON-RPC:

import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; async function main() { // 传输层:启动 echo Server 子进程,路径改成你自己的 const transport = new StdioClientTransport({ command: "node", args: ["../mcp-hello-server/build/index.js"] }); const client = new Client({ name: "hello-client", version: "1.0.0" }); await client.connect(transport); try { const result = await client.callTool({ name: "echo", arguments: { message: "hello mcp" } }); console.log("Tool response:", JSON.stringify(result, null, 2)); } finally { await client.close(); } } main().catch((err) => { console.error("Client error:", err); process.exit(1); });

几个关键点:command是node,args指向 Server 编译后的入口;callTool的name必须和 Server 注册的工具名完全一致;arguments的字段名也要和 Server 的 zod schema 对齐,否则会返回参数校验错误。

3.5 环境变量与 TaoToken 配置片段

如果你要在 Client 里顺带调模型,把 Key 放到环境变量,不要硬编码。Linux/macOS:

export TAOTOKEN_API_KEY="你的Key"

Windows PowerShell:

$env:TAOTOKEN_API_KEY="你的Key"

然后在代码里读取:

const apiKey = process.env.TAOTOKEN_API_KEY; const baseURL = "https://taotoken.net/api";

这样 Client 里只有一处引用 Key,换环境只改环境变量。

4. 验证请求:构建、启动与预期输出

先构建:

npm run build

看到build/index.js生成即成功。然后启动:

npm start

预期输出类似:

Tool response: { "content": [ { "type": "text", "text": "hello mcp" } ] }

只要content里出现你传进去的message,说明整条链路通了:Client 启动子进程 → stdio 传输 JSON-RPC → Server 收到tools/call→ 执行 echo → 返回结果 → Client 打印。

如果你想验证模型调用这一层,可以用模型对话入口快速测一下 Key 是否可用:

https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite

在页面里发一条消息,能正常返回就说明 Key 和 endpoint 都没问题。这一步和 MCP 链路是独立的,先分开验证,出问题好定位。

5. 本篇常见错排查

5.1 报错Cannot find module '@modelcontextprotocol/sdk/client/index.js'

原因通常是"type": "module"没加,或者moduleResolution不是 Node16。检查package.json和tsconfig.json,改完重新npm run build。

5.2 启动后无输出,进程直接退出

大概率是 Server 路径写错,子进程启动失败但错误被吞了。把args里的路径改成绝对路径试一次,比如d:/projects/mcp-hello-server/build/index.js。另外确认 Server 已经npm run build过,build/index.js真实存在。

5.3Tool response里返回isError: true

说明请求发出去了,但 Server 侧执行失败。常见原因是工具名不对或参数不匹配。检查 Server 里server.tool("echo", ...)的第一个参数是不是echo,以及 zod schema 的字段名是不是message。两边必须逐字一致。

5.4 连接超时或connect卡住

stdio 传输依赖子进程的标准输入输出,如果 Server 启动时往 stdout 打了非 JSON-RPC 的日志,会污染协议流。检查 Server 代码里有没有console.log打在协议消息之外,有的话改成console.error。

5.5 环境变量读不到

process.env.TAOTOKEN_API_KEY返回undefined,先确认是在同一个终端会话里 export 的,或者用.env文件配合dotenv加载。Windows 下注意 PowerShell 和 CMD 的语法不同。

6. 下一步:从 Hello world 到长期编码 Agent

Hello world 跑通之后,下一步通常是把 MCP Client 接到真实的编码场景里,让 Agent 自动选择工具、连续调用。这时候单次callTool就不够了,需要处理多轮对话、工具结果回填、上下文管理。如果你打算长期跑编码类 Agent,可以看下 Coding Plan 的接入方式:

https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite

接入文档里有完整的 endpoint 和参数说明:

https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

我的建议是先把这篇的 stdio 链路跑稳,再逐步加 resources 和 prompts 的调用,最后接模型。每一步都单独验证,出问题能快速定位到是协议层、传输层还是模型层。

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

音乐摄影网站建设宗旨速查手册:解决没人访问的7个坑

音乐摄影网站建设宗旨速查手册:解决没人访问的7个坑 网站上线三个月,后台日志里全是爬虫,真人访问寥寥无几。这种“网站做好了没人访问”的焦虑,是无数音乐人和摄影工作室负责人的噩梦。你花了大几万做了个精美绝伦的官网,图片高清、音乐流畅,但百度搜不到,谷歌也没收录。别慌,这不是技术bug,而是你没搞懂搜索…

作者头像 李华
网站建设 2026/9/27 17:42:33

深圳营销型网站定制从零搭建避坑指南

深圳营销型网站定制从零搭建避坑指南 改个需求建站公司拖一周,这种憋屈事儿深圳的老板们太熟了。别怪你脾气不好,谁的钱都不是大风刮来的,时间更是命脉。很多人以为找个大厂就能高枕无忧,结果发现从需求沟通到上线,中间全是坑。其实,想要搞定深圳营销型网站定制,核心在于你心里有没有底,能不能 从零搭建…

作者头像 李华
网站建设 2026/9/27 17:42:19

自己做黑彩网站源码下载避坑:3天搞定部署不踩雷

自己做黑彩网站源码下载避坑:3天搞定部署不踩雷 改个需求建站公司拖一周,这种憋屈感谁懂? 想自己动手,网上搜【自己做黑彩网站】,满屏都是诱导下载的陷阱。 别急着去搞那些来路不明的 源码下载 ,先看清楚这背后的法律红线和技术逻辑。…

作者头像 李华
网站建设 2026/9/27 17:42:08

图解步骤拆解网站的push运营怎么做告别域名服务器焦虑

图解步骤拆解网站的push运营怎么做告别域名服务器焦虑 很多刚入行的朋友一听到“网站的push运营怎么做”就头大,尤其是看着后台那些密密麻麻的域名解析、服务器配置选项,瞬间觉得自己像个文盲。别慌,这种对 域名服务器搞不懂…

作者头像 李华
网站建设 2026/9/27 17:41:48

国内优秀公司网站设计避坑指南:从零搭建高转化官网

国内优秀公司网站设计避坑指南:从零搭建高转化官网 昨晚十一点,客户急吼吼打来电话,说官网首页突然跳出一个博彩弹窗,后台也被注入了恶意脚本。这就是典型的网站被黑挂马,而且往往是因为初期建站时安全基线没打好,或者过度依赖老旧模板导致的。很多老板觉得网站只是门面,其实它是数字资产。如果你正面临…

作者头像 李华
网站建设 2026/9/27 17:41:38

0代码基础WordPress怎么找主题避坑指南含源码下载技巧

0代码基础WordPress怎么找主题避坑指南含源码下载技巧 自己不会代码想做网站,最头疼的不是写程序,而是找主题。很多人一上来就去搜“免费WordPress主题”,结果下了一堆,装上去全是BUG,或者速度慢得让人想摔键盘。别慌,这行干了10年,见过太多小白在这上面栽跟头。找主题这事儿,其实有套路,…

作者头像 李华