ARTICLE DETAIL

资讯详情

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

从0到1开发MCP服务器和客户端:TaoToken统一Key接入完整教程

从0到1开发MCP服务器和客户端:TaoToken统一Key接入完整教程 1. 为什么我要自己搭一套 MCP 服务器和客户端MCPModel Context Protocol说白了就是给大模型装一个「标准插座」模型不直接碰你的数据库、文件系统或内部接口而是通过 MCP 服务器暴露出来的资源Resources、工具Tools、提示Prompts来间接操作。这样做的好处是上下文来源和模型交互彻底解耦你换模型、换客户端服务器那套工具逻辑不用重写。这篇要带你从零跑通一条最小可用链路一个能注册工具的 MCP 服务器 一个能连上去调用的 MCP 客户端模型调用入口统一走 TaoToken 的 Key/API 通道。适合谁已经会点 Node.js/TypeScript想把自己的内部能力接进 AI 工作流但被「服务器怎么起、客户端怎么连、Key 怎么配」卡住的开发者。全程可复制配置骨架和启动命令我都会给全最后做一次端到端调用验证。我试过把工具注册和模型调用混在一个文件里结果调试时根本分不清是协议层错了还是模型层错了所以下面会刻意把这两层拆开讲。2. TaoToken 前置准备统一 Key 与 API 通道在写代码之前先把模型调用入口准备好。MCP 服务器负责「提供能力」但真正要跟大模型对话、让模型决定调哪个工具时需要一个稳定的 API 通道。TaoToken 在这里的角色就是统一入口一个 Key 走通模型对话、编码计划、控制台管理这些场景不用为每个模型单独维护一套鉴权和地址。你需要做三件事第一注册并登录官网拿到账号https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。第二进控制台创建 API Key地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 只在创建时完整显示一次复制到安全的地方。第三如果你后面要接 Claude Code 这类编码 Agent可以顺手看下 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它和按量调用是两条不同的计费路径长期跑 Agent 的话值得对比。API 的基础地址是https://taotoken.net/api注意这个地址不带任何查询参数配置时直接填这个就行。Key 的管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 遇到鉴权或参数问题优先翻文档。注意Key 不要硬编码进提交到 Git 的源码里用环境变量或本地配置文件承载下面配置骨架里我会用占位符。3. 可复制配置config.toml 与 settings.json 骨架MCP 生态里不同客户端读的配置文件不一样我按最常见的两类给你骨架一类是 TOML 风格的config.toml很多 CLI 工具和 Agent 用一类是 JSON 风格的settings.json编辑器类客户端常用。两者核心字段是一致的服务器怎么启动、环境变量传什么、模型通道指向哪。先看config.toml# ~/.mcp/config.toml [mcp] # 服务器启动方式stdio 适合本地进程http 适合远程 transport stdio [mcp.servers.local-tools] command node args [./dist/server/server.js] # 把 TaoToken 的 Key 通过环境变量注入不要写死在代码里 env { TAOTOKEN_API_KEY sk-你的Key, TAOTOKEN_BASE_URL https://taotoken.net/api } [model] # 统一模型调用入口 provider taotoken base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY # 按你实际可用的模型名填不要照抄 model 你的模型名再看settings.json{ mcpServers: { local-tools: { command: node, args: [./dist/server/server.js], env: { TAOTOKEN_API_KEY: sk-你的Key, TAOTOKEN_BASE_URL: https://taotoken.net/api } } }, model: { provider: taotoken, baseUrl: https://taotoken.net/api, apiKeyEnv: TAOTOKEN_API_KEY, model: 你的模型名 } }两个文件的关键点commandargs决定服务器进程怎么被拉起来env负责把 Key 和 Base URL 传进去model段决定模型请求打到哪。你只要保证TAOTOKEN_BASE_URL指向https://taotoken.net/api客户端和服务器就都走同一条通道。4. 从零写 MCP 服务器环境初始化与工具注册4.1 初始化项目mkdir mcp-demo cd mcp-demo npm init -y npm install modelcontextprotocol/sdk zod npm install typescript ts-node types/node --save-dev npx tsc --inittsconfig.json里确保module和moduleResolution都用NodeNexttarget用ES2020outDir指向./distinclude覆盖src/**/*。这几项不对后面 import 路径会各种报错。4.2 注册一个工具MCP 服务器的核心就是往实例上挂资源、工具、提示。下面这个服务器注册了一个「查订单状态」的工具参数用 zod 校验返回结构化文本// src/server/server.ts import { McpServer } from modelcontextprotocol/sdk/server/mcp.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import { z } from zod; const server new McpServer({ name: OrderMcpServer, version: 1.0.0 }); // 模拟订单库 const orders: Recordstring, string { A1001: 已发货, A1002: 待付款, }; server.tool( getOrderStatus, { orderId: z.string().describe(订单号例如 A1001) }, async ({ orderId }) { const status orders[orderId]; if (!status) { return { content: [{ type: text, text: 未找到订单 ${orderId} }], isError: true, }; } return { content: [{ type: text, text: 订单 ${orderId} 状态${status} }] }; } ); async function main() { const transport new StdioServerTransport(); await server.connect(transport); console.error(OrderMcpServer 已启动); } main().catch((err) { console.error(启动失败:, err); process.exit(1); });注意日志用console.error而不是console.logstdio 传输下 stdout 是协议通道往里写普通日志会污染消息流客户端直接解析失败。这个坑我第一次搭的时候踩得很实。4.3 启动命令npx ts-node src/server/server.ts编译后则是node ./dist/server/server.js也就是配置文件里args指向的那个路径。启动成功你会看到 stderr 打出「OrderMcpServer 已启动」进程保持挂起等待客户端连接。5. 写 MCP 客户端并做端到端验证5.1 客户端连接// src/client/client.ts import { Client } from modelcontextprotocol/sdk/client/index.js; import { StdioClientTransport } from modelcontextprotocol/sdk/client/stdio.js; async function main() { const transport new StdioClientTransport({ command: npx, args: [ts-node, src/server/server.ts], env: { ...process.env, TAOTOKEN_API_KEY: process.env.TAOTOKEN_API_KEY ?? , TAOTOKEN_BASE_URL: https://taotoken.net/api, }, }); const client new Client({ name: OrderMcpClient, version: 1.0.0 }); await client.connect(transport); const tools await client.listTools(); console.log(可用工具:, tools.tools.map((t) t.name)); const result await client.callTool({ name: getOrderStatus, arguments: { orderId: A1001 }, }); console.log(调用结果:, JSON.stringify(result, null, 2)); await transport.close(); } main().catch((err) { console.error(客户端出错:, err); process.exit(1); });5.2 一次成功的验证动作export TAOTOKEN_API_KEYsk-你的Key npx ts-node src/client/client.ts预期输出里能看到可用工具: [ getOrderStatus ]紧接着调用结果里content[0].text是「订单 A1001 状态已发货」。到这一步服务器注册、客户端连接、工具调用这条最小链路就通了。如果你还想直接跟模型对话验证通道可以打开模型对话页 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 手动发一条消息确认 Key 和 Base URL 没问题。6. 本篇常见错误排查报错一Unexpected token或 JSON 解析失败。九成是服务器往 stdout 写了日志。检查所有console.log改成console.errorstdio 模式下 stdout 只能走协议消息。报错二客户端连上但listTools返回空。工具注册代码在server.connect()之后才执行或者注册时名字重复被覆盖。把server.tool(...)全部放在main()里connect之前。报错三401 / 鉴权失败。检查TAOTOKEN_API_KEY是否真的注入到了进程环境TAOTOKEN_BASE_URL是否写成https://taotoken.net/api不要多加路径或参数。Key 失效就去 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 重新生成。报错四Cannot find module路径错误。tsconfig.json的moduleResolution没设成NodeNext或者 import 时漏了.js后缀。NodeNext 模式下相对导入要带扩展名。报错五进程启动后立刻退出。main()里没有await server.connect(transport)或者 connect 抛错被吞了。给main().catch加上明确的错误打印。排障时优先对照接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里的参数说明大部分鉴权和地址问题那里都有答案。7. 下一步怎么接链路跑通后你可以把getOrderStatus换成真实业务接口再往服务器上挂更多工具客户端侧则把模型调用接进来让模型根据用户问题自动选工具。长期跑编码类 Agent 的话Coding Plan 那条路径 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 比按量调用更划算值得单独配一套。先把今天这条最小链路跑稳后面加工具就是复制粘贴改参数的事。
返回列表