内容
# MCP 服务器 Сільпо (silpo-mcp)
MCP(模型上下文協議)服務器,用於通過 AI 助手(Claude Desktop,Claude Code 等)與線上超市 **Сільпо** 進行交互。
基於線上超市 Сільпо 的 storefront-API(`sf-ecom-api.silpo.ua`)構建,刷新自網路流量。沒有官方的 SDK — API 可能會在未經通知的情況下變更。
## 功能
- 🔍 **商品搜尋** — 按名稱或關鍵字
- 📁 **分類** — 查看和篩選商品分類
- 🏷️ **優惠** — 折扣商品
- 📦 **分類商品** — 篩選和排序
- 🛒 **購物車** — 線上超市 Сільпо 的實際購物車;首次添加商品時自動創建
- 🧾 **購物清單** — 與購物車分開,有「已購買」標記
- 🚚 **配送** — 檢查區域、配送類型、時間段
- 💬 **評論** — 商品註釋(「切」、「成熟」)
- 🔐 **授權** — 訂單歷史和獎勵積分令牌
## 安裝
```bash
# 全局安裝
npm install -g silpo-mcp
# 或無安裝
npx silpo-mcp
```
從源代碼:
```bash
git clone https://github.com/MIt9/silpo-mcp.git
cd silpo-mcp
npm install
npm run build
npm start
```
## 設定
### Claude Desktop / Claude Code
`claude_desktop_config.json` 或 `.mcp.json`:
```json
{
"mcpServers": {
"silpo": {
"command": "npx",
"args": ["-y", "silpo-mcp"]
}
}
}
```
或從源代碼:
```json
{
"mcpServers": {
"silpo": {
"command": "node",
"args": ["/absolute/path/to/silpo-mcp/dist/index.js"]
}
}
}
```
> 商店 ID(`branch`)在設置配送地址後自動確定。
## 遠端託管(Claude web / 自定義連接器)
除了本地 stdio 模式,服務器具有 **遠端 HTTP 模式**(`dist/http.js`),
通過 OAuth 2.1 保護 — Claude 正是通過「自定義連接器」連接它。
Claude 中的 `OAuth Client ID` / `OAuth Client Secret` 欄位不是 **IP 防護**,
而是標準的 OAuth:Claude 作為 OAuth 客戶端,服務器作為授權服務器。
訪問受 **登錄頁面密碼**(`SILPO_MCP_PASSWORD`)限制,因此即使知道 URL,
第三方也無法使用。
### 啟動
```bash
npm run build
SILPO_MCP_BASE_URL="https://silpo.example.com" \
SILPO_MCP_PASSWORD="您的可靠密碼" \
SILPO_MCP_PORT=3000 \
npm run start:http
```
環境變數:
| 變數 | 必需 | 描述 |
| --- | --- | --- |
| `SILPO_MCP_BASE_URL` | 是 | 服務器的公開 **https** URL(OAuth 發行者) |
| `SILPO_MCP_PASSWORD` | 是 | 登錄密碼(訪問門檻) |
| `SILPO_MCP_PORT` | 否 | 端口(默認 3000) |
| `SILPO_MCP_TOKEN_TTL` | 否 | access 令牌生存時間,秒(默認 **2592000** = 30 天) |
| `SILPO_MCP_STATE_FILE` | 否 | OAuth 持久性文件(客戶端 + 令牌)。默認 `.oauth-state.json` 在工作目錄中 |
| `SILPO_MCP_SESSION_FILE` | 否 | 會話持久性文件(地址、`basketId`、令牌和帳戶 cookie)。默認 `session.json` 在 `SILPO_MCP_STATE_FILE` 旁邊 |
| `SILPO_OAUTH_CLIENT_ID` / `SILPO_OAUTH_CLIENT_SECRET` | 否 | 事先註冊的客戶端(適用於 Claude 中的欄位) |
| `SILPO_OAUTH_REDIRECT_URIS` | 否 | 靜態客戶端的允許 redirect_uri(逗號分隔) |
> **持久性**。在遠端模式下,OAuth 令牌和會話狀態存儲在磁盤上(權限文件 `0600`),
因此重啟/部署/重新啟動 **不需要** 在 Claude 中重新授權,
也不會丟失地址/購物車。帳戶令牌和 **cookie** 也存儲在 `SILPO_MCP_SESSION_FILE` 中 —
請保持文件私密(cookie 允許更新令牌代表帳戶)。
### HTTPS 必需
Claude 需要 **https**,具有有效的證書和域名 — **裸 IP 地址** 不夠用。
請在反向代理後啟動服務器,例如 Caddy(自動 Let's Encrypt):
```
silpo.example.com {
reverse_proxy localhost:3000
}
```
### 在 Claude 中連接
1. 在 HTTPS 域名後部署服務器。
2. 在 Claude 中,前往「添加自定義連接器」並指定 **服務器 URL**:`https://silpo.example.com/mcp`。
3. **客戶端 ID/密碼留空** — 服務器支持動態客戶端註冊,因此 Claude 將註冊自身。(或設置 `SILPO_OAUTH_CLIENT_*` 并填入這些欄位。)
4. 連接時,Claude 將打開登錄頁面 — 輸入 `SILPO_MCP_PASSWORD`。
5. 完成:所有工具都可用。會話狀態(地址、購物車)由服務器共享。
### 端點
- `POST/GET/DELETE /mcp` — MCP Streamable-HTTP 傳輸(受 Bearer 令牌保護)
- `/.well-known/oauth-protected-resource/mcp`,`/.well-known/oauth-authorization-server` — 元數據
- `/authorize`,`/token`,`/register`,`/revoke` — 標準 OAuth 端點
- `/login` — 密碼登錄頁面
## 快速開始
在搜尋商品之前,請設置配送地址 — 它確定最近的商店:
```
「設置配送地址:Lvov,Street Strizka,45A」
「您要根據座標 49.8030, 24.0196 配送嗎?」
「查詢牛奶」
「顯示優惠」
「什麼時候可以訂購配送?」
```
個人功能(訂單歷史,獎勵積分)需要授權。有兩種方法:
- **Cookie(推薦)** — `set_auth_cookie` 保存會話 cookie `.AspNetCore.Identity.Application`(auth.silpo.ua),
服務器 **自動更新** 帳戶令牌,當令牌過期時(每個 ~24 小時),無需手動干預。
- **令牌** — `set_auth_token` 接受一次性 Bearer 令牌(有效期 ~24 小時,之後需要手動插入新的)。
```
「我的購物車:fadff098-d1ed-47dd-a312-5cdd11a54a67」
「Сільпо 授權 Cookie:CfDJ8PokYHNhxS1Nmvi…」
「Сільпо 帳戶令牌:eyJhbGciOiJSUzI1NiIs…」
```
**從哪裡獲取 cookie:** DevTools → Application → Cookies → `https://auth.silpo.ua` → `.AspNetCore.Identity.Application` 的值。**令牌:** 請求 `sf-ecom-api.silpo.ua` 帶有標頭 `authorization: Bearer …`。
## 可用工具
### 會話設置
| 工具 | 描述 |
| --- | --- |
| `set_delivery_address` | 設置配送地址(文本或座標) |
| `get_current_address` | 當前地址和商店 |
| `set_auth_cookie` | 帳戶令牌自動更新的會話 cookie(推薦) |
| `set_auth_token` | 一次性帳戶授權令牌(無自動更新) |
| `set_basket_id` | 連接現有的 Сільпо 購物車 |
| `get_session_info` | 當前會話狀態 |
### 商品和搜尋
| 工具 | 描述 |
| --- | --- |
| `search_products` | 按查詢搜尋商品 |
| `get_categories` | 分類列表 |
| `get_category_products` | 分類中的商品(排序,分頁) |
| `get_promotions` | 折扣商品 |
| `get_product` | 按 slug 獲取商品詳情 |
| `get_product_images` | 按 slug 獲取商品圖片 — 返回圖片本身(非連結) |
### 配送
| 工具 | 描述 |
| --- | --- |
| `check_delivery_zone` | 座標是否在配送區域內 |
| `get_delivery_modes` | 按座標的所有配送類型 |
| `get_time_slots` | 可用的配送時間段 |
| `set_delivery_slot` / `get_delivery_slot` | 選擇的配送時間 |
### 購物車(實際的 Сільпо 購物車)
`add_to_cart`,`get_cart`,`update_cart_item`,`remove_from_cart`,`clear_cart`,`create_cart`,`add_item_comment`
購物車存儲在 Сільпо 服務器上 — 這是與網站/應用程式中看到的相同的購物車。
它在第一次 `add_to_cart` 時 **自動創建**(需要設置配送地址);
`create_cart` 存在於顯式創建新購物車。商品由 **productId** 識別(來自 `search_products` / `get_product` 的 uuid)。
`update_cart_item` 帶有 `quantity: 0` (或 `remove_from_cart`)刪除商品。
不需要授權 — 購物車僅由 `basketId` 識別;可以選擇傳遞令牌。
### 購物清單
`add_to_shopping_list`,`get_shopping_list`,`remove_from_shopping_list`,`clear_shopping_list`,`set_shopping_list_item_checked`,`shopping_list_to_cart`
購物清單是一個輕量級的草稿清單(名稱 + 數量),存儲在服務器的會話中,不涉及 Сільпо API。
`shopping_list_to_cart` 在目錄中找到每個項目(按 slug 或名稱)並將其添加到 Сільпо 購物車中。
### 帳戶(需要授權)
`get_orders_history`,`get_order_products`,`get_loyalty_balance`,`silpo_suggest_from_history`
`get_orders_history` 返回訂單列表(編號,狀態,金額,日期,地址)。
`get_order_products` 返回特定訂單的 **項目**(按編號或最後一個):名稱,數量,金額,`productId`(以便將其添加回購物車),替換/刪除標記。
需要令牌(`set_auth_token`)或更好 — cookie(`set_auth_cookie`)— 使用 cookie,令牌會自動更新,當它過期時。
在 401 時,服務器嘗試更新令牌並重試請求。
## 限制
- 在 stdio 模式下,會話(地址,`basketId`,購物清單)僅存儲在內存中(在啟動之間不保存)。
在遠端模式下,狀態存儲在 `SILPO_MCP_SESSION_FILE` 中並在重啟後保留。
- 購物車與 Сільпо 同步,但下單需要網站授權。
- **購物車是短暫的** — Сільпо 在一段時間不活動後刪除它們;
然后 `get_cart` 返回 404,隨後的 `add_to_cart` 將創建一個新的。
- 創建購物車需要選擇的配送時間段(如果未設置,則自動選擇)並且 **受頻率限制**(HTTP 429)。
如果您已經有 `basketId` — 請使用 `set_basket_id`。
- 購物車變更異步應用(服務器響應 202),因此服務器進行重複 `GET` 以顯示當前狀態。
- `set_delivery_address` 接受座標(推薦)或文本。文本通過 OpenStreetMap Nominatim 進行地理編碼,
因為 Сільпо 的自動補全功能尚未恢復。
- **帳戶令牌有效期為 ~24 小時。** 使用 `set_auth_cookie` 自動更新(通過會話 cookie 的靜默 OIDC 流);
沒有 cookie,令牌過期後,您需要手動插入新的令牌。如果 cookie 停止工作 — 請插入新的令牌。
- **暫時禁用** (在 `src/index.ts` 中註釋,直到恢復真實端點):`search_address` (單獨的地址搜尋)和 `search_recipes` / `get_recipe_filters` 配方。
- API 通過逆向工程恢復,可能會更改;個別操作可能被 Cloudflare 阻止。
## 開發
```bash
npm run dev # 監視構建
npm run build # 構建
npm start # 啟動構建的服務器
```
## 結構
```
silpo-mcp/
├── src/
│ ├── index.ts # buildServer() + 所有 MCP 工具,stdio 模式
│ ├── http.ts # 遠端 HTTP 模式(Streamable HTTP + OAuth)
│ ├── oauth.ts # OAuth 2.1 授權服務器(密碼門檻,DCR)
│ ├── silpo-api.ts # Сільпо API HTTP 客戶端
│ ├── silpo-auth.ts # 帳戶令牌自動更新(PKCE prompt=none,通過 cookie)
│ └── session.ts # 會話狀態,購物清單
├── .env.example # 遠端模式的變數
├── dist/
├── package.json
└── tsconfig.json
```