Skip to main content
Glama
shopping-mcp

shopping-mcp

by EastMG

shopping-mcp

MCP Python License Smoke Live JD

一个 MCP server,把淘宝 / 京东 / 拼多多的商品搜索、详情、转链(含优惠券)收成同一套工具,直接接进 DSH。

只调官方开放平台接口。 没有第三方代理、没有远程配置下发、没有凭证转发。

淘宝   淘宝联盟 / 淘宝客  →  https://eco.taobao.com/router/rest
京东   京东联盟            →  https://api.jd.com/routerjson
拼多多 多多进宝            →  https://gw-api.pinduoduo.com/api/router

为什么不用现成的 taoke-mcp

调研过 liuliang520530/taoke-mcp(125 星,功能对口),放弃的原因写在 docs/why-not-taoke-mcp.md。一句话:它的授权走作者的 OAuth 应用,启动时还会从 config.sinataoke.cn 拉配置。本项目把这两条都换成了「你自己的 appkey + 本地 .env」。

Related MCP server: Kettu Marketplace Intelligence

快速开始

# 1. 装依赖
uv sync

# 2. 先看状态(此时三家都是 mock 模式,没有任何凭证也能跑)
uv run shopping-mcp

shopping-mcp 是 stdio 传输的 MCP server,正常用法是被 DSH 拉起来,而不是手动运行。

挂进 DSH

推荐做法:用 DSH 自带的 MCP 管理界面。

如果你装了 dsh-mcp-manager-plus(设置里的「MCP 管理」页),这是最干净的一条路:写入由 DSH 主进程完成,本来就有 profile 目录的写权限;profile 是 patchReload: live,所以约 1 秒热生效,不需要重启,而且是持久化的。

  1. 设置 → MCP 管理 → 添加

  2. 粘贴下面这段(格式自动识别):

{
  "mcpServers": {
    "shopping": {
      "command": "<项目路径>/.venv/Scripts/python.exe",
      "args": ["-m", "shopping_mcp.server"]
    }
  }
}
  1. 保存后展开 shopping 那一行,应能看到 4 个工具:shopping_status / search_products / get_product / convert_link

凭证不要写在这里——server 自己读项目根目录的 .env。管理器的掩码机制(KEY|SECRET|TOKEN 类值会打码)也说明这类配置本就是给它看的,密钥不该放进去。


以下三条是没有管理器时的备选,需要改文件或换启动参数。注意在 DSH 会话内(沙箱里)写 ~/.dsh 会被拒绝,所以要在这之外执行。

叠加层文件已经写好并做过结构校验:dsh/mcp-shopping.patch.yml。

最省事:双击 scripts/register-mcp.cmd —— 在普通 PowerShell 窗口执行(不要在 DSH 的终端里),会先备份再追加,写完校验 YAML。

或者在 PowerShell 里手动跑(等价):

cd <项目路径>
# 若 uv 缓存目录不可写,再按需设置 UV_CACHE_DIR
uv run --with pyyaml python scripts\register_mcp.py

其它两种姿势:

A. 手动粘贴 — 把 dsh/mcp-shopping.patch.yml 里 - insert: 那一段追加到 C:\Users\<你>\.dsh\profiles\desktop\cordis.patch.yml 末尾,重启 DSH。

B. 临时挂载 — 不写任何配置,每次启动带参数:

dsh --profile desktop --patch "<项目路径>\dsh\mcp-shopping.patch.yml" web

凭证不写在这些配置里。server 启动时自己读项目根目录的 .env,所以配置文件里看不到密钥,也不会进 config dump。

启动后调用 shopping_status 应能看到 serverName: shopping 下的四个工具。

配置凭证

Copy-Item .env.example .env
# 然后编辑 .env,只填你拿到的那几家

未填的平台会自动降级成 mock 模式:工具照样能用,返回的是 mock.local 域名下的假数据,字段和真实数据完全一致。这样在等审核期间就能把链路和 prompt 调好。

随时调用 shopping_status 看当前哪家是 live、哪家是 mock、缺哪个变量。

填完先自检

拿到 appkey 后别急着让 agent 搜商品,先跑一次凭证自检——它真的发一次请求,很便宜:

uv run python scripts\probe_creds.py              # 验证所有已配置的平台
uv run python scripts\probe_creds.py --platform pdd

它会区分这几类失败(它们的报错长得不一样,脚本会把 code 和原始返回一起打出来):

现象

含义

签名错误

secret 填错,或首尾有多余空格/引号

应用凭证无效 / 应用未上线

key 复制错,或应用还在审核、没发布

权限不足 / 不支持的接口

最常见:多多进宝没绑定、淘宝客权限没批下来

PID / 推广位无效

PID 取错

授权 session 失效

OAuth token 过期,要重新授权

成功时会打印平台真实返回的字段名和我们的归一化结果并排对照,同时把完整原始返回写到 _probe_raw_<platform>.json。把这个输出贴给 agent,就能据此校准字段映射——现在的映射是照文档推的,只有对过真实返回才算数。

拼多多的完整申请流程见 docs/apply-pdd.md(含最容易漏的「多多进宝绑定」那一步)。

三家平台的申请门槛

拼多多多多进宝(门槛最低,建议先做这家)

  1. 注册 拼多多开放平台 应用 → 拿 client_id / client_secret

  2. 登录 多多进宝 → 推广管理 → 创建推广位 → 拿 PID

  3. 给应用申请 pdd.ddk.*(多多进宝)接口权限

个人可注册,需实名。

京东联盟

  1. 京东联盟 注册推广者 → 拿网站 ID(SITE_ID)和推广位 ID(POSITION_ID)

  2. 在京东开放平台创建应用 → 拿 app_key / app_secret → 申请 jd.union.open.* 权限

淘宝联盟(门槛最高)

  1. 阿里妈妈 注册淘宝客 → 实名认证 + 推广媒体备案

  2. 淘宝开放平台 创建应用 → 申请淘宝客 API 权限(审核通常 1-3 工作日)

  3. 通过 oauth.taobao.com 授权拿 session

  4. PID 形如 mm_<memberId>_<siteId>_<adzoneId>,site_id 与 adzone_id 由本程序自动从 PID 解析

三家具体权限目录以平台当期审核为准,本 README 不替代官方文档。

工具

工具

作用

shopping_status

三家凭证状态、当前模式、申请指引

search_products(platform, keyword, ...)

关键词搜索;支持 has_coupon、排序

get_product(platform, item_id)

按 id 查详情

convert_link(platform, item, sub_pid)

商品 id/链接 → 自己的推广链接

platform 取 taobao / jd / pdd。

统一后的商品字段:

{
  "platform": "pdd",
  "item_id": "1234567890",
  "title": "...",
  "price": 179.0,              // 券后价 / 到手价
  "original_price": 259.0,
  "coupon_amount": 80.0,
  "commission_rate": 5.5,      // 百分比
  "commission_amount": 9.85,   // 预估佣金
  "sales": 12000,
  "shop_name": "...",
  "item_url": "...",
  "promotion_url": "...",
  "image_url": "..."
}

单位归一化(踩过的坑)

平台

坑

本项目怎么处理

三大平台通用

commission_rate 历史上有过小数/百分比/万分比几种口径

_normalize_rate() 按量级判断,原始值保留在 raw

拼多多

所有金额单位是分

_cents() 统一除以 100

拼多多

promotion_rate 是千分比(100 = 10%)

_per_mille() 除以 10

京东

业务结果藏在 <method>_response.result 里,而且是 JSON 字符串

二次解析

淘宝

has_coupon 要传字符串 "true" 不是布尔

adapter 内转换

任何平台返回的原始 payload 都在 raw 字段(to_dict() 默认不输出,调试时可用)。归一化一旦有偏差,用 raw 对照官方文档核对——不要直接相信换算结果。

安全边界

  • 凭证只从本地 .env 或进程环境读取,不写进 DSH 配置,所以不会出现在配置 dump 或共享 patch 里

  • 不抓网页、不模拟登录、不碰支付环节

  • 只读性质:搜索、查详情、生成推广链接。没有下单、没有改价、没有动账户设置

  • .env 必须留在本机,不要提交到 git

支持情况

平台

搜索

详情

转链

前置条件

拼多多

✅

✅

✅ 短链

多多进宝绑定 + 推广位授权备案

淘宝

✅

✅

✅ 淘口令 + 短链

权限包 27939 / 16189 / 11655,见 docs/apply-taobao.md

京东

❌

⚠️ 部分

❌

基础权限包不含 goods.query / bysubunionid,返回 403,见 docs/apply-jd.md

已验证

项

方式

结果

签名算法(三平台共用)

与手算 MD5 对齐

通过

单位归一化(分→元、千分比→百分比、汇率三口径)

单元断言

通过

淘宝 PID 解析 / 拼多多 sales_tip 解析 / goods_sign 判别

单元断言

通过

四个工具的 MCP 协议往返

内存传输握手 + tools/list + tools/call

43/43 通过

商品字段一致性(价格 = 原价 − 券)

断言

通过

has_coupon 确实只返回有券商品

断言

通过

非法 platform 不崩、返回 ok:false

断言

通过

DSH 叠加层结构与 YAML 合法性

结构校验

通过

smoke 的机器无关性

灌入假凭证后重跑

仍 43/43,不依赖本机 .env

拼多多真实接口全链路

真实 appkey + 已完成授权备案

✅ 通过

淘宝真实接口全链路

真实 appkey + 权限包

✅ 通过

跑法:uv run python scripts\smoke.py(43 项,全 mock,无需凭证)

各平台实测要点

拼多多

  • 签名、搜索、详情、转链、授权查询全部走通真实网关

  • 传数字 goods_id 会被拒绝,必须用 extra.goods_sign

  • 搜索 page_size 必须在 10-100,adapter 内已 clamp

淘宝

  • OAuth 回调必须是非淘系域名(example.com 可用,www.taobao.com 会被拒)

  • access_token 1 天有效、refresh_token 30 天,用 scripts\taobao_refresh_token.py 续

  • 权限包 27939 打开的是 .upgrade 变体,经典版 tbk.dg.material.optional 永远报权限不足

  • tbk.item.info.get 不含券/佣金,适配器从搜索缓存补齐

  • privilege.get 无权限,转链走 tbk.tpwd.create(淘口令 + 短链)

未验证

  • 京东 API 未打通(不是资质问题)。推客审核已过、appkey/AppSecret/PID 都拿到了,但基础权限包只有 19 个接口,goods.query(关键词搜索)和 promotion.bysubunionid.get(导购媒体转链)都返回 403 无访问权限。详见 docs/apply-jd.md

  • DSH 里的 stdio 启动 未验证。会话内沙箱禁止创建子进程双向管道(WinError 5),所以协议层是用内存传输测的;真实 stdio 拉起要等你注册并重启 DSH 后确认

  • 拼多多 ddk.goods.search 对新应用有节流,同样关键词有时返回 0 条、有时 3 条。这不是 bug,重试即可

  • 拼多多对高频查询但不出单的账号会限用(40009)。适配器已内置缓存 / 最小间隔 / 日配额 / 冷却四道闸,详见下文

踩过的坑(已修,都是真实接口才暴露的)

坑

表现

修法

commission_rate 走 to_float()

该函数为金额舍入到 2 位,把 0.155 变成 0.15 → 报 15.0% 而非 15.5%

改用原始 float()

Windows 管道 stdout 默认 cp936

中文标题乱码 / UnicodeEncodeError

main() 里 reconfigure(encoding="utf-8")

拼多多响应 key 不总镜像方法名

member.authority.query 实际返回 authority_query_response,被误报 "unexpected response shape"

回退到唯一的 *_response key

pageSize 必须 10-100

传 2 报 50001 / 3000000

adapter 内 clamp

goods_id_list 已下线

转链报 40005,详情报 40004

改用 goods_sign(单数)/ goods_sign_list(转链)

pdd.ddk.rp.prom.url.generate 要 p_id_list

报「请求参数不能为空:p_id_list」

传数组

promotion_url 被误赋成图片地址

归一化结果里推广链接变成了商品图

置 None,只有转链后才有

sales 是字符串 "7万+"

直接 to_int 得到 None

新增 _parse_sales_tip()

拼多多搜索不返回店铺名

mall_name 恒为空字符串

如实返回 null,不用品牌名冒充

拼多多调用节流

拼多多的规则是「调取商品接口多、实际出单少 → 限用」(40009)。这个限制是账号级的,触发后所有搜索都会失败,而且继续调用只会加重,所以适配器内置四道闸:

层

作用

默认

结果缓存

同关键词/页码/排序在 TTL 内不重复请求

900 秒

最小间隔

两次请求之间至少隔这么久

3 秒

每日配额

一天最多调用次数,跨进程持久化到 .pdd_quota.json

150 次

冷却

撞到 40009 后主动停用,期间直接失败不打网络

1800 秒

全部可用环境变量覆盖:PDD_MIN_INTERVAL / PDD_CACHE_TTL / PDD_DAILY_BUDGET / PDD_COOLDOWN。

状态文件 .pdd_quota.json 在 .gitignore 里。想提前重试可以删掉它,但平台侧的解封要等它自己(通常数小时到数天)。

开发

uv sync                                              # 装依赖
uv run python scripts\smoke.py                       # 43 项检查,全部走 mock,不需要任何凭证
uv run --with pyyaml python scripts\check_patch.py    # 校验 DSH 叠加层结构
uv run python scripts\probe_creds.py                 # 用真实凭证验证字段映射

scripts/register_mcp.py 负责把服务注册进 DSH profile,幂等、自动备份、写后校验。 scripts/register-mcp.cmd 是它的双击入口。

smoke.py 是 hermetic 的:它会忽略真实 .env 并清掉环境里所有凭证变量,所以无论你机器上配没配 appkey,结果都一样。填了真凭证之后它也不会误报。

License

MIT © 2026 EastMG

本项目只调用各平台官方开放平台 API,不包含任何平台的数据或代码。使用前请自行确认符合各平台的开放平台协议与推广规则。

Available Tools

4 tools
get_productA

按商品 id 查详情。

淘宝传 num_iid,京东传 skuId,拼多多传 goods_sign(搜索结果 item.extra.goods_sign 那一长串 token —— 拼多多已停用数字 goods_id)。

Args: platform: taobao / jd / pdd item_id: 淘宝 num_iid / 京东 skuId / 拼多多 goods_sign

Inputs: item_id (required), platform (required). Returns: result

search_productsA

按关键词搜索商品,返回统一字段(价格/券后价/券额/佣金率/销量/店铺/链接)。

Args: platform: taobao / jd / pdd keyword: 搜索关键词,中文即可 page: 页码,从 1 开始 page_size: 每页条数,1-50 has_coupon: 只要带优惠券的商品 sort: default / commission(佣金高)/ sales(销量)/ price_asc / price_desc / coupon_price

Inputs: keyword (required), platform (required), page, sort, +2 more. Returns: result

shopping_statusA

查看三个平台(taobao / jd / pdd)的凭证配置状态、当前运行模式与申请指引。

返回每个平台的 mode(live=真实数据 / mock=假数据)、缺失的环境变量名、 以及该平台该去哪里申请、需要什么资质。开始任何调用前先看这个。

Inputs: no named parameters. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 4 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose: status/config check, keyword search, single-item detail lookup, and affiliate-link conversion. The descriptions explicitly differentiate item_id semantics per platform (num_iid vs skuId vs goods_sign), leaving no room for misselection.

    Naming Consistency4/5

    Three tools follow a clean verb_noun pattern (search_products, get_product, convert_link), but shopping_status uses a domain prefix plus noun rather than a verb, a minor deviation. The set is still highly readable and predictable.

    Tool Count4/5

    Four tools is a tight but sensible scope for an affiliate-shopping workflow (search, detail, link conversion, plus a setup/status helper). It leans slightly thin — a category or batch-conversion tool could earn its place — but nothing is redundant.

    Completeness4/5

    The core affiliate lifecycle (discover via search, inspect via get_product, monetize via convert_link, verify setup via status) is fully covered. Minor gaps like batch conversion or order/reporting operations exist but are workable around.

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      A
      quality
      B
      maintenance
      Enables unified product search, coupon retrieval, and cross-platform price comparison across Taobao, JD, and Pinduoduo affiliate APIs through MCP.
      5
      5
      -
    • F
      license
      Not graded
      quality
      B
      maintenance
      Enables searching Taobao products, retrieving item details, and turning listings or official campaign pages into affiliate promotion links, Taobao share codes (淘口令), and short URLs. It calls the official Taobao Alliance open API directly with your own AppKey, requiring no third-party wrapper services, so agents can generate commission-earning shopping links on demand.
      1
      -