Surfing Dog Inbox

ai.surfingdog由 surfingdog.ai 發布官方發布者v0.2.0更新於 Oct 31, 2026

Message, ask for a quote or book a call with Surfing Dog, through its open-source inbox.

已驗證Streamable HTTP可網頁執行效率與工作流溝通與協作商業與電商

概覽

AI 產生的概覽

商家的結構化收件匣,讓助理代替使用者預約服務、訂購商品、詢價並與商家溝通。

可以做什麼
  • 讀取商家資料、可預約服務與可訂購商品,含即時價格與庫存
  • 查詢空閒時段並建立預約或商品訂單,涉及價格時先提供摘要待使用者確認
  • 送出客製詢價,並回應商家提出的報價、改期或其他條件
  • 查看事項狀態與對話紀錄,傳送訊息並補上商家索取的資料
  • 對已付款預約或訂單行使撤回權、申請退貨、取消事項並會簽回執
適用情境
當使用者希望助理代為聯繫某家使用此收件匣的商家時使用,例如預約服務、購買商品、索取報價或追蹤既有請求。
執行需求
需要商家收件匣位址上的遠端 MCP 端點,示範執行個體公開可用;未宣告 API 金鑰。助理需保存建立事項時回傳的 access_token,並可能需要傳入使用者的通行憑證與自行產生的冪等鍵。
安裝前請注意
含價格的預約與訂單須經使用者確認摘要後才生效,接受前應如實轉述條款與商家提議。相關操作會建立、變更、取消真實預約與訂單,部分涉及價格或延遲取消費用。access_token 是日後讀取或取消該事項的唯一憑證,須妥善保存。身分驗證會寄送六位數驗證碼到客戶電子郵件。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Surfing Dog Inbox,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/ai.surfingdog%2Finbox/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。

{
  "mcpServers": {
    "surfing-dog-inbox": {
      "type": "http",
      "url": "https://inbox.surfingdog.ai/mcp"
    }
  }
}

README

Surfing Dog Inbox

An inbox for the bookings, orders, quote requests and messages that people and their AI agents send a business. Your rules answer the routine ones, and you see the rest. Open source, and you run it.

Try it in 60 seconds

Add our demo bike shop to Claude or ChatGPT as a custom connector (an MCP server):

https://demo.surfingdog.ai/mcp

Then ask it: "Book a bike service with Oficina Maré on Saturday morning." Watch the booking arrive, and the shop confirm it, at https://demo.surfingdog.ai/demo/live. The demo never emails anyone who uses it, shows no names and is wiped every night.

The same with curl, step by step: https://surfingdog.ai/try/

How ready is a business for AI agents today? The free AI agent readiness checker reads any website the way a customer's assistant would and shows what it can do there, and what to add.

Install

We host it for you, free, at an address on your own domain: get your agent inbox. Or run it yourself, three ways:

On your own server: Point a subdomain, such as inbox.yourbusiness.com, at an Ubuntu or Debian server, then run one command. HTTPS, a backup every night, and updates that undo themselves if they fail.

bash
curl -fsSL https://surfingdog.ai/install.sh | sudo sh

Docker, or a platform you use: the image ghcr.io/surfingdogai/inbox, for amd64 and arm64. The data lives in the volume. deploy/ has the Compose file with HTTPS, and templates for Coolify, Fly.io, Render, Railway and a DigitalOcean Droplet. On Render it is one button (a paid Starter instance, as only those keep a disk): Deploy to Render. By hand, it answers on the server itself only, behind a proxy with TLS that drops a CF-Connecting-IP the caller sent:

bash
(umask 077; echo "INBOX_SECRET_KEY=$(openssl rand -base64 32)" > inbox.env)   # keep a copy somewhere safedocker run -d --name inbox --restart unless-stopped -p 127.0.0.1:8787:8787 \  -v inbox-data:/opt/inbox/data --env-file inbox.env \  -e [email protected] -e INBOX_PUBLIC_URL=https://inbox.yourbusiness.com \  ghcr.io/surfingdogai/inbox:0.2.0

Cloudflare Workers, with D1, a queue and a cron. Press Deploy to Cloudflare. What to have ready, and what to do after, is in the quickstart. By hand, it's path A of the install guide.

From source, on Node 22.16+, 24 or 26 (one process and one SQLite file):

bash
git clone https://github.com/surfingdogai/inbox && cd inboxpnpm installpnpm --filter @surfingdog/inbox buildnode apps/inbox/dist/server.mjs        # http://localhost:8787

Or give your AI the install guide and let it do the work: it is written for that, with a check after every step. The whole guide to running it yourself, with updates and backups: surfingdog.ai/docs/run-it-yourself.

Docs

  • Quickstart: every setting, Docker, and a public demo of your own
  • Connect your AI: the owner's MCP server
  • API: REST and MCP; every instance also serves /openapi.json
  • Decision records: read these before changing how things work

Working on it

bash
pnpm dev               # the server on Node, http://localhost:8787pnpm dev:workers       # the same app on workerdpnpm test              # every test, on Node and on Workers./scripts/verify.sh    # everything CI runs

How to send a change, ask for an integration or report a security problem: CONTRIBUTING.md and SECURITY.md.

  • apps/inbox: the server and the owner app, one codebase for Workers and Node
  • deploy: the self-host kit: the one-command installer, the Compose file, the inbox command, platform templates
  • apps/site: surfingdog.ai, with the docs. It counts visits with Cloudflare Web Analytics only when built with WEB_ANALYTICS_TOKEN set, as our deploy does; any other build sends nothing anywhere
  • packages/core: items, their states, rules and receipts
  • packages/adapters: REST, MCP, sign-in, email in, webhooks and networks
  • packages/platform: the database, mail and job seams for each runtime
  • packages/spec: the discovery manifest and receipt formats, with test vectors
  • packages/sdk: verify webhooks; sign requests and check receipts from a customer's agent
  • packages/ui: design tokens and components
  • packages/network-check: checks a network against the network protocol
  • examples/network: a small network of your own, at the protocol's directory level

Licence

MIT, for everything in this repository: the server, the app, the site, the spec, the SDK, packages/network-check and examples/network. You can run it, change it and build on it; nothing you build has to be shared. See LICENSE.

來源:README.md,提交 b577438

工具

19

get_business_profile

Business profile

Name, time zone, currency, languages and the item types this business accepts, and where it takes any other kind instead (doors_elsewhere: each with its URL, and the platform it is on when there is one).

無需輸入參數。

list_services

Services

Bookable services with duration and price. A price per person (price.per = person) is for each person in the booking: send partySize, and the total is the price times it.

輸入參數limitcursor

list_products

Products

Orderable products with prices in minor units, each with its barcode (gtin, 14 digits) where it has one and whether it is in stock. ids: read the live price of products a network showed you, before your person agrees; gtin: the products with that barcode, in any of its lengths. The price here is the one that counts.

輸入參數qidsgtinlimitcursor

check_availability

Check availability

Free start times for a service between two instants (at most 14 days). A time that has started, or that starts within the business's minimum notice, is not offered.

輸入參數to必填from必填party_sizeservice_id必填

request_quote

Request a quote

Ask for a price on something custom. Creates a quote_request item.

輸入參數keypasscontactmessagepayload必填attachmentsidempotency_key

create_booking

Request a booking

Request a service at a time. Check availability first. A fixed-price service costs the business's price from list_services; a different totalPrice you send is only noted for the business. A priced booking binds your person only once they confirmed it: without terms_sha nothing is sent, and you get the summary to show them (confirm.summary, confirm.terms_sha); call again with that terms_sha on their clear yes. Returns the item and, if you have no account, an access_token.

輸入參數keypasscontactmessagepayload必填terms_shavisit_forattachmentsidempotency_key

create_order

Place an order

Order products. Prices are in minor units. A line naming a product (productId or sku) costs the business's price from list_products, and the total follows; a different price you send is only noted for the business. A line naming no product waits for the business to price it. A priced order binds your person only once they confirmed it: without terms_sha nothing is sent, and you get the summary to show them (confirm.summary, confirm.terms_sha); call again with that terms_sha on their clear yes.

輸入參數keypasscontactmessagepayload必填terms_shaattachmentsidempotency_key

get_item_status

Item status

The current state of an item you created, in the business's words: what it proposed and waits for your person to answer (offer, with its terms_sha), who it waits on, what they can do next, and the conversation so far (thread: the business's replies and your person's messages).

輸入參數keypassitem_id必填access_token

accept_offer

Accept what the business proposed

Accept another time the business proposed for a booking, its quote, its changes to an order, or a change it asks for to a confirmed booking or an accepted order (offer.kind change: the promise moves). This binds your person, so send terms_sha — offer.terms_sha from get_item_status — only after they said yes to offer.human, and offer_id (offer.id) so an answer to an offer since replaced does nothing. Without terms_sha nothing is booked: you get the terms to show them. An accepted quote becomes a confirmed booking or order (linked). A yes to a change that can no longer be made online goes to a person there instead (passed_on), and what was agreed stands.

輸入參數keypassitem_id必填offer_idterms_shaaccess_tokenidempotency_key

decline_offer

Decline what the business proposed

Say no to another time or to changes the business proposed (the booking request or the order is closed) or to its quote. To a change it asks for to a confirmed booking or an accepted order, no keeps what was agreed; on a change your person asked for (requested_change), it takes that back. Add reason (and reason_code) for anything your person wants the business to know.

輸入參數keypassreasonitem_id必填offer_idreason_codeaccess_tokenidempotency_key

suggest_time

Ask for another time

Instead of the time the business proposed, ask for another: start_time must be one of the free times check_availability lists (the end follows the service's length). The business confirms it or proposes again. On a confirmed booking it asks the business to move it (the end keeps the booking's length), and the booking stays as agreed until the business says yes. After a few rounds, or past the changes a booking may have, a person there answers it instead (passed_on).

輸入參數keynotepassitem_id必填start_time必填access_tokenidempotency_key

make_offer

Suggest a change

Answer what the business proposed with only what your person would change: another start_time (a booking: one of the free times check_availability lists; a quote request: the time it is for), other quantities for the lines of changes it suggested to an order (by index in offer.terms.lines; 0 drops one), another delivery_when, or how many (quantity) for a quote request. It goes back to the business as their request. On a confirmed booking or an accepted order it asks for a change to what was agreed (lines by index in the order's orderedItem), which stands until the business says yes. A price of their own is their answer only where get_business_profile says price_negotiable: total_price for a time it proposed (start_time optional), unit_price on lines of changes to an order; it goes back to the business, which takes it or answers. Otherwise — a price where the business sets its prices, on a quote, on something it does not haggle, or asked too often — it goes to a person there as their message, as do a note alone and a suggestion after a few rounds (passed_on): never refused, and what the business proposed, or what was agreed, still stands.

輸入參數keynotepassterms必填item_id必填offer_idreason_codeaccess_tokenidempotency_key

provide_details

Send the details

Answer what the business asked about an item (get_item_status says it needs a detail). The item moves on; on any other item your details are kept as a message for the business.

輸入參數keypassdetails必填item_id必填access_tokenidempotency_key

withdraw_from_contract

Withdraw from contract here

Your person withdraws from their booking (one they paid for) or order, within the period the business states (withdrawal on get_item_status). Two steps: without confirm_withdrawal nothing is sent and you get the statement to show them (confirm.statement); send confirm_withdrawal: true on their yes. Before the goods went out the order ends and what was paid is refunded; once they reached your person, the goods come back (lines: only some of them) and are refunded. The business emails a copy. Never refused: past the period, or for something that cannot be returned, it goes to a person there instead (passed_on), or becomes a return under the business's own policy.

輸入參數keynotepasslinesitem_id必填access_tokenidempotency_keyconfirm_withdrawal

request_return

Send goods back

Once an order's goods reached your person: ask to send them back. reason faulty, not_as_described or wrong_item (the legal guarantee: it costs them nothing), or changed_mind (a withdrawal while the period runs, agreed at once; after it, a return the business answers under its own policy). lines: which, by index in orderedItem, and how many; all when left out. The return comes back as linked; get_item_status lists it under refunds.

輸入參數keynotepasslineswantsreason必填item_id必填access_tokenidempotency_key

cancel_item

Cancel

Cancel an item you created. After the business's cancellation window, a confirmed booking is cancelled late where the business records late cancellations (it may count against the customer), and refused where it does not. A confirmed stay answers first with the fee under its policy and what is owed back (confirm): send its fee_sha once your person said yes.

輸入參數keypassreasonfee_shaitem_id必填access_tokenidempotency_key

send_message

Send a message

Start a conversation, or reply on an item you own.

輸入參數keybody必填passcontactitem_idsubjectmessage_idaccess_tokenidempotency_key

acknowledge_receipt

Acknowledge a receipt

Counter-sign a receipt this item earned, so both sides hold it: a promise, a change both sides agreed to it (kind amended), how it ended, or a refund's. Read the item to find its receipts; then send a compact JWS signed with your own Ed25519 key — header {alg:'EdDSA', typ:'sdi-receipt-ack+jws', jwk:<your public jwk>}, payload {rcp:<receipt id>, sha:<base64url(SHA-256(receipt jws))>, iat:<unix seconds>}. The instance verifies it against the key you carry and keeps it. Acknowledging twice is harmless.

輸入參數keypassitem_id必填receiptreceipt_idaccess_tokencounter_signature

verify_customer

Prove a known customer

When a result says identity.recognised is weak, the person gave the email of a customer the business knows. Call this with item_id and access_token to email them six digits; ask the person for the code and call it again with code. Then the business recognises them.

輸入參數codeitem_id必填access_token

版本歷史

2
  1. v0.2.0最新Oct 31, 2026
  2. v0.1.0Sep 23, 2026

評分

已滿足適用檢查項的 100%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

其他 Surfingdog 整合