内容
# ShopTalk
**实时演示:** **[shop-talk-pied.vercel.app](https://shop-talk-pied.vercel.app)** — 一个独立的演示,包含**示例数据**(没有真实的商店,没有后端)。实际的仪表盘在本地运行,与您的商店连接。
**在 iMessage 中向您的 Shopify 商店提问,获得实时答案。**
> *"今天我卖了多少钱?"* → *"今天我卖了 1,240 美元,共 18 笔订单。"*
> *"显示我的最后 5 笔订单。"* → 一个整洁的订单编号、客户和总金额的列表。
ShopTalk 是一个小型后端,连接 AI 文本助手到 Shopify 商店,允许忙碌的店主通过发送短信查询业务状况 — 无需仪表盘,无需登录,无需 SQL。它专为 **Shopify 企业家** 设计:他们生活在商店的数据中,但不想每天打开管理面板十次。
---
## 适用人群
单个创始人和小型团队经营 Shopify 商店,他们希望像询问合伙人一样询问商店 — "什么正在销售?","我有哪些订单尚未发货?","谁是我的重复客户?" — 并在几秒钟内从手机上获得答案,无需打开任何东西。
目前,ShopTalk **只读** — 安全地发送短信,无需更改商店 — 并专注于商家实际提出的问题。它旨在成长:编写操作(履行订单,调整库存)和更丰富的分析是自然的下一步。
---
## 首先,两个术语(以防您不熟悉)
**什么是"Poke"?** [Poke](https://poke.com)(由加利福尼亚州互动公司开发)是一个个人 AI 助手,您可以通过 **Apple Messages (iMessage), SMS, WhatsApp, Telegram, 和 RCS** 等方式像与朋友一样进行交流,无需打开单独的应用程序。单独使用时,它可以处理电子邮件、日历和提醒等事务。连接 **外部工具** 后,它可以做更多的事情 — 而连接这些工具的方式是 **MCP**。
**什么是"MCP"?** [Model Context Protocol](https://modelcontextprotocol.io) 是一个开放标准(类似于"USB-C for AI 助手"),允许 AI 连接到外部工具或数据源的方式一致。支持 MCP 的程序公开了一组 **工具**,AI 可以调用。Poke 充当 **MCP 主机**:您添加集成(内置"配方"或自定义 MCP 服务器 URL),Poke 发现服务器公开的工具,并在需要时调用它们。**ShopTalk 就是这样一个自定义 MCP 服务器** — 它公开了六个只读工具,由 Shopify Admin API 支持,Poke 是调用这些工具的客户端。
流程如下:
```
您(iMessage) ──> Poke(AI 助手) ──MCP──> ShopTalk ──> Shopify Admin API
```
您向 Poke 发送短信 → Poke 决定哪个 ShopTalk 工具回答您的问题 → ShopTalk 查询 Shopify 并返回数据 → Poke 用普通语言回复。
---
## 您可以用 ShopTalk 做什么(六个工具)
| 工具 | 回答的问题 |
|------|--------------------------|
| `list_stores` | "哪些商店是连接的?" |
| `get_sales` | "今天/本周/本月我卖了多少钱?(收入,订单,平均订单价值 — 按商店或所有商店合计)" |
| `get_orders` | "显示我的最近订单" / "有哪些订单未发货?" |
| `get_order` | "订单 #1042 里有什么?" |
| `search_products` | "找到我的连帽衫" / "我卖什么?" |
| `search_customers` | "谁是我的重复客户?" |
目前,每个工具都是 **只读** 的 — ShopTalk 不能更改、创建或删除商店中的任何内容,由授予的只读权限强制执行,因此误读的文本永远不会修改您的数据。写入是下一步,有意添加 — 一个新工具一次,一个工具后面有相同的 MCP 接口。
---
## 内部机制
ShopTalk 是一个生产级别的全栈项目。亮点:
- **基于流式 HTTP 的 MCP 服务器** — 实现模型上下文协议,因此任何 MCP 客户端(Poke,Claude 等)都可以使用它。无状态传输:每个请求都有一个全新的服务器实例,无需会话状态泄漏或增长。
- **现代 Shopify 身份验证** — Shopify 在 2026 年删除了静态 API 令牌,因此 ShopTalk 使用 **OAuth 客户端凭证授权**:它用应用的客户端 ID/密钥交换短期(24 小时)访问令牌,**在内存中缓存每个商店,并在到期和 401 时自动刷新**。
- **交互式演示仪表盘** — 一个独立的 Next.js 应用,从 **示例数据** 渲染每个工具的结果(收入图表,订单,产品,客户),因此任何人都可以查看 Poke 对话的外观,而无需 Shopify 商店。无需后端,无需真实数据 — 您的真实数字仅发送给 Poke。
- **多商店支持** — 配置驱动的注册表;查询按商店运行或汇总所有商店,按货币分组(从不跨不匹配的货币求和)。
- **关注正确性细节** — 销售窗口按商店的 **时区** 计算(因此"今天"表示商家的今天,而不是 UTC);大型结果集显示"上限"标志,而不是静默减少计数。
- **注重安全** — 只读权限;`/mcp` 和 SSE 流需要共享密钥,**如果未设置,则关闭并仅允许环回请求**;`/internal/broadcast` 仅限 localhost 访问;CORS 受到限制;凭证仅存储在环境变量中,从不存储在存储库中。
- **经过测试和审查** — 数据层的单元测试(Node 的内置运行器),以及项目经过多代理代码审查(本地传递和云"超级审查"),其发现的问题 — 身份验证强化,时区正确性,汇总准确性,重试错误 — 都已修复并重新审查。
**技术栈:** Node 22 · Express · `@modelcontextprotocol/sdk` · Zod · Shopify Admin GraphQL · Next.js 14 / React 18 · Tailwind。 后端可部署到 Railway/Render/Fly;演示托管在 Vercel 上。
**架构一览**
```
backend/
server.js Express:REST + SSE + MCP-over-HTTP 在 /mcp(身份验证保护)
mcp-tools.js 6 个只读 MCP 工具(createMcpServer 工厂)
shopify.js Admin GraphQL 客户端 + OAuth 令牌交换/缓存 + 读取函数
stores.js 多商店注册表(解析 SHOPIFY_STORES)
test/ 单元测试(node --test)
frontend/ 独立演示(示例数据,无后端)
app/page.js 演示仪表盘
components/ ResultPanel,RevenueChart,PanelUI,ChatPanel,ActivityLog
lib/demoData.mjs 示例商店 + 脚本化问答
lib/useDemo.js 按需演示引擎
```
该项目最初是 **MockBase** (相同的实时 MCP + 仪表盘骨架,连接到一个临时 SQLite 数据库),后来重新指向真实的 Shopify API — 提交历史显示了逐步演进。
---
## 自己运行 ShopTalk
**要求:** [Poke](https://poke.com) 账户(免费层可用),Shopify 商店和 Node 22+。
### 1. 创建 Shopify 应用(客户端凭证)
1. 在 Shopify **[开发仪表盘](https://dev.shopify.com)** 中,在您的组织下创建一个应用。
2. 授予读取权限 — `read_orders`,`read_products`,`read_customers` — 并 **发布** 版本。
3. 在您的商店中安装它并复制 **客户端 ID** 和 **客户端密钥** (`shpss_…`)。
4. 记录您的商店的 `*.myshopify.com` 域名(设置 → 域名)。
### 2. 配置和运行后端
创建 `backend/.env`(gitignored — 永远不要提交它):
```
PORT=4000
# 单引号括住值,以便 Node 的 --env-file 解析器保持完整。
SHOPIFY_STORES='[{"key":"main","label":"Main Store","shopDomain":"your-store.myshopify.com","clientId":"your_api_key","clientSecret":"shpss_xxx","apiVersion":"2026-01"}]'
# /mcp 和 SSE 流的共享密钥。 如果没有设置,两个都只接受环回(本地)请求 — 设置它以允许远程客户端,如 Poke。
MCP_TOKEN=some-long-random-string
```
```bash
cd backend && npm install && node --env-file=.env server.js # http://localhost:4000
cd frontend && npm install && npm run dev # http://localhost:3000 (演示,示例数据)
```
针对您的真实商店进行健康检查(只读):`cd backend && node --env-file=.env smoke.js`
### 3. 连接 Poke
通过 CLI 添加 ShopTalk 作为集成:
```bash
npx poke@latest login
npx poke@latest mcp add http://localhost:4000/mcp -n ShopTalk -k <MCP_TOKEN> # 本地(隧道到公共 URL)
```
或从 Poke 的 Web 应用(**集成 → 新建**):粘贴 MCP 服务器 URL 和密钥。无论哪种方式,Poke 都将密钥作为 `Authorization: Bearer <token>` 头部发送到每个请求中,ShopTalk 将其与 `MCP_TOKEN` 验证;连接后,它会自动发现六个工具。然后只需向 Poke 提问。
### 部署(始终在线)
将 `backend/` 部署到 Railway/Render/Fly(包含 Dockerfile)。将 `SHOPIFY_STORES` 和 `MCP_TOKEN` 设置为主机环境变量(以及 `CORS_ORIGIN` 到您的仪表盘 URL,如果您部署前端)。指向 Poke `https://<host>/mcp` 并使用 `-k <MCP_TOKEN>` — 无需隧道,24/7 运行。不是无服务器:SSE 流需要长期连接。
---
## 路线图
ShopTalk 一开始是只读且安全的 — 而且它 ** built to grow**。接下来是什么:
- **写入操作** — 履行订单,调整库存,标记客户。今天只读;工具层通过相同的 MCP 接口干净地添加每个工具。
- **更深入的分析** — 销售趋势图和畅销商品排名,按销售单位(今天 `get_sales` 返回周期总数 + 订单数)。
- **灵活的时间范围** — 自定义日期范围超出当前 `today` / `7d` / `30d`。
- **更大的结果窗口** — 分页超过当前单个 250 订单页面(`capped` 标志已经显示溢出)。
## 测试
```bash
cd backend && node --test
```
## 许可证
MIT — 见 [LICENSE](LICENSE)。