sb_connect
Log in and list the sites this account can operate. Call this first. Reads SB_EMAIL and SB_PASSWORD from the environment unless you pass them.
emailpassword
io.github.vuluu2k由 GitHub 帳號 vuluu2k 發布v0.104.0更新於 Oct 31, 2026
Design, fill with real store data, render and publish Store Builder pages from an AI agent.
讓助理透過商店 API 金鑰設計、填入真實商店資料、渲染並發佈 Store Builder 網站頁面。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
參照 儲存庫 中的啟動說明。
sbuilder-mcpAn MCP stdio server that lets an AI agent operate a Store Builder site end to end — design its pages, fill them with real data, look at the result, and publish it — with no human clicking anything.
One command writes this server into every agent client on your machine:
It knows Claude Code, Claude Desktop, Cursor, Windsurf, VS Code and Codex, and installs into
the ones it finds. Name them with --client cursor,codex, or rehearse with --dry-run. An
option it does not know is refused, not ignored — a flag that silently does nothing is
worse than one that does not exist.
--site is optional and worth passing: a key belongs to exactly one site, so it is written
as SB_SITE and every tool then defaults to it. Without it the model has to carry the id
through the session, which it can only get by listing pages and reading one back.
--site-name "Your Store" rides alongside it as SB_SITE_NAME. It is a label, never an
address — nothing resolves by it — but it lets the agent say the store's name back to you
instead of a 32-character id you did not choose. The Apps → AI agent screen appends it
whenever the store has a name.
It merges: the servers already in those files stay, whatever it replaces is copied to
<file>.sbuilder-backup, and a config it cannot parse is refused rather than overwritten —
a file with a trailing comma is far likelier than one worth discarding, and it is what you
need to fix it.
The store's Apps → AI agent screen hands you this command with the key already in it.
Open your store, go to Apps → AI agent, and press Create key. That screen hands you the config block for your client with the key already in it — this whole section is what it saves you reading.
One key is all you need. It reaches both the partner surface (/api/v1) and the private
site API, including the page document and the live-edit socket, and it is bounded three ways
on every request: its own scopes, the live role of the member who created it, and the single
store it belongs to.
SB_EMAIL + SB_PASSWORD remain optional, and buy exactly one thing: account-level
calls — listing your sites, managing members and roles — which a key deliberately cannot
make, because those mean "this person's account".
SB_API defaults to http://localhost:8080. Secrets are read from the environment only.
sb_media_upload's photo search needs no key here: it calls the platform's own
GET /api/sites/{siteId}/images/search, which runs a rotated pool of provider keys behind the
credential this server already holds. An operator enables it by setting PEXELS_API_KEYS on the
SERVER (comma separated; free keys at https://www.pexels.com/api/). With none configured the
search answers "unavailable" and tells the caller to find a photograph by its own means and pass
the URL — which the platform then fetches server-side. There is deliberately no fallback provider
in this client: one would put the very key the platform exists to hold back into every install.
Thirty-eight tools, 949 API operations (354 of the 441 writes carrying a body shape read
off the handler), 124 elements, 96 binding sources. sb_api_find
is an index rather than a tool per endpoint, so the tool list stays short while everything
the platform can do stays reachable — and operations added to the platform arrive with the
next npm run codegen.
Every result is compact JSON, every directive is said once per process, and every tool carries MCP annotations — a client that honours them stops asking a person to confirm a read.
Full reference: docs/tools.md. What the builder supports natively, and where it stops: docs/capabilities.md.
The platform publishes two generated, committed artifacts. A build step reads them out of a checkout and emits the catalog:
So this repository vendors no platform code — it depends on two data files with a
maintained contract. src/catalog/api.generated.ts is committed, so npm install needs no
checkout at all.
Contributor guide: CLAUDE.md. Design rationale:
docs/superpowers/specs/.
A push to main that touches src/** releases on its own
(.github/workflows/auto-release.yml): the gate runs (build, test, smoke), the version
bump is read off the commit subject — feat is minor, BREAKING CHANGE or ! is major,
anything else is patch — Claude writes the changelog entry in both languages,
server.json is synced, the release is committed as chore(release): vX.Y.Z and tagged,
then published to npm, as a GitHub Release, and to the MCP Registry through GitHub OIDC.
workflow_dispatch runs the same flow with a bump you choose. A commit whose subject
contains chore(release): or release: v is skipped, so a release never triggers another.
The workflow needs two repository secrets in the prod environment: NPM_ACCESS_TOKEN
and CLAUDE_CODE_OAUTH_TOKEN. The registry step needs none.
npm run release (scripts/release.mjs) is the offline path — a machine with no CI, or a
release cut while a secret is being rotated. It runs the same gate and writes the same
## [x.y.z] - date changelog heading, so the two never disagree.
Five platform rules fail silently if a client does not know them, so they are encoded here as tested code rather than advice:
[header][middle][footer], or the platform
refuses every save.sb_set writes per breakpoint, because a design should
respond. Base is the cascade's fallback layer, not a trap.app: true.All three phases shipped: authentication and full API reach; the page document, patch protocol, builder and the five traps; the live-edit socket, the yield rule, and the vision loop. Since then: a token diet across every result, and releases that cut themselves.
Requires Node ≥22 (the global WebSocket) and, for sb_look only, system Google
Chrome — playwright-core bundles no browser, so installing downloads nothing.
MIT.
來源:README.md,提交 0d06612
Log in and list the sites this account can operate. Call this first. Reads SB_EMAIL and SB_PASSWORD from the environment unless you pass them.
emailpasswordList the sites this account can operate.
無需輸入參數。
Find API operations by intent (query), or get a call sheet (id): parameters, credential, body fields and handler caveats. Reaches all 949 operations.
idtaglimitqueryCall an operation from sb_api_find (id), or a route the catalog lacks (method+path); dry run by default. pick selects fields, max_items caps lists, item_offset skips items. Lists over 60 KB say so.
idbodyfilepathpickmergequerymethoddry_runsite_idif_matchmax_items另有 2 個Open a page for editing and return its outline. Call before any sb_add / sb_set / sb_move / sb_remove. Find page ids with sb_api_find "list pages". Or form_id: edit that form's field document (fields, specials.formRules on its root).
form_idpage_idsite_idRename a page root that is not "ROOT" (sppro_1, rt_<hex> — left by older seeds) to ROOT, for one page or, without page_id, every page on the site. Draft only; a published page is listed for re-publishing. dry_run (default true) lists what would change.
dry_runpage_idsite_idThe open page as a compressed tree — id, type, name, child count, band, and whether a node is a shared global or a site overlay. Never the raw document: a real page is hundreds of KB of JSON.
depthchromeOne node in full — style, config, specials, per-breakpoint overrides, bindings.
id必填Find an element type by what it does — or OMIT query to browse every type, the only way to meet one you would not have searched for. detail:true adds the AI hints, as does sb_traits_for. query "icon:<word>" lists icon names.
limitquerydetailThis element's INSPECTOR, as a person sees it: tabs, groups, and every control name — with what each DECLARED control writes, and the AI hints for using the element. Read this before styling an element; pass control to read one control in full.
type必填controlAdd an element — or a whole NESTED subtree — under a parent. One call builds a complete section: pass children rather than calling this once per node.
spec必填forceindexdry_runparent_id必填Write style, config or specials keys on one node, or on many through edits (one save, one live frame). Per BREAKPOINT by default; base:true writes the fallback layer, right for a value that should not vary.
idbasekeyseditsforcestateunsetdry_runnamespacebreakpointMove a node to another parent at an index.
id必填forceindex必填dry_runparent_id必填Remove a node and its whole subtree.
id必填forcedry_runWhat a VISITOR would meet on the open page (blank band, placeholder, dead binding) AND what stands between this store and a paid order (checkout page, gateway, delivery, a cart link). Run it before calling a page done; page_id: only that page.
page_idCopy a node and everything under it, under fresh ids, right after the original. The move a designer makes constantly — build one card, duplicate it twice. to_page_id (and to_site_id) pastes the copy onto another page instead, as the editor's copy/paste does: a cross-site copy has its images copied into the target library and references that cannot travel blanked and listed; the open page becomes the target.
id必填forceindexdry_runparent_idto_page_idto_site_idThe store's saved section templates — designed sections a person starts from rather than assembling one. Use sb_template_use to drop one into the open page.
site_idAdd a section template to a page, above the footer — a sb_templates row (another site's is copied in first) or one of the BUILT-IN layouts sb_templates lists, which are composed against this page's own tokens rather than copied.
dry_runpage_id必填site_idtemplate_id必填Every page on the site, with its slug and whether it is live.
site_idA store type (product, category, search, blog, post, complete, account) arrives with the document the editor gives a merchant — product carries the whole bound buy box; seed:false for blank. Any other type is empty and sb_page_open seeds its ROOT. TYPE is the route: /checkout and /products/{slug} need a PUBLISHED page of that type or they 404.
name必填seedslugtypechromelocaledry_runsite_idheadlinesettingsis_homepageCompile the draft into the live page, and report which revision went live (id, publishedAt, fromVersionId). PUBLISH CASCADES to every page sharing a changed global section or overlay; the dry run lists them (would_cascade) and warns FIRST when it would ship shared edits nobody published. verify:true then fetches the live page and says whether the origin is serving that revision yet — the storefront caches for 60s, so a reload showing the old page is that, not a failed publish.
verifydry_runpage_id必填site_idpublish_draftsWhich of this page's three copies is which: the DRAFT the editor canvas shows, the PUBLISHED row the storefront serves, and what this session holds. Says whether the editor will render the canvas BLANK (its hydrate gate discards a document whose root is missing and shows an empty ROOT, silently — the Go renderer has no such gate, which is how "the live page has data but the canvas is empty" happens), whether the draft has changes the live page does not, and where the recovery points are.
page_idsite_idEdit a page's name, slug, home flag, order, SEO (merged key by key) or members_only. Reads the page first and merges `settings`, so keys it does not name survive. On a template page (product, category, post, blog, course, brand): default_template makes it the type's default, render_for/render_default move entities onto it or back to the default.
seonameslugdry_runpage_id必填site_idrender_forsort_orderis_homepagemembers_onlyrender_defaultdefault_templateA page's platform recovery points, everyone's edits included (sb_undo covers this process only). action:"list" — named versions and autosave history; "save" {label} — snapshot the current draft; "restore" {version_id | history_id} — put the draft back. Writes are dry runs by default.
labelaction必填dry_runpage_idsite_idhistory_idversion_idThe site's custom code files — tracking pixels, analytics, chat widgets, site-wide CSS — injected at head, body_start or body_end of every page (no page_id) or one page. Create infers language from the extension, placement from the language. scss/typescript compile on write (compile_error). json/text: placement "none" only; an enabled site-wide "none" file is served at its url. action:"list" | "set" (no id creates; with id merges the named fields over the stored row) | "remove". Not the custom-code element.
idnameaction必填contentdry_runenabledpage_idsite_idlanguagepositionplacementBackend functions: server-side TS/JS at /_wb/fn/<slug> with the site's secrets, collections and fetch ("_" slug = importable module). Not sb_code. action: list | get | set (no id creates; id merges) | remove (id, or secret key) | test (method/path/query/headers/cookies/body) | logs | usage | secret (no key lists; key+value sets). Owner/admin only.
idkeybodypathsluglimitqueryvalueaction必填methodcontentcookies另有 5 個Join the site's live-edit room as a visible peer: every write then appears in any open editor as it happens, with the agent shown by the API key's own name rather than a person's. Always yields, so it is safe beside a human. Works with SB_TOKEN or with SB_EMAIL / SB_PASSWORD.
site_idSave, render through the platform's own renderer, and return screenshots at desktop, tablet and mobile widths, measured boxes for the bands and their children, and any layout defect measured on the render (overflow, overlap, unreadable text). node_id frames one element. Judge your work from these, not from memory.
urlformatwidthsnode_idbox_depthwith_boxesThe site's media library. Reuse an image before adding another; search by name, filter by type, page with limit/offset.
limitoffsetsearchsite_idmedia_typePut an image into the media library and get its URL back, ready for sb_set. Takes a local path, a URL, or a SEARCH — `query` returns real photographs with their own descriptions, and `pick` uploads the one you chose, or several at once to stock a site you just built. The only way to add an image.
urlnamepathpickpathsquerydry_runsite_idfolder_idorientationGive a node a click action — open the cart, go to a page, open a pop-up. A purchase is not one: use sb_bind action.
id必填forceaction必填dry_runpayloadtriggerBind a node to real store data so the page shows actual products, not placeholder text. action makes a button a purchase control.
id必填field必填forceactionsource必填dry_runRun a store flow that must happen in a fixed order. action:"checkout" makes the order form, configures it, saves its fields with this store's real payment and delivery options, then creates and PUBLISHES the checkout page — /checkout 404s without all four. action:"checkout_sync" re-reads the store's payment and delivery methods into every existing order form and republishes the checkout page — run it after adding a shipping method or switching on a gateway, since the form keeps the options it was saved with. action:"form" seeds any of the platform's other form templates (login, contact, booking, stay and more — settings merge into the record) with its own field document, which is the part that cannot be guessed. action:"chrome" gives every page ONE shared header (footer:true — footer) built on a real site menu of page/category/product references: site name, desktop menu, mobile drawer, search, cart and account icons — the gap sb_review reports as siteChrome. action:"menu" binds a menu node on the open page to the site's menu and resolves its links, the way the editor does. action:"overlay_attach" puts a pop-up on the open page (kind:"popup") or points a list-dataset at a quick-view panel (kind:"quickview", list_id), creating either from the platform's own seed when overlay_id is omitted, and re-reads the page afterwards as the editor must. action:"cart" creates the site's cart drawer from the editor's seed when it has none — without it every open_cart control opens nothing. action:"app" installs one of the platform's built-in apps (app_key) and creates the pages it needs that installing it does not — today only "courses" has any, from the platform's own scaffold; every other key installs with nothing further to build. action:"global_attach" puts an EXISTING shared section (global_id) on the open page and action:"global_detach" takes it off, writing the reference the platform reads and placing it in the band ROOT's child order demands — the answer for a page that is
kindnameaction必填footerapp_keydry_runlist_idmenu_idnode_idsite_idheadlinelanguage另有 8 個The site's palette and type scale — the layer every element's style preset resolves from, so one token repaints every page at once. Call it with nothing to read what the site actually has. `colors` and `text_styles` PATCH the saved document: what you do not name is kept, and so does `presets` (a preset's own literal outranks the text style). A mobile/tablet/laptop object writes that breakpoint. `locale` sets the site's language (settings.locale, what <html lang> is served from) — site-wide, every other setting kept.
colorslocaledry_runpresetssite_idtext_stylesMultilingual, as the editor does it. status | locales (add/remove) | page (rows: missing, done, outdated) | write (node id+field+value; registry fields only) | auto (machine-fill missing) | review (approve).
addallfromaction必填localeoffsetremovesourcedry_runentriespage_idsite_idRead a page from any public URL and add its structure and content to the OPEN page as real elements, styled with this page's own tokens. Not a clone: the source's layout and CSS are not copied. Dry run returns what was found.
url必填dry_runsite_idmax_nodesmax_imagesmax_sectionsupload_imagesnav_timeout_msRead a WHOLE site from one URL — its sitemap, or the links on that page — and give each page found its own DRAFT page here, built from this site's tokens. Not a clone. Dry run returns the page list before anything is created.
navurl必填depththemedry_runexcludeincludesite_idhomepagemax_nodesmax_pagesmax_images另有 2 個Put back what a write replaced — a page or form edit made here (sb_add, sb_set, sb_duplicate …), or a PUT through sb_api_call. An undo records what IT replaced, so the newest entry right after one is its redo. A page is refused if anyone else saved it since. IN THIS PROCESS ONLY, capped; the platform's own page history (GET .../pages/{pageId}/history) survives a restart. No argument lists what is undoable.
allindexdry_run已滿足適用檢查項的 90%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
npx -y sbuilder-mcp install --token wbk_… --api https://your-host --site site_…{ "mcpServers": { "sbuilder": { "command": "npx", "args": ["-y", "sbuilder-mcp"], "env": { "SB_API": "https://api.your-host", "SB_TOKEN": "wbk_…", "SB_SITE": "site_…" } } }}WB_REPO=/path/to/web_builder npm run codegennpm run build # tsc -> dist/npm test # vitestnpm run smoke # offline self-test; must print ALL GOOD