ARTICLE DETAIL

资讯详情

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

MCP 三大核心概念实战:用 TaoToken 统一 Key 拆解 Resources、Tools、Prompts

MCP 三大核心概念实战:用 TaoToken 统一 Key 拆解 Resources、Tools、Prompts 1. 为什么你的 MCP Server 总是“连上了却不好用”很多人第一次搭 MCP Server卡点不在协议本身而在三个概念混着用Resources、Tools、Prompts。它们看起来都是“给模型提供能力”但职责完全不同。我见过最常见的翻车现场是——把日志文件塞进 Tools 里让模型去读结果模型每次都要“调用一次工具”才能拿到数据token 消耗翻倍或者把“生成故障报告”这种固定套路写成 Tool导致模型每次输出格式都不一样。MCPModel Context Protocol是 Anthropic 在 2024 年底推出的开放协议核心目标就一句话让大语言模型能标准化地对接外部数据和工具。它把能力拆成三块——Resources 负责“喂数据”Tools 负责“干活”Prompts 负责“给剧本”。这三者不是替代关系而是流水线关系Resources 提供原材料Tools 执行动作Prompts 约束输出形态。这篇文章面向正在搭建 MCP Server 或准备接入 AI 工具的开发者。我会用一个“日志分析助手”的完整案例把三个概念各自落地成可复制的配置片段并且全程用 TaoToken 的统一 Key 来管理模型调用。你跟着做完能拿到三个可验证的结果Resources 能被正确读取、Tools 能被成功调用、Prompts 能渲染出预期模板。每一步都有具体的命令和返回示例不是“连上后就能用”这种空话。先说清楚适合谁如果你已经在写 MCP Server但不确定某个功能该放 Resources 还是 Tools或者你手上有多个模型供应商的 Key想统一管理再接入 MCP 客户端——这篇就是给你写的。如果你还没接触过 MCP建议先跑通一个最小 Server 再回来否则配置片段会看得比较吃力。TaoToken 在这里的角色是“统一 Key 网关”。MCP 客户端比如 Claude Desktop、Cline、Cursor在调用模型时需要填 Base URL、API Key、Model ID 三件套。如果你同时用 Claude、GPT、Gemini就要维护三套配置。TaoToken 把这些收敛成一个 Key 和一个 Base URLMCP Server 侧只需要认这一套凭证切换模型时改 Model ID 就行。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 注意 API 地址不带 UTM 参数配置时别抄错。下面进入实操。我会先给一个最小可跑的 MCP Server 骨架然后逐个拆解 Resources、Tools、Prompts 的实现和验证方式。每个环节都有“预期结果”和“如果不对怎么查”。2. TaoToken 统一 Key 前置配置Base URL、Key、Model ID 三件套在写 MCP Server 之前先把模型调用这一层理顺。MCP Server 本身不负责“选模型”它只负责暴露 Resources、Tools、Prompts真正调用模型的是 MCP 客户端。但很多开发者会在 Server 里内置一些“辅助调用”比如让模型先总结一下日志这时候就需要在 Server 侧配置模型凭证。TaoToken 的接入方式很直接一个 Base URL、一个 API Key、一个 Model ID。这三件套在 MCP 生态里出现的频率极高尤其是 Claude Code、Cline、Codex 这类工具配置项名字可能不同但本质都是这三样。先拿 Key。打开 https://taotoken.net/api-keys 登录后创建一个新 Key。建议按用途命名比如mcp-log-analyzer方便后面排查是哪个项目在用。创建后立刻复制页面刷新后就不再完整显示。拿到 Key 后配置环境变量。不要硬编码在代码里MCP Server 经常要提交到 Git硬编码等于泄露。用.env文件或者系统环境变量export TAOTOKEN_API_KEYsk-你的Key export TAOTOKEN_BASE_URLhttps://taotoken.net/api如果你用的是 Claude Code 或者 Cline它们的配置文件里通常有baseUrl、apiKey、model三个字段。以 Cline 的 MCP 配置为例路径一般在~/.cline/mcp_settings.json或者项目根目录的.cline/mcp.json{ mcpServers: { log-analyzer: { command: node, args: [./mcp-server/index.js], env: { TAOTOKEN_API_KEY: sk-你的Key, TAOTOKEN_BASE_URL: https://taotoken.net/api, TAOTOKEN_MODEL_ID: claude-sonnet-4-20250514 } } } }注意TAOTOKEN_MODEL_ID这个字段。TaoToken 支持多个模型Model ID 要写完整版本号不要只写claude-sonnet。具体可用列表在 https://taotoken.net/doc 里有配置前先确认一下当前支持的模型名。如果你用的是 Claude Code 的 Anthropic 兼容模式配置在~/.claude/settings.json或者项目级.claude/settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的Key, ANTHROPIC_MODEL: claude-sonnet-4-20250514 } }这里有个坑Claude Code 的ANTHROPIC_BASE_URL不要带/v1后缀TaoToken 的 API 地址已经处理了路径。如果你写成https://taotoken.net/api/v1会报 404。这个错误在后面的排障章节会详细说。配置完成后先别急着写 MCP Server用 curl 验证一下 Key 是否可用curl -X POST https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: 回复 OK 两个字母}] }预期返回是一个 JSONcontent数组里有一段文本OK。如果返回 401说明 Key 不对或者没带上如果返回model not found说明 Model ID 写错了。这一步过了再往下走。3. 可复制配置Resources、Tools、Prompts 三件套的 Server 实现现在进入核心部分。我用 Node.js 写一个最小 MCP Server暴露一个日志文件作为 Resource、一个“统计错误行数”的 Tool、一个“生成故障报告”的 Prompt。完整代码可以直接复制运行。先初始化项目mkdir mcp-log-analyzer cd mcp-log-analyzer npm init -y npm install modelcontextprotocol/sdk然后创建index.js。先看 Resources 部分。Resources 的本质是“只读数据暴露”客户端可以列出、读取、订阅。这里我把app.log暴露成一个 ResourceURI 用file://logs/app.log这种格式import { Server } from modelcontextprotocol/sdk/server/index.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import { ListResourcesRequestSchema, ReadResourceRequestSchema, ListToolsRequestSchema, CallToolRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from modelcontextprotocol/sdk/types.js; import fs from fs/promises; import path from path; const LOG_PATH path.resolve(./app.log); const server new Server( { name: log-analyzer, version: 1.0.0 }, { capabilities: { resources: {}, tools: {}, prompts: {} } } ); // ---------- Resources ---------- server.setRequestHandler(ListResourcesRequestSchema, async () { return { resources: [ { uri: file://logs/app.log, name: 应用日志, description: 当前应用的运行日志包含错误和警告信息, mimeType: text/plain, }, ], }; }); server.setRequestHandler(ReadResourceRequestSchema, async (request) { if (request.params.uri ! file://logs/app.log) { throw new Error(未知资源: ${request.params.uri}); } const content await fs.readFile(LOG_PATH, utf-8); return { contents: [ { uri: request.params.uri, mimeType: text/plain, text: content, }, ], }; });Resources 的关键点ListResourcesRequestSchema返回资源清单ReadResourceRequestSchema返回实际内容。客户端比如 Claude Desktop会先列出来用户选中后再读取。这里没有实现订阅如果需要实时更新要加SubscribeRequestSchema和UnsubscribeRequestSchema并在文件变化时发notifications/resources/updated。接着是 Tools。Tools 是“可执行动作”模型可以主动调用。这里实现一个count_errors统计日志里 ERROR 出现的次数// ---------- Tools ---------- server.setRequestHandler(ListToolsRequestSchema, async () { return { tools: [ { name: count_errors, description: 统计日志文件中 ERROR 级别的行数, inputSchema: { type: object, properties: { keyword: { type: string, description: 要统计的关键词默认 ERROR, }, }, }, }, ], }; }); server.setRequestHandler(CallToolRequestSchema, async (request) { if (request.params.name ! count_errors) { throw new Error(未知工具: ${request.params.name}); } const keyword request.params.arguments?.keyword || ERROR; const content await fs.readFile(LOG_PATH, utf-8); const count content.split(\n).filter((line) line.includes(keyword)).length; return { content: [ { type: text, text: 关键词 ${keyword} 出现次数: ${count}, }, ], }; });Tools 和 Resources 最大的区别Tools 有inputSchema模型会根据 schema 生成参数Resources 没有参数只有 URI。另外 Tools 的返回是content数组Resources 的返回是contents数组拼写差一个字母写错会报 schema 校验失败。最后是 Prompts。Prompts 是“预定义模板”用户主动选择填入参数后生成一段完整的提示词。这里实现一个fault_report接收日志片段和错误数量生成故障报告模板// ---------- Prompts ---------- server.setRequestHandler(ListPromptsRequestSchema, async () { return { prompts: [ { name: fault_report, description: 根据日志内容生成故障报告, arguments: [ { name: log_snippet, description: 日志片段, required: true, }, { name: error_count, description: 错误数量, required: true, }, ], }, ], }; }); server.setRequestHandler(GetPromptRequestSchema, async (request) { if (request.params.name ! fault_report) { throw new Error(未知提示: ${request.params.name}); } const { log_snippet, error_count } request.params.arguments || {}; return { messages: [ { role: user, content: { type: text, text: 你是一名运维工程师。请根据以下日志片段生成一份故障报告。\n\n错误数量: ${error_count}\n\n日志片段:\n${log_snippet}\n\n报告要求:\n1. 概述问题现象\n2. 分析可能原因\n3. 给出修复建议\n4. 输出格式为 Markdown, }, }, ], }; }); // ---------- 启动 ---------- const transport new StdioServerTransport(); await server.connect(transport);Prompts 的返回是messages数组不是content。这是三个概念里最容易写错的地方。messages里可以放多条消息模拟多轮对话但大多数场景一条 user 消息就够了。把这三段拼成一个完整的index.js然后创建测试日志cat app.log EOF 2025-01-01 10:00:00 INFO 服务启动 2025-01-01 10:01:00 ERROR 数据库连接失败 2025-01-01 10:01:05 WARN 重试中 2025-01-01 10:01:10 ERROR 数据库连接超时 2025-01-01 10:02:00 INFO 服务恢复 EOF现在 Server 已经可以跑了。但怎么验证三个概念都生效下一节用 MCP Inspector 逐项测试。4. 逐项验证Resources 读取、Tools 调用、Prompts 渲染是否生效MCP 官方提供了一个调试工具叫 MCP Inspector可以直接在浏览器里测试 Server 的三大能力。先安装npx modelcontextprotocol/inspector node index.js运行后终端会输出一个本地地址通常是http://localhost:5173打开后能看到 Inspector 界面。左侧是 Server 连接状态右侧有三个标签页Resources、Tools、Prompts。先验证 Resources。点击 Resources 标签应该能看到file://logs/app.log这一条。点击它右侧会显示日志内容。如果列表为空检查ListResourcesRequestSchema的 handler 是否返回了resources数组如果点击后报错检查ReadResourceRequestSchema里的 URI 判断逻辑大小写和斜杠都要完全匹配。预期结果能看到完整的 5 行日志。如果只看到部分内容可能是文件读取编码问题fs.readFile要指定utf-8。接着验证 Tools。点击 Tools 标签应该看到count_errors。点击后会出现一个参数输入框keyword留空或填ERROR然后点“Run Tool”。预期返回关键词 ERROR 出现次数: 2。如果返回 0检查日志文件里是否真的有ERROR大写如果报 schema 错误检查inputSchema的type是不是objectproperties里每个字段的type是否写对。这里有个细节Tools 的调用是模型驱动的Inspector 里手动调用只是模拟。真正接入客户端后模型会根据description判断什么时候调用。所以description要写清楚不要写“统计错误”这种模糊描述要写“统计日志文件中 ERROR 级别的行数”模型才能准确匹配。最后验证 Prompts。点击 Prompts 标签应该看到fault_report。点击后会出现两个参数输入框log_snippet和error_count。填入一段日志和数字2点击“Get Prompt”。预期返回一段完整的提示词包含你填入的日志片段和错误数量。如果 Prompts 列表为空检查ListPromptsRequestSchema是否返回了prompts数组如果点击后报错检查GetPromptRequestSchema里request.params.arguments的取值方式。注意arguments可能是undefined要用|| {}兜底。三项都通过后把 Server 接入真实客户端。以 Cline 为例在mcp_settings.json里加上{ mcpServers: { log-analyzer: { command: node, args: [/绝对路径/mcp-log-analyzer/index.js], env: { TAOTOKEN_API_KEY: sk-你的Key, TAOTOKEN_BASE_URL: https://taotoken.net/api, TAOTOKEN_MODEL_ID: claude-sonnet-4-20250514 } } } }重启 Cline 后在对话里输入“帮我看看日志里有多少错误”模型应该会自动调用count_errors工具。如果模型没有调用而是直接回答“我无法访问日志”说明 Tools 的description不够明确或者客户端没有正确加载 MCP Server。检查 Cline 的 MCP 日志通常在~/.cline/logs/下。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节列四个高频报错都是我在实际接入中踩过的。401 Unauthorized。最常见的原因是 Key 没带上或者带错了。检查三处环境变量TAOTOKEN_API_KEY是否导出成功echo $TAOTOKEN_API_KEY看有没有值MCP 配置里的env字段是否拼写正确请求头是x-api-key还是Authorization: Bearer。TaoToken 的 Anthropic 兼容接口用x-api-keyOpenAI 兼容接口用Authorization: Bearer别混用。如果 Key 刚创建就报 401检查是否复制了完整字符串有些编辑器会自动截断。local proxy failed。这个报错通常出现在 Claude Code 或 Cline 连接本地 MCP Server 时。原因是客户端尝试通过本地代理转发请求但代理进程没起来。检查mcp_settings.json里的command和args路径是否正确用绝对路径不要用相对路径。如果 Server 启动时报Cannot find module说明npm install没跑或者node_modules不在预期位置。另外Windows 下路径要用双反斜杠或正斜杠单反斜杠会被转义。reading choices。这个报错一般出现在模型返回格式不符合预期时。比如你让模型调用 Tool但模型返回了一段自然语言而不是 JSON。检查CallToolRequestSchema的返回结构content数组里每个元素必须有type和text。如果type写成string而不是text客户端解析会失败。另外如果 Tool 的inputSchema里required字段没写对模型可能生成空参数导致 Server 侧报错。OAuth 相关报错。如果你用的是需要 OAuth 的 MCP 客户端比如某些企业版工具报错信息里会出现OAuth token expired或invalid_client。TaoToken 的 Key 是静态 Key不需要 OAuth 流程。如果客户端强制走 OAuth检查是否选错了认证模式。在 Cline 里认证模式选“API Key”而不是“OAuth”。如果配置里同时存在oauth和apiKey字段删掉oauth相关配置。还有一个隐蔽的坑Model ID 写错导致的model not found。这个报错不会出现在 401 里而是返回 400。检查 https://taotoken.net/doc 里的模型列表确认版本号完整。比如claude-sonnet-4-20250514不能简写成claude-sonnet-4。排障时建议打开客户端的详细日志。Cline 在设置里有“Show Logs”选项Claude Code 用--debug参数启动。日志里会显示完整的请求和响应比猜快得多。6. 把三件套用对Resources 喂数据、Tools 干活、Prompts 定格式回到最初的问题为什么“连上了却不好用”因为很多人把三个概念用混了。Resources 是只读数据适合放日志、配置、文档这类“模型需要看但不修改”的内容Tools 是可执行动作适合放查询、计算、发送这类“模型需要做”的操作Prompts 是模板适合放“固定格式的输出要求”比如报告、摘要、代码审查。一个实用的判断标准如果这个能力需要模型“主动决定什么时候用”放 Tools如果这个能力是“用户主动选择”放 Prompts如果这个能力只是“提供数据”放 Resources。按这个标准日志文件是 Resources统计错误数是 Tools生成报告是 Prompts。TaoToken 在这里的价值是让模型调用层统一。你不需要在 MCP Server 里维护多套模型凭证只需要一个 Base URL 和一个 Key。切换模型时改TAOTOKEN_MODEL_ID就行Server 代码不用动。这对于需要对比不同模型效果的场景特别有用——同一套 Resources、Tools、Prompts换个 Model ID 就能跑。最后给一个进阶用法把 Prompts 和 Tools 组合起来。比如先调用count_errors拿到错误数量再把数量和日志片段填入fault_report模板最后让模型生成报告。这个流程在客户端里可以手动触发也可以写成自动化脚本。MCP 的协议设计允许这种组合因为 Prompts 返回的是标准messages可以直接作为下一轮对话的输入。如果你还没拿到 Key从 https://taotoken.net/api-keys 创建一个然后按第 2 节的 curl 命令验证。接入文档在 https://taotoken.net/doc 里面有各客户端的详细配置示例。长期做编码和 Agent 开发的话Coding Plan 在 https://taotoken.net/coding-plan 有更完整的额度方案。模型对话调试入口在 https://taotoken.net/chat 可以快速验证 Model ID 是否可用。配置过程中如果遇到 Inspector 里三项都通过、但客户端里模型不调用 Tools 的情况优先检查客户端的 MCP 日志而不是改 Server 代码。大多数时候是客户端的工具发现机制没触发重启客户端或者重新加载 MCP 配置就能解决。
返回列表