Skip to main content
Glama
Eduardo-Orsi

yampi-mcp

by Eduardo-Orsi

一个 MCP 服务器,让你可以从 Claude 与你的 Yampi 商店对话—— 查询订单、创建商品、调整库存、创建优惠券和促销活动。

每个商家都在 Cloudflare 上托管自己的副本。这不是一项服务:除了你之外,没有人持有你的 凭据。 非官方项目,与 Yampi 无关联。

工作原理

Yampi 凭据属于用户,而不是商店:如果你在一个登录账号下运营四家商店,四家都会显示出来。 你只需连接一次,然后在每条命令中指定要操作的商店。

Related MCP server: MCP Shopify

安装

你需要一个 Cloudflare 账户(免费套餐就足够了)和已安装的 Node。

git clone https://github.com/Eduardo-Orsi/yampi-mcp && cd yampi-mcp
npm install
cp wrangler.example.jsonc wrangler.jsonc
npx wrangler kv namespace create OAUTH_KV   # paste the returned id into wrangler.jsonc
npx wrangler deploy

在你的 Claude 客户端(claude.ai、Desktop 或 Code)中,添加一个指向 https://yampi-mcp.<your-subdomain>.workers.dev/mcp 的自定义连接器。

连接时,屏幕会要求你输入 User-Token 和 User-Secret-Key。你可以在 Yampi 后台的 Perfil › Credenciais de API(个人资料 › API 凭据)中找到它们。就这样——无需创建密码。

使用方法

连接后,就是普通的对话:

"6 月 1 日到 15 日之间,X 商店收到了多少笔已付款订单?" "创建一个名为 Black T-Shirt 的商品,品牌 Acme,SKU TS-BLACK-M,R$ 79.90,库存 20 件。" "SKU TS-BLACK-M 的价格标错了——改成 R$ 89.90,库存降到 5 件。" "这周有哪些被放弃的购物车,它们合计多少钱?" "创建一个 15% 的优惠券,月底前有效,最低消费 R$ 100,限用 50 次。"

如果账号下有多个商店,请说明是哪一个——工具明确要求指定商店,这样就不会把数据写到错误的商店。

功能列表

工具

功能

describe_store

商店、订单状态、分类和品牌——相当于一张地图,让模型不再猜测 id

search_orders

按状态、时间段和自由文本筛选订单

get_order

单个订单,包含商品、客户、支付、地址和历史信息

search_products

商品目录,包含 SKU、价格和图片

get_product

单个商品,包含变体、库存、品牌和分类

search_customers

客户和地址

customer_history

一个客户及其所有订单

abandoned_carts

从未转化为订单的购物车

create_product

创建商品及其 SKU

update_product

编辑商品字段

manage_sku

创建 SKU,或更新价格和库存

create_coupon

折扣优惠券

advance_order_status ⚠️

将订单移动到另一个状态

add_order_comment ⚠️

在订单上添加内部备注

manage_offers

返现、订单加购、追加销售和免费赠品

⚠️ 未针对线上 API 验证。 其他十三个工具已针对真实商店进行了端到端测试——创建商品、修改价格、写入库存、发放优惠券——字段名也是在这个过程中修正的。这两个工具需要一个已有订单,而测试商店没有。端点是正确的;请求体来自文档,而文档在其他五个写入操作中每一个都至少缺少一个必填字段。首次调用预计会返回 422——错误消息会指出缺少的字段。

刻意不做的事情

它不会取消订单、退款或切换支付网关。 这不是一个藏在环境变量后面的功能:而是代码根本不存在。这些是 API 中不可逆的操作,而 Claude Desktop 和 claude.ai 都不支持 elicitation——也就是说服务器无法真正请求确认。不实现这些功能是唯一不依赖于有人保持警惕的保证。

这个禁令在两个地方强制执行,且都有测试覆盖:状态别名处 (tools/write.ts)以及每个请求都会经过的接缝处 (yampi.ts)。理由见 docs/adr/0002。

订单物流跟踪也不在范围内:Yampi 将该路由限制为每小时 3 次请求,这使得该工具 实际上毫无用处——调用两次后代理就会被卡住 20 分钟。

你的凭据

  • 以加密(AES-GCM)形式存储在 OAuth 授权属性中,位于你的 KV 里。

  • 用于加密的密钥由从访问令牌派生的密钥包裹,而 KV 只保存令牌的哈希。仅 KV 泄露 无法打开凭据。

  • Claude 永远不会收到它们:它只能看到一个不透明的令牌。

  • 撤销意味着删除授权——其他连接不受影响。

/authorize 是公开的,会验证凭据,这从技术上讲使其成为测试被盗密钥的预言机。 因此限制为每个 IP 每分钟 5 次尝试。

要将实例限制为特定商店:

npx wrangler secret put ALLOWED_STORES   # e.g. my-store,other-store

API 限制

Yampi 对每个路由每分钟的限制为:商品和 SKU 30 次/分钟,订单读取 120 次,写入 30 次, 一般请求 60 次。服务器使用 include= 在单次调用中拉取关联数据,而不是 N+1 次调用, 从每个响应中读取 X-RateLimit-Remaining,并在配额即将用完时警告模型——而不是让模型 通过 429 错误才发现。

出问题时怎么办

所有请求都返回 403,包括读取。 商店在 Yampi 后台中为 active: false。 非活跃商店会拒绝所有路由。重新激活它,然后重新连接连接器。

写入返回 422。 错误消息会指出 Yampi 拒绝的确切字段——服务器会转发完整的 errors 对象。Claude 通常会在下一次尝试时自行纠正。

"Grant without credential"(授权缺少凭据)。 授权丢失了其属性。删除连接器并重新添加。

切换凭据。 只需重新连接:新的授权会替换旧的。要在不重新连接的情况下切断访问, 请删除 KV 命名空间。

商店从列表中缺失。 要么它处于非活跃状态,要么凭据无法访问它。 运行 describe_store 查看服务器能看到什么。

Yampi API 的怪癖

通过针对线上 API 测试发现。每一个都可能耗费数小时,而且文档中都没有明确说明:

  • 筛选器需要数组语法。 ?status_id=4 会被静默忽略并返回整个数据集; ?status_id[]=4 才会筛选。active[] 同理。一个不起作用的筛选器比没有筛选器更糟: 代理会基于 55,000 条订单做总结,却以为自己看到的是 7 月的数据。

  • 日期使用一种特殊格式:?date=created_at:2026-06-01|2026-06-30。其他任何格式 都会返回 500 或被忽略。

  • filters[...] 不筛选。 它只是将响应切换为 scroll_id 分页。

  • /auth/me 是 POST,不是 GET,并且返回凭据下的所有商店——因为凭据属于用户, 而不是商店。

  • 订单 include 有一个封闭的枚举:items、customer、marketplace、status、 statuses、shipping_address、promocode、transactions、comments、files、discounts、 seller、labels。没有 payments。

  • GET 响应在 Yampi 端会被缓存 30 分钟。 在代理场景中这会造成误导: 创建一个商品,然后要求读回它,你会得到之前的状态。此服务器在每次读取时都会发送 ?skipCache=true。

  • 库存不是 SKU 字段。 SKU 上的 quantity 始终为 null——包括真实商店中真实 SKU 也是如此。 库存位于 /logistics/stocks(库存位置),通过 /catalog/skus/{id}/stocks 关联到 SKU。 而且 stock_id 不是 /logistics/warehouses 中的 id,那是完全不同的资源。

  • 优惠券 discount_type 只接受 p 或 v,不接受 percentage/fixed。

  • 优惠券日期需要 Y-m-d H:i:s 格式。 仅日期会返回 422。

  • PUT /catalog/skus/{id} 即使部分更新也需要 product_id 和 price_cost。

  • 创建商品需要 simple、brand_id 和 skus.*.blocked_sale,这些都不明显。

  • active: false 的商店对所有请求返回 403,包括读取。此服务器在连接时就会过滤掉 这些商店,因此模型永远不会被提供一个注定失败的选项。

  • 422 响应带有 errors 对象,指出失败的确切字段。值得将其转发给模型,而不仅仅 显示状态码——这正是让模型能够自我纠正的关键。

开发

npm test              # 32 unit tests, no network
npm run typecheck
npm run dev           # wrangler dev

针对你自己的商店进行测试

单元测试套件使用模拟的 fetch 来验证服务器的逻辑。它无法发现 Yampi 更改端点、字段名或筛选语法——而在构建这个项目时这种情况反复发生。 另一半由集成测试套件覆盖,它针对线上 API 发起请求,只读,不创建或修改任何内容:

cp .env.example .env    # fill in the alias and credentials of YOUR store
npm run test:integration

它检查商店发现是否正常、状态别名是否存在、按状态筛选是否真的生效、日期格式是否被接受、 include 是否能展开关联关系、以及配额响应头是否到达。如果其中一项失败,说明 API 变了, 服务器会在开始出错之前就开始撒谎。

架构只有一条规则:没有工具直接发起 HTTP 请求。 所有请求都经过 src/yampi.ts。这正是"不会触及被禁止路由"这一承诺可审计的原因—— 整个表面区域都集中在一个文件中。

项目词汇表见 CONTEXT.md。决策记录见 docs/adr/。

已知限制

  • 不支持订单物流跟踪(Yampi 每小时 3 次的限制使其无法使用)。

  • 不支持横幅、免运费规则、阶梯折扣或组合优惠。

  • advance_order_status 和 add_order_comment 从未针对线上 API 运行过。

  • 库存写入商店注册的第一个库存位置。使用多个位置的人需要调整 src/tools/write.ts 中的 defaultStockId()。

贡献

欢迎提交 Pull Request。Fork 项目,向 main 分支发起 PR,CI 会运行类型检查和 单元测试。对于比 bug 修复更大的改动,请先开一个 issue。

有一类改动无论补丁质量如何都不会被合并:任何取消订单、退款或切换支付网关的代码, 包括间接实现方式。这种缺失正是这个项目的意义所在——推理过程见 ADR 0002。

详情见 CONTRIBUTING.md。发现安全问题?不要公开提交 issue——请参阅 SECURITY.md。

许可证

MIT——见 LICENSE。

assets/ 中的 Yampi 标志是 Yampi 的商标,此处仅用于标识此服务器所对接的平台。它不受 MIT 许可证保护,且本项目与 Yampi 无关联,亦未获得 Yampi 的认可。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A comprehensive MCP server for Shopify Admin API integration, enabling AI assistants to manage products, orders, customers, inventory, analytics, and more through natural language.
    20 npm
    19
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that integrates with the FacturaScripts ERP system, providing resources and tools to manage clients, products, invoices, accounting entries, and business analytics through natural language.
    10
    -
  • A
    license
    B
    quality
    A
    maintenance
    Servidor MCP para integrar la plataforma CLI MARKET con asistentes de IA. Permite gestionar productos, pedidos, clientes e inventario de tu tienda marketplace mediante lenguaje natural.
    32
    1
    MIT