如何设计一个既提供绘图Tools又提供example_data的MCP服务器:TaoToken统一Key接入与配置骨架
发布时间:2026/9/28 4:33:48来源:尧图网络
1. 为什么要把 example_data 也做成 Tool先说结论如果你正在写一个 MCP 服务器想让大模型自己完成「拿数据 → 画图」这条链路那把 example_data 做成 Tool 比做成 Resource 更省心。原因很直接——Tool 是模型可以主动调用的Resource 通常需要客户端或用户先选中模型才能读到内容。我见过不少同学第一次写 MCP 服务器时习惯性把示例数据塞进 Resource觉得「数据嘛静态的放 Resource 天经地义」。结果联调时发现模型画图前总要等用户手动选一下数据源整个自动化流程断成两截。这不是模型不聪明是能力边界没设计对。MCP 服务器Model Context Protocol Server本质上是给 AI 工具暴露一组可调用的能力。它通过tools、resources、prompts三类能力与客户端通信。绘图场景里create_chart显然是 Tool因为它有副作用、有参数、要返回结果而example_data到底算 Tool 还是 Resource取决于你希望谁来触发它。适合谁看这篇正在用 Node.js 或 Python 写 MCP 服务器、需要让 AI 稳定调用绘图能力、并且希望把模型接入通道统一管理的开发者。下面我会给出可复制的config.toml与settings.json骨架再演示一次 Tools 调用和 example_data 返回的完整验证动作。2. TaoToken 统一 Key 接入把模型通道先固定下来MCP 服务器本身不负责「模型从哪来」它只负责暴露能力。真正让模型跑起来、并且能稳定调用你这些 Tool 的是背后的模型接入通道。这里我用 TaoToken 做统一入口好处是一个 Key 覆盖对话、编码、Agent 多类场景配置一次到处复用。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 注意 API 地址不带 UTM 参数写配置时别把查询串带进去。你需要先拿到 Key。进入控制台创建https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 然后在 API Keys 页面生成https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。生成后复制那串sk-开头的字符串后面配置里要用。如果你打算长期跑编码类或 Agent 类任务可以看下 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它更适合高频调用场景。只是想先验证模型能不能正常对话用模型对话页更快https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。注意Key 只放在本地配置文件或环境变量里不要硬编码进提交到 Git 的源码。下面骨架里我用占位符sk-xxxx你替换成自己的。3. 可复制配置骨架config.toml 与 settings.json这一节是全文的核心配置写对了后面验证基本不会翻车。我分成两块一块是 MCP 服务器自身的声明config.toml一块是客户端侧的接入设置settings.json。3.1 config.toml声明服务器与模型通道# config.toml # MCP 服务器基础声明 TaoToken 统一通道 [server] name chart-generator version 1.0.0 # 同时开启 tools 能力example_data 也走 tools capabilities [tools] [server.transport] # 本地开发用 stdio最省事 type stdio [model] # TaoToken 统一入口注意 API 地址不带 UTM base_url https://taotoken.net/api api_key sk-xxxx # 按你实际使用的模型名填写 model claude-sonnet [model.retry] max_attempts 3 backoff_ms 800 [tools.get_example_data] description 获取绘图示例数据 data_types [sales, temperature, population] [tools.create_chart] description 根据数据创建图表 chart_types [line, bar, pie]几个容易写错的地方capabilities里如果只写tools那 example_data 就必须是 Tool不能是 Resource否则客户端列不出来。base_url结尾不要加斜杠也不要拼/v1之类的后缀具体路径由 SDK 处理。3.2 settings.json客户端接入设置{ mcpServers: { chart-generator: { command: node, args: [dist/index.js], env: { TAOTOKEN_BASE_URL: https://taotoken.net/api, TAOTOKEN_API_KEY: sk-xxxx } } }, model: { provider: taotoken, baseUrl: https://taotoken.net/api, apiKey: sk-xxxx, model: claude-sonnet } }command和args指向你编译后的入口文件。如果你用 Python 写就换成python加脚本路径。env里放 Key代码里用process.env.TAOTOKEN_API_KEY读取这样配置和代码解耦。3.3 两个 Tool 的注册骨架// 只保留关键结构方便你对照 server.setRequestHandler(ListToolsRequestSchema, async () { return { tools: [ { name: get_example_data, description: 获取绘图示例数据, inputSchema: { type: object, properties: { type: { type: string, enum: [sales, temperature, population], description: 示例数据类型 } } } }, { name: create_chart, description: 根据数据创建图表, inputSchema: { type: object, properties: { data: { type: array, description: 图表数据 }, chartType: { type: string, enum: [line, bar, pie] }, title: { type: string } }, required: [data, chartType] } } ] }; });inputSchema里的enum很关键它等于给模型画了可选范围模型乱传参数的概率会明显下降。required只写真正必需的字段title这种可选的别加进去否则模型每次都得编一个标题。4. 验证请求一次 Tools 调用 example_data 返回配置写完别急着接大流程先做最小验证。我习惯分两步先确认 example_data 能返回再确认 create_chart 能拿到数据并出图。4.1 验证 example_data 返回启动服务器后在客户端里发一条调用请求参数type传sales{ method: tools/call, params: { name: get_example_data, arguments: { type: sales } } }预期返回是一段 JSON 文本内容形如[ { month: Jan, value: 100 }, { month: Feb, value: 150 }, { month: Mar, value: 120 } ]如果返回的是空数组先检查type是否落在enum范围内再检查你的EXAMPLE_DATA字典键名和enum是否一致。我踩过的坑就是键名写成Sales大写模型传sales小写结果一直返回空。4.2 验证 create_chart 调用拿到数据后把这段数组直接喂给create_chart{ method: tools/call, params: { name: create_chart, arguments: { data: [ { month: Jan, value: 100 }, { month: Feb, value: 150 }, { month: Mar, value: 120 } ], chartType: bar, title: 季度销售 } } }成功时返回类似Chart created successfully: url的文本。这里的url是你绘图逻辑产出的地址本地开发可以先返回一个占位路径确认链路通了再换成真实存储。4.3 让模型自己串起来两步都通之后把「先调 get_example_data再调 create_chart」写进系统提示或工具描述里。因为两个都是 Tool模型可以自主完成不需要用户中途选数据。这就是全 Tools 方案的价值流程不断档。5. 本篇常见错排查下面这些是我在联调时真实遇到过的按出现频率排。报错一Tool not found: get_example_data多半是ListToolsRequestSchema里没注册这个 Tool或者capabilities只写了resources。检查config.toml的capabilities是否包含tools。报错二模型传参chartType为空inputSchema里chartType没写进required模型可能省略。把它加进required数组即可。报错三401 或鉴权失败Key 没读到。确认settings.json的env里TAOTOKEN_API_KEY拼写正确代码里读取的变量名一致。另外确认base_url是https://taotoken.net/api不要带多余路径。报错四example_data 返回字符串而非数组JSON.stringify之后模型拿到的是文本这是正常的。如果你希望模型直接当数组用在 Tool 描述里说明「返回 JSON 字符串需解析后使用」。报错五绘图 Tool 超时绘图逻辑本身耗时建议在create_chart里加超时和降级返回别让整个 MCP 请求卡死。config.toml里的retry只对模型通道生效Tool 内部逻辑要自己兜底。提示排障阶段建议把服务器日志级别调高把每次tools/call的入参和返回都打出来定位问题快很多。6. 接入通道与后续动作配置和验证都跑通后接下来就是把它接到真实工作流里。如果你主要在做排障和接入调试重点看 API Keys 和接入文档https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 文档入口在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。想先确认模型对话是否正常用模型对话页试一条https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。如果你要长期跑编码或 Agent 类任务Coding Plan 更合适https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。用 Claude Code 这类工具接入的话参考 Anthropic 接入说明https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite 。最后留一个实用建议把get_example_data的返回结构固定成[{x, y}]这种通用格式而不是{month, value}这种业务字段。这样你的绘图 Tool 不用为每种数据类型写适配逻辑模型也更容易理解。等你要接真实数据源时只要替换数据获取层Tool 签名和绘图逻辑都不用动。
网站建设高端定制企业官网