商家與服務資料
代理要先讀得懂你賣什麼,才找得到你、約得成。
商家與服務資料:已上線。商品feed:規劃中。
代理讀的是結構化資料
SOP把每家商家整理成結構化資料:商家資料、預約與取消規則,以及每項服務的價格與時長。資料由你逐項確認後才上線,哪些服務與時段公開,也由你決定。
步驟
- 商家 → SOP:商家資料、服務、價格、時段與取消規則
- SOP → SOP:商家確認後才上線
- 代理 → SOP:search_businesses
- SOP → 代理:回傳符合的商家與部分服務
- 代理 → SOP:get_business
- SOP → 代理:回傳商家資料、服務價格與時段、規則
- 代理 → SOP:get_availability
- SOP → 代理:回傳空檔與價格
商家資料
get_business回傳以下內容:
| 欄位 | 說明 |
|---|---|
business_id、name、categories、city | 商家代號、名稱、類別與城市 |
profile | 公開的地址、營業時間、預約政策、付款說明、停車、備註與聯絡方式 |
faq | 常見問題 |
quantity | 人數或名額的名稱、單位與每次預約的上限 |
online_cancellation | 線上取消的截止時間 |
payment | 付款方式:到店付款或線上付款,以及付款時限 |
booking_mode | request_here(在這裡預約)或external_link(用商家自己的預約系統) |
取得商家與服務:get_business
curl
curl -sS -X POST https://mcp.srct.tw/mcp \
-H "User-Agent: my-agent/1.0" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"get_business","arguments":{"business_id":"coach-dunken"}}}'
Python
import json
import urllib.error
import urllib.request
BASE = "https://mcp.srct.tw"
def call(method, path, body=None, headers=None):
req = urllib.request.Request(
BASE + path,
data=None if body is None else json.dumps(body).encode(),
method=method,
headers={"User-Agent": "my-agent/1.0", "Content-Type": "application/json", **(headers or {})},
)
try:
with urllib.request.urlopen(req) as res:
return res.status, json.loads(res.read())
except urllib.error.HTTPError as err: # 4xx and 5xx responses still carry a JSON body
return err.code, json.loads(err.read())
def show(status, body):
print("HTTP", status)
print(json.dumps(body, ensure_ascii=False, indent=2))
MCP = {"Accept": "application/json, text/event-stream"} # the server requires both types
show(*call("POST", "/mcp", {"jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": {"name": "get_business", "arguments": {"business_id": "coach-dunken"}}}, MCP))
Node.js
const BASE = "https://mcp.srct.tw";
async function call(method, path, body, headers = {}) {
const res = await fetch(BASE + path, {
method,
headers: { "User-Agent": "my-agent/1.0", "Content-Type": "application/json", ...headers },
body: body === undefined ? undefined : JSON.stringify(body),
});
return { status: res.status, body: await res.json() };
}
function show({ status, body }) {
console.log("HTTP", status);
console.log(JSON.stringify(body, null, 2));
}
const MCP = { Accept: "application/json, text/event-stream" }; // the server requires both types
(async () => {
show(await call("POST", "/mcp", { jsonrpc: "2.0", id: 4, method: "tools/call", params: { name: "get_business", arguments: { business_id: "coach-dunken" } } }, MCP));
})();
回應範例
HTTP 200
{
"result": {
"content": [
{
"type": "text",
"text": …
}
],
"structuredContent": {
"ok": true,
"business": {
"business_id": "coach-dunken",
"name": "Dunken教練",
"categories": [
"coaching"
],
"booking_mode": "request_here",
"city": "台北市信義區(Taipei Xinyi)",
"profile": {
"city": "台北市信義區(Taipei Xinyi)",
"address": "…",
"hours": "每天08:00至20:00",
"booking_policy": "取消與改期需在課程開始24小時前(經AI助理線上取消也是開始前24小時截止)。遲到15分鐘將直接結束當次課程,且無法退費。",
"payment": "現金或轉帳。課程一次購買10堂NT$18,000(每堂折合NT$1,800)。",
"notes": "請自行準備合適的訓練服裝,至少提早10分鐘抵達教室。",
"contact": "…"
},
"faq": [],
"quantity": {
"label": "人數",
"unit": "位",
"max_per_booking": 1
},
"online_cancellation": {
"closes_minutes_before_start": 1440,
"text": "Online cancellation closes 24 hours before the start time; after that, contact the business directly."
},
"pending_hold": {
"minutes": 10,
"text": "Bookings that need the business's confirmation are held for 10 minutes. If the business does not confirm by then, the hold is released automatically and the customer can choose another slot."
},
"payment": {
"mode": "venue",
"text": "Pay at the venue."
}
},
"services": [
{
"service_id": "first_assessment",
"name": "初次體能檢查(含InBody一次)",
"category": "一對一",
"summary": "第一次上課:基本動作與體能檢查,並免費做一次InBody身體組成量測(非醫療評估)。",
"price": {
"amount": 0,
"currency": "TWD",
"unit": "每次",
"text": "免費"
},
"duration_min": 60,
"schedule": [
{
"weekday": "sun",
"time": "08:00",
"teacher": "Dunken"
},
{
"weekday": "sun",
"time": "09:00",
"teacher": "Dunken"
},
…
],
"capacity_per_slot": 1,
"teachers": [
"Dunken"
],
"credit_cost": 0
},
…
],
"payment": "Paid services are paid at the venue; services priced at 0 are free. This connector does not take payments."
},
"isError": false
},
"jsonrpc": "2.0",
"id": 4
}已對正式服務實際執行(唯讀):為顯示而截短;…表示省略的部分。result.content[0].text(同一份JSON的字串版)與商家的地址、聯絡方式已省略。
服務資料
每項可預約的服務有service_id、name、category、summary、價格(amount、currency、unit、text)與時長duration_min。代理查空檔、建立預約都用service_id。
商品feed
零售商品需要另一種資料:商品、庫存、價格與促銷,由商家批次提供。這部分的現況是規劃中:目前沒有商品feed的匯入功能,所以這裡不提供格式與範例。
與商品feed的對照
| 商品feed的概念 | SOP服務資料裡的對應 |
|---|---|
| 基本商品資料 | service_id、名稱與商家資料 |
| 價格 | price(新臺幣;預約金額以最小單位計) |
| 可售量與庫存 | get_availability回傳的空檔,以及每個時段的名額 |
| 履約 | 地址、營業時間,以及預約與取消規則 |
| 變體 | 分成不同服務,各有自己的service_id |
| 圖片、評價、促銷 | 不提供 |