webcake-landing-mcp 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,535 @@
1
+ # WebCake Landing MCP Server
2
+
3
+ MCP (Model Context Protocol) server that teaches AI agents how to build a complete
4
+ **WebCake landing-page source JSON** from a requirement — and persist it to a WebCake backend.
5
+
6
+ It exposes the element catalog, per-element usage hints + `specials`, the full page JSON Schema,
7
+ valid element/page skeletons, a page validator, and tools to create or edit pages on the backend.
8
+ The AI agent produces the full `{ page, popup, settings, options, cartConfigs }` JSON; `create_page`
9
+ persists it (source-only — the page opens in the editor where re-saving renders it).
10
+
11
+ ## Two ways to run
12
+
13
+ | Mode | Command | When |
14
+ |------|---------|------|
15
+ | **CDN / npx** (no clone) | `npx -y webcake-landing-mcp` | Fastest start — npm fetches & runs it, no clone or build. Auto-updates to the latest published version. |
16
+ | **Local** (cloned build) | `node /abs/path/dist/index.js` | Hacking on the server, offline, or pinning a specific build. Run `npm run build` first. |
17
+
18
+ Both expose the exact same tools. Every IDE config below shows the **local** form; to use **CDN** mode,
19
+ just swap `command`/`args` for the npx form (see [Run without cloning](#run-without-cloning-npx)).
20
+
21
+ ## Quick Install (Recommended)
22
+
23
+ Run the auto-install script — it handles everything: clone, install dependencies, build, and configure your IDE.
24
+
25
+ ### macOS / Linux
26
+
27
+ If you already cloned the repo:
28
+ ```bash
29
+ ./install.sh
30
+ ```
31
+
32
+ Or download and run directly:
33
+ ```bash
34
+ curl -fsSL https://raw.githubusercontent.com/vuluu2k/webcake-landing-mcp/main/install.sh -o install.sh && bash install.sh
35
+ ```
36
+
37
+ The installer is interactive: it asks where to install (default `~/.webcake-landing-mcp`), prompts for
38
+ the env vars (`WEBCAKE_API_BASE`, `WEBCAKE_JWT`, `WEBCAKE_ORG_ID` — all optional, Enter to skip), then
39
+ lets you pick which IDE(s) to configure: `claude-desktop`, `claude-code`, `cursor`, `windsurf`, `augment`,
40
+ `codex`, or all.
41
+
42
+ Uninstall (removes the MCP server entry from every configured IDE):
43
+ ```bash
44
+ ./install.sh --uninstall
45
+ ```
46
+
47
+ ### Windows (PowerShell)
48
+
49
+ If you already cloned the repo:
50
+ ```powershell
51
+ .\install.ps1
52
+ ```
53
+
54
+ Or download and run directly:
55
+ ```powershell
56
+ irm https://raw.githubusercontent.com/vuluu2k/webcake-landing-mcp/main/install.ps1 -OutFile install.ps1; .\install.ps1
57
+ ```
58
+
59
+ Uninstall:
60
+ ```powershell
61
+ .\install.ps1 --uninstall
62
+ ```
63
+
64
+ ---
65
+
66
+ ## Update
67
+
68
+ Update to the latest version:
69
+
70
+ ```bash
71
+ cd ~/.webcake-landing-mcp # or wherever you installed it
72
+ git pull
73
+ npm install
74
+ npm run build
75
+ ```
76
+
77
+ Then restart your IDE.
78
+
79
+ ---
80
+
81
+ ## Run without cloning (npx)
82
+
83
+ Once published to npm, the server runs straight from the registry — no clone, no build:
84
+
85
+ ```bash
86
+ npx -y webcake-landing-mcp
87
+ ```
88
+
89
+ Or run the latest from GitHub (npx clones + builds via the `prepare` script on the fly):
90
+
91
+ ```bash
92
+ npx -y github:vuluu2k/webcake-landing-mcp
93
+ ```
94
+
95
+ The MCP config is the same as the local one, but `command`/`args` point at `npx` instead of a built file:
96
+
97
+ ```json
98
+ {
99
+ "mcpServers": {
100
+ "webcake-landing": {
101
+ "command": "npx",
102
+ "args": ["-y", "webcake-landing-mcp"],
103
+ "env": {
104
+ "WEBCAKE_API_BASE": "http://localhost:5800",
105
+ "WEBCAKE_JWT": "<your-jwt>"
106
+ }
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
112
+ > npx caches the package after the first run, so subsequent launches are fast. Use a pinned version
113
+ > (`webcake-landing-mcp@1.0.0`) if you need a reproducible build.
114
+
115
+ ## Manual Setup (local)
116
+
117
+ ```bash
118
+ git clone https://github.com/vuluu2k/webcake-landing-mcp.git
119
+ cd webcake-landing-mcp
120
+ npm install # postinstall `prepare` builds dist/ automatically
121
+ npm run build # (re)build: tsc -> dist/ + copies page-schema.json
122
+ npm run smoke # offline self-test of factory + validator (prints "ALL GOOD")
123
+ ```
124
+
125
+ The reference/validation tools work with **zero config**. Env vars are only needed for the persistence
126
+ tools (`create_page`, `update_page`, `list_pages`, `get_page`, `list_organizations`).
127
+
128
+ ## Environment Variables
129
+
130
+ | Variable | Required | Description |
131
+ |----------|----------|-------------|
132
+ | `WEBCAKE_API_BASE` | No* | Backend base URL, e.g. `http://localhost:5800`. Required to persist. |
133
+ | `WEBCAKE_JWT` | No* | Account JWT (dashboard auth). Required to persist — expires, refresh when needed. |
134
+ | `WEBCAKE_ORG_ID` | No | Default organization id for `create_page` (overridden by its `organization_id` arg). Omit → personal page. |
135
+ | `WEBCAKE_HOST` | No | Optional `Host` header (Phoenix routes by host, e.g. `builder.localhost`). |
136
+ | `WEBCAKE_APP_BASE` | No | Optional base used to build editor/preview URLs in the result. |
137
+
138
+ > \* `WEBCAKE_API_BASE` and `WEBCAKE_JWT` are only needed for the persistence tools. The reference and
139
+ > validation tools (`get_generation_guide`, `list_elements`, `get_element`, `validate_page`, …) work without them.
140
+
141
+ > Persisting writes a real page to whatever `WEBCAKE_API_BASE` points at, using the JWT as that account.
142
+ > Start against local/staging.
143
+
144
+ ### How to get `WEBCAKE_JWT`
145
+
146
+ 1. Open the WebCake builder dashboard and log in
147
+ 2. Open DevTools (`F12` or `Cmd + Option + I`)
148
+ 3. Go to the **Network** tab > click any page
149
+ 4. Find an API request (e.g. `@me`, `organizations`…)
150
+ 5. In **Request Headers**, copy the value after `Authorization: Bearer ` → this is your `WEBCAKE_JWT`
151
+ 6. Use the `list_organizations` tool to list orgs and pick `WEBCAKE_ORG_ID`
152
+
153
+ ---
154
+
155
+ ## Configuration by IDE / AI Tool
156
+
157
+ > Replace `/absolute-path/webcake-landing-mcp/dist/index.js` below with the actual path where you
158
+ > cloned/built the repo. Example: `/Users/username/webcake-landing-mcp/dist/index.js`.
159
+ > Run `npm run build` first so `dist/` exists.
160
+
161
+ ### 1. Claude Desktop
162
+
163
+ Open Settings > Developer > Edit Config, or edit the file directly:
164
+
165
+ - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
166
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
167
+ - **Linux**: `~/.config/Claude/claude_desktop_config.json`
168
+
169
+ ```json
170
+ {
171
+ "mcpServers": {
172
+ "webcake-landing": {
173
+ "command": "node",
174
+ "args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
175
+ "env": {
176
+ "WEBCAKE_API_BASE": "http://localhost:5800",
177
+ "WEBCAKE_JWT": "<your-jwt>",
178
+ "WEBCAKE_HOST": "builder.localhost",
179
+ "WEBCAKE_APP_BASE": "http://builder.localhost:5800"
180
+ }
181
+ }
182
+ }
183
+ }
184
+ ```
185
+
186
+ Restart Claude Desktop. The MCP tools will appear in the chat input (hammer icon).
187
+
188
+ ---
189
+
190
+ ### 2. Claude Code (CLI)
191
+
192
+ Run in terminal — **local** build:
193
+
194
+ ```bash
195
+ claude mcp add webcake-landing \
196
+ -e WEBCAKE_API_BASE=http://localhost:5800 \
197
+ -e WEBCAKE_JWT=<your-jwt> \
198
+ -e WEBCAKE_HOST=builder.localhost \
199
+ -- node /absolute-path/webcake-landing-mcp/dist/index.js
200
+ ```
201
+
202
+ Or **CDN / npx** (no clone):
203
+
204
+ ```bash
205
+ claude mcp add webcake-landing \
206
+ -e WEBCAKE_API_BASE=http://localhost:5800 \
207
+ -e WEBCAKE_JWT=<your-jwt> \
208
+ -- npx -y webcake-landing-mcp
209
+ ```
210
+
211
+ Or create `.claude.json` at project root (or `~/.claude.json` globally):
212
+
213
+ ```json
214
+ {
215
+ "mcpServers": {
216
+ "webcake-landing": {
217
+ "command": "node",
218
+ "args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
219
+ "env": {
220
+ "WEBCAKE_API_BASE": "http://localhost:5800",
221
+ "WEBCAKE_JWT": "<your-jwt>"
222
+ }
223
+ }
224
+ }
225
+ }
226
+ ```
227
+
228
+ Verify:
229
+ ```bash
230
+ claude mcp list
231
+ ```
232
+
233
+ ---
234
+
235
+ ### 3. Cursor
236
+
237
+ Create `.cursor/mcp.json` at project root (or `~/.cursor/mcp.json` globally):
238
+
239
+ ```json
240
+ {
241
+ "mcpServers": {
242
+ "webcake-landing": {
243
+ "command": "node",
244
+ "args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
245
+ "env": {
246
+ "WEBCAKE_API_BASE": "http://localhost:5800",
247
+ "WEBCAKE_JWT": "<your-jwt>"
248
+ }
249
+ }
250
+ }
251
+ }
252
+ ```
253
+
254
+ Restart Cursor and check Settings > MCP Servers for **"Connected"** status.
255
+
256
+ ---
257
+
258
+ ### 4. Windsurf
259
+
260
+ Create `~/.codeium/windsurf/mcp_config.json`:
261
+
262
+ ```json
263
+ {
264
+ "mcpServers": {
265
+ "webcake-landing": {
266
+ "command": "node",
267
+ "args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
268
+ "env": {
269
+ "WEBCAKE_API_BASE": "http://localhost:5800",
270
+ "WEBCAKE_JWT": "<your-jwt>"
271
+ }
272
+ }
273
+ }
274
+ }
275
+ ```
276
+
277
+ Restart Windsurf. Type `@` in Cascade chat to see `webcake-landing` tools.
278
+
279
+ ---
280
+
281
+ ### 5. Augment (VS Code Extension)
282
+
283
+ Open Command Palette: `Cmd + Shift + P` > **"Augment: Edit MCP Settings"**, then add:
284
+
285
+ ```json
286
+ {
287
+ "mcpServers": {
288
+ "webcake-landing": {
289
+ "command": "node",
290
+ "args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
291
+ "env": {
292
+ "WEBCAKE_API_BASE": "http://localhost:5800",
293
+ "WEBCAKE_JWT": "<your-jwt>"
294
+ }
295
+ }
296
+ }
297
+ }
298
+ ```
299
+
300
+ Restart VS Code.
301
+
302
+ ---
303
+
304
+ ### 6. Codex (OpenAI CLI)
305
+
306
+ Add to `~/.codex/config.toml`:
307
+
308
+ ```toml
309
+ [mcp_servers.webcake-landing]
310
+ command = "node"
311
+ args = ["/absolute-path/webcake-landing-mcp/dist/index.js"]
312
+ env = { "WEBCAKE_API_BASE" = "http://localhost:5800", "WEBCAKE_JWT" = "<your-jwt>" }
313
+ ```
314
+
315
+ Verify:
316
+ ```bash
317
+ codex mcp list
318
+ ```
319
+
320
+ ---
321
+
322
+ ## Usage Examples
323
+
324
+ ### Example 1: Build a new landing page from a brief
325
+
326
+ **Prompt:**
327
+ ```
328
+ Build me a WebCake landing page for "Acme Coffee" — a hero with a CTA, a 3-feature
329
+ section, and a signup form. Persist it to my default org.
330
+ ```
331
+
332
+ **AI agent will automatically:**
333
+
334
+ **Step 1** — Call `get_generation_guide` to learn conventions (canvas, coordinate system, events, workflow)
335
+
336
+ **Step 2** — Call `new_page_skeleton` for an empty top-level source, then `get_element` for each type it uses:
337
+
338
+ ```
339
+ get_element({ type: "section" })
340
+ get_element({ type: "text-block" })
341
+ get_element({ type: "button" })
342
+ get_element({ type: "form" })
343
+ ```
344
+
345
+ **Step 3** — Assemble the full `{ page, popup, settings, options, cartConfigs }` JSON, then validate:
346
+
347
+ ```
348
+ validate_page({ source })
349
+ → { ok: false, errors: ["BUTTON-2: event target 'POPUP-9' not found"] } # fix every error, re-validate
350
+ validate_page({ source })
351
+ → { ok: true, errors: [] }
352
+ ```
353
+
354
+ **Step 4** — Persist (dry-run first, then for real):
355
+
356
+ ```
357
+ list_organizations({}) → pick the org
358
+ create_page({ source }) → dry-run preview (JWT masked)
359
+ create_page({ source, dry_run: false }) → { page_id, editor_url, preview_url }
360
+ ```
361
+
362
+ Open the page in the editor and re-save to render `app`/`app_css`.
363
+
364
+ ---
365
+
366
+ ### Example 2: Edit an existing page
367
+
368
+ **Prompt:**
369
+ ```
370
+ On my "Acme Coffee" landing page, change the hero headline to "Freshly Roasted Daily"
371
+ and make the CTA button green.
372
+ ```
373
+
374
+ **AI agent edits surgically — never regenerates the whole tree:**
375
+
376
+ ```
377
+ # Step 1: find the page
378
+ list_pages({})
379
+ → [{ id: "page_42", name: "Acme Coffee", organization_id: "org_1", ... }]
380
+
381
+ # Step 2: fetch its decoded source tree
382
+ get_page({ page_id: "page_42" })
383
+
384
+ # Step 3: change ONLY the headline text + button color, keep every other id/coordinate,
385
+ # then validate and write back
386
+ validate_page({ source }) → ok
387
+ update_page({ page_id: "page_42", source }) → dry-run preview
388
+ update_page({ page_id: "page_42", source, dry_run: false })
389
+ ```
390
+
391
+ ---
392
+
393
+ ### Example 3: Inspect an element type before using it
394
+
395
+ **Prompt:**
396
+ ```
397
+ What specials does a form element need, and show me a valid example.
398
+ ```
399
+
400
+ **AI agent calls:**
401
+
402
+ ```
403
+ get_element({ type: "form" })
404
+ → {
405
+ hints: "Each input needs a unique specials.field_name…",
406
+ specials: { ... },
407
+ skeleton: { ... }, # structurally-valid default node
408
+ example: { ... } # filled, realistic example
409
+ }
410
+ ```
411
+
412
+ ---
413
+
414
+ ## Detailed Tool Usage Guide
415
+
416
+ The tools split into three groups: **reference** (learn the model — no config needed),
417
+ **generation** (build valid nodes), and **persistence** (save to the backend — needs env vars).
418
+
419
+ ### Step 1: Read the guide first — `get_generation_guide`
420
+
421
+ Always call this **first**. It returns the output shape, coordinate system (desktop ≈ 960px,
422
+ mobile ≈ 420px), event vocabulary, and the end-to-end workflow.
423
+
424
+ ```
425
+ get_generation_guide({})
426
+ → "## Output shape… ## Canvas… ## Events… ## Workflow…"
427
+ ```
428
+
429
+ ### Step 2: Browse the element catalog — `list_elements` / `get_element`
430
+
431
+ ```
432
+ # All element types by category (summary + when-to-use + is it a container?)
433
+ list_elements({})
434
+ → { categories: { layout: [...], content: [...], form: [...], ... } }
435
+
436
+ # Deep-dive one type — hints, key specials, default skeleton, filled example
437
+ get_element({ type: "button" })
438
+ ```
439
+
440
+ ### Step 3: Get valid building blocks — `new_element` / `new_page_skeleton`
441
+
442
+ ```
443
+ # A structurally-valid default node for a type (fresh id)
444
+ new_element({ type: "section" })
445
+
446
+ # An empty but complete top-level source
447
+ new_page_skeleton({})
448
+ → { page: [], popup: [], settings: {…}, options: { currency, mobileOnly, versionID }, cartConfigs: {} }
449
+ ```
450
+
451
+ ### Step 4: Inspect / validate — `get_page_schema` / `validate_page`
452
+
453
+ ```
454
+ # Full JSON Schema (Draft 2020-12) of a page source
455
+ get_page_schema({})
456
+
457
+ # Structural + semantic validation — fix every error before persisting
458
+ validate_page({ source })
459
+ → { ok: false, errors: [...], warnings: [...] }
460
+ ```
461
+
462
+ `validate_page` **errors are blocking**; warnings (dangling event target, missing `field_name`) are advisory.
463
+
464
+ ### Step 5: Persist — `list_organizations` / `create_page` / `update_page`
465
+
466
+ ```
467
+ # List the account's organizations — ask which to use; default = the is_default org
468
+ list_organizations({})
469
+ → [{ id: "org_1", name: "Acme", is_default: true }, ...]
470
+
471
+ # Create a NEW page (source-only). Defaults to dry_run=true.
472
+ create_page({ source, organization_id: "org_1" }) # preview
473
+ create_page({ source, dry_run: false }) # actually create
474
+
475
+ # Edit an EXISTING page
476
+ list_pages({}) # find the page
477
+ get_page({ page_id }) # fetch decoded source
478
+ update_page({ page_id, source, dry_run: false }) # overwrite (dry_run=true by default)
479
+ ```
480
+
481
+ `create_page` calls **`POST {WEBCAKE_API_BASE}/api/v1/ai/create_page_from_source`** on the backend.
482
+ Both `create_page` and `update_page` **default to `dry_run=true`** (validate and return the request they
483
+ *would* send, JWT masked); set `dry_run=false` to actually write. The result returns `page_id` + editor/preview URLs.
484
+
485
+ ---
486
+
487
+ ## Suggested prompt
488
+
489
+ > Build me a WebCake landing page for &lt;brand/offer&gt;. Use the webcake-landing MCP:
490
+ > call `get_generation_guide`, `new_page_skeleton`, then `get_element` for each element type you use,
491
+ > assemble the `{ page, popup, settings, options }` JSON, `validate_page` until zero errors,
492
+ > then `create_page` (dry-run first).
493
+
494
+ ---
495
+
496
+ ## Available Tools
497
+
498
+ ### Reference (no config needed)
499
+ | Tool | Description |
500
+ |------|-------------|
501
+ | `get_generation_guide` | **Read FIRST.** Output shape, coordinate system, event vocabulary, workflow. |
502
+ | `list_elements` | All element types by category (summary + when-to-use + container?). |
503
+ | `get_element` | One type: hints, key `specials`, default skeleton, filled example. |
504
+ | `get_page_schema` | Full JSON Schema (Draft 2020-12) of a page source. |
505
+
506
+ ### Generation
507
+ | Tool | Description |
508
+ |------|-------------|
509
+ | `new_element` | A structurally-valid default node for a type (fresh id). |
510
+ | `new_page_skeleton` | An empty but complete top-level source `{ page, popup, settings, options, cartConfigs }`. |
511
+ | `validate_page` | Structural + semantic validation (ids, event targets, containers, `field_name`). |
512
+
513
+ ### Persistence (needs `WEBCAKE_API_BASE` + `WEBCAKE_JWT`)
514
+ | Tool | Description |
515
+ |------|-------------|
516
+ | `list_organizations` | List the account's organizations (id, name, is_default). Default = the `is_default` org. |
517
+ | `create_page` | Persist a generated source as a new page (source-only). **Defaults to `dry_run=true`.** |
518
+ | `list_pages` | List the account's pages (id, name, organization_id, updated_at) to pick one to edit. |
519
+ | `get_page` | Fetch an existing page's decoded source tree so you can edit it. |
520
+ | `update_page` | Overwrite an existing page's source with an edited tree. **Defaults to `dry_run=true`.** |
521
+
522
+ ---
523
+
524
+ ## Model notes
525
+
526
+ - **Absolute-positioning canvas:** every child carries numeric `top/left/width/height` per breakpoint;
527
+ sections stack vertically and own a `height`. Content lives in `specials` (`text`, `src`, …), never in `styles`.
528
+ - **Top-level source:** `{ page: [sections], popup: [popups], settings: {…}, options: { currency, mobileOnly, versionID }, cartConfigs: {} }`.
529
+ Popups are a **separate** top-level array, not nested in `page`.
530
+ - Per-breakpoint animation lives in `config.animation = { name, delay, duration, repeat }`.
531
+ - Colors are `rgba()`; `top/left/width/height/fontSize` are numbers (px); form inputs need a unique `specials.field_name`.
532
+
533
+ Reference: [docs/page-element-schema.md](docs/page-element-schema.md) and
534
+ [src/page-schema.json](src/page-schema.json) (the bundled JSON Schema, Draft 2020-12). The schema mirrors
535
+ the real editor `page_source` shape.