开源MCP交易平台:用OpenAPI与Stripe搭建可计费的MCP服务市场

发布时间:2026/10/2 18:53:57
开源MCP交易平台:用OpenAPI与Stripe搭建可计费的MCP服务市场
1. 从零搭一个能收钱的 MCP 服务市场到底卡在哪你可能已经写好了一个挺有意思的 MCP 工具比如查企业工商信息、做图片超分、跑一段代码审计本地用 Claude Desktop 或 Cline 调得挺顺。但一旦想把它变成「别人也能用、还能按量付费」的服务问题就全冒出来了用户怎么注册、API Key 怎么发、调用次数怎么统计、Stripe 订阅怎么和额度挂钩、回调丢了怎么办。这些和 MCP 本身没半点关系却能把一个周末项目拖成烂尾工程。我试过最原始的方案自己写一张api_keys表用 Flask 加个/v1/chat转发再手动对账。结果第一个真实用户就翻车了——他调了 300 次我的计数脚本因为并发写丢了 40 次月底对账差了十几块钱虽然不多但那种「账对不上」的感觉非常糟糕。后来才意识到MCP 交易平台的核心不是 MCP而是计费闭环OpenAPI 定义契约、Stripe 管钱、MCP 网关管鉴权和计量三者缺一不可。这篇就按这个思路走用 OpenAPI 描述你的 MCP 工具能力用 Stripe 建产品和价格再把两者接到一个可运行的 MCP 服务市场上最后跑一次从下单到 webhook 回调的完整验证。全程给可复制的配置片段不玩虚的。适合已经会写 MCP Server、但被支付和用户体系卡住的开发者。如果你还没写过 MCP Server建议先跑通一个 echo 工具再回来不然会有点跳。2. 前置准备TaoToken 的 Key、模型与 MCP 接入位在动手写交易平台之前得先有一个稳定的模型调用入口否则你的 MCP 工具里但凡涉及 LLM 推理比如摘要、分类、代码生成测试阶段就会卡在额度或鉴权上。我这边统一用 TaoToken 来做模型侧的前置它的 API 地址是https://taotoken.net/api兼容 OpenAI 风格的请求MCP Server 里直接当普通 HTTP 客户端调就行。第一步是拿 Key。打开https://taotoken.net/api-keys登录后创建一个新 Key复制出来形如sk-xxxxxxxx。注意这个 Key 只在创建时完整显示一次丢了只能重建。拿到后先别急着写进代码用 curl 验一下curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的Key \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, messages: [{role: user, content: 只回复 ok}] }返回里choices[0].message.content是ok就说明 Key 和网络都通了。这一步很重要因为后面 MCP 工具内部如果调模型失败报错会藏在工具执行日志里很难定位。第二步是确认模型 ID。TaoToken 的模型列表在https://taotoken.net/models常用的有gpt-4o-mini、claude-3-5-sonnet这类。你的 MCP 工具如果按 Token 计费模型 ID 要写进 OpenAPI 的x-pricing扩展字段里Stripe 那边建价格时也要对应上不然后面按量计费会对不上账。第三步是 MCP 接入位。如果你用的是 Claude Code 或 Cline它们的 MCP 配置里需要填 Base URL、Key、Model ID 三件套。以 Claude Code 为例配置文件在~/.claude/claude_desktop_config.json不同版本路径略有差异MCP Server 段落长这样{ mcpServers: { my-market-gateway: { command: npx, args: [-y, my/mcp-gateway], env: { TAOTOKEN_BASE_URL: https://taotoken.net/api, TAOTOKEN_API_KEY: sk-你的Key, TAOTOKEN_MODEL_ID: gpt-4o-mini } } } }这里TAOTOKEN_BASE_URL不要带末尾斜杠TAOTOKEN_MODEL_ID必须和你在 OpenAPI 里声明的模型一致。三件套缺一个MCP 工具在调用模型时就会报 401 或 model not found。如果你更习惯用 Coding Plan 做长期编码和 Agent 调试可以在https://taotoken.net/coding-plan看套餐但本文的验证流程用按量 Key 就够了。3. 可复制配置OpenAPI 契约 Stripe 价格 MCP 注册这一节是全文的核心三份配置要能直接抄。先讲 OpenAPI 怎么描述一个可计费的 MCP 工具。MCP 工具本质是一个带 JSON Schema 入参的函数OpenAPI 3.1 刚好能表达。下面是一个「文本摘要」MCP 工具的规范片段保存为summarize.openapi.yamlopenapi: 3.1.0 info: title: Summarize MCP Tool version: 1.0.0 x-mcp-server: name: summarize transport: stdio entry: node ./dist/summarize.js paths: /summarize: post: operationId: summarize_text summary: 对输入文本做摘要 x-mcp-tool: true x-pricing: mode: per_token model_id: gpt-4o-mini input_price_per_1k: 0.002 output_price_per_1k: 0.006 requestBody: required: true content: application/json: schema: type: object required: [text] properties: text: type: string description: 待摘要的原文 max_words: type: integer default: 120 responses: 200: description: 摘要结果 content: application/json: schema: type: object properties: summary: type: string关键在x-mcp-tool: true和x-pricing。前者告诉平台「这个 operation 要暴露成 MCP 工具」后者声明计费模式。per_token模式下平台会在每次调用后读取模型返回的 usage按input_price_per_1k和output_price_per_1k折算金额。如果你只想按次收费把mode改成per_call再加一个price_per_call: 0.01即可。接着是 Stripe 侧。登录 Stripe Dashboard先建产品Product再建价格Price。按量计费要用metered price配置如下在 Stripe 后台操作这里给对应字段字段值说明Product nameSummarize MCP产品名Pricing modelUsage-based按量Metersummarize_tokens计量单位Price per unit0.000002 USD每 Token 单价Billing periodMonthly月结建完后拿到price_id形如price_1Qxxxx。这个 ID 要写进平台的环境变量。同时建一个 webhook endpoint指向你的平台/api/stripe/webhook订阅checkout.session.completed、invoice.paid、customer.subscription.updated三个事件。webhook secret 形如whsec_xxxx也存进环境变量。最后是 MCP 服务注册。平台侧需要一个注册接口把 OpenAPI 文件、Stripe price_id、以及 MCP 启动命令绑在一起。配置文件market.config.json{ services: [ { id: summarize, openapi: ./summarize.openapi.yaml, stripe_price_id: price_1Qxxxx, stripe_meter_event: summarize_tokens, mcp: { command: node, args: [./dist/summarize.js], env: { TAOTOKEN_BASE_URL: https://taotoken.net/api, TAOTOKEN_API_KEY: sk-你的Key, TAOTOKEN_MODEL_ID: gpt-4o-mini } }, auth: { type: api_key, header: X-MCP-Key, issue_on: checkout.session.completed } } ] }注意auth.issue_on用户完成 Stripe 结账后平台自动生成一个 MCP Key 并绑定到该用户。这个 Key 就是后续调用 MCP 工具时的凭证。三份配置齐了平台启动时读market.config.json加载 OpenAPI 生成工具列表同时把 Stripe price_id 和计量事件注册进去。4. 端到端验证从下单到 webhook 回调跑通一次配置写完得真跑一次。我用 Stripe 的测试模式流程分四步创建 Checkout Session、模拟支付、接收 webhook、用 MCP Key 调工具并上报用量。第一步创建 Checkout Session。平台提供一个/api/checkout接口内部调 Stripe SDKconst session await stripe.checkout.sessions.create({ mode: subscription, line_items: [{ price: price_1Qxxxx, quantity: 1 }], success_url: https://your-market.com/success?session_id{CHECKOUT_SESSION_ID}, cancel_url: https://your-market.com/cancel, metadata: { service_id: summarize, user_id: u_123 } });返回的session.url就是支付页。测试模式下用卡号4242 4242 4242 4242任意未来日期和 CVC 即可完成支付。第二步webhook 接收。Stripe 会 POST 到/api/stripe/webhook你的处理逻辑要验签并处理事件app.post(/api/stripe/webhook, express.raw({type: application/json}), (req, res) { const sig req.headers[stripe-signature]; let event; try { event stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET); } catch (err) { return res.status(400).send(Webhook Error: ${err.message}); } if (event.type checkout.session.completed) { const session event.data.object; const userId session.metadata.user_id; const mcpKey generateMcpKey(userId, session.metadata.service_id); db.saveKey(mcpKey, userId); } res.json({ received: true }); });验签失败会返回 400Stripe 会重试。这里有个坑express.raw必须放在express.json之前否则 body 被解析过验签永远失败。第三步用 MCP Key 调工具。拿到mcpKey后通过 MCP 客户端调用summarize_textcurl -X POST https://your-market.com/mcp/summarize \ -H X-MCP-Key: mcp_xxxxxxxx \ -H Content-Type: application/json \ -d {text: 很长的一段原文..., max_words: 80}平台收到请求后先校验 Key再转发给 MCP Server 执行拿到结果后读取模型 usage向 Stripe 上报计量事件await stripe.billing.meterEvents.create({ event_name: summarize_tokens, payload: { value: String(totalTokens), stripe_customer_id: customerId } });第四步验证结果。在 Stripe Dashboard 的「Meters」页面能看到summarize_tokens的累计值在「Customers」里能看到该用户的用量和预估账单。如果这两处都有数说明从下单到计费的闭环通了。我实测下来从支付完成到 meter 出现数据大约有 10 到 30 秒延迟属于正常范围别急着以为没上报。5. 常见报错排查401、local proxy failed、reading choices、OAuth跑通一次不代表稳定下面这几个错我踩过按报错原文对照排查。401 Unauthorized。两种可能一是 MCP Key 没带上或带错 header检查X-MCP-Key是否和平台签发的一致二是 TaoToken 的 Key 失效检查TAOTOKEN_API_KEY是否过期。区分方法看报错来自平台还是来自模型侧。平台侧 401 会返回{error:invalid mcp key}模型侧 401 会返回 OpenAI 风格的{error:{message:Incorrect API key}}。local proxy failed。这个通常出现在 MCP 客户端Claude Code、Cline启动 MCP Server 时说明客户端连不上你配置的 Base URL。检查TAOTOKEN_BASE_URL是否写成https://taotoken.net/api不要带/v1也不要带末尾斜杠。另外确认本机没有残留的 HTTP_PROXY 环境变量有的话unset HTTP_PROXY HTTPS_PROXY再重启客户端。reading choices。报错形如Cannot read properties of undefined (reading choices)说明模型返回体里没有choices字段。最常见原因是请求体里model写错或者 TaoToken 侧返回了错误对象但代码没判断response.error。加一层防御const data await res.json(); if (!data.choices || !data.choices[0]) { throw new Error(model call failed: ${JSON.stringify(data)}); }OAuth 相关报错。如果你用 Claude Code 的 OAuth 登录方式接 MCP报OAuth token exchange failed多半是回调地址和注册时填的不一致。Claude Code 的 OAuth 回调固定为http://localhost:PORT/callback端口每次启动可能变所以注册应用时要么填通配要么用 API Key 方式替代。我后来统一改成 API Key 鉴权省掉这一堆麻烦。三件套Base URL Key Model ID只要对齐OAuth 问题就不会出现。6. 把闭环跑稳之后下一步做什么到这一步你已经有了一个能收钱、能计量、能鉴权的 MCP 服务市场最小闭环。接下来可以做的把x-pricing扩展成支持阶梯定价比如前 1000 次免费、之后按量给 webhook 加幂等处理防止 Stripe 重试导致重复发 Key在平台侧加一个用量看板直接读 Stripe 的 meter 数据展示给用户。如果你还没开始写 MCP Server建议先去https://taotoken.net/doc看接入文档把模型调用跑通再回来套本文的计费配置。模型对话调试可以用https://taotoken.net/chat长期跑 Agent 和编码任务的话https://taotoken.net/coding-plan更划算。API Key 管理在https://taotoken.net/api-keys记得定期轮换。最后说个真实经验Stripe 的测试模式和 live 模式数据完全隔离上线前一定要用 live key 再跑一次完整流程尤其是 webhook secret测试和生产的值不一样别直接复制。我见过有人上线后订单一直不生效查了半天发现 webhook secret 还是测试的。