Skip to main content
Glama
vuluu2k

WebCake Landing MCP

by vuluu2k

WebCake Landing MCP

English · Tiếng Việt

npm version npm downloads GitHub stars MCP

Describe a landing page in plain words — your AI builds it, checks it, and ships it straight to WebCake.

⭐ If this saves you an afternoon of dragging boxes, give it a star — it's a one-dev project and every star keeps it alive.

"Build a landing page for my coffee shop — a hero with a sign-up button, a 3-feature section, and a lead form. Save it to my workspace."

…and a real, editable WebCake page appears in your account. No dragging boxes, no learning the schema, no hand-writing JSON.


🧩 How it works

This server is the bridge between your AI assistant and WebCake. The AI never guesses what a WebCake page looks like — it asks this MCP, which knows the entire element model, validates the result, and saves it for you.

   You              AI assistant            webcake-landing MCP            WebCake
  ┌──────┐  prompt  ┌────────────┐  tools  ┌──────────────────────┐  API  ┌──────────┐
  │ idea │ ───────► │  Claude /  │ ──────► │ • knows the element  │ ────► │  a real  │
  │      │          │  Cursor /  │         │   model + AI hints   │       │ editable │
  │      │ ◄─────── │  Windsurf  │ ◄────── │ • builds + validates │ ◄──── │  page in │
  └──────┘ page URL └────────────┘ result  │ • saves to your acct │       │  WebCake │
                                           └──────────────────────┘       └──────────┘
  1. You ask in plain language — goal, brand, sections, CTA, form fields.

  2. The AI learns the model from the MCP: the element catalog, the absolute-positioning canvas, the event vocabulary — so it builds a real WebCake page, not a guess.

  3. It assembles + validates the full { page, popup, settings, options } JSON. validate_page catches off-canvas boxes, dangling CTAs, and missing form fields before anything is saved.

  4. It persists to your WebCake account — dry-run preview first, then for real.

  5. You get an editor link — open it, tweak, publish. The AI did the heavy lifting.

Why it's reliable

📚 Knows the real model

Serves WebCake's actual element catalog (40+ types — hero, form, countdown, gallery, product list…), each with its exact specials and AI hints, drawn straight from the editor's renderers.

✅ Validates before saving

Structural + semantic checks (unique ids, on-canvas layout, working CTAs, unique form fields) so the page isn't broken when it lands.

🛡️ Safe by default

Every write is dry-run first (preview the request, token masked) — nothing touches your account until you confirm.

✏️ Edits surgically

Ask for one change ("make the CTA green") and it edits only that element — every other id, coordinate, and block stays exactly as it was.

💡 Lead-gen, events, invitations, app promos — or selling COD/online? It speaks WebCake's commerce model too (product lists, variations, cart).


Related MCP server: webappmcp

✨ What you can build

One sentence to your AI → a finished, editable WebCake page. A taste of what people ship with it:

Just say…

🧲 Lead-gen landing

"A SaaS waitlist page — hero, 3 benefits, an email-capture form."

🛒 COD / online store

"A one-product page for my skincare serum — gallery, price, variations, an order form with cart."

🎟️ Event / webinar

"A registration page for Saturday's webinar — countdown, agenda, sign-up form."

💌 Invitation

"A wedding invite — names, date, a map, an RSVP form."

📱 App promo

"A page for my fitness app — phone mockups, feature list, App Store + Google Play buttons."

⚡ Flash sale

"A flash-sale page — big countdown, discounted product grid, a sticky Buy button."

🔗 Link-in-bio

"A link-in-bio for my creator profile — avatar, short bio, 5 link buttons, socials."

🎉 Product launch

"A launch page for v2 — hero, what's-new list, an early-access form."

…then "make the CTA green" or "add a 4th feature" and it edits only that block — every other id and coordinate stays exactly where it was.

🤖 Works in Claude Desktop, Claude Code, Cursor, Windsurf, Augment, Codex, Antigravity, Gemini CLI, Cline, Kiro, OpenCode, or any MCP-capable client — and the reference + generation tools need zero setup, so you can try it before ever pasting a token.


Under the hood

MCP (Model Context Protocol) server that teaches AI agents how to build a complete WebCake landing-page source JSON from a requirement — and persist it to a WebCake backend.

It exposes the element catalog, per-element usage hints + specials, the full page JSON Schema, valid element/page skeletons, a page validator, and tools to create or edit pages on the backend. The AI agent produces the full { page, popup, settings, options, cartConfigs } JSON; create_page persists it and auto-publishes (build + publish_html) so the preview renders immediately (the edit tools save source-only — re-publish via publish_page after edits).

Method

Best for

Auth

npx (local) — runs on your machine

Personal daily use, full control

browser login, a JWT, or none (reference tools)

Hosted URL — use our live server, nothing to install

No Node.js, teams, the claude.ai dialog

your personal ?jwt= link / x-webcake-jwt header

The reference + generation tools (get_generation_guide, list_elements, validate_page, …) and the ingest tools (ingest_html, ingest_url — turn an existing HTML or URL into a layout anchor so the AI can recreate or adapt it) work with zero config; only the persistence tools (create_page, update_page, add_section, patch_page, publish_page, list_pages, find_pages, get_page, list_organizations) need a token. Credentials resolve in order: per-request header → env var → saved auth.json (login).


🚀 Get connected — the 2 main ways

Pick one. Both hand your AI tool (Claude, Cursor, …) the full Webcake landing toolkit. No coding.

① npx — runs on your machine (recommended for personal use)

Zero install, always the latest version, needs Node.js 18+. One line grabs your token and writes the IDE config:

# Interactive — pick environment, log in via browser (or paste a JWT), pick IDE(s)
npx -y webcake-landing-mcp install

# Non-interactive — configure every supported IDE at once (env + token via flags)
npx -y webcake-landing-mcp install --ide all --env prod --jwt <your-jwt>

# Remove the server from every IDE config
npx -y webcake-landing-mcp uninstall

It writes a webcake-landing entry into the right config file for each target: claude-desktop, claude-code, cursor, windsurf, augment (VS Code), codex, antigravity, gemini (Gemini CLI), cline, kiro, opencode, or all. Flags: --ide, --env, --jwt, --org-id, --api-base/--app-base, --npx/--local, -y — see install --help.

Just want to run the server (configure by hand later)? npx -y webcake-landing-mcp

🛠️ Hand-written per-IDE config, shell-script installers (install.sh/install.ps1), or a cloned local build → docs/manual-install.md.

② Remote URL …/mcp?jwt= — hosted, nothing to install

The server is already live at https://mcp.toolvn.io.vn/mcp — no Node.js, no machine to keep awake. Grab your personal link (your token is baked in) and paste it into your client's Add custom connector / config:

https://mcp.toolvn.io.vn/mcp?jwt=<YOUR_TOKEN>

Two ways to get the link:

Optional extras: &env=prod, &org_id=…, &api_base=…. Hand each teammate a link with their own jwt → per-user, no OAuth. Clients that support headers should send the token as x-webcake-jwt instead of putting it in the URL — the full header ↔ env mapping is in docs/configuration.md.

✅ Best for: no Node.js, team/shared use, the claude.ai connector dialog (URL-only, no headers). ⚠️ The link contains your personal token — treat it like a password, always use HTTPS.


⚙️ Configuration

The quick version — only the persistence tools need any of this:

npx -y webcake-landing-mcp login    # opens the browser once, saves the token to ~/.webcake-landing-mcp/auth.json

…or set WEBCAKE_ENV (local | staging | prod — fills in all base URLs) + WEBCAKE_JWT.

For publish_page to actually put a page live, a build host is needed (it renders the app/app_css that the live publish_html route requires):

  • prod preset auto-configures https://build.webcake.io — no extra setup (the preset applies when the env resolves to prod: WEBCAKE_ENV=prod, --env prod, or x-webcake-env: prod).

  • For staging/local, set WEBCAKE_BUILD_BASE=<url> or send the x-webcake-build-base header per request.

  • Without it, publish_page falls back to a legacy source-only save with rendered:false, live:false + a warning — nothing goes live.

  • A page is only permanently live with a custom_domain; without one the returned /preview/<page_id> link expires ~10 minutes after the publish.

Everything else — the full env-var table, environment presets, per-request headers for the hosted server, the login browser flow (+ backend contract), and how to grab a JWT by hand — lives in docs/configuration.md.


📚 Docs

Guide

What's inside

Connect your IDE / claude.ai

Step-by-step connection for every client (npx & hosted URL), troubleshooting table.

Configuration

Env vars, --env presets, browser login, per-request headers, getting a JWT.

Tools reference

All 23 tools in detail + the step-by-step workflow + model notes.

Usage examples

Three end-to-end walkthroughs: build from a brief, surgical edit, inspect a type.

Manual / advanced install

Shell installers, cloned builds, hand-written per-IDE config.

Page-element schema

The full element-model reference (+ every special/event).


🧰 The tools at a glance

23 tools in five groups — full descriptions in docs/tools.md:

Group

Tools

Needs

Reference

get_generation_guide · list_elements · get_element · get_page_schema

nothing

Generation

new_element · new_page_skeleton · validate_page · layout (exact centering/row/grid/stack coordinates, both breakpoints)

nothing

Media

search_images (real Pexels stock photos) · get_icon_svg (Material Symbols / Font Awesome icon names → inline SVG via Iconify) · upload_images (re-host external images, data: URIs, or local file paths from the user's machine — files into your media collection when Webcake creds and an org are available; the org is required and must match the page's, so settle it up front — 1 org auto-selects, 2+ with none chosen returns organization_required + the list; no JWT → the public CDN) · render_preview (screenshot a page/URL so the model can see + compare it)

nothing

Ingest

ingest_html · ingest_url (recreate an existing page)

nothing

Persistence

list_organizations · create_page · list_pages · find_pages · get_page · update_page · add_section · patch_page · publish_page

WEBCAKE_API_BASE + WEBCAKE_JWT

Every write defaults to dry_run=true — it previews the exact request (token masked) and only touches your account when you re-run with dry_run=false.

Suggested prompt

Build me a WebCake landing page for &lt;brand/offer&gt;. Use the webcake-landing MCP: call get_generation_guide, new_page_skeleton, then get_element for each element type you use, assemble the { page, popup, settings, options } JSON, validate_page until zero errors, then create_page (dry-run first).


⭐ Like the idea? Drop a star

This is a solo, open-source project — every ⭐ genuinely keeps it moving and helps other builders discover it.

  • ⭐ Star the repo — 2 seconds, huge motivation.

  • 🐛 Open an issue — a bug, a missing element type, or just an idea.

  • 🔁 Share it with anyone still building landing pages box by box.

Star History Chart

Built with ❤️ for the WebCake community. Thanks for being here.

Available Tools

23 tools
add_sectionInspect

Appends one or more section nodes to the end of an existing page's page array, server-side: only the new sections are sent, and the backend rejects element ids that already exist on the page. The sections are validated first. dry_run defaults to true: it validates, caches the payload under a draft_id and previews the request; dry_run:false appends. A validation failure also returns a draft_id, which patch_page accepts for element-level fixes. Section-level saves cannot change page settings, so font weights that need new font links are reported in font_weights_notice. Requires Webcake credentials.

ParametersJSON Schema
NameRequiredDescriptionDefault
dry_runNoDefault TRUE — validate the section(s) and preview the request without writing. Set false to actually append.
page_idYesThe page id to append to (from create_page or list_pages; must be owned by the account).
draft_idNoA draft id returned by a previous add_section call (dry_run=true or validation failure). Loads the cached section payload, so the sections are not re-sent.
sectionsNoOne section node, or an array of section nodes, appended to the end of `page` (object/array or JSON string). Each is a normal section element { id, type:'section', responsive, children, … } with a unique id; sections stack vertically after the existing ones. Nodes may be sparse — omitted properties/runtime/empty events and children/per-breakpoint config are filled from factory defaults. Required unless draft_id is supplied.
create_pageInspect

Creates a new page in the user's Webcake account from a page source { page, popup, settings, options, cartConfigs }, saves it, and then publishes it (builds the rendered app on the Webcake build host and publishes it through the editor's publish route) so its preview renders; publish:false skips publishing, and a failed publish does not fail the create (result.publish reports the outcome). Before validating it applies deterministic layout corrections (off-canvas boxes, elements below wrapped text, containers grown to fit) and lists them in auto_fixed. External images and self-hosted font files in the source are re-hosted on Webcake's CDN during the save. dry_run defaults to true: it validates, caches the source under a draft_id, and returns the request it would send with the token masked; dry_run:false performs the create. A draft_id (from a validation failure, dry run, or timed-out create) re-runs from the cached source. Organization: explicit organization_id ('personal' = no organization), then WEBCAKE_ORG_ID / x-webcake-org-id, then automatic — no organizations → personal, exactly one → selected (organization_auto_selected:true), two or more → ok:false with the organization list. A page without a custom domain has a preview link that renders for about 10 minutes after each publish. Requires Webcake credentials.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoPage name (default 'AI Page').
sourceNoPage source { page, popup, settings, options, cartConfigs } (object or JSON string). Required unless draft_id is given. Elements may be sparse — id, type, responsive.<bp>.styles for both breakpoints, specials and real events; omitted properties/runtime/empty events and children/per-breakpoint config are filled from factory defaults (full nodes also work).
dry_runNoDefault TRUE — validate, cache the source as draft_id, and preview the request without sending. Set false to actually create.
publishNoDefault TRUE — after a successful create, automatically build the rendered app and publish (publish_html) so the preview renders immediately. Set false to create source-only (blank preview until publish_page runs).
draft_idNoA draft_id from a previous create_page call (validation failure, dry_run=true, or a timed-out/failed create). Loads the cached source, so the full JSON is not re-sent; covers the dry-run → real call step, fixes after errors, and retries after a timeout.
organization_idNoOrganization to create the page in (an organization id). The string 'personal' saves without any organization and skips auto-resolution. When omitted: WEBCAKE_ORG_ID / x-webcake-org-id, else automatic — one organization is selected, two or more return the list (ok:false), none means personal.
find_pages
Read-only
Inspect

Searches the account's pages by name, domain and/or page id. Filters are AND-combined; name and domain are case-insensitive substrings, and domain matches custom_domain or default_domain. Each result includes id, name, organization_id, custom_domain, default_domain and updated_at. With no filters it returns the most recently updated pages. Requires Webcake credentials.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoCase-insensitive substring of the page name to match.
limitNoMax results (default 50, capped at 100).
domainNoCase-insensitive substring of the page's domain (matches custom_domain OR default_domain).
page_idNoExact page id — narrows to that single page (useful to confirm it exists/owned).
get_element
Read-only
Inspect

Returns usage details for one element type, or for several via types: [...]: a summary, when it applies, key specials fields, a sparse skeleton node (the server fills omitted boilerplate), and for common types a filled example. types returns { elements: { [type]: details } }; type returns a single doc.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoSingle element type.
typesNoSeveral element types fetched in one call, e.g. ['section','text-block','button','form','input'].
get_generation_guideA
Read-only
Inspect

Returns the page-building conventions reference: output shape, the absolute-positioning coordinate system, event vocabulary, and the recommended workflow.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the description adds little behavioral context beyond the content list. It doesn't disclose any side effects or permissions, but the read-only nature is clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the purpose and lists the specific topics. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter reference tool with no output schema, the description adequately covers what the tool provides. It lists the key conventions, making it complete for its purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and 100% schema description coverage. The description does not need to add parameter information. Baseline 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states what the tool returns: 'page-building conventions reference' with detailed contents (output shape, coordinate system, event vocabulary, workflow). This clearly distinguishes it from sibling tools like get_page_schema or list_pages.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool should be used when conventions are needed but does not explicitly state when or when not to use it. No alternatives or exclusions are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_icon_svg
Read-only
Inspect

Resolves icon-font names into inline SVG markup via the public Iconify API (https://iconify.design/docs/api/). Accepts Material Symbols refs ("ms:verified"), Font Awesome refs ("fa:chart-line"), Iconify ids ("mdi:home"), or bare names (treated as Material Symbols); underscores become hyphens, and Material Symbols resolve to the outlined variant with a filled fallback. These are the same ms: / fa: refs that ingest results report in block.icon. Returns { icons: { "": { ok, svg, iconify } } }. In Webcake an icon renders as an SVG mask on a rectangle element: the SVG goes in responsive.desktop.config.svgMask and responsive.mobile.config.svgMask (each breakpoint is read separately), the visible color comes from styles.background (the SVG's own fill is ignored), and the mask is stretched to the box (preserveAspectRatio='none'), so a square box keeps its proportions. No Webcake credentials needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
iconsYesIcon references to resolve (1–40), e.g. ["ms:verified", "ms:support_agent", "fa:chart-line"] — typically the block.icon values from an ingest result.
get_page
Read-only
Inspect

Fetches an existing page's source tree { page, popup, settings, options, cartConfigs } with its name, organization_id and source_version. By default the tree is compacted: boilerplate shared by every element (properties, runtime, empty events/children, per-breakpoint config and factory-default style keys) is stripped, giving the same sparse shape the save tools accept and re-hydrate. compact:false returns the raw stored tree. Requires Webcake credentials.

ParametersJSON Schema
NameRequiredDescriptionDefault
compactNoDefault TRUE — strip factory-default boilerplate from every element (sparse shape, far fewer tokens). false returns the raw stored tree.
page_idYesThe page id (from list_pages or a URL).
get_page_schemaA
Read-only
Inspect

Returns the full JSON Schema (Draft 2020-12) of a Webcake page source object { page: [...], settings: {...} } for structural reference and validation.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the description's statement of returning full JSON Schema aligns and adds detail (Draft 2020-12, structure). No hidden behaviors or contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, front-loaded with verb and object, no wasted words. Perfectly concise for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read-only tool, the description fully covers what it does and what it returns. No output schema exists but the description specifies the return structure sufficiently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters (schema coverage 100% with empty schema). Baseline is 4 as per rule. Description adds no param info because none are needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verb 'Returns' and resource 'full JSON Schema of a Webcake page source object' with clear purpose 'for structural reference and validation'. It distinguishes from siblings like validate_page or get_page by stating it returns the schema itself.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies when to use (when needing schema for reference/validation) but does not explicitly mention when not to use or name alternatives. However, the context of sibling tools and the tool's name make the use case unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ingest_html
Read-only
Inspect

Parses an HTML string into a reference AST for rebuilding the page in Webcake: title, description, og_image, language, and sections classified by role (header, hero, features, about, form, cta, gallery, testimonials, pricing, faq, footer, unknown), each with headings, paragraphs, images, CTAs, links, form fields and a size_hint (desktop section height in px — from CSS when explicit, else estimated). Also returns top colors, fonts, palette and background_images; for Tailwind-CDN pages (e.g. Google Stitch) the palette and design_tokens (spacing grid, corner radii, type scale) come from the page's tailwind.config. detail:'compact' (default, ~2–5 KB) or 'full' (up to ~25 KB: per-section blocks such as cards and steps, lists, gradients, images as { src, alt }, and widgets — the cleaned HTML + CSS of composite visuals such as device mockups). Fonts: font_groups lists self-hosted fonts from @font-face rules in the settings.fontGroups shape; typography and per-section text_styles give the computed font size (desktop and mobile), weight, family, line height and letter spacing. Absolute-canvas builder exports (LadiPage-family or Webcake-published HTML) are detected and converted deterministically into a complete Webcake page source, with clone_notes listing approximations and canvas_summary summarizing per-section geometry; external images in that source are re-hosted automatically when it is saved. Garbled Vietnamese text (UTF-8 read as Latin-1) is repaired, with a warning. No credentials, no writes.

ParametersJSON Schema
NameRequiredDescriptionDefault
htmlYesRaw HTML of a page or a section.
detailNoLevel of detail in the returned AST. 'compact' (default, ~2–5 KB): sections, top colors and fonts. 'full': adds the CSS custom-property palette (design tokens by name), background_images from stylesheets, gradients, per-section blocks (repeating card/tile/step structures with title/body/image/cta), li lists, extended paragraphs, images as { src, alt }, and per-section widgets = { hint, html, css? } — the cleaned source HTML + matching CSS of composite visuals (device mockup, chat thread, dashboard, browser frame). Both levels lift the design system from a `tailwind.config` block when present (Google Stitch / Tailwind-CDN pages): `palette` named by token (e.g. primary → #a43b38), `colors` ranked by usage, and `design_tokens` with the resolved spacing grid, corner radii and type scale (e.g. display-lg → 48px). Image URLs in the result (images, background_images, og_image) belong to the source page. Absolute-canvas builder exports return the deterministic `source` at either level.
intentNoHow the result will be used. 'adapt' (default): the reference provides layout and imagery while the text is rewritten for the user's brand. 'clone': text and images stay close to the original. Absolute-canvas exports return a clone `source` either way.
base_urlNoThe page's original URL, when the HTML was saved or copied from a live site. Resolves relative font and image URLs and fetches the page's external stylesheets (+ @imports), so self-hosted fonts (`font_groups`) and computed type (`typography` / `text_styles`) defined outside the HTML are included.
sectionsNoAbsolute-canvas mode only: return only these canvas section ids (from a previous result's canvas_summary.sections[].id; 'SECTION_POPUP' selects the popups). A full-page result marked canvas_summary.truncated:true has its styles pruned to fit the size cap; per-section results carry each section's `source` untrimmed, and `source.page[0]` is a single section node.
ingest_url
Read-only
Inspect

Fetches a public webpage (GET, 10 s timeout, 2 MB cap) together with its external stylesheets and @imports, and parses it into the same reference AST as ingest_html: role-classified sections with size_hint heights, palette, design tokens, self-hosted fonts (font_groups), computed typography, images, and — with detail:'full' — per-section blocks, lists and widgets. Absolute-canvas builder exports (LadiPage-family or Webcake-published pages) are detected and converted deterministically into a complete Webcake page source with clone_notes and canvas_summary. JavaScript is not executed, so client-rendered sites (React/Vue/Next.js) may return little content; the result then carries a warning that the body was empty. Fetches are restricted to public hosts (private and link-local addresses are blocked). No credentials, no writes. Docs: https://github.com/vuluu2k/webcake-landing-mcp/blob/main/docs/tools.md

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesPublic HTTP(S) URL of the page to fetch.
detailNoLevel of detail in the returned AST. 'compact' (default, ~2–5 KB): sections, top colors and fonts. 'full': adds the CSS custom-property palette (design tokens by name), background_images from stylesheets, gradients, per-section blocks (repeating card/tile/step structures with title/body/image/cta), li lists, extended paragraphs, images as { src, alt }, and per-section widgets = { hint, html, css? } — the cleaned source HTML + matching CSS of composite visuals (device mockup, chat thread, dashboard, browser frame). Both levels lift the design system from a `tailwind.config` block when present (Google Stitch / Tailwind-CDN pages): `palette` named by token (e.g. primary → #a43b38), `colors` ranked by usage, and `design_tokens` with the resolved spacing grid, corner radii and type scale (e.g. display-lg → 48px). Image URLs in the result (images, background_images, og_image) belong to the source page. Absolute-canvas builder exports return the deterministic `source` at either level.
intentNoHow the result will be used. 'adapt' (default): the reference provides layout and imagery while the text is rewritten for the user's brand. 'clone': text and images stay close to the original. Absolute-canvas exports return a clone `source` either way.
sectionsNoAbsolute-canvas mode only: return only these canvas section ids (from a previous result's canvas_summary.sections[].id; 'SECTION_POPUP' selects the popups). A full-page result marked canvas_summary.truncated:true has its styles pruned to fit the size cap; per-section results carry each section's `source` untrimmed, and `source.page[0]` is a single section node.
layout
Read-only
Inspect

Computes on-canvas coordinates (top/left/width/height) for a group of elements on both breakpoints. Modes: 'center' (one box centered on the canvas), 'row' (N boxes in a centered horizontal row on desktop, stacked into one column on mobile), 'grid' (N uniform cells in cols columns, stacked on mobile), 'stack' (a vertical list down the content column). Respects the page margins (content column 80–880 on desktop and 20–400 on mobile by default). Returns one box per item in input order, plus notes for off-canvas or over-wide inputs. Pure computation: no credentials, no network.

ParametersJSON Schema
NameRequiredDescriptionDefault
gapNoHorizontal gap between row/grid items (px). Default 24.
topNoDesktop start y inside the section (px). Default 0.
colsNoGrid columns. Default min(itemCount, 3).
modeYesLayout pattern. center=one box; row=horizontal row (stacks on mobile); grid=cols×rows (stacks on mobile); stack=vertical list.
alignNoHorizontal alignment of the block within the canvas. Default center.
countNoUniform shortcut: number of identical boxes (use with itemWidth/itemHeight).
itemsNoExplicit per-item sizes in order (row/stack may vary sizes). Provide this OR count+itemWidth+itemHeight.
rowGapNoVertical gap between grid rows / stacked items (px). Default = gap.
itemWidthNoUniform item width (with count).
mobileTopNoMobile start y (px). Default = top.
itemHeightNoUniform item height (with count).
canvasMobileNoMobile canvas width. Default 420 (use 360 to match a narrow design).
marginMobileNoMobile page margin / content inset. Default 20.
canvasDesktopNoDesktop canvas width. Default 960 (use 1200 for wide pages).
marginDesktopNoDesktop page margin / content inset. Default 80.
mobileItemWidthNoStacked-mobile item width (row/grid). Default = mobile content width.
list_elementsA
Read-only
Inspect

List every supported element type, grouped by category, with a one-line summary and whether it is a container (can hold children).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, and description adds detail about output format (grouped by category, summary, container info). No contradictions; it enhances transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence with no wasted words, front-loaded with action and resource, structured with logical groupings of output details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters and annotations, the description fully covers what the tool does and returns. No output schema, but description explains output content adequately.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist, and schema coverage is 100% (empty). Description does not need to add parameter information; baseline for 0 params is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'list', the resource 'supported element types', and specifies grouping by category, one-line summary, and container flag. It distinguishes from sibling tools like 'get_element' (singular) and 'new_element' (creation).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for browsing all element types but does not explicitly state when to use or not use this tool versus alternatives. Context from sibling tools suggests it's for overall listing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_organizationsA
Read-only
Inspect

Returns the account's Webcake organizations (id, name, is_default). The default org (type===1, usually the personal workspace) is where pages normally go. Needs WEBCAKE_API_BASE + WEBCAKE_JWT.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the bar is lower. The description adds value by specifying output fields and the default org concept, plus authentication requirements (WEBCAKE_API_BASE + WEBCAKE_JWT). No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences deliver purpose, output fields, a usage hint, and authentication prerequisites. No wasted words; front-loaded with action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless list tool with annotations, the description fully covers what is returned, the significance of the default org, and environment requirements. No gaps given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has zero parameters and 100% coverage. Per guidelines, baseline is 4. The description does not add parameter detail, but none is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool 'Returns the account's Webcake organizations' with specific fields (id, name, is_default). It adds context about the default org, distinguishing it from other organization-related calls. No sibling tool duplicates this purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains when to use this tool (to get organizations, especially the default org for page routing) but does not explicitly exclude alternatives or compare to siblings. The context is clear, but lacking exclusions prevents a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pagesA
Read-only
Inspect

Lists the pages owned by the account (id, name, organization_id, updated_at), most-recent first. Needs WEBCAKE_API_BASE + WEBCAKE_JWT.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the description adds value by specifying the ordering (most-recent first) and the exact fields returned. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose, and every word contributes. No extra fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, fields, and ordering, but lacks information on pagination, limits, or whether the list is complete. Given no output schema, missing pagination details reduces completeness for a list operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has no parameters, and schema coverage is 100% (no properties). The description does not need to add parameter meaning beyond what the schema provides; baseline for 0 parameters is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists pages owned by the account, specifies returned fields (id, name, organization_id, updated_at), and indicates ordering (most-recent first). However, it does not differentiate from sibling tools like find_pages, which may filter.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The only usage guidance is authentication requirements (WEBCAKE_API_BASE and WEBCAKE_JWT). No context on when to use this tool versus alternatives like find_pages or get_page, and no exclusions or prerequisites are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

new_element
Read-only
Inspect

Returns a default element node for a type in the sparse authoring shape: a fresh id, seeded styles for both breakpoints, and seeded specials. properties, runtime, empty events and per-breakpoint config are omitted because the server fills them from factory defaults on validate and save.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoOptional properties.name override (layer label).
typeYesElement type to create.
new_page_skeleton
Read-only
Inspect

Returns an empty, complete top-level page source { page:[], popup:[], settings, options, cartConfigs } in the Webcake editor's shape. desktopWidth (960 or 1200) and mobileWidth (420 or 360) set settings.width_section, the canvas width that all element coordinates are measured in.

ParametersJSON Schema
NameRequiredDescriptionDefault
mobileOnlyNotrue if the page renders mobile-only.
mobileWidthNoMobile canvas width (settings.width_section.mobile). 420 (default) or 360 (to match a ~360–390 mobile design).
desktopWidthNoDesktop canvas width (settings.width_section.desktop). 960 (default, simple/narrow) or 1200 (wide/multi-column/editorial, or cloning a >960 reference).
patch_page
Destructive
Inspect

Edits a page by element id without sending the whole source. The target is either a live page (page_id) or a cached draft (draft_id) returned by a failed or dry-run create_page, add_section or update_page call. Ops: {op:'update', id, type?, specials?, styles?:{desktop?,mobile?}, config?:{desktop?,mobile?}, events?, properties?} shallow-merges fields (op defaults to 'update'; it cannot delete existing keys), {op:'replace', id, element} swaps the node, {op:'remove', id} deletes it, and {op:'add', parent_id, element} appends a child to a container; element may be sparse. The server loads the source, applies the ops, validates the whole merged tree (errors block the save) and saves: a live page is updated in place, a create draft becomes a new page, a section draft is appended, and an update draft is re-saved. With a draft_id and no patches, the cached draft is committed as-is (the retry after a timeout). dry_run defaults to true (load, merge, validate, preview; no write); dry_run:false saves. Requires Webcake credentials; a page_id patch reads the live page, so it needs them even on a dry run.

ParametersJSON Schema
NameRequiredDescriptionDefault
forceNoDefault false. Only meaningful when committing an 'update' draft: true saves the cached snapshot even though the page changed outside this session, discarding those changes. A page_id patch never needs it — it merges into the tree it just read.
dry_runNoDefault TRUE — load, merge, validate and preview the resulting save WITHOUT writing. Set false to actually save.
page_idNoA live page id to edit (must be owned by the account). Provide page_id OR draft_id; with a sections or update draft_id, page_id overrides the stored target page.
patchesNoOne op object or an array of them (object/array or JSON string). Each targets an element by id: {op:'update',id,type?,specials?,styles?:{desktop?,mobile?},config?:{desktop?,mobile?},events?,properties?} merges fields into the element (op may be omitted; `type` changes the element type; a merge cannot delete an existing key, so schema 'must NOT have additional properties' errors are fixed with op:'replace' and a clean node); {op:'replace',id,element} swaps the node; {op:'remove',id} deletes it; {op:'add',parent_id,element} appends a child to a container. `element` may be a sparse node (id/type/styles/specials/events); omitted boilerplate is filled from factory defaults. Empty or omitted with a draft_id: the cached draft is committed as-is.
draft_idNoCommit or fix a CACHED source: from create_page (failed/timed-out → new page created once valid), add_section (dry_run or failure → sections appended), or update_page/live-page patch (timed-out/failed → updatePageSource retried). The originating tool's error/dry_run response returns draft_id. Provide page_id OR draft_id. Empty/omitted patches = commit the cached draft as-is (the RETRY PATH after a timeout).
publish_page
Destructive
Inspect

Publishes an existing page: builds the rendered app on the Webcake build host (POST /render/build; https://build.webcake.io in production, overridable with WEBCAKE_BUILD_BASE / x-webcake-build-base) and then creates or updates the published record that public serving reads. With custom_domain (already pointed at Webcake) the page is served at that domain; when omitted, the page's currently attached domain is reused; with no domain, or custom_domain:'', only the preview link (/preview/) is returned, and it renders for about 10 minutes after the publish. Without a build host, or if the build fails, it falls back to a source-only publish that saves a version but serves nothing, and returns a warning. dry_run defaults to true and makes no network calls; dry_run:false builds and publishes. Requires Webcake credentials.

ParametersJSON Schema
NameRequiredDescriptionDefault
dry_runNoDefault TRUE — preview the request without sending. Does NOT call the build host. Set false to actually publish (build + publish).
page_idYesThe page id to publish (must be owned by the account).
custom_pathNoOptional path under the custom domain (e.g. 'sale').
custom_domainNoOptional custom domain to serve the page at (e.g. 'shop.example.com' — must already point at Webcake). OMIT to reuse the page's CURRENTLY-ATTACHED domain (so republishing keeps it live at the same URL, like the editor's publish modal); if the page has none it publishes domain-less (preview-host URL). Pass an empty string '' to force a domain-less publish even when the page has a domain.
render_preview
Read-only
Inspect

Renders a public URL to a PNG screenshot and returns it as an image. page_id targets a created page's preview URL (/preview/); url targets any public page and takes precedence. full_page (default true) captures the whole scrollable page and width sets the viewport; tiles:true returns a tall page as several top-to-bottom band images (requires a self-hosted Playwright host via RENDER_SCREENSHOT_BASE, otherwise a single image is returned). Engine: Microlink's free tier by default (API: https://microlink.io/docs/api/getting-started/overview; about 50 requests/day per IP — when rate-limited the result is ok:false with HTTP 429), or a self-hosted screenshot proxy set by RENDER_SCREENSHOT_BASE / x-render-screenshot-base; MICROLINK_API_KEY / x-microlink-key raises the quota. A page published without a custom domain serves its preview for about 10 minutes after the last publish; after that the preview shows 'Preview page is expired'. Docs: https://github.com/vuluu2k/webcake-landing-mcp/blob/main/docs/tools.md

ParametersJSON Schema
NameRequiredDescriptionDefault
urlNoAny public http(s) URL to screenshot (e.g. the reference page being cloned). Wins over page_id.
tilesNoTall pages: return the page as MULTIPLE top→bottom band images (each readable in detail) instead of one squished full-page image. Requires a Playwright host (RENDER_SCREENSHOT_BASE); without one it falls back to a single image.
widthNoViewport width in px (default 1280; ~960 or 1200 matches the desktop page canvas, ~420 the mobile one).
page_idNoA created page's id — screenshots its /preview/<id> URL (built from the preview base). Provide page_id OR url.
full_pageNoCapture the whole scrollable page (default true) vs just the viewport.
search_images
Read-only
Inspect

Searches Pexels stock photos (API: https://www.pexels.com/api/documentation/) by short English subject queries. Each photo includes hotlinkable URLs at several sizes, a sizes map with each variant's pixel dimensions, avg_color, and the photographer's name and attribution URL; the response also includes a size_guide mapping slot widths to variants (hero/banner ~940–1880px → large/large2x, card ~350px → medium, avatar → tiny). queries: [...] runs several searches in parallel and returns { queries: { [q]: result } } — pick:'best' (default) keeps only the top photo per query, pick:'all' the full list; query runs a single search. Works without configuration through a shared hosted proxy; a PEXELS_API_KEY env var or x-pexels-key header uses a personal Pexels quota.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoResult page for pagination (default 1).
pickNoWith `queries`, 'best' (default) returns only the top photo per query (compact, drop-in for specials.src); 'all' returns the full result. Single-query calls always return the full result.
sizeNoMinimum photo size to return (default any).
colorNoOptional color filter: a name (red, blue, …) or a hex like '6a8f3c'.
queryNoSingle subject query; returns the full result.
queriesNoSeveral subject queries (typically one per image slot), run in parallel in one call.
per_pageNoPhotos per query (default 5).
orientationNoPreferred shape — 'landscape' for heroes/banners, 'portrait' for tall cards, 'square' for icons/avatars.
update_page
Destructive
Inspect

Replaces an existing page's stored source with an edited tree (source only; the published build is not refreshed). Validates first. Concurrency check: the save is refused with page_changed_externally when the page was edited elsewhere since it was last read (base_version, or the version the server recorded), or with unverified_overwrite when an unverified save would delete live element ids; force:true overrides. dry_run defaults to true: it validates, caches the source under a draft_id and returns the masked request; dry_run:false saves. A draft_id from a dry run or a failed/timed-out update re-runs from the cached source. Requires Webcake credentials.

ParametersJSON Schema
NameRequiredDescriptionDefault
forceNoDefault false. true saves even when the page changed outside this session, discarding those outside changes.
sourceNoThe edited page source { page, popup, settings, options, cartConfigs } (object or JSON string). Required unless draft_id is given. The compacted tree from get_page can be edited and sent back AS-IS — sparse nodes are re-hydrated from factory defaults (a full tree also works).
dry_runNoDefault TRUE — validate, cache the source as draft_id, and preview without sending. Set false to actually save.
page_idNoThe page id to update (must be owned by the account). Required unless draft_id is given (the page_id is stored in the draft).
draft_idNoA draft_id from a previous update_page call (dry_run=true or a timed-out/failed update). Loads the cached source, so the full JSON is not re-sent; covers the dry-run → real call step and retries after a timeout.
base_versionNoThe page's source_version as returned by get_page. When it no longer matches the live page, the save is rejected rather than reverting edits made in the Webcake editor meanwhile. Optional — when omitted, the server uses the version it recorded at this session's last read or write of the page.
upload_imagesInspect

Re-hosts images on Webcake's CDN (statics.pancake.vn) and returns a map from each original entry to its hosted URL. Accepts up to 20 entries per call, processed in parallel, up to 200 MB each: http(s) image URLs, data:image/…;base64 URIs, and — only when the server runs locally over stdio — local file paths (absolute, ~/, file://, or Windows drive paths; rejected per entry on the remote HTTP transport). Upload target: with Webcake credentials and a resolved organization, each image is filed into that organization's media collection (the library the Webcake editor's media picker shows) and marked collection:true with its asset_id; without credentials the public CDN endpoint is used (the URL works, but the image is not in any collection: collection:false). Organization resolution: organization_id, then WEBCAKE_ORG_ID / x-webcake-org-id, then automatic selection when the account has exactly one organization; with two or more and none given, the result is ok:false with reason:'organization_required' and the organization list. dry_run defaults to false, because this only adds images to the media library and changes no page data; dry_run:true lists what would be processed without any network or filesystem access.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlsYesImage sources to upload — 1–20 per call. Accepted formats: • http(s) URLs (remote images to download and re-host) • data:image/...;base64,... URIs (inline image data) • Local file paths from the user's machine: absolute POSIX paths (/home/user/photo.jpg), home-dir paths (~/Pictures/logo.png), file:// URIs, or Windows drive paths (C:\Users\…). Local paths are only allowed when the server runs in stdio mode (the user's own machine); they are rejected on the remote HTTP transport. Up to 200 MB per image (the backend multipart limit).
dry_runNoDefault FALSE — the call actually reads/downloads and uploads, returning hosted URLs. Set true to only preview the endpoint and entries that WOULD be processed, without any network or filesystem activity (local paths: reports whether the file exists and its size).
in_folderNoCollection folder id to file the uploaded assets into (the media library's folder). Omit to use the account's root folder. Ignored when the upload falls back to the public CDN endpoint (no credentials).
organization_idNoOrganization whose media collection receives the images — normally the organization the page lives in. Optional when WEBCAKE_ORG_ID / x-webcake-org-id is set or the account has exactly one organization; with two or more and none given, the result is reason:'organization_required' with the organization list. Ignored without credentials (public CDN fallback).
validate_page
Read-only
Inspect

Validates a page source against the JSON schema and semantic rules: unique ids, dangling event targets, children only on container types, missing field_name, top-level types, and form-data bindings (duplicate field_name within one form; dangling promoId / connectedSurvey / connectedForm / set_field_value targets). Before validating it applies deterministic layout corrections (off-canvas boxes moved on-canvas, elements below wrapped text moved down) and lists them in auto_fixed. Returns errors (structural problems that block saving) and warnings (visible layout defects such as overlapping text, off-canvas bounds, or empty bands).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageYesThe page source object { page:[...], settings:{} } OR a JSON string of it.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 11 tool updatesv1.5.11
    • Changedadd_section3 fields changed
      • changedInput schema / properties / draft_id / description
        Previous value: -"A draft id returned by a previous add_section call (dry_run=true or validation failure). Loads the cached section payload — no need to re-send the sections JSON. Use for dry-run → real call transitions and fix-after-error rounds."New value: +"A draft id returned by a previous add_section call (dry_run=true or validation failure). Loads the cached section payload, so the sections are not re-sent."
      • addedInput schema / properties / sections / anyOf
        Added value: +[
        +  {
        +    "additionalProperties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {
        +      "additionalProperties": {},
        +      "type": "object"
        +    },
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / sections / description
        Previous value: -"One section node, or an array of section nodes, to append to the END of `page` (object/array or JSON string). Each is a normal section element { id, type:'section', responsive, children, … } with a UNIQUE id; they stack vertically after the existing sections. Author SPARSE nodes — omit properties/runtime/empty events+children/per-breakpoint config; the server hydrates them from factory defaults. Required unless draft_id is supplied."New value: +"One section node, or an array of section nodes, appended to the end of `page` (object/array or JSON string). Each is a normal section element { id, type:'section', responsive, children, … } with a unique id; sections stack vertically after the existing ones. Nodes may be sparse — omitted properties/runtime/empty events and children/per-breakpoint config are filled from factory defaults. Required unless draft_id is supplied."
    • Changedcreate_page4 fields changed
      • changedInput schema / properties / draft_id / description
        Previous value: -"A draft_id from a previous create_page call (validation failure, dry_run=true, or a timed-out/failed create). Loads the cached source — no need to re-send the full JSON. Use for dry-run → real call transitions, fix-after-error rounds, and retrying after a timeout."New value: +"A draft_id from a previous create_page call (validation failure, dry_run=true, or a timed-out/failed create). Loads the cached source, so the full JSON is not re-sent; covers the dry-run → real call step, fixes after errors, and retries after a timeout."
      • changedInput schema / properties / organization_id / description
        Previous value: -"Organization to create the page in (id from list_organizations). Pass the string 'personal' to explicitly save without any organization (skips auto-resolution). Omit to fall back to WEBCAKE_ORG_ID env; if that is also unset, the server calls list_organizations: 1 org → auto-selected; 2+ orgs → returns the list and asks you to pick; 0 orgs → personal."New value: +"Organization to create the page in (an organization id). The string 'personal' saves without any organization and skips auto-resolution. When omitted: WEBCAKE_ORG_ID / x-webcake-org-id, else automatic — one organization is selected, two or more return the list (ok:false), none means personal."
      • addedInput schema / properties / source / anyOf
        Added value: +[
        +  {
        +    "additionalProperties": {},
        +    "type": "object"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / source / description
        Previous value: -"Page source { page, popup, settings, options, cartConfigs } (object or JSON string). Required unless draft_id is given. Author elements SPARSE — only id, type, responsive.<bp>.styles for BOTH breakpoints, specials, and real events; OMIT properties/runtime/empty events+children/per-breakpoint config — the server hydrates them from factory defaults (a full node also works)."New value: +"Page source { page, popup, settings, options, cartConfigs } (object or JSON string). Required unless draft_id is given. Elements may be sparse — id, type, responsive.<bp>.styles for both breakpoints, specials and real events; omitted properties/runtime/empty events and children/per-breakpoint config are filled from factory defaults (full nodes also work)."
    • Changedget_element2 fields changed
      • changedInput schema / properties / type / description
        Previous value: -"Single element type — backward-compat. Prefer `types` when fetching more than one."New value: +"Single element type."
      • changedInput schema / properties / types / description
        Previous value: -"Multiple element types to fetch in one call (recommended for a section that needs several types, e.g. ['section','text-block','button','form','input'])."New value: +"Several element types fetched in one call, e.g. ['section','text-block','button','form','input']."
    • Changedingest_html4 fields changed
      • addedInput schema / properties / base_url
        Added value: +{
        +  "description": "The page's original URL, when the HTML was saved or copied from a live site. Resolves relative font and image URLs and fetches the page's external stylesheets (+ @imports), so self-hosted fonts (`font_groups`) and computed type (`typography` / `text_styles`) defined outside the HTML are included.",
        +  "type": "string"
        +}
      • changedInput schema / properties / detail / description
        Previous value: -"Level of detail in the returned AST. Both levels also lift the design system from a `tailwind.config` block when present (Google Stitch / Tailwind-CDN pages keep the WHOLE design system there, not in CSS): `palette` is named by token (primary→#a43b38, surface-container-low→#f3f3f3 — map utility classes like text-primary/bg-surface-container-low back to it), `colors` is usage-ranked from the classes actually on the page, and `design_tokens` carries the resolved spacing grid, corner radii, and TYPE SCALE (e.g. display-lg→48px, xl→80px) — REBUILD from these tokens so sizing/spacing/color match the original. 'compact' (default) — backward-compatible ~2-5 KB shape with top colors/fonts from inline styles. 'full' — richer AST: CSS custom-property palette (design tokens by name), background_images from stylesheets, gradients, per-section blocks (repeating card/tile/step structures with title/body/image/cta), li lists, extended paragraphs, images as { src, alt } objects, and per-section widgets = { hint, html, css? } — the cleaned source HTML + matching CSS of composite visuals (phone/device mockup, chat thread, dashboard, browser frame) to rebuild VERBATIM as ONE html-box (inline the css; don't re-imagine the markup). Use 'full' for clone-faithful rebuilds. Image URLs found in the result (images, background_images, og_image) are the user's assets: re-host them via upload_images and reuse them in the generated page for BOTH intents (never hotlink, never replace them with search_images stock photos). NOTE: for absolute-canvas builder exports the deterministic `source` is returned regardless of detail."New value: +"Level of detail in the returned AST. 'compact' (default, ~2–5 KB): sections, top colors and fonts. 'full': adds the CSS custom-property palette (design tokens by name), background_images from stylesheets, gradients, per-section blocks (repeating card/tile/step structures with title/body/image/cta), li lists, extended paragraphs, images as { src, alt }, and per-section widgets = { hint, html, css? } — the cleaned source HTML + matching CSS of composite visuals (device mockup, chat thread, dashboard, browser frame). Both levels lift the design system from a `tailwind.config` block when present (Google Stitch / Tailwind-CDN pages): `palette` named by token (e.g. primary → #a43b38), `colors` ranked by usage, and `design_tokens` with the resolved spacing grid, corner radii and type scale (e.g. display-lg → 48px). Image URLs in the result (images, background_images, og_image) belong to the source page. Absolute-canvas builder exports return the deterministic `source` at either level."
      • changedInput schema / properties / intent / description
        Previous value: -"How the caller intends to use the result. 'adapt' (default) — use as a layout reference and rewrite the TEXT for the user's brand (images from the reference are still re-hosted via upload_images and reused). 'clone' — keep text and images close to the original. For absolute-canvas exports the deterministic `source` is a clone either way."New value: +"How the result will be used. 'adapt' (default): the reference provides layout and imagery while the text is rewritten for the user's brand. 'clone': text and images stay close to the original. Absolute-canvas exports return a clone `source` either way."
      • changedInput schema / properties / sections / description
        Previous value: -"Absolute-canvas mode only: return ONLY these canvas section ids (use the ids from a previous call's canvas_summary.sections[].id; 'SECTION_POPUP' selects the popups). When a full-page call comes back canvas_summary.truncated:true (styles pruned to fit the size cap), re-call per section to get each section's `source` in FULL untrimmed detail — pairs naturally with building the page incrementally via add_section (pass that call's source.page[0] to add_section)."New value: +"Absolute-canvas mode only: return only these canvas section ids (from a previous result's canvas_summary.sections[].id; 'SECTION_POPUP' selects the popups). A full-page result marked canvas_summary.truncated:true has its styles pruned to fit the size cap; per-section results carry each section's `source` untrimmed, and `source.page[0]` is a single section node."
    • Changedingest_url3 fields changed
      • changedInput schema / properties / detail / description
        Previous value: -"Level of detail in the returned AST. Both levels also lift the design system from a `tailwind.config` block when present (Google Stitch / Tailwind-CDN pages keep the WHOLE design system there, not in CSS): `palette` is named by token (primary→#a43b38, surface-container-low→#f3f3f3 — map utility classes like text-primary/bg-surface-container-low back to it), `colors` is usage-ranked from the classes actually on the page, and `design_tokens` carries the resolved spacing grid, corner radii, and TYPE SCALE (e.g. display-lg→48px, xl→80px) — REBUILD from these tokens so sizing/spacing/color match the original. 'compact' (default) — backward-compatible ~2-5 KB shape with top colors/fonts from inline styles. 'full' — richer AST: CSS custom-property palette (design tokens by name), background_images from stylesheets, gradients, per-section blocks (repeating card/tile/step structures with title/body/image/cta), li lists, extended paragraphs, images as { src, alt } objects, and per-section widgets = { hint, html, css? } — the cleaned source HTML + matching CSS of composite visuals (phone/device mockup, chat thread, dashboard, browser frame) to rebuild VERBATIM as ONE html-box (inline the css; don't re-imagine the markup). Use 'full' for clone-faithful rebuilds. Image URLs found in the result (images, background_images, og_image) are the user's assets: re-host them via upload_images and reuse them in the generated page for BOTH intents (never hotlink, never replace them with search_images stock photos). NOTE: for absolute-canvas builder exports the deterministic `source` is returned regardless of detail."New value: +"Level of detail in the returned AST. 'compact' (default, ~2–5 KB): sections, top colors and fonts. 'full': adds the CSS custom-property palette (design tokens by name), background_images from stylesheets, gradients, per-section blocks (repeating card/tile/step structures with title/body/image/cta), li lists, extended paragraphs, images as { src, alt }, and per-section widgets = { hint, html, css? } — the cleaned source HTML + matching CSS of composite visuals (device mockup, chat thread, dashboard, browser frame). Both levels lift the design system from a `tailwind.config` block when present (Google Stitch / Tailwind-CDN pages): `palette` named by token (e.g. primary → #a43b38), `colors` ranked by usage, and `design_tokens` with the resolved spacing grid, corner radii and type scale (e.g. display-lg → 48px). Image URLs in the result (images, background_images, og_image) belong to the source page. Absolute-canvas builder exports return the deterministic `source` at either level."
      • changedInput schema / properties / intent / description
        Previous value: -"How the caller intends to use the result. 'adapt' (default) — use as a layout reference and rewrite the TEXT for the user's brand (images from the reference are still re-hosted via upload_images and reused). 'clone' — keep text and images close to the original. For absolute-canvas exports the deterministic `source` is a clone either way."New value: +"How the result will be used. 'adapt' (default): the reference provides layout and imagery while the text is rewritten for the user's brand. 'clone': text and images stay close to the original. Absolute-canvas exports return a clone `source` either way."
      • changedInput schema / properties / sections / description
        Previous value: -"Absolute-canvas mode only: return ONLY these canvas section ids (use the ids from a previous call's canvas_summary.sections[].id; 'SECTION_POPUP' selects the popups). When a full-page call comes back canvas_summary.truncated:true (styles pruned to fit the size cap), re-call per section to get each section's `source` in FULL untrimmed detail — pairs naturally with building the page incrementally via add_section (pass that call's source.page[0] to add_section)."New value: +"Absolute-canvas mode only: return only these canvas section ids (from a previous result's canvas_summary.sections[].id; 'SECTION_POPUP' selects the popups). A full-page result marked canvas_summary.truncated:true has its styles pruned to fit the size cap; per-section results carry each section's `source` untrimmed, and `source.page[0]` is a single section node."
    • Changedpatch_page3 fields changed
      • changedInput schema / properties / page_id / description
        Previous value: -"Edit a LIVE page by id (from create_page, list_pages, or find_pages; must be owned by the account). Provide page_id OR draft_id. For a sections or update draft_id you may also pass page_id here to override the stored page target."New value: +"A live page id to edit (must be owned by the account). Provide page_id OR draft_id; with a sections or update draft_id, page_id overrides the stored target page."
      • addedInput schema / properties / patches / anyOf
        Added value: +[
        +  {
        +    "additionalProperties": {},
        +    "type": "object"
        +  },
        +  {
        +    "items": {
        +      "additionalProperties": {},
        +      "type": "object"
        +    },
        +    "type": "array"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • changedInput schema / properties / patches / description
        Previous value: -"One op object or an array of them (object/array or JSON string). Each targets an element by id: {op:'update',id,type?,specials?,styles?:{desktop?,mobile?},config?:{desktop?,mobile?},events?,properties?} merges fields into the element (op may be omitted; set `type` to fix a wrong element type; update MERGES — it cannot DELETE an existing/stray key, so 'must NOT have additional properties' errors need op:'replace' with a clean node); {op:'replace',id,element} swaps the node; {op:'remove',id} deletes it; {op:'add',parent_id,element} appends a child to a container. `element` may be a SPARSE node (id/type/styles/specials/events only) — the server hydrates omitted boilerplate from factory defaults. OMIT (or pass empty array) when draft_id is given and you just want to commit/retry the cached draft as-is."New value: +"One op object or an array of them (object/array or JSON string). Each targets an element by id: {op:'update',id,type?,specials?,styles?:{desktop?,mobile?},config?:{desktop?,mobile?},events?,properties?} merges fields into the element (op may be omitted; `type` changes the element type; a merge cannot delete an existing key, so schema 'must NOT have additional properties' errors are fixed with op:'replace' and a clean node); {op:'replace',id,element} swaps the node; {op:'remove',id} deletes it; {op:'add',parent_id,element} appends a child to a container. `element` may be a sparse node (id/type/styles/specials/events); omitted boilerplate is filled from factory defaults. Empty or omitted with a draft_id: the cached draft is committed as-is."
    • Changedrender_preview1 field changed
      • changedInput schema / properties / width / description
        Previous value: -"Viewport width in px (default 1280; use ~960/1200 to match the page canvas, ~420 for mobile)."New value: +"Viewport width in px (default 1280; ~960 or 1200 matches the desktop page canvas, ~420 the mobile one)."
    • Changedsearch_images2 fields changed
      • changedInput schema / properties / queries / description
        Previous value: -"Multiple subject queries (one per image slot) to run in parallel — recommended for a page with 2+ images so each only costs ONE round-trip."New value: +"Several subject queries (typically one per image slot), run in parallel in one call."
      • changedInput schema / properties / query / description
        Previous value: -"Single subject query — backward-compat. Prefer `queries` when the page needs 2+ images."New value: +"Single subject query; returns the full result."
    • Changedupdate_page4 fields changed
      • changedInput schema / properties / base_version / description
        Previous value: -"The source_version get_page returned for this page. When it no longer matches the live page the save is REJECTED instead of reverting whatever was edited in the Webcake editor meanwhile. Optional — omit it and the server uses the version it recorded on your last read/write of this page."New value: +"The page's source_version as returned by get_page. When it no longer matches the live page, the save is rejected rather than reverting edits made in the Webcake editor meanwhile. Optional — when omitted, the server uses the version it recorded at this session's last read or write of the page."
      • changedInput schema / properties / draft_id / description
        Previous value: -"A draft_id from a previous update_page call (dry_run=true or a timed-out/failed update). Loads the cached source — no need to re-send the full JSON. Use for dry-run → real call transitions and retrying after a timeout."New value: +"A draft_id from a previous update_page call (dry_run=true or a timed-out/failed update). Loads the cached source, so the full JSON is not re-sent; covers the dry-run → real call step and retries after a timeout."
      • changedInput schema / properties / force / description
        Previous value: -"Default false. true = save even when the page changed outside this session, discarding those changes. Only pass it after the user has said to."New value: +"Default false. true saves even when the page changed outside this session, discarding those outside changes."
      • addedInput schema / properties / source / anyOf
        Added value: +[
        +  {
        +    "additionalProperties": {},
        +    "type": "object"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
    • Changedupload_images1 field changed
      • changedInput schema / properties / organization_id / description
        Previous value: -"Organization whose media collection the images are filed into — REQUIRED when the account has 2+ orgs, and it must match the org the page is created in. Omit only to use WEBCAKE_ORG_ID / x-webcake-org-id, or to auto-select when the account has exactly ONE org; with 2+ orgs and none given the call returns reason:'organization_required' with the org list. Ignored when there are no credentials (public CDN fallback)."New value: +"Organization whose media collection receives the images — normally the organization the page lives in. Optional when WEBCAKE_ORG_ID / x-webcake-org-id is set or the account has exactly one organization; with two or more and none given, the result is reason:'organization_required' with the organization list. Ignored without credentials (public CDN fallback)."
    • Changedvalidate_page2 fields changed
      • addedInput schema / properties / page / anyOf
        Added value: +[
        +  {
        +    "additionalProperties": {},
        +    "type": "object"
        +  },
        +  {
        +    "type": "string"
        +  }
        +]
      • addedInput schema / required
        Added value: +[
        +  "page"
        +]
  2. 2 tool updatesv1.5.2
    • Changedpatch_page1 field changed
      • addedInput schema / properties / force
        Added value: +{
        +  "description": "Default false. Only meaningful when committing an 'update' draft: true saves the cached snapshot even though the page changed outside this session, discarding those changes. A page_id patch never needs it — it merges into the tree it just read.",
        +  "type": "boolean"
        +}
    • Changedupdate_page2 fields changed
      • addedInput schema / properties / base_version
        Added value: +{
        +  "description": "The source_version get_page returned for this page. When it no longer matches the live page the save is REJECTED instead of reverting whatever was edited in the Webcake editor meanwhile. Optional — omit it and the server uses the version it recorded on your last read/write of this page.",
        +  "type": "string"
        +}
      • addedInput schema / properties / force
        Added value: +{
        +  "description": "Default false. true = save even when the page changed outside this session, discarding those changes. Only pass it after the user has said to.",
        +  "type": "boolean"
        +}
  3. 23 tool updatesv1.5.0
    • First observedadd_section
    • First observedcreate_page
    • First observedfind_pages
    • First observedget_element
    • First observedget_generation_guide
    • First observedget_icon_svg
    • First observedget_page
    • First observedget_page_schema
    • First observedingest_html
    • First observedingest_url
    • First observedlayout
    • First observedlist_elements
    • First observedlist_organizations
    • First observedlist_pages
    • First observednew_element
    • First observednew_page_skeleton
    • First observedpatch_page
    • First observedpublish_page
    • First observedrender_preview
    • First observedsearch_images
    • First observedupdate_page
    • First observedupload_images
    • First observedvalidate_page

TDQS

A3.9/5.0

Scored across 23 tools

Disambiguation3/5

Most tools are action-specific, but several pairs overlap: find_pages mirrors list_pages with no filters, get_element returns sparse element skeletons much like new_element, and update_page/patch_page/add_section all mutate pages at different granularities. The long descriptions help disambiguate, but an agent could still select the wrong one.

Naming Consistency4/5

Nearly all tools use snake_case verb_noun naming (list_pages, get_eement, create_page, upload_images), and get_/ list_/ create_ / patch_ verbs consistently encode their role. Minor deviations are 'new_element'/'new_page_skeleton' using 'new' instead of 'create', and 'layout' standing alone as a bare noun.

Tool Count3/5

At 23 tools, the surface is in the heavy 16-25 range for a single MCP server. The count is largely justified by the full build pipeline — ingestion, assets, layout, validation, persistence, publishing — but it could be trimmed by consolidating find_pages/list_pages or new_element/get_element.

Completeness3/5

The build/clone workflow is well covered: reference ingestion, asset handling, element construction, validation, layout math, and page persistence/publishing are all present. However, there is no delete_page tool, and no domain-management tool for attaching or listing custom domains needed for permanent public URLs, so the lifecycle has notable gaps.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers