ARTICLE DETAIL

资讯详情

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

第 08 篇:MCP 网关 —— 从开发玩具到生产基础设施,TaoToken 统一 Key 接入 Cloudflare Workers 的配置骨架

第 08 篇:MCP 网关 —— 从开发玩具到生产基础设施,TaoToken 统一 Key 接入 Cloudflare Workers 的配置骨架 1. 从本地玩具到生产MCP 网关到底卡在哪本地跑通一个 MCP Server 只要几十行代码但一旦要把它交给团队里其他人用、或者接入到线上 Agent 流程里问题就会成串冒出来。我见过最常见的场景是开发机上 Claude Desktop 连得好好的换到同事电脑就连不上或者某个 Agent 高频调用把 Server 打挂日志里却查不到是谁调的。这些都不是 MCP 协议本身的问题而是缺少一层统一的入口——也就是 MCP 网关。MCP 网关可以理解成 MCP 世界的 API Gateway。它插在客户端和后端 MCP Server 之间把认证、路由、限流、监控、审计这些横切关注点收拢到一处。后端 Server 只负责业务逻辑不用每个都重复实现一遍 OAuth、HTTPS、日志。对于个人开发者网关能帮你把本地玩具变成可分享的服务对于团队它是把 MCP 从实验推进到生产基础设施的关键一步。这篇聚焦一个具体路径用 Cloudflare Workers 作为运行环境通过 TaoToken 统一 Key 和 API 通道接入 MCP 服务。我会给出可复制的config.toml、settings.json配置骨架Workers 侧的路由与鉴权示例以及 curl 验证请求和日志排查动作。适合已经写过一两个 MCP Server、想把它部署成稳定服务的读者。2. TaoToken 前置统一 Key 与通道准备在把 MCP 服务搬到 Workers 之前先把上游模型的访问通道理顺。TaoToken 在这里扮演的是统一 Key 和 API 通道的角色——你不需要在 Worker 里硬编码多个厂商的 Key而是通过一个统一的入口去调用模型能力MCP 工具内部需要模型推理时直接走这条通道。第一步是拿到 API Key。访问 https://taotoken.net/api-keys 创建建议按环境分 Key比如mcp-dev、mcp-prod各一个方便后续在 Workers 的 secrets 里区分。创建后立刻复制保存页面刷新后不再显示完整 Key。第二步是确认接入文档里的 Base URL 和请求格式。文档地址在 https://taotoken.net/doc 重点看两处一是 API 的 Base URL二是鉴权头的写法。通常是在请求头里带Authorization: Bearer 你的Key具体以文档为准。第三步是决定模型通道。如果你只是让 MCP 工具做简单的文本处理用默认通道即可如果涉及长上下文或代码生成可以在 https://taotoken.net/models 里对比一下可用模型选一个性价比合适的。对于长期跑编码类 Agent 的场景可以了解下 Coding Planhttps://taotoken.net/coding-plan 它针对持续编码调用做了额度优化比按量计费更可控。这里有个容易踩的坑不要把 Key 直接写进wrangler.toml的[vars]里然后提交到 Git。Workers 的[vars]是明文环境变量正确做法是用wrangler secret put写入加密 secret后面配置章节会演示。3. 可复制配置config.toml 与 settings.json 骨架这一节给出两份可以直接抄的配置。第一份是 Workers 项目的wrangler.toml第二份是客户端侧的settings.json以 Claude Desktop 风格为例其他客户端字段名可能不同按官方文档映射。先看wrangler.toml。关键点有三个main指向 Worker 入口compatibility_date用较新的日期以启用 Streamable HTTP 相关能力敏感信息全部走 secret 而不是[vars]。name mcp-gateway main src/index.ts compatibility_date 2026-01-01 compatibility_flags [nodejs_compat] # 非敏感配置放这里 [vars] MCP_SERVER_NAME taotoken-mcp-gateway UPSTREAM_BASE_URL https://taotoken.net/api LOG_LEVEL info # 路由把 /mcp 暴露为 MCP 端点 [observability] enabled true # 注意TAOTOKEN_API_KEY 不要写在这里 # 用 wrangler secret put TAOTOKEN_API_KEY 写入写入 secret 的命令wrangler secret put TAOTOKEN_API_KEY # 粘贴你的 Key回车确认再看客户端侧的settings.json。远程 MCP Server 用type: url本地命令式用command两者不要混。这里同时给出一个通过网关访问的远程配置和一个本地调试配置方便对照。{ mcpServers: { taotoken-gateway-prod: { type: url, url: https://mcp-gateway.your-account.workers.dev/mcp, headers: { Authorization: Bearer ${TAOTOKEN_API_KEY} } }, taotoken-gateway-local: { command: npx, args: [wrangler, dev, --local], env: { TAOTOKEN_API_KEY: dev-key-placeholder } } } }注意${TAOTOKEN_API_KEY}这种占位写法是否被客户端支持取决于具体客户端。如果不支持环境变量插值就改成明文仅限本地调试或者用客户端提供的 secret 机制。生产配置里永远不要出现明文 Key。4. Workers 侧路由与鉴权示例配置就绪后写 Worker 入口。核心逻辑是解析路径/health放行/mcp先鉴权再交给 MCP transport 处理其余返回 404。鉴权部分做两层——先校验请求头里的 Bearer Token 是否匹配我们配置的 Key再可选校验 Cloudflare Access 的 JWT。import { McpServer } from modelcontextprotocol/sdk/server/mcp.js; import { StreamableHTTPServerTransport } from modelcontextprotocol/sdk/server/streamableHttp.js; import { z } from zod; interface Env { TAOTOKEN_API_KEY: string; UPSTREAM_BASE_URL: string; MCP_SERVER_NAME: string; LOG_LEVEL: string; } const server new McpServer({ name: taotoken-mcp-gateway, version: 1.0.0, }); server.registerTool( summarize_text, { description: 调用上游模型对文本做摘要, inputSchema: z.object({ text: z.string().describe(待摘要文本), maxWords: z.number().default(120).describe(摘要最大词数), }), }, async ({ text, maxWords }, extra) { const env extra?.env as Env; const resp await fetch(${env.UPSTREAM_BASE_URL}/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${env.TAOTOKEN_API_KEY}, }, body: JSON.stringify({ model: default, messages: [ { role: system, content: 用不超过 ${maxWords} 词做摘要。 }, { role: user, content: text }, ], }), }); if (!resp.ok) { return { content: [{ type: text, text: 上游错误${resp.status} }], isError: true, }; } const data await resp.json(); return { content: [{ type: text, text: data.choices?.[0]?.message?.content ?? }], }; } ); function unauthorized(msg: string) { return new Response(JSON.stringify({ error: msg }), { status: 401, headers: { Content-Type: application/json }, }); } export default { async fetch(request: Request, env: Env): PromiseResponse { const url new URL(request.url); if (url.pathname /health) { return new Response(OK, { status: 200 }); } if (url.pathname ! /mcp) { return new Response(Not Found, { status: 404 }); } // 鉴权Bearer Token 必须匹配 secret const auth request.headers.get(Authorization) ?? ; const token auth.startsWith(Bearer ) ? auth.slice(7) : ; if (!token || token ! env.TAOTOKEN_API_KEY) { return unauthorized(invalid token); } const transport new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, // 无状态模式便于水平扩展 }); await server.connect(transport); return transport.handleRequest(request); }, };这段代码里有两个设计选择值得说明。一是sessionIdGenerator: undefined走无状态模式这样网关可以自由路由到任意 Worker 实例不用维护会话亲和性。二是鉴权放在 transport 之前未通过鉴权的请求根本不会进入 MCP 协议处理减少无效开销。如果你还想叠加 Cloudflare Access可以在 Bearer 校验之后再加一层 JWT 校验逻辑和上一节类似这里不重复展开。两层鉴权不是必须的但对公网暴露的网关建议至少保留一层。5. 验证请求与成功结果部署完成后先用 curl 验证健康检查和 MCP 端点。健康检查最简单curl -i https://mcp-gateway.your-account.workers.dev/health # 期望HTTP/2 200body 为 OK再验证鉴权是否生效。不带 Token 应该返回 401curl -i -X POST https://mcp-gateway.your-account.workers.dev/mcp \ -H Content-Type: application/json \ -d {jsonrpc:2.0,id:1,method:tools/list} # 期望HTTP/2 401body 含 invalid token带上正确 Token 再请求一次应该能拿到工具列表curl -i -X POST https://mcp-gateway.your-account.workers.dev/mcp \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d {jsonrpc:2.0,id:1,method:tools/list} # 期望HTTP/2 200body 里能看到 summarize_text 工具如果工具列表返回正常再调一次实际工具确认上游通道打通curl -X POST https://mcp-gateway.your-account.workers.dev/mcp \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { jsonrpc:2.0,id:2,method:tools/call, params:{name:summarize_text,arguments:{text:MCP 网关把认证、限流、监控统一收拢。,maxWords:30}} } # 期望返回一段摘要文本说明上游模型调用成功实测下来从wrangler deploy到 curl 拿到工具列表通常一两分钟就能跑通。如果卡在某一步看下一节的排查清单。6. 本篇常见错排查401 一直不消失先确认wrangler secret put TAOTOKEN_API_KEY写入的值和 curl 里用的完全一致包括前后空格。secret 写入后需要重新 deploy 才生效改完记得wrangler deploy。404 Not Found检查url.pathname是否严格等于/mcp。Workers 的 URL 解析对大小写敏感/MCP不会匹配。另外确认wrangler.toml里的main指向的文件路径正确。工具调用返回上游错误多半是UPSTREAM_BASE_URL或模型名不对。先用 curl 直接打一次上游接口确认 Key 和 Base URL 可用再回到 Worker 里排查。上游返回 4xx 时Worker 里的resp.status会原样带出来看日志能快速定位。日志看不到wrangler.toml里[observability] enabled true要打开然后用wrangler tail实时看日志。如果本地wrangler dev正常、线上异常优先对比两边的 secret 和 vars 是否一致。客户端连不上远程端点确认客户端配置里用的是type: url而不是command并且 URL 带上了/mcp路径。有些客户端对自签证书或非标准端口敏感Workers 默认的*.workers.dev域名一般没问题。排障过程中如果发现是 Key 或通道配置的问题回到 https://taotoken.net/api-keys 重新生成一个 Key 对比测试能快速排除是不是 Key 本身失效。接入细节以 https://taotoken.net/doc 为准模型通道选择可以在 https://taotoken.net/models 对照。需要长期跑编码类 Agent 的话Coding Planhttps://taotoken.net/coding-plan 的额度模型比按量更省心。想先在网页里验证模型通道是否通可以直接用模型对话https://taotoken.net/chat 发一条消息试试。
返回列表