webcake-landing-mcp 1.0.9 → 1.0.11
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 +57 -267
- package/README.vi.md +50 -264
- package/dist/auth/login.js +15 -24
- package/dist/http.js +1 -1
- package/dist/index.js +33 -0
- package/dist/install.js +74 -40
- package/dist/persistence/config.js +32 -8
- package/dist/persistence/webcake-client.js +0 -2
- package/dist/smoke.js +17 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -54,80 +54,18 @@ valid element/page skeletons, a page validator, and tools to create or edit page
|
|
|
54
54
|
The AI agent produces the full `{ page, popup, settings, options, cartConfigs }` JSON; `create_page`
|
|
55
55
|
persists it (source-only — the page opens in the editor where re-saving renders it).
|
|
56
56
|
|
|
57
|
-
##
|
|
57
|
+
## Two ways to run
|
|
58
58
|
|
|
59
|
-
|
|
|
60
|
-
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
| 3 | **Remote HTTP (`serve`)** — run as an HTTP server, test with MCP Inspector / `mcp-remote` / curl | Trying the remote transport locally | per-request `x-webcake-jwt` header, or env | [Remote](#run-as-a-remote-connector-streamable-http) |
|
|
64
|
-
| 4 | **VPS + claude.ai connector** — deploy public HTTPS, add as a custom connector | Sharing one hosted server | single-account (env token); per-user needs OAuth (not implemented) | [Deploy on a VPS](#deploy-on-a-vps) |
|
|
65
|
-
|
|
66
|
-
Two **run forms** apply to any method: **`npx -y webcake-landing-mcp …`** (no clone, auto-updates) or **`node /abs/path/dist/index.js …`** (a cloned build — run `npm run build` first). The IDE configs below show the local form; swap `command`/`args` for the npx form to use CDN mode.
|
|
59
|
+
| Method | Best for | Auth |
|
|
60
|
+
|--------|----------|------|
|
|
61
|
+
| **npx (local stdio)** — add to an IDE with one command | Daily use on your machine | browser `login`, a JWT, or none (reference tools) |
|
|
62
|
+
| **Remote HTTP (`serve`)** — run as a connector behind a URL | A hosted/shared server (e.g. Coolify) | per-request `x-webcake-jwt` header / `?jwt=` |
|
|
67
63
|
|
|
68
64
|
The **reference + generation tools** (`get_generation_guide`, `list_elements`, `validate_page`, …) work with **zero config**; only the **persistence tools** (`create_page`, `update_page`, `list_pages`, `get_page`, `list_organizations`) need a token. Credentials resolve in order: **per-request header → env var → saved `auth.json`** (`login`).
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Run the auto-install script — it handles everything: clone, install dependencies, build, and configure your IDE.
|
|
73
|
-
|
|
74
|
-
### macOS / Linux
|
|
75
|
-
|
|
76
|
-
If you already cloned the repo:
|
|
77
|
-
```bash
|
|
78
|
-
./install.sh
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Or download and run directly:
|
|
82
|
-
```bash
|
|
83
|
-
curl -fsSL https://raw.githubusercontent.com/vuluu2k/webcake-landing-mcp/main/install.sh -o install.sh && bash install.sh
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
The installer is interactive: it asks where to install (default `~/.webcake-landing-mcp`), prompts for
|
|
87
|
-
the env vars (`WEBCAKE_API_BASE`, `WEBCAKE_JWT`, `WEBCAKE_ORG_ID` — all optional, Enter to skip), then
|
|
88
|
-
lets you pick which IDE(s) to configure: `claude-desktop`, `claude-code`, `cursor`, `windsurf`, `augment`,
|
|
89
|
-
`codex`, or all.
|
|
66
|
+
> 🛠️ Prefer a shell-script installer (`install.sh`/`install.ps1`), a cloned local build, or hand-written per-IDE config? See **[docs/manual-install.md](docs/manual-install.md)**.
|
|
90
67
|
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
./install.sh --uninstall
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Windows (PowerShell)
|
|
97
|
-
|
|
98
|
-
If you already cloned the repo:
|
|
99
|
-
```powershell
|
|
100
|
-
.\install.ps1
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Or download and run directly:
|
|
104
|
-
```powershell
|
|
105
|
-
irm https://raw.githubusercontent.com/vuluu2k/webcake-landing-mcp/main/install.ps1 -OutFile install.ps1; .\install.ps1
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Uninstall:
|
|
109
|
-
```powershell
|
|
110
|
-
.\install.ps1 --uninstall
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
## Update
|
|
116
|
-
|
|
117
|
-
Update to the latest version:
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
cd ~/.webcake-landing-mcp # or wherever you installed it
|
|
121
|
-
git pull
|
|
122
|
-
npm install
|
|
123
|
-
npm run build
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Then restart your IDE.
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## Run without cloning (npx)
|
|
68
|
+
## Install (npx)
|
|
131
69
|
|
|
132
70
|
Once published to npm, the server runs straight from the registry — no clone, no build:
|
|
133
71
|
|
|
@@ -143,18 +81,18 @@ npx -y github:vuluu2k/webcake-landing-mcp
|
|
|
143
81
|
|
|
144
82
|
### Auto-configure your IDE (`install` subcommand)
|
|
145
83
|
|
|
146
|
-
`npx` only **runs** the server — unlike
|
|
147
|
-
config into your IDE. The bundled `install` subcommand does that step for you, no clone needed:
|
|
84
|
+
`npx` only **runs** the server — unlike the [shell installers](docs/manual-install.md), it does not
|
|
85
|
+
write the MCP config into your IDE. The bundled `install` subcommand does that step for you, no clone needed:
|
|
148
86
|
|
|
149
87
|
```bash
|
|
150
|
-
# Interactive —
|
|
88
|
+
# Interactive — pick environment, log in via browser (or paste a JWT), pick IDE(s)
|
|
151
89
|
npx -y webcake-landing-mcp install
|
|
152
90
|
|
|
153
|
-
# Non-interactive — configure every supported IDE at once
|
|
154
|
-
npx -y webcake-landing-mcp install --ide all --jwt <your-jwt>
|
|
91
|
+
# Non-interactive — configure every supported IDE at once (env + token via flags)
|
|
92
|
+
npx -y webcake-landing-mcp install --ide all --env prod --jwt <your-jwt>
|
|
155
93
|
|
|
156
|
-
#
|
|
157
|
-
npx -y webcake-landing-mcp install --ide cursor --jwt <your-jwt>
|
|
94
|
+
# Local dev — point at your local stack (localhost:5800 / :5173)
|
|
95
|
+
npx -y webcake-landing-mcp install --ide cursor --env local --jwt <your-jwt>
|
|
158
96
|
|
|
159
97
|
# Remove the server from every IDE config
|
|
160
98
|
npx -y webcake-landing-mcp uninstall
|
|
@@ -162,8 +100,10 @@ npx -y webcake-landing-mcp uninstall
|
|
|
162
100
|
|
|
163
101
|
It writes a `webcake-landing` entry (using the `npx` launch form below) into the right config file
|
|
164
102
|
for each target: `claude-desktop`, `claude-code`, `cursor`, `windsurf`, `augment` (VS Code), `codex`,
|
|
165
|
-
or `all`.
|
|
166
|
-
|
|
103
|
+
or `all`. Interactively it asks for the **environment** (`local`/`staging`/`prod`, which sets the API +
|
|
104
|
+
app URLs) and whether to **log in via the browser or paste a JWT**. Flags: `--ide`, `--env`, `--jwt`,
|
|
105
|
+
`--org-id`, `--api-base`/`--app-base` (advanced overrides), `--npx`/`--local`, `-y`. Run
|
|
106
|
+
`npx -y webcake-landing-mcp install --help` for the full list.
|
|
167
107
|
|
|
168
108
|
### Manual config
|
|
169
109
|
|
|
@@ -176,7 +116,7 @@ The MCP config is the same as the local one, but `command`/`args` point at `npx`
|
|
|
176
116
|
"command": "npx",
|
|
177
117
|
"args": ["-y", "webcake-landing-mcp"],
|
|
178
118
|
"env": {
|
|
179
|
-
"
|
|
119
|
+
"WEBCAKE_ENV": "prod",
|
|
180
120
|
"WEBCAKE_JWT": "<your-jwt>"
|
|
181
121
|
}
|
|
182
122
|
}
|
|
@@ -219,10 +159,10 @@ via headers, so a hosted server is multi-user and never bakes in a shared secret
|
|
|
219
159
|
| Header | Maps to | Notes |
|
|
220
160
|
|--------|---------|-------|
|
|
221
161
|
| `x-webcake-jwt` (or `Authorization: Bearer <jwt>`) | `WEBCAKE_JWT` | the account token — sent per request |
|
|
162
|
+
| `x-webcake-env` | `WEBCAKE_ENV` | named environment (`local`/`staging`/`prod`) |
|
|
222
163
|
| `x-webcake-org-id` | `WEBCAKE_ORG_ID` | default org |
|
|
223
|
-
| `x-webcake-api-base` | `WEBCAKE_API_BASE` |
|
|
224
|
-
| `x-webcake-
|
|
225
|
-
| `x-webcake-app-base` | `WEBCAKE_APP_BASE` | editor/preview URL base |
|
|
164
|
+
| `x-webcake-api-base` | `WEBCAKE_API_BASE` | overrides the env preset's API base |
|
|
165
|
+
| `x-webcake-app-base` | `WEBCAKE_APP_BASE` | overrides the env preset's app base |
|
|
226
166
|
|
|
227
167
|
Any header that is absent falls back to the corresponding env var — so you can also run it **single-user**
|
|
228
168
|
by setting `WEBCAKE_API_BASE` + `WEBCAKE_JWT` in the host's env and keeping the URL private.
|
|
@@ -280,19 +220,6 @@ running `serve` server on your machine:
|
|
|
280
220
|
through the dialog, but the token appears in logs), or use a header-capable client (`mcp-remote --header …`),
|
|
281
221
|
or add **OAuth** (not implemented) for the cleanest flow.
|
|
282
222
|
|
|
283
|
-
## Manual Setup (local)
|
|
284
|
-
|
|
285
|
-
```bash
|
|
286
|
-
git clone https://github.com/vuluu2k/webcake-landing-mcp.git
|
|
287
|
-
cd webcake-landing-mcp
|
|
288
|
-
npm install # postinstall `prepare` builds dist/ automatically
|
|
289
|
-
npm run build # (re)build: tsc -> dist/ + copies src/**/*.json (page-schema.json) into dist/
|
|
290
|
-
npm run smoke # offline self-test of factory + validator (prints "ALL GOOD")
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
The reference/validation tools work with **zero config**. Env vars are only needed for the persistence
|
|
294
|
-
tools (`create_page`, `update_page`, `list_pages`, `get_page`, `list_organizations`).
|
|
295
|
-
|
|
296
223
|
## Connect once — grab your token automatically (`login`)
|
|
297
224
|
|
|
298
225
|
Instead of copying a JWT by hand, run:
|
|
@@ -301,7 +228,11 @@ Instead of copying a JWT by hand, run:
|
|
|
301
228
|
# Production — zero config (defaults: connect via webcake.io, API via api.webcake.io):
|
|
302
229
|
npx -y webcake-landing-mcp login
|
|
303
230
|
|
|
304
|
-
# Local dev —
|
|
231
|
+
# Local dev / staging — pick a named environment (see Environments below):
|
|
232
|
+
node dist/index.js login --env local # SPA :5173 + API :5800
|
|
233
|
+
node dist/index.js login --env staging # staging.webcake.io + api.staging.webcake.io
|
|
234
|
+
|
|
235
|
+
# …or point at custom URLs explicitly (these override --env):
|
|
305
236
|
node dist/index.js login \
|
|
306
237
|
--connect-url http://localhost:5173/mcp-connect \
|
|
307
238
|
--api-base http://localhost:5800
|
|
@@ -317,9 +248,8 @@ deployment (env vars still take precedence). The landing JWT lasts ~90 days, so
|
|
|
317
248
|
|
|
318
249
|
Two URLs, don't mix them up:
|
|
319
250
|
|
|
320
|
-
- **Connect page = the SPA** (`--connect-url`
|
|
321
|
-
|
|
322
|
-
`/mcp-connect`, defaulting to `https://webcake.io/mcp-connect`.
|
|
251
|
+
- **Connect page = the SPA** (`--connect-url`): derived from the `--env` app base + `/mcp-connect`
|
|
252
|
+
(`https://webcake.io/mcp-connect` for prod, `http://localhost:5173/mcp-connect` for local). Override with `--connect-url`.
|
|
323
253
|
- **API base = the backend** (`--api-base` / `WEBCAKE_API_BASE`): `https://api.webcake.io` in prod,
|
|
324
254
|
`http://localhost:5800` locally. Defaults to `https://api.webcake.io`.
|
|
325
255
|
|
|
@@ -346,12 +276,11 @@ flow can also be done entirely in the SPA, no backend route needed.)
|
|
|
346
276
|
|
|
347
277
|
| Variable | Required | Description |
|
|
348
278
|
|----------|----------|-------------|
|
|
349
|
-
| `
|
|
279
|
+
| `WEBCAKE_ENV` | No | Named environment: `local` \| `staging` \| `prod`. Fills in `WEBCAKE_API_BASE` + `WEBCAKE_APP_BASE` from a preset (see table below). Also settable with the `--env <name>` flag. Explicit vars win. |
|
|
280
|
+
| `WEBCAKE_API_BASE` | No* | Backend base URL, e.g. `http://localhost:5800`. Required to persist (or set `WEBCAKE_ENV`). |
|
|
350
281
|
| `WEBCAKE_JWT` | No* | Account JWT (dashboard auth). Required to persist — expires, refresh when needed. |
|
|
351
282
|
| `WEBCAKE_ORG_ID` | No | Default organization id for `create_page` (overridden by its `organization_id` arg). Omit → personal page. |
|
|
352
|
-
| `WEBCAKE_HOST` | No | Optional `Host` header (Phoenix routes by host, e.g. `builder.localhost`). |
|
|
353
283
|
| `WEBCAKE_APP_BASE` | No | Optional base used to build editor/preview URLs in the result. |
|
|
354
|
-
| `WEBCAKE_CONNECT_URL` | No | The SPA "connect" page for `login` (default `https://webcake.io/mcp-connect`; else `WEBCAKE_APP_BASE` + `/mcp-connect`). |
|
|
355
284
|
| `WEBCAKE_CONFIG_DIR` | No | Dir for the saved `auth.json` written by `login` (default `~/.webcake-landing-mcp`). |
|
|
356
285
|
|
|
357
286
|
> \* `WEBCAKE_API_BASE` and `WEBCAKE_JWT` are only needed for the persistence tools. The reference and
|
|
@@ -360,183 +289,44 @@ flow can also be done entirely in the SPA, no backend route needed.)
|
|
|
360
289
|
> Persisting writes a real page to whatever `WEBCAKE_API_BASE` points at, using the JWT as that account.
|
|
361
290
|
> Start against local/staging.
|
|
362
291
|
|
|
363
|
-
###
|
|
364
|
-
|
|
365
|
-
1. Open the WebCake builder dashboard and log in
|
|
366
|
-
2. Open DevTools (`F12` or `Cmd + Option + I`)
|
|
367
|
-
3. Go to the **Network** tab > click any page
|
|
368
|
-
4. Find an API request (e.g. `@me`, `organizations`…)
|
|
369
|
-
5. In **Request Headers**, copy the value after `Authorization: Bearer ` → this is your `WEBCAKE_JWT`
|
|
370
|
-
6. Use the `list_organizations` tool to list orgs and pick `WEBCAKE_ORG_ID`
|
|
371
|
-
|
|
372
|
-
---
|
|
373
|
-
|
|
374
|
-
## Configuration by IDE / AI Tool
|
|
292
|
+
### Environments (`--env` / `WEBCAKE_ENV`)
|
|
375
293
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
> Run `npm run build` first so `dist/` exists.
|
|
294
|
+
Instead of setting both base URLs by hand, pick a named environment — one source of
|
|
295
|
+
truth for the API + app bases:
|
|
379
296
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
386
|
-
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
387
|
-
|
|
388
|
-
```json
|
|
389
|
-
{
|
|
390
|
-
"mcpServers": {
|
|
391
|
-
"webcake-landing": {
|
|
392
|
-
"command": "node",
|
|
393
|
-
"args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
|
|
394
|
-
"env": {
|
|
395
|
-
"WEBCAKE_API_BASE": "http://localhost:5800",
|
|
396
|
-
"WEBCAKE_JWT": "<your-jwt>",
|
|
397
|
-
"WEBCAKE_HOST": "builder.localhost",
|
|
398
|
-
"WEBCAKE_APP_BASE": "http://builder.localhost:5800"
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
Restart Claude Desktop. The MCP tools will appear in the chat input (hammer icon).
|
|
406
|
-
|
|
407
|
-
---
|
|
408
|
-
|
|
409
|
-
### 2. Claude Code (CLI)
|
|
410
|
-
|
|
411
|
-
Run in terminal — **local** build:
|
|
297
|
+
| `--env` / `WEBCAKE_ENV` | API base (`WEBCAKE_API_BASE`) | App base (`WEBCAKE_APP_BASE`) |
|
|
298
|
+
|-------------------------|-------------------------------|-------------------------------|
|
|
299
|
+
| `local` | `http://localhost:5800` | `http://localhost:5173` |
|
|
300
|
+
| `staging` | `https://api.staging.webcake.io` | `https://staging.webcake.io` |
|
|
301
|
+
| `prod` | `https://api.webcake.io` | `https://webcake.io` |
|
|
412
302
|
|
|
413
303
|
```bash
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
-e WEBCAKE_HOST=builder.localhost \
|
|
418
|
-
-- node /absolute-path/webcake-landing-mcp/dist/index.js
|
|
304
|
+
node dist/index.js serve --env staging # remote server on the staging backend
|
|
305
|
+
node dist/index.js login --env local # connect against your local SPA + API
|
|
306
|
+
WEBCAKE_ENV=prod node dist/index.js # stdio, prod (env var form)
|
|
419
307
|
```
|
|
420
308
|
|
|
421
|
-
|
|
309
|
+
Explicit `WEBCAKE_API_BASE` / `WEBCAKE_APP_BASE` (or `--api-base`) still override the
|
|
310
|
+
preset, field by field. On the remote HTTP server a client can override the server's
|
|
311
|
+
environment per request with the **`x-webcake-env`** header or **`?env=`** query
|
|
312
|
+
(e.g. `…/mcp?jwt=<token>&env=staging`) — so one server can serve multiple environments.
|
|
422
313
|
|
|
423
|
-
|
|
424
|
-
claude mcp add webcake-landing \
|
|
425
|
-
-e WEBCAKE_API_BASE=http://localhost:5800 \
|
|
426
|
-
-e WEBCAKE_JWT=<your-jwt> \
|
|
427
|
-
-- npx -y webcake-landing-mcp
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
Or create `.claude.json` at project root (or `~/.claude.json` globally):
|
|
431
|
-
|
|
432
|
-
```json
|
|
433
|
-
{
|
|
434
|
-
"mcpServers": {
|
|
435
|
-
"webcake-landing": {
|
|
436
|
-
"command": "node",
|
|
437
|
-
"args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
|
|
438
|
-
"env": {
|
|
439
|
-
"WEBCAKE_API_BASE": "http://localhost:5800",
|
|
440
|
-
"WEBCAKE_JWT": "<your-jwt>"
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
Verify:
|
|
448
|
-
```bash
|
|
449
|
-
claude mcp list
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
---
|
|
453
|
-
|
|
454
|
-
### 3. Cursor
|
|
455
|
-
|
|
456
|
-
Create `.cursor/mcp.json` at project root (or `~/.cursor/mcp.json` globally):
|
|
457
|
-
|
|
458
|
-
```json
|
|
459
|
-
{
|
|
460
|
-
"mcpServers": {
|
|
461
|
-
"webcake-landing": {
|
|
462
|
-
"command": "node",
|
|
463
|
-
"args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
|
|
464
|
-
"env": {
|
|
465
|
-
"WEBCAKE_API_BASE": "http://localhost:5800",
|
|
466
|
-
"WEBCAKE_JWT": "<your-jwt>"
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
Restart Cursor and check Settings > MCP Servers for **"Connected"** status.
|
|
474
|
-
|
|
475
|
-
---
|
|
476
|
-
|
|
477
|
-
### 4. Windsurf
|
|
478
|
-
|
|
479
|
-
Create `~/.codeium/windsurf/mcp_config.json`:
|
|
480
|
-
|
|
481
|
-
```json
|
|
482
|
-
{
|
|
483
|
-
"mcpServers": {
|
|
484
|
-
"webcake-landing": {
|
|
485
|
-
"command": "node",
|
|
486
|
-
"args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
|
|
487
|
-
"env": {
|
|
488
|
-
"WEBCAKE_API_BASE": "http://localhost:5800",
|
|
489
|
-
"WEBCAKE_JWT": "<your-jwt>"
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
Restart Windsurf. Type `@` in Cascade chat to see `webcake-landing` tools.
|
|
497
|
-
|
|
498
|
-
---
|
|
499
|
-
|
|
500
|
-
### 5. Augment (VS Code Extension)
|
|
501
|
-
|
|
502
|
-
Open Command Palette: `Cmd + Shift + P` > **"Augment: Edit MCP Settings"**, then add:
|
|
503
|
-
|
|
504
|
-
```json
|
|
505
|
-
{
|
|
506
|
-
"mcpServers": {
|
|
507
|
-
"webcake-landing": {
|
|
508
|
-
"command": "node",
|
|
509
|
-
"args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
|
|
510
|
-
"env": {
|
|
511
|
-
"WEBCAKE_API_BASE": "http://localhost:5800",
|
|
512
|
-
"WEBCAKE_JWT": "<your-jwt>"
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
```
|
|
314
|
+
### How to get `WEBCAKE_JWT`
|
|
518
315
|
|
|
519
|
-
|
|
316
|
+
1. Open the WebCake builder dashboard and log in
|
|
317
|
+
2. Open DevTools (`F12` or `Cmd + Option + I`)
|
|
318
|
+
3. Go to the **Network** tab > click any page
|
|
319
|
+
4. Find an API request (e.g. `@me`, `organizations`…)
|
|
320
|
+
5. In **Request Headers**, copy the value after `Authorization: Bearer ` → this is your `WEBCAKE_JWT`
|
|
321
|
+
6. Use the `list_organizations` tool to list orgs and pick `WEBCAKE_ORG_ID`
|
|
520
322
|
|
|
521
323
|
---
|
|
522
324
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
Add to `~/.codex/config.toml`:
|
|
526
|
-
|
|
527
|
-
```toml
|
|
528
|
-
[mcp_servers.webcake-landing]
|
|
529
|
-
command = "node"
|
|
530
|
-
args = ["/absolute-path/webcake-landing-mcp/dist/index.js"]
|
|
531
|
-
env = { "WEBCAKE_API_BASE" = "http://localhost:5800", "WEBCAKE_JWT" = "<your-jwt>" }
|
|
532
|
-
```
|
|
325
|
+
## Per-IDE config
|
|
533
326
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
---
|
|
327
|
+
The npx **`install`** subcommand (above) writes the right config for each IDE automatically. For
|
|
328
|
+
hand-written config (Claude Desktop, Claude Code, Cursor, Windsurf, Augment, Codex) and the
|
|
329
|
+
cloned-build variants, see **[docs/manual-install.md](docs/manual-install.md#configuration-by-ide--ai-tool)**.
|
|
540
330
|
|
|
541
331
|
## Usage Examples
|
|
542
332
|
|
package/README.vi.md
CHANGED
|
@@ -55,79 +55,18 @@ element/trang hợp lệ, bộ kiểm tra trang, và các tool để tạo/sửa
|
|
|
55
55
|
`{ page, popup, settings, options, cartConfigs }`; `create_page` lưu nó (chỉ-source — trang mở trong editor,
|
|
56
56
|
lưu lại sẽ render).
|
|
57
57
|
|
|
58
|
-
##
|
|
58
|
+
## Hai cách chạy
|
|
59
59
|
|
|
60
|
-
|
|
|
61
|
-
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
| 3 | **Remote HTTP (`serve`)** — chạy như HTTP server, test bằng MCP Inspector / `mcp-remote` / curl | Thử transport remote ở local | header `x-webcake-jwt` mỗi request, hoặc env | [Remote](#chạy-như-remote-connector-streamable-http) |
|
|
65
|
-
| 4 | **VPS + claude.ai connector** — deploy HTTPS public, thêm làm custom connector | Chia sẻ 1 server hosted | single-account (token env); per-user cần OAuth (chưa có) | [Deploy lên VPS](#deploy-lên-vps) |
|
|
66
|
-
|
|
67
|
-
Hai **dạng chạy** áp dụng cho mọi cách: **`npx -y webcake-landing-mcp …`** (không clone, tự cập nhật) hoặc **`node /abs/path/dist/index.js …`** (bản đã clone & build — chạy `npm run build` trước). Cấu hình IDE bên dưới dùng dạng local; đổi `command`/`args` sang dạng npx để dùng CDN.
|
|
60
|
+
| Cách | Hợp cho | Auth |
|
|
61
|
+
|------|---------|------|
|
|
62
|
+
| **npx (local stdio)** — gắn vào IDE bằng một lệnh | Dùng hằng ngày trên máy | browser `login`, JWT, hoặc không cần (tool tham chiếu) |
|
|
63
|
+
| **Remote HTTP (`serve`)** — chạy như connector sau một URL | Server hosted/chia sẻ (vd Coolify) | header `x-webcake-jwt` mỗi request / `?jwt=` |
|
|
68
64
|
|
|
69
65
|
Các **tool tham chiếu + generation** (`get_generation_guide`, `list_elements`, `validate_page`, …) chạy **zero config**; chỉ **tool lưu trữ** (`create_page`, `update_page`, `list_pages`, `get_page`, `list_organizations`) mới cần token. Token ưu tiên theo thứ tự: **header mỗi request → biến env → file `auth.json`** (`login`).
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
Chạy script tự cài — lo trọn gói: clone, cài dependencies, build, và cấu hình IDE của bạn.
|
|
74
|
-
|
|
75
|
-
### macOS / Linux
|
|
76
|
-
|
|
77
|
-
Nếu bạn đã clone repo:
|
|
78
|
-
```bash
|
|
79
|
-
./install.sh
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Hoặc tải & chạy trực tiếp:
|
|
83
|
-
```bash
|
|
84
|
-
curl -fsSL https://raw.githubusercontent.com/vuluu2k/webcake-landing-mcp/main/install.sh -o install.sh && bash install.sh
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Trình cài tương tác: hỏi nơi cài (mặc định `~/.webcake-landing-mcp`), hỏi các biến môi trường
|
|
88
|
-
(`WEBCAKE_API_BASE`, `WEBCAKE_JWT`, `WEBCAKE_ORG_ID` — đều tuỳ chọn, Enter để bỏ qua), rồi cho bạn chọn
|
|
89
|
-
IDE cần cấu hình: `claude-desktop`, `claude-code`, `cursor`, `windsurf`, `augment`, `codex`, hoặc tất cả.
|
|
67
|
+
> 🛠️ Cần script cài (install.sh/.ps1), build từ clone, hay cấu hình IDE thủ công? Xem **[docs/manual-install.vi.md](docs/manual-install.vi.md)**.
|
|
90
68
|
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
./install.sh --uninstall
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### Windows (PowerShell)
|
|
97
|
-
|
|
98
|
-
Nếu bạn đã clone repo:
|
|
99
|
-
```powershell
|
|
100
|
-
.\install.ps1
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Hoặc tải & chạy trực tiếp:
|
|
104
|
-
```powershell
|
|
105
|
-
irm https://raw.githubusercontent.com/vuluu2k/webcake-landing-mcp/main/install.ps1 -OutFile install.ps1; .\install.ps1
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Gỡ cài:
|
|
109
|
-
```powershell
|
|
110
|
-
.\install.ps1 --uninstall
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
## Cập nhật
|
|
116
|
-
|
|
117
|
-
Cập nhật lên bản mới nhất:
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
cd ~/.webcake-landing-mcp # hoặc nơi bạn đã cài
|
|
121
|
-
git pull
|
|
122
|
-
npm install
|
|
123
|
-
npm run build
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Rồi khởi động lại IDE.
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## Chạy không cần clone (npx)
|
|
69
|
+
## Cài đặt (npx)
|
|
131
70
|
|
|
132
71
|
Sau khi đã publish lên npm, server chạy thẳng từ registry — không clone, không build:
|
|
133
72
|
|
|
@@ -143,27 +82,29 @@ npx -y github:vuluu2k/webcake-landing-mcp
|
|
|
143
82
|
|
|
144
83
|
### Tự cấu hình IDE (lệnh con `install`)
|
|
145
84
|
|
|
146
|
-
`npx` chỉ **chạy** server — khác với
|
|
85
|
+
`npx` chỉ **chạy** server — khác với [script cài đặt](docs/manual-install.vi.md), nó không ghi cấu hình MCP vào IDE.
|
|
147
86
|
Lệnh con `install` đi kèm sẽ làm hộ bạn bước đó, không cần clone:
|
|
148
87
|
|
|
149
88
|
```bash
|
|
150
|
-
# Tương tác —
|
|
89
|
+
# Tương tác — chọn môi trường, đăng nhập qua trình duyệt (hoặc dán JWT), chọn IDE
|
|
151
90
|
npx -y webcake-landing-mcp install
|
|
152
91
|
|
|
153
|
-
# Không tương tác — cấu hình mọi IDE hỗ trợ cùng lúc
|
|
154
|
-
npx -y webcake-landing-mcp install --ide all --jwt <your-jwt>
|
|
92
|
+
# Không tương tác — cấu hình mọi IDE hỗ trợ cùng lúc (env + token qua cờ)
|
|
93
|
+
npx -y webcake-landing-mcp install --ide all --env prod --jwt <your-jwt>
|
|
155
94
|
|
|
156
|
-
#
|
|
157
|
-
npx -y webcake-landing-mcp install --ide cursor --jwt <your-jwt>
|
|
95
|
+
# Local dev — trỏ vào stack local của bạn (localhost:5800 / :5173)
|
|
96
|
+
npx -y webcake-landing-mcp install --ide cursor --env local --jwt <your-jwt>
|
|
158
97
|
|
|
159
98
|
# Gỡ server khỏi mọi cấu hình IDE
|
|
160
99
|
npx -y webcake-landing-mcp uninstall
|
|
161
100
|
```
|
|
162
101
|
|
|
163
102
|
Nó ghi entry `webcake-landing` (dùng dạng khởi chạy `npx` bên dưới) vào đúng file cấu hình của từng IDE:
|
|
164
|
-
`claude-desktop`, `claude-code`, `cursor`, `windsurf`, `augment` (VS Code), `codex`, hoặc `all`.
|
|
165
|
-
|
|
166
|
-
|
|
103
|
+
`claude-desktop`, `claude-code`, `cursor`, `windsurf`, `augment` (VS Code), `codex`, hoặc `all`. Khi tương
|
|
104
|
+
tác, nó hỏi **môi trường** (`local`/`staging`/`prod` — mặc định `prod`, dùng để đặt API + app URL) và cho
|
|
105
|
+
chọn **đăng nhập qua trình duyệt hay dán JWT**. Cờ: `--ide`, `--env`, `--jwt`, `--org-id`,
|
|
106
|
+
`--api-base`/`--app-base` (ghi đè nâng cao), `--npx`/`--local`, `-y`. Chạy
|
|
107
|
+
`npx -y webcake-landing-mcp install --help` để xem đầy đủ.
|
|
167
108
|
|
|
168
109
|
### Cấu hình thủ công
|
|
169
110
|
|
|
@@ -176,7 +117,7 @@ Cấu hình MCP giống bản local, chỉ khác `command`/`args` trỏ tới `n
|
|
|
176
117
|
"command": "npx",
|
|
177
118
|
"args": ["-y", "webcake-landing-mcp"],
|
|
178
119
|
"env": {
|
|
179
|
-
"
|
|
120
|
+
"WEBCAKE_ENV": "prod",
|
|
180
121
|
"WEBCAKE_JWT": "<your-jwt>"
|
|
181
122
|
}
|
|
182
123
|
}
|
|
@@ -219,9 +160,10 @@ nên server hosted là đa người dùng và không nhúng secret chung:
|
|
|
219
160
|
| Header | Tương ứng | Ghi chú |
|
|
220
161
|
|--------|-----------|---------|
|
|
221
162
|
| `x-webcake-jwt` (hoặc `Authorization: Bearer <jwt>`) | `WEBCAKE_JWT` | token tài khoản — gửi mỗi request |
|
|
163
|
+
| `x-webcake-env` | `WEBCAKE_ENV` | môi trường có tên (`local`/`staging`/`prod`) |
|
|
222
164
|
| `x-webcake-org-id` | `WEBCAKE_ORG_ID` | org mặc định |
|
|
223
|
-
| `x-webcake-api-base` | `WEBCAKE_API_BASE` |
|
|
224
|
-
| `x-webcake-app-base` | `WEBCAKE_APP_BASE` | base
|
|
165
|
+
| `x-webcake-api-base` | `WEBCAKE_API_BASE` | ghi đè API base của preset |
|
|
166
|
+
| `x-webcake-app-base` | `WEBCAKE_APP_BASE` | ghi đè app base của preset |
|
|
225
167
|
|
|
226
168
|
Header nào thiếu thì fallback về biến env tương ứng — nên cũng chạy **một người dùng** được bằng cách đặt
|
|
227
169
|
`WEBCAKE_API_BASE` + `WEBCAKE_JWT` trong env của host và giữ URL riêng tư.
|
|
@@ -278,19 +220,6 @@ chạy trên máy:
|
|
|
278
220
|
nhưng token lộ trong log), hoặc dùng client hỗ trợ header (`mcp-remote --header …`), hoặc thêm **OAuth**
|
|
279
221
|
(chưa làm) cho gọn nhất.
|
|
280
222
|
|
|
281
|
-
## Cài thủ công (local)
|
|
282
|
-
|
|
283
|
-
```bash
|
|
284
|
-
git clone https://github.com/vuluu2k/webcake-landing-mcp.git
|
|
285
|
-
cd webcake-landing-mcp
|
|
286
|
-
npm install # postinstall `prepare` tự build dist/
|
|
287
|
-
npm run build # (re)build: tsc -> dist/ + copy src/**/*.json (page-schema.json) vào dist/
|
|
288
|
-
npm run smoke # self-test offline của factory + validator (in "ALL GOOD")
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
Các tool tham chiếu/kiểm tra chạy với **zero config**. Biến môi trường chỉ cần cho các tool lưu trữ
|
|
292
|
-
(`create_page`, `update_page`, `list_pages`, `get_page`, `list_organizations`).
|
|
293
|
-
|
|
294
223
|
## Kết nối một lần — tự lấy token (`login`)
|
|
295
224
|
|
|
296
225
|
Thay vì copy JWT bằng tay, chạy:
|
|
@@ -315,9 +244,8 @@ ngày nên hiếm khi phải kết nối lại.
|
|
|
315
244
|
|
|
316
245
|
Hai URL, đừng nhầm:
|
|
317
246
|
|
|
318
|
-
- **Trang connect = SPA** (`--connect-url`
|
|
319
|
-
`http://localhost:5173/mcp-connect` ở local.
|
|
320
|
-
mặc định `https://webcake.io/mcp-connect`.
|
|
247
|
+
- **Trang connect = SPA** (`--connect-url`): suy ra từ app base của `--env` + `/mcp-connect`
|
|
248
|
+
(`https://webcake.io/mcp-connect` ở prod, `http://localhost:5173/mcp-connect` ở local). Ghi đè bằng `--connect-url`.
|
|
321
249
|
- **API base = backend** (`--api-base` / `WEBCAKE_API_BASE`): `https://api.webcake.io` ở prod,
|
|
322
250
|
`http://localhost:5800` ở local. Mặc định `https://api.webcake.io`.
|
|
323
251
|
|
|
@@ -344,12 +272,11 @@ SPA cũng được, khỏi cần route backend.)
|
|
|
344
272
|
|
|
345
273
|
| Biến | Bắt buộc | Mô tả |
|
|
346
274
|
|----------|----------|-------------|
|
|
347
|
-
| `
|
|
275
|
+
| `WEBCAKE_ENV` | Không | Môi trường có tên: `local` \| `staging` \| `prod`. Điền sẵn `WEBCAKE_API_BASE` + `WEBCAKE_APP_BASE` từ preset (xem bảng bên dưới). Cũng đặt được qua cờ `--env <name>`. Biến tường minh sẽ thắng. |
|
|
276
|
+
| `WEBCAKE_API_BASE` | Không* | Base URL backend, ví dụ `http://localhost:5800`. Cần để lưu trang (hoặc đặt `WEBCAKE_ENV`). |
|
|
348
277
|
| `WEBCAKE_JWT` | Không* | JWT tài khoản (auth dashboard). Cần để lưu trang — sẽ hết hạn, làm mới khi cần. |
|
|
349
278
|
| `WEBCAKE_ORG_ID` | Không | Organization mặc định cho `create_page` (bị ghi đè bởi tham số `organization_id`). Bỏ trống → trang cá nhân. |
|
|
350
|
-
| `WEBCAKE_HOST` | Không | Header `Host` tuỳ chọn (Phoenix route theo host, ví dụ `builder.localhost`). |
|
|
351
279
|
| `WEBCAKE_APP_BASE` | Không | Base tuỳ chọn để dựng URL editor/preview trong kết quả. |
|
|
352
|
-
| `WEBCAKE_CONNECT_URL` | Không | Trang "connect" (SPA) cho `login` (mặc định `https://webcake.io/mcp-connect`; nếu không thì `WEBCAKE_APP_BASE` + `/mcp-connect`). |
|
|
353
280
|
| `WEBCAKE_CONFIG_DIR` | Không | Thư mục chứa `auth.json` do `login` ghi (mặc định `~/.webcake-landing-mcp`). |
|
|
354
281
|
|
|
355
282
|
> \* `WEBCAKE_API_BASE` và `WEBCAKE_JWT` chỉ cần cho các tool lưu trữ. Các tool tham chiếu và kiểm tra
|
|
@@ -358,183 +285,42 @@ SPA cũng được, khỏi cần route backend.)
|
|
|
358
285
|
> Lưu trang sẽ ghi một trang thật vào nơi `WEBCAKE_API_BASE` trỏ tới, dùng JWT làm tài khoản đó.
|
|
359
286
|
> Hãy bắt đầu với local/staging.
|
|
360
287
|
|
|
361
|
-
###
|
|
362
|
-
|
|
363
|
-
1. Mở dashboard builder WebCake và đăng nhập
|
|
364
|
-
2. Mở DevTools (`F12` hoặc `Cmd + Option + I`)
|
|
365
|
-
3. Vào tab **Network** > click một trang bất kỳ
|
|
366
|
-
4. Tìm một request API (ví dụ `@me`, `organizations`…)
|
|
367
|
-
5. Trong **Request Headers**, copy giá trị sau `Authorization: Bearer ` → đó là `WEBCAKE_JWT`
|
|
368
|
-
6. Dùng tool `list_organizations` để liệt kê org và chọn `WEBCAKE_ORG_ID`
|
|
369
|
-
|
|
370
|
-
---
|
|
371
|
-
|
|
372
|
-
## Cấu hình theo IDE / công cụ AI
|
|
373
|
-
|
|
374
|
-
> Thay `/absolute-path/webcake-landing-mcp/dist/index.js` bên dưới bằng đường dẫn thật nơi bạn đã
|
|
375
|
-
> clone/build repo. Ví dụ: `/Users/username/webcake-landing-mcp/dist/index.js`.
|
|
376
|
-
> Chạy `npm run build` trước để `dist/` tồn tại.
|
|
377
|
-
|
|
378
|
-
### 1. Claude Desktop
|
|
379
|
-
|
|
380
|
-
Mở Settings > Developer > Edit Config, hoặc sửa file trực tiếp:
|
|
381
|
-
|
|
382
|
-
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
383
|
-
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
384
|
-
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
385
|
-
|
|
386
|
-
```json
|
|
387
|
-
{
|
|
388
|
-
"mcpServers": {
|
|
389
|
-
"webcake-landing": {
|
|
390
|
-
"command": "node",
|
|
391
|
-
"args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
|
|
392
|
-
"env": {
|
|
393
|
-
"WEBCAKE_API_BASE": "http://localhost:5800",
|
|
394
|
-
"WEBCAKE_JWT": "<your-jwt>",
|
|
395
|
-
"WEBCAKE_HOST": "builder.localhost",
|
|
396
|
-
"WEBCAKE_APP_BASE": "http://builder.localhost:5800"
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
Khởi động lại Claude Desktop. Các tool MCP sẽ hiện trong ô chat (biểu tượng búa).
|
|
404
|
-
|
|
405
|
-
---
|
|
406
|
-
|
|
407
|
-
### 2. Claude Code (CLI)
|
|
408
|
-
|
|
409
|
-
Chạy trong terminal — bản **local**:
|
|
410
|
-
|
|
411
|
-
```bash
|
|
412
|
-
claude mcp add webcake-landing \
|
|
413
|
-
-e WEBCAKE_API_BASE=http://localhost:5800 \
|
|
414
|
-
-e WEBCAKE_JWT=<your-jwt> \
|
|
415
|
-
-e WEBCAKE_HOST=builder.localhost \
|
|
416
|
-
-- node /absolute-path/webcake-landing-mcp/dist/index.js
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
Hoặc **CDN / npx** (không clone):
|
|
420
|
-
|
|
421
|
-
```bash
|
|
422
|
-
claude mcp add webcake-landing \
|
|
423
|
-
-e WEBCAKE_API_BASE=http://localhost:5800 \
|
|
424
|
-
-e WEBCAKE_JWT=<your-jwt> \
|
|
425
|
-
-- npx -y webcake-landing-mcp
|
|
426
|
-
```
|
|
288
|
+
### Môi trường (`--env` / `WEBCAKE_ENV`)
|
|
427
289
|
|
|
428
|
-
|
|
290
|
+
Thay vì đặt thủ công cả hai base URL, hãy chọn một môi trường có tên — một nguồn sự thật duy nhất
|
|
291
|
+
cho API + app base (mặc định là `prod`):
|
|
429
292
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
"args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
|
|
436
|
-
"env": {
|
|
437
|
-
"WEBCAKE_API_BASE": "http://localhost:5800",
|
|
438
|
-
"WEBCAKE_JWT": "<your-jwt>"
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
```
|
|
293
|
+
| `--env` / `WEBCAKE_ENV` | API base (`WEBCAKE_API_BASE`) | App base (`WEBCAKE_APP_BASE`) |
|
|
294
|
+
|-------------------------|-------------------------------|-------------------------------|
|
|
295
|
+
| `local` | `http://localhost:5800` | `http://localhost:5173` |
|
|
296
|
+
| `staging` | `https://api.staging.webcake.io` | `https://staging.webcake.io` |
|
|
297
|
+
| `prod` *(mặc định)* | `https://api.webcake.io` | `https://webcake.io` |
|
|
444
298
|
|
|
445
|
-
Kiểm tra:
|
|
446
299
|
```bash
|
|
447
|
-
|
|
300
|
+
node dist/index.js serve --env staging # server remote trỏ backend staging
|
|
301
|
+
node dist/index.js login --env local # đăng nhập vào SPA + API local
|
|
302
|
+
WEBCAKE_ENV=prod node dist/index.js # stdio, prod (dạng biến môi trường)
|
|
448
303
|
```
|
|
449
304
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
305
|
+
`WEBCAKE_API_BASE` / `WEBCAKE_APP_BASE` (hoặc `--api-base`) tường minh vẫn ghi đè preset theo từng
|
|
306
|
+
trường. Trên server HTTP remote, client có thể ghi đè môi trường của server theo từng request bằng
|
|
307
|
+
header **`x-webcake-env`** hoặc query **`?env=`** (ví dụ `…/mcp?jwt=<token>&env=staging`) — nên một
|
|
308
|
+
server phục vụ được nhiều môi trường.
|
|
453
309
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
```json
|
|
457
|
-
{
|
|
458
|
-
"mcpServers": {
|
|
459
|
-
"webcake-landing": {
|
|
460
|
-
"command": "node",
|
|
461
|
-
"args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
|
|
462
|
-
"env": {
|
|
463
|
-
"WEBCAKE_API_BASE": "http://localhost:5800",
|
|
464
|
-
"WEBCAKE_JWT": "<your-jwt>"
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
Khởi động lại Cursor và xem Settings > MCP Servers để thấy trạng thái **"Connected"**.
|
|
472
|
-
|
|
473
|
-
---
|
|
474
|
-
|
|
475
|
-
### 4. Windsurf
|
|
476
|
-
|
|
477
|
-
Tạo `~/.codeium/windsurf/mcp_config.json`:
|
|
478
|
-
|
|
479
|
-
```json
|
|
480
|
-
{
|
|
481
|
-
"mcpServers": {
|
|
482
|
-
"webcake-landing": {
|
|
483
|
-
"command": "node",
|
|
484
|
-
"args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
|
|
485
|
-
"env": {
|
|
486
|
-
"WEBCAKE_API_BASE": "http://localhost:5800",
|
|
487
|
-
"WEBCAKE_JWT": "<your-jwt>"
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
Khởi động lại Windsurf. Gõ `@` trong chat Cascade để thấy các tool `webcake-landing`.
|
|
495
|
-
|
|
496
|
-
---
|
|
497
|
-
|
|
498
|
-
### 5. Augment (Extension VS Code)
|
|
499
|
-
|
|
500
|
-
Mở Command Palette: `Cmd + Shift + P` > **"Augment: Edit MCP Settings"**, rồi thêm:
|
|
501
|
-
|
|
502
|
-
```json
|
|
503
|
-
{
|
|
504
|
-
"mcpServers": {
|
|
505
|
-
"webcake-landing": {
|
|
506
|
-
"command": "node",
|
|
507
|
-
"args": ["/absolute-path/webcake-landing-mcp/dist/index.js"],
|
|
508
|
-
"env": {
|
|
509
|
-
"WEBCAKE_API_BASE": "http://localhost:5800",
|
|
510
|
-
"WEBCAKE_JWT": "<your-jwt>"
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
```
|
|
310
|
+
### Cách lấy `WEBCAKE_JWT`
|
|
516
311
|
|
|
517
|
-
|
|
312
|
+
1. Mở dashboard builder WebCake và đăng nhập
|
|
313
|
+
2. Mở DevTools (`F12` hoặc `Cmd + Option + I`)
|
|
314
|
+
3. Vào tab **Network** > click một trang bất kỳ
|
|
315
|
+
4. Tìm một request API (ví dụ `@me`, `organizations`…)
|
|
316
|
+
5. Trong **Request Headers**, copy giá trị sau `Authorization: Bearer ` → đó là `WEBCAKE_JWT`
|
|
317
|
+
6. Dùng tool `list_organizations` để liệt kê org và chọn `WEBCAKE_ORG_ID`
|
|
518
318
|
|
|
519
319
|
---
|
|
520
320
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
Thêm vào `~/.codex/config.toml`:
|
|
524
|
-
|
|
525
|
-
```toml
|
|
526
|
-
[mcp_servers.webcake-landing]
|
|
527
|
-
command = "node"
|
|
528
|
-
args = ["/absolute-path/webcake-landing-mcp/dist/index.js"]
|
|
529
|
-
env = { "WEBCAKE_API_BASE" = "http://localhost:5800", "WEBCAKE_JWT" = "<your-jwt>" }
|
|
530
|
-
```
|
|
321
|
+
## Cấu hình theo IDE
|
|
531
322
|
|
|
532
|
-
|
|
533
|
-
```bash
|
|
534
|
-
codex mcp list
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
---
|
|
323
|
+
Lệnh con `install` của npx (xem trên) tự ghi cấu hình đúng cho từng IDE. Nếu muốn tự viết tay cấu hình cho Claude Desktop, Claude Code, Cursor, Windsurf, Augment, hay Codex — và cả dạng dùng file build từ clone — xem **[docs/manual-install.vi.md](docs/manual-install.vi.md#cấu-hình-theo-ide--công-cụ-ai)**.
|
|
538
324
|
|
|
539
325
|
## Ví dụ sử dụng
|
|
540
326
|
|
package/dist/auth/login.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* which the stdio/http server then reads automatically.
|
|
12
12
|
*
|
|
13
13
|
* Backend contract (added to landing_page_backend — owned by the user):
|
|
14
|
-
* GET
|
|
14
|
+
* GET <connect-url>?redirect_uri=<loopback>&state=<s> (connect-url = appBase + /mcp-connect)
|
|
15
15
|
* → read cookie `jwt` → 302 to <redirect_uri>?token=<jwt>&state=<s>
|
|
16
16
|
* (or 302 to the login page first, then back). Restrict redirect_uri to
|
|
17
17
|
* http://127.0.0.1:* / http://localhost:* for safety.
|
|
@@ -19,13 +19,7 @@
|
|
|
19
19
|
import { createServer } from "node:http";
|
|
20
20
|
import { randomBytes } from "node:crypto";
|
|
21
21
|
import { spawn } from "node:child_process";
|
|
22
|
-
import { saveSavedConfig } from "../persistence/config.js";
|
|
23
|
-
// Production defaults — the connect page lives on the SPA (webcake.io), the API
|
|
24
|
-
// lives on api.webcake.io. For local dev override with --connect-url / --api-base
|
|
25
|
-
// (e.g. http://localhost:5173/mcp-connect and http://localhost:5800) or the
|
|
26
|
-
// WEBCAKE_APP_BASE / WEBCAKE_API_BASE env vars.
|
|
27
|
-
const DEFAULT_CONNECT_URL = "https://webcake.io/mcp-connect";
|
|
28
|
-
const DEFAULT_API_BASE = "https://api.webcake.io";
|
|
22
|
+
import { saveSavedConfig, resolveEnv, ENVIRONMENTS } from "../persistence/config.js";
|
|
29
23
|
function parseArgs(argv) {
|
|
30
24
|
const get = (name) => {
|
|
31
25
|
const i = argv.indexOf(name);
|
|
@@ -53,21 +47,20 @@ function openBrowser(url) {
|
|
|
53
47
|
const SUCCESS_HTML = `<!doctype html><meta charset="utf-8"><title>Connected</title>
|
|
54
48
|
<body style="font-family:system-ui;text-align:center;padding:48px">
|
|
55
49
|
<h2>✓ Connected to Webcake</h2><p>You can close this tab and return to your terminal.</p></body>`;
|
|
56
|
-
function resolveConnectUrl(opts) {
|
|
50
|
+
function resolveConnectUrl(opts, appBase) {
|
|
57
51
|
if (opts.connectUrl)
|
|
58
|
-
return opts.connectUrl;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// The connect page is on the SPA (WEBCAKE_APP_BASE), NOT the API base.
|
|
62
|
-
const appBase = process.env.WEBCAKE_APP_BASE;
|
|
63
|
-
if (appBase)
|
|
64
|
-
return `${appBase.replace(/\/+$/, "")}/mcp-connect`;
|
|
65
|
-
return DEFAULT_CONNECT_URL;
|
|
52
|
+
return opts.connectUrl; // explicit --connect-url override
|
|
53
|
+
// The connect page is on the SPA (appBase, from the env preset), NOT the API base.
|
|
54
|
+
return `${appBase.replace(/\/+$/, "")}/mcp-connect`;
|
|
66
55
|
}
|
|
67
56
|
export async function runLogin(argv) {
|
|
68
57
|
const opts = parseArgs(argv);
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
// Named environment (set by the global --env flag / WEBCAKE_ENV); prod is the
|
|
59
|
+
// zero-config default. Explicit --api-base / WEBCAKE_APP_BASE still win per field.
|
|
60
|
+
const preset = resolveEnv(process.env.WEBCAKE_ENV) ?? ENVIRONMENTS.prod;
|
|
61
|
+
const apiBase = opts.apiBase || process.env.WEBCAKE_API_BASE || preset.apiBase;
|
|
62
|
+
const appBase = process.env.WEBCAKE_APP_BASE || preset.appBase;
|
|
63
|
+
const connectUrl = resolveConnectUrl(opts, appBase);
|
|
71
64
|
const state = randomBytes(16).toString("hex");
|
|
72
65
|
await new Promise((resolve, reject) => {
|
|
73
66
|
const server = createServer((req, res) => {
|
|
@@ -83,15 +76,13 @@ export async function runLogin(argv) {
|
|
|
83
76
|
}
|
|
84
77
|
const path = saveSavedConfig({
|
|
85
78
|
jwt: token,
|
|
86
|
-
|
|
79
|
+
base: apiBase.replace(/\/+$/, ""),
|
|
80
|
+
appBase: appBase.replace(/\/+$/, ""),
|
|
87
81
|
...(opts.orgId ? { orgId: opts.orgId } : {}),
|
|
88
82
|
savedAt: new Date().toISOString(),
|
|
89
83
|
});
|
|
90
84
|
res.writeHead(200, { "content-type": "text/html" }).end(SUCCESS_HTML);
|
|
91
|
-
console.error(`\n✓ Connected. Token saved to ${path}
|
|
92
|
-
if (!apiBase) {
|
|
93
|
-
console.error(" tip: also set WEBCAKE_API_BASE (or pass --api-base) so the server knows the backend URL.");
|
|
94
|
-
}
|
|
85
|
+
console.error(`\n✓ Connected. Token saved to ${path} (api ${apiBase}).`);
|
|
95
86
|
server.close();
|
|
96
87
|
resolve();
|
|
97
88
|
});
|
package/dist/http.js
CHANGED
|
@@ -39,9 +39,9 @@ async function readBody(req) {
|
|
|
39
39
|
// require HTTPS, and disable query-string logging on your reverse proxy.
|
|
40
40
|
const QUERY_AUTH = {
|
|
41
41
|
jwt: "x-webcake-jwt",
|
|
42
|
+
env: "x-webcake-env",
|
|
42
43
|
api_base: "x-webcake-api-base",
|
|
43
44
|
org_id: "x-webcake-org-id",
|
|
44
|
-
host: "x-webcake-host",
|
|
45
45
|
app_base: "x-webcake-app-base",
|
|
46
46
|
};
|
|
47
47
|
function applyQueryAuth(req) {
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,40 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
19
19
|
import { createServer } from "./server.js";
|
|
20
|
+
import { ENVIRONMENTS, ENV_NAMES, isEnvName } from "./persistence/config.js";
|
|
21
|
+
/**
|
|
22
|
+
* Global `--env <local|staging|prod>` flag (or `--env=<name>`): selects the API +
|
|
23
|
+
* app base URLs from a named preset by setting WEBCAKE_ENV, which readConfig + login
|
|
24
|
+
* then pick up. Explicit WEBCAKE_API_BASE / WEBCAKE_APP_BASE still win. An unknown
|
|
25
|
+
* value from the flag fails fast; an unknown WEBCAKE_ENV is dropped so explicit
|
|
26
|
+
* bases (or per-request headers) still resolve. stderr only — stdout is the MCP channel.
|
|
27
|
+
*/
|
|
28
|
+
function applyEnvFlag(argv) {
|
|
29
|
+
let fromFlag;
|
|
30
|
+
for (let i = 2; i < argv.length; i++) {
|
|
31
|
+
const a = argv[i];
|
|
32
|
+
if (a === "--env")
|
|
33
|
+
fromFlag = argv[i + 1];
|
|
34
|
+
else if (a.startsWith("--env="))
|
|
35
|
+
fromFlag = a.slice("--env=".length);
|
|
36
|
+
}
|
|
37
|
+
const name = fromFlag ?? process.env.WEBCAKE_ENV;
|
|
38
|
+
if (!name)
|
|
39
|
+
return;
|
|
40
|
+
if (!isEnvName(name)) {
|
|
41
|
+
console.error(`[webcake] unknown environment "${name}". Valid: ${ENV_NAMES.join(", ")}.`);
|
|
42
|
+
if (fromFlag)
|
|
43
|
+
process.exit(1); // explicit flag typo → fail fast
|
|
44
|
+
delete process.env.WEBCAKE_ENV; // bad WEBCAKE_ENV → ignore, fall through to explicit bases
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
process.env.WEBCAKE_ENV = name;
|
|
48
|
+
const p = ENVIRONMENTS[name];
|
|
49
|
+
console.error(`[webcake] environment "${name}" — api ${p.apiBase}, app ${p.appBase}`);
|
|
50
|
+
}
|
|
20
51
|
async function main() {
|
|
52
|
+
// Resolve the named environment (--env / WEBCAKE_ENV) before any config is read.
|
|
53
|
+
applyEnvFlag(process.argv);
|
|
21
54
|
// Subcommand dispatch: `webcake-landing-mcp install|uninstall` runs the
|
|
22
55
|
// bundled IDE installer instead of starting the MCP server. Default (no
|
|
23
56
|
// subcommand) starts the stdio server as usual.
|
package/dist/install.js
CHANGED
|
@@ -22,6 +22,8 @@ import { dirname, join } from "node:path";
|
|
|
22
22
|
import { fileURLToPath } from "node:url";
|
|
23
23
|
import { spawnSync } from "node:child_process";
|
|
24
24
|
import { createInterface } from "node:readline";
|
|
25
|
+
import { ENVIRONMENTS, isEnvName } from "./persistence/config.js";
|
|
26
|
+
import { runLogin } from "./auth/login.js";
|
|
25
27
|
const NAME = "webcake-landing";
|
|
26
28
|
const PKG = "webcake-landing-mcp";
|
|
27
29
|
const HOME = homedir();
|
|
@@ -63,8 +65,6 @@ function parseArgs(argv) {
|
|
|
63
65
|
o.jwt = next();
|
|
64
66
|
else if (a.startsWith("--org-id") || a.startsWith("--org"))
|
|
65
67
|
o.orgId = next();
|
|
66
|
-
else if (a.startsWith("--host"))
|
|
67
|
-
o.host = next();
|
|
68
68
|
else if (a.startsWith("--app-base"))
|
|
69
69
|
o.appBase = next();
|
|
70
70
|
else if (a === "--help" || a === "-h")
|
|
@@ -290,18 +290,18 @@ function printHelp() {
|
|
|
290
290
|
${c.bold}webcake-landing-mcp install${c.reset} — configure the MCP server in your IDE(s)
|
|
291
291
|
|
|
292
292
|
${c.bold}Usage${c.reset}
|
|
293
|
-
npx -y ${PKG} install # interactive (
|
|
294
|
-
npx -y ${PKG} install --ide all # non-interactive, all IDEs
|
|
295
|
-
npx -y ${PKG} install --ide claude-code --jwt <JWT>
|
|
293
|
+
npx -y ${PKG} install # interactive: pick environment, log in (or paste a JWT), pick IDEs
|
|
294
|
+
npx -y ${PKG} install --ide all # non-interactive, all IDEs (defaults to --env prod)
|
|
295
|
+
npx -y ${PKG} install --ide claude-code --env local --jwt <JWT>
|
|
296
296
|
npx -y ${PKG} uninstall # remove from every IDE config
|
|
297
297
|
|
|
298
298
|
${c.bold}Flags${c.reset}
|
|
299
299
|
--ide <list> comma list: claude-desktop, claude-code, cursor, windsurf, augment, codex, all
|
|
300
|
-
--
|
|
301
|
-
--jwt <token> WEBCAKE_JWT (account token; optional
|
|
302
|
-
--org-id <id> WEBCAKE_ORG_ID (optional)
|
|
303
|
-
--
|
|
304
|
-
--app-base <url>
|
|
300
|
+
--env <name> WEBCAKE_ENV: local | staging | prod (default prod) — sets the API + app base URLs
|
|
301
|
+
--jwt <token> WEBCAKE_JWT (account token; optional — or log in via the browser interactively)
|
|
302
|
+
--org-id <id> WEBCAKE_ORG_ID (optional default organization)
|
|
303
|
+
--api-base <url> override the --env API base (advanced)
|
|
304
|
+
--app-base <url> override the --env app base (advanced)
|
|
305
305
|
--npx | --local force the launch command form (default: auto-detect)
|
|
306
306
|
-y, --yes accept defaults, skip confirmations
|
|
307
307
|
--uninstall remove the server from all IDE configs
|
|
@@ -317,36 +317,70 @@ export async function runInstaller(argv) {
|
|
|
317
317
|
log(`\n${c.cyan}${c.bold}Webcake Landing MCP — installer${c.reset}`);
|
|
318
318
|
log(`${c.gray}Build & edit Webcake landing pages from a prompt. 12 tools.${c.reset}`);
|
|
319
319
|
const interactive = !o.ide && process.stdin.isTTY && process.stdout.isTTY;
|
|
320
|
-
// 1)
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
let
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
log(
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
320
|
+
// 1) environment — one choice sets the API + app base URLs (replaces the old
|
|
321
|
+
// separate WEBCAKE_API_BASE / WEBCAKE_APP_BASE prompts). The global --env flag
|
|
322
|
+
// / WEBCAKE_ENV is already validated in index.ts (applyEnvFlag).
|
|
323
|
+
let envName = isEnvName(process.env.WEBCAKE_ENV) ? process.env.WEBCAKE_ENV : "prod";
|
|
324
|
+
if (interactive && !isEnvName(process.env.WEBCAKE_ENV)) {
|
|
325
|
+
log(`\n${c.bold}1) Environment${c.reset} ${c.gray}(sets the Webcake API + app URLs)${c.reset}`);
|
|
326
|
+
log(` 1) prod ${c.gray}${ENVIRONMENTS.prod.apiBase}${c.reset} ${c.gray}(default)${c.reset}`);
|
|
327
|
+
log(` 2) staging ${c.gray}${ENVIRONMENTS.staging.apiBase}${c.reset}`);
|
|
328
|
+
log(` 3) local ${c.gray}${ENVIRONMENTS.local.apiBase}${c.reset}`);
|
|
329
|
+
const pick = (await ask(" Select [1=prod, Enter to accept]: ")).trim();
|
|
330
|
+
envName = { "1": "prod", "2": "staging", "3": "local" }[pick] ?? "prod";
|
|
331
|
+
}
|
|
332
|
+
process.env.WEBCAKE_ENV = envName; // so `login` below connects to the same environment
|
|
333
|
+
const preset = ENVIRONMENTS[envName];
|
|
334
|
+
// 2) authentication — interactively ASK how to authenticate: browser login (token
|
|
335
|
+
// saved to ~/.webcake-landing-mcp/auth.json) or a pasted JWT. An explicit --jwt
|
|
336
|
+
// skips the prompt; a non-TTY falls back to the WEBCAKE_JWT env var (for scripted
|
|
337
|
+
// installs). Reference/validation tools work with no auth at all.
|
|
338
|
+
let jwt = o.jwt ?? "";
|
|
339
|
+
let authNote = jwt ? "JWT (from --jwt)" : "";
|
|
340
|
+
if (interactive && !jwt) {
|
|
341
|
+
log(`\n${c.bold}2) Authentication${c.reset} ${c.gray}(only needed to save pages to your account)${c.reset}`);
|
|
342
|
+
log(` 1) Log in via browser ${c.gray}(recommended — opens Webcake, saves a token)${c.reset}`);
|
|
343
|
+
log(` 2) Paste a JWT token`);
|
|
344
|
+
log(` 3) Skip for now ${c.gray}(reference/validation tools still work)${c.reset}`);
|
|
345
|
+
const pick = (await ask(" Select [1]: ")).trim() || "1";
|
|
346
|
+
if (pick === "1") {
|
|
347
|
+
info(`Connecting to ${preset.appBase} …`);
|
|
348
|
+
try {
|
|
349
|
+
await runLogin([]); // reads WEBCAKE_ENV for the connect URL + API base; saves auth.json
|
|
350
|
+
authNote = "browser login (saved to auth.json)";
|
|
351
|
+
}
|
|
352
|
+
catch (e) {
|
|
353
|
+
warn(`Login didn't complete (${e?.message ?? e}). Paste a JWT now, or run \`${PKG} login\` later.`);
|
|
354
|
+
jwt = (await ask(" WEBCAKE_JWT (or Enter to skip): ")).trim();
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else if (pick === "2") {
|
|
358
|
+
jwt = (await ask(" WEBCAKE_JWT: ")).trim();
|
|
359
|
+
}
|
|
335
360
|
}
|
|
336
|
-
else if (!
|
|
337
|
-
|
|
361
|
+
else if (!interactive) {
|
|
362
|
+
jwt = jwt || process.env.WEBCAKE_JWT || ""; // scripted / CI: fall back to ambient env
|
|
363
|
+
}
|
|
364
|
+
if (!authNote)
|
|
365
|
+
authNote = jwt ? "JWT" : "none — reference tools only";
|
|
366
|
+
// 3) optional default organization for create_page
|
|
367
|
+
let orgId = o.orgId ?? process.env.WEBCAKE_ORG_ID ?? "";
|
|
368
|
+
if (interactive && !orgId) {
|
|
369
|
+
orgId = (await ask(`\n${c.bold}3) WEBCAKE_ORG_ID${c.reset} ${c.gray}(optional, Enter to skip): ${c.reset}`)).trim();
|
|
338
370
|
}
|
|
339
|
-
|
|
340
|
-
|
|
371
|
+
// env block written into IDE configs: WEBCAKE_ENV drives the URLs. A pasted JWT is
|
|
372
|
+
// written too; a browser login lives in auth.json instead. --api-base/--app-base/
|
|
373
|
+
// --host stay as advanced overrides for non-standard setups.
|
|
374
|
+
const env = { WEBCAKE_ENV: envName };
|
|
341
375
|
if (jwt)
|
|
342
376
|
env.WEBCAKE_JWT = jwt;
|
|
343
377
|
if (orgId)
|
|
344
378
|
env.WEBCAKE_ORG_ID = orgId;
|
|
345
|
-
if (
|
|
346
|
-
env.
|
|
347
|
-
if (appBase)
|
|
348
|
-
env.WEBCAKE_APP_BASE = appBase;
|
|
349
|
-
//
|
|
379
|
+
if (o.apiBase)
|
|
380
|
+
env.WEBCAKE_API_BASE = o.apiBase;
|
|
381
|
+
if (o.appBase)
|
|
382
|
+
env.WEBCAKE_APP_BASE = o.appBase;
|
|
383
|
+
// 4) which IDEs
|
|
350
384
|
let ides = [];
|
|
351
385
|
if (o.ide) {
|
|
352
386
|
ides = o.ide
|
|
@@ -355,7 +389,7 @@ export async function runInstaller(argv) {
|
|
|
355
389
|
.filter(Boolean);
|
|
356
390
|
}
|
|
357
391
|
else if (interactive) {
|
|
358
|
-
log(`\n${c.bold}
|
|
392
|
+
log(`\n${c.bold}4) Which IDE(s) to configure?${c.reset}`);
|
|
359
393
|
log(" 1) Claude Desktop 2) Claude Code (CLI) 3) Cursor");
|
|
360
394
|
log(" 4) Windsurf 5) Augment (VS Code) 6) Codex");
|
|
361
395
|
log(" 7) All 0) Skip");
|
|
@@ -383,13 +417,13 @@ export async function runInstaller(argv) {
|
|
|
383
417
|
warn("No IDE selected — skipping configuration.");
|
|
384
418
|
return;
|
|
385
419
|
}
|
|
386
|
-
//
|
|
420
|
+
// 5) write
|
|
387
421
|
const launch = resolveLaunch(o);
|
|
388
|
-
log(`\n${c.bold}
|
|
422
|
+
log(`\n${c.bold}5) Writing config${c.reset} ${c.gray}(launch: ${launch.command} ${launch.args.join(" ")})${c.reset}`);
|
|
389
423
|
runConfigure(ides, launch, env);
|
|
390
|
-
//
|
|
424
|
+
// 6) summary
|
|
391
425
|
log(`\n${c.green}${c.bold}✓ Done.${c.reset}`);
|
|
392
|
-
log(` ${c.gray}
|
|
393
|
-
log(` ${c.gray}
|
|
426
|
+
log(` ${c.gray}Environment : ${envName} (api ${o.apiBase || preset.apiBase})${c.reset}`);
|
|
427
|
+
log(` ${c.gray}Auth : ${authNote}${c.reset}`);
|
|
394
428
|
log(` Restart your IDE, then ask the AI: “Build a Webcake landing page”.\n`);
|
|
395
429
|
}
|
|
@@ -12,19 +12,44 @@
|
|
|
12
12
|
* { config: null, missing } when required values are absent so the persistence
|
|
13
13
|
* tools can report exactly what to provide.
|
|
14
14
|
*
|
|
15
|
+
* WEBCAKE_ENV optional named environment (local|staging|prod) — fills in the
|
|
16
|
+
* API + app base URLs from a preset (see ENVIRONMENTS below). An
|
|
17
|
+
* explicit WEBCAKE_API_BASE / WEBCAKE_APP_BASE still wins over it.
|
|
15
18
|
* WEBCAKE_API_BASE e.g. http://localhost:5800 (required to call the backend)
|
|
16
19
|
* WEBCAKE_JWT the account JWT (required to call the backend)
|
|
17
20
|
* WEBCAKE_ORG_ID optional default organization id for create_page
|
|
18
|
-
* WEBCAKE_HOST optional Host header override (Phoenix routes by host)
|
|
19
21
|
* WEBCAKE_APP_BASE optional base for editor/preview URLs in the result
|
|
20
22
|
* WEBCAKE_CONFIG_DIR optional dir for the saved auth.json (default ~/.webcake-landing-mcp)
|
|
21
23
|
*/
|
|
22
24
|
import { homedir } from "node:os";
|
|
23
25
|
import { join } from "node:path";
|
|
24
26
|
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
27
|
+
/**
|
|
28
|
+
* Named deployment environments — the single source of truth for the API + app
|
|
29
|
+
* base URLs. Selecting one (via the `--env` flag, WEBCAKE_ENV, the `x-webcake-env`
|
|
30
|
+
* header, or `?env=` in the URL) fills in both bases so callers don't repeat them.
|
|
31
|
+
* Explicit WEBCAKE_API_BASE / WEBCAKE_APP_BASE (or per-request overrides) win over
|
|
32
|
+
* the preset. `apiBase` is the backend; `appBase` is the SPA (editor/preview/connect).
|
|
33
|
+
*/
|
|
34
|
+
export const ENVIRONMENTS = {
|
|
35
|
+
local: { apiBase: "http://localhost:5800", appBase: "http://localhost:5173" },
|
|
36
|
+
staging: { apiBase: "https://api.staging.webcake.io", appBase: "https://staging.webcake.io" },
|
|
37
|
+
prod: { apiBase: "https://api.webcake.io", appBase: "https://webcake.io" },
|
|
38
|
+
};
|
|
39
|
+
export const ENV_NAMES = Object.keys(ENVIRONMENTS);
|
|
40
|
+
/** True when `v` names a known environment (local|staging|prod). */
|
|
41
|
+
export function isEnvName(v) {
|
|
42
|
+
return typeof v === "string" && Object.prototype.hasOwnProperty.call(ENVIRONMENTS, v);
|
|
43
|
+
}
|
|
44
|
+
/** The base URLs for a named environment, or undefined when the name is absent/unknown. */
|
|
45
|
+
export function resolveEnv(name) {
|
|
46
|
+
return isEnvName(name) ? ENVIRONMENTS[name] : undefined;
|
|
47
|
+
}
|
|
25
48
|
export function readConfig(overrides = {}) {
|
|
26
49
|
const saved = readSavedConfig();
|
|
27
|
-
|
|
50
|
+
// A named environment supplies default base URLs; explicit values still win.
|
|
51
|
+
const preset = resolveEnv(overrides.env ?? process.env.WEBCAKE_ENV);
|
|
52
|
+
const base = overrides.base ?? process.env.WEBCAKE_API_BASE ?? preset?.apiBase ?? saved.base;
|
|
28
53
|
const jwt = overrides.jwt ?? process.env.WEBCAKE_JWT ?? saved.jwt;
|
|
29
54
|
const missing = [];
|
|
30
55
|
if (!base)
|
|
@@ -38,8 +63,7 @@ export function readConfig(overrides = {}) {
|
|
|
38
63
|
base: base.replace(/\/+$/, ""),
|
|
39
64
|
jwt: jwt,
|
|
40
65
|
orgId: overrides.orgId ?? process.env.WEBCAKE_ORG_ID ?? saved.orgId,
|
|
41
|
-
|
|
42
|
-
appBase: (overrides.appBase ?? process.env.WEBCAKE_APP_BASE ?? saved.appBase)?.replace(/\/+$/, ""),
|
|
66
|
+
appBase: (overrides.appBase ?? process.env.WEBCAKE_APP_BASE ?? preset?.appBase ?? saved.appBase)?.replace(/\/+$/, ""),
|
|
43
67
|
},
|
|
44
68
|
missing: [],
|
|
45
69
|
};
|
|
@@ -53,9 +77,9 @@ function header(headers, name) {
|
|
|
53
77
|
* send its own credentials per request instead of a server-wide env token:
|
|
54
78
|
* x-webcake-jwt the account JWT (or `Authorization: Bearer <jwt>`)
|
|
55
79
|
* x-webcake-org-id organization id
|
|
56
|
-
* x-webcake-
|
|
57
|
-
* x-webcake-
|
|
58
|
-
* x-webcake-app-base editor/preview URL base
|
|
80
|
+
* x-webcake-env named environment (local|staging|prod) for the base URLs
|
|
81
|
+
* x-webcake-api-base backend base URL (overrides the env preset)
|
|
82
|
+
* x-webcake-app-base editor/preview URL base (overrides the env preset)
|
|
59
83
|
* Any header that is absent falls back to the corresponding env var in readConfig.
|
|
60
84
|
*/
|
|
61
85
|
export function configFromHeaders(headers) {
|
|
@@ -65,8 +89,8 @@ export function configFromHeaders(headers) {
|
|
|
65
89
|
base: header(headers, "x-webcake-api-base"),
|
|
66
90
|
jwt: header(headers, "x-webcake-jwt") ?? bearer,
|
|
67
91
|
orgId: header(headers, "x-webcake-org-id"),
|
|
68
|
-
host: header(headers, "x-webcake-host"),
|
|
69
92
|
appBase: header(headers, "x-webcake-app-base"),
|
|
93
|
+
env: header(headers, "x-webcake-env"),
|
|
70
94
|
};
|
|
71
95
|
}
|
|
72
96
|
/** Directory for the saved auth file (override with WEBCAKE_CONFIG_DIR). */
|
|
@@ -10,8 +10,6 @@ function authHeaders(config, orgId) {
|
|
|
10
10
|
Authorization: `Bearer ${config.jwt}`,
|
|
11
11
|
Cookie: `jwt=${config.jwt}`,
|
|
12
12
|
};
|
|
13
|
-
if (config.host)
|
|
14
|
-
headers["Host"] = config.host;
|
|
15
13
|
const org = orgId ?? config.orgId;
|
|
16
14
|
if (org != null && `${org}` !== "")
|
|
17
15
|
headers["x-org-id"] = `${org}`;
|
package/dist/smoke.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { createElement, CONTAINER_TYPES, FIELD_TYPES, LIBRARY, ELEMENT_TYPES, ELEMENTS, } from "./domains/landing/elements/index.js";
|
|
6
6
|
import { validatePage, pageSchema } from "./domains/landing/validate.js";
|
|
7
|
+
import { readConfig, resolveEnv, ENV_NAMES } from "./persistence/config.js";
|
|
7
8
|
let failures = 0;
|
|
8
9
|
const check = (name, cond, extra) => {
|
|
9
10
|
if (cond) {
|
|
@@ -208,5 +209,21 @@ const bindingsGood = {
|
|
|
208
209
|
};
|
|
209
210
|
const rbg = validatePage(bindingsGood);
|
|
210
211
|
check("clean form has no binding warnings", rbg.warnings.length === 0, rbg.warnings);
|
|
212
|
+
console.log("== config: named environment presets (local/staging/prod) ==");
|
|
213
|
+
{
|
|
214
|
+
// Deterministic: isolate from any ambient WEBCAKE_* and the saved auth.json on the dev box.
|
|
215
|
+
for (const k of ["WEBCAKE_API_BASE", "WEBCAKE_APP_BASE", "WEBCAKE_ENV", "WEBCAKE_JWT", "WEBCAKE_ORG_ID"])
|
|
216
|
+
delete process.env[k];
|
|
217
|
+
process.env.WEBCAKE_CONFIG_DIR = "/nonexistent/webcake-smoke";
|
|
218
|
+
check("env names are local/staging/prod", setEq(new Set(ENV_NAMES), ["local", "staging", "prod"]), ENV_NAMES);
|
|
219
|
+
check("staging preset resolves to api+app bases", resolveEnv("staging")?.apiBase === "https://api.staging.webcake.io" && resolveEnv("staging")?.appBase === "https://staging.webcake.io");
|
|
220
|
+
check("unknown env name → undefined", resolveEnv("bogus") === undefined);
|
|
221
|
+
const prod = readConfig({ env: "prod", jwt: "t" }).config;
|
|
222
|
+
check("readConfig(env=prod) fills api+app base", prod?.base === "https://api.webcake.io" && prod?.appBase === "https://webcake.io", prod);
|
|
223
|
+
const local = readConfig({ env: "local", jwt: "t" }).config;
|
|
224
|
+
check("readConfig(env=local) fills api+app base", local?.base === "http://localhost:5800" && local?.appBase === "http://localhost:5173", local);
|
|
225
|
+
check("explicit base overrides the preset", readConfig({ env: "prod", base: "http://x:1", jwt: "t" }).config?.base === "http://x:1");
|
|
226
|
+
check("unknown env leaves base missing", readConfig({ env: "bogus", jwt: "t" }).missing.includes("WEBCAKE_API_BASE"));
|
|
227
|
+
}
|
|
211
228
|
console.log(`\n${failures === 0 ? "ALL GOOD" : failures + " FAILURE(S)"}`);
|
|
212
229
|
process.exit(failures === 0 ? 0 : 1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webcake-landing-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "MCP server exposing Webcake landing-page element schemas + AI usage hints, and persisting LLM-generated page sources to a Webcake backend.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|