MCP 与命令行 · 接入准备
消费者购物
MCP 快速开始
做 AI Agent 的话,可以不自己拼请求、算签名,直接用 MCP 接入:每个工具对应一条接口, 业务规则、风控与直接调接口完全一致。
- 1开通
最简单:连接时不带凭证,支持 OAuth 的客户端(Claude Code、Cursor、VS Code 等)会自动弹出浏览器,用开发者手机号登录、 选择 appKey 授权即可(新号码自动开通体验 appKey(7 天有效、每天 1000 次调用),正式 appKey 在控制台申请)。 也可以用 Token:在开发者控制台签发(体验或正式 appKey 都行), 会给出 Token 已填好的安装命令。Token 只展示一次,等同接口调用权,只放在你的服务端或你自己的电脑上。
- 2连接
地址
https://api.gowu.net/mcp(Streamable HTTP,仅POST),请求头带Authorization: Bearer <MCP Token>。 - 3自查
先调
account_whoami确认权限与收款模式;tools/list只返回你已授权接口对应的工具。 - 4按流程调用
按「MCP · 接入指南」的顺序调用:
lm_search_products→lm_get_product→lm_checkout_preview→lm_create_payment_link→ 把付款码交给用户 →lm_get_payment查结果。
凭证:只有 MCP Token
MCP 客户端不传 appKey,也不传 app_secret。平台按 Token 找到它所属的 appKey,以该 appKey 的身份完成签名与校验, 所以权限、限流、调用记录都与这个 appKey 直接调接口时完全一致:
- 修改 appKey 的接口权限,下一次请求起工具清单随之变化。
- Token 泄露请联系平台重置,旧 Token 立即失效;撤销 Token 只停 MCP,不影响 REST 接口。
- appKey 停用后,MCP 与 REST 同时失效。
1import { Client } from "@modelcontextprotocol/sdk/client/index.js";2import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";3 4// 每个终端用户一条连接:x-open-user 放在连接上,不放在工具参数里5const transport = new StreamableHTTPClientTransport(new URL("https://api.gowu.net/mcp"), {6 requestInit: {7 headers: {8 Authorization: `Bearer ${process.env.GOWU_MCP_TOKEN}`,9 "x-open-user": userId10 }11 }12});13const client = new Client({ name: "your-agent", version: "1.0.0" });14await client.connect(transport);15 16const { tools } = await client.listTools(); // 交给你的模型17const res = await client.callTool({18 name: "lm_search_products",19 arguments: { keyword: "蓝牙耳机", pageSize: 10 }20});消费者购物
终端用户身份
涉及用户的工具(下单、订单、售后、地址)需要请求头 x-open-user,取值同直接调接口时的用户标识,规则见「通用约定」。
- 没带时用户类工具返回明确错误;商品搜索等只读工具照常可用(未登录只给首屏,见「商品」)。
- 浏览器登录授权的连接以开发者本人为终端用户(
dev-<开发者 ID>),不用带x-open-user。 装进个人 Agent 自己用的 Token(体验 Token,或开通时选了「个人 Agent」)同样绑定了一个默认用户:连接不带x-open-user时以它的身份调用,所以安装命令里不用填。服务端按用户接入的 Token 没有默认用户,漏带就报错,不会把用户并到一起。
按用户建连接、在连接上带这个头,不要让模型通过工具参数传用户——参数由模型生成,可能被提示注入改成别人; 取值来自你服务端的登录态,不要透传前端传来的值。
1// 你的服务端:按用户缓存 MCP 连接,x-open-user 取自登录态2const clients = new Map(); // userId → Client3 4async function mcpFor(userId) {5 if (!clients.has(userId)) {6 const transport = new StreamableHTTPClientTransport(new URL("https://api.gowu.net/mcp"), {7 requestInit: { headers: {8 Authorization: `Bearer ${process.env.GOWU_MCP_TOKEN}`,9 "x-open-user": userId10 } }11 });12 const client = new Client({ name: "your-agent", version: "1.0.0" });13 await client.connect(transport);14 clients.set(userId, client);15 }16 return clients.get(userId);17}18 19// ✅ 用户由你的会话决定20const client = await mcpFor(req.session.userId);21// ❌ 不要让模型在工具参数里决定「是谁」