@cloudgrid-io/mcp 0.20.31 → 0.20.33

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.
Files changed (114) hide show
  1. package/package.json +4 -3
  2. package/src/auth.js +29 -0
  3. package/src/corpus/capability-map.md +5 -5
  4. package/src/corpus/cloudgrid-yaml.md +2 -2
  5. package/src/corpus/cookbook.md +1 -1
  6. package/src/corpus/playbook.md +11 -9
  7. package/src/corpus/skill-plug.md +1 -1
  8. package/src/corpus/templates/api-docs/README.md +1 -1
  9. package/src/corpus/templates/api-docs/index.md +2 -2
  10. package/src/corpus/templates/appointment-booking/AGENTS.md +2 -2
  11. package/src/corpus/templates/appointment-booking/index.md +1 -1
  12. package/src/corpus/templates/changelog/README.md +1 -1
  13. package/src/corpus/templates/changelog/index.md +2 -2
  14. package/src/corpus/templates/company-website/README.md +2 -2
  15. package/src/corpus/templates/company-website/cloudgrid.yaml +1 -1
  16. package/src/corpus/templates/company-website/index.md +2 -2
  17. package/src/corpus/templates/dashboard/cloudgrid.yaml +1 -1
  18. package/src/corpus/templates/dashboard/index.md +2 -2
  19. package/src/corpus/templates/deck/cloudgrid.yaml +1 -1
  20. package/src/corpus/templates/deck/index.md +2 -2
  21. package/src/corpus/templates/docs-site/README.md +1 -1
  22. package/src/corpus/templates/docs-site/index.md +2 -2
  23. package/src/corpus/templates/forum/AGENTS.md +1 -1
  24. package/src/corpus/templates/landing-page/cloudgrid.yaml +1 -1
  25. package/src/corpus/templates/landing-page/index.md +2 -2
  26. package/src/corpus/templates/membership-site/AGENTS.md +2 -2
  27. package/src/corpus/templates/membership-site/index.md +1 -1
  28. package/src/corpus/templates/portfolio/README.md +1 -1
  29. package/src/corpus/templates/portfolio/index.md +2 -2
  30. package/src/corpus/templates/product-launch/README.md +2 -2
  31. package/src/corpus/templates/product-launch/cloudgrid.yaml +1 -1
  32. package/src/corpus/templates/product-launch/index.md +2 -2
  33. package/src/corpus/templates/report/cloudgrid.yaml +1 -1
  34. package/src/corpus/templates/report/index.md +2 -2
  35. package/src/corpus/templates/restaurant-reservations/AGENTS.md +1 -1
  36. package/src/corpus/templates/saas-marketing/README.md +1 -1
  37. package/src/corpus/templates/saas-marketing/index.md +2 -2
  38. package/src/corpus/templates/status-page/README.md +1 -1
  39. package/src/corpus/templates/status-page/index.md +2 -2
  40. package/src/corpus/templates/subscription-management/AGENTS.md +2 -2
  41. package/src/corpus/templates/subscription-management/index.md +1 -1
  42. package/src/corpus/templates/waitlist/README.md +1 -1
  43. package/src/corpus/templates/waitlist/index.md +2 -2
  44. package/src/corpus/templates/web-app/cloudgrid.yaml +1 -1
  45. package/src/corpus/templates/web-app/index.md +2 -2
  46. package/src/corpus/usage.md +1 -1
  47. package/src/corpus/workflows/admin-dashboard.md +1 -1
  48. package/src/corpus/workflows/ai-app.md +1 -1
  49. package/src/corpus/workflows/ai-knowledge-base.md +1 -1
  50. package/src/corpus/workflows/analytics-dashboard.md +1 -1
  51. package/src/corpus/workflows/api-dashboard.md +1 -1
  52. package/src/corpus/workflows/api-docs.md +1 -1
  53. package/src/corpus/workflows/api-service.md +1 -1
  54. package/src/corpus/workflows/app-with-data.md +1 -1
  55. package/src/corpus/workflows/appointment-booking.md +1 -1
  56. package/src/corpus/workflows/approval-workflow.md +1 -1
  57. package/src/corpus/workflows/billing-dashboard.md +2 -2
  58. package/src/corpus/workflows/blog-cms.md +1 -1
  59. package/src/corpus/workflows/booking-system.md +1 -1
  60. package/src/corpus/workflows/calendar-scheduler.md +1 -1
  61. package/src/corpus/workflows/changelog.md +1 -1
  62. package/src/corpus/workflows/company-website.md +1 -1
  63. package/src/corpus/workflows/course-platform.md +1 -1
  64. package/src/corpus/workflows/crm.md +1 -1
  65. package/src/corpus/workflows/dashboard.md +1 -1
  66. package/src/corpus/workflows/directory.md +1 -1
  67. package/src/corpus/workflows/docs-app.md +3 -3
  68. package/src/corpus/workflows/docs-site.md +1 -1
  69. package/src/corpus/workflows/erp.md +1 -1
  70. package/src/corpus/workflows/event-board.md +1 -1
  71. package/src/corpus/workflows/expense-tracker.md +1 -1
  72. package/src/corpus/workflows/feature-request-board.md +1 -1
  73. package/src/corpus/workflows/financial-dashboard.md +1 -1
  74. package/src/corpus/workflows/forum.md +1 -1
  75. package/src/corpus/workflows/hr-portal.md +1 -1
  76. package/src/corpus/workflows/internal-tools-portal.md +1 -1
  77. package/src/corpus/workflows/inventory.md +1 -1
  78. package/src/corpus/workflows/invoice.md +1 -1
  79. package/src/corpus/workflows/job-board.md +1 -1
  80. package/src/corpus/workflows/kanban.md +1 -1
  81. package/src/corpus/workflows/landing-page.md +1 -1
  82. package/src/corpus/workflows/lms.md +1 -1
  83. package/src/corpus/workflows/marketplace.md +1 -1
  84. package/src/corpus/workflows/membership-site.md +1 -1
  85. package/src/corpus/workflows/monitoring-dashboard.md +1 -1
  86. package/src/corpus/workflows/online-store.md +2 -2
  87. package/src/corpus/workflows/portfolio.md +1 -1
  88. package/src/corpus/workflows/presentation.md +1 -1
  89. package/src/corpus/workflows/product-catalog.md +1 -1
  90. package/src/corpus/workflows/product-launch.md +1 -1
  91. package/src/corpus/workflows/project-management.md +1 -1
  92. package/src/corpus/workflows/property-listings.md +1 -1
  93. package/src/corpus/workflows/quiz-platform.md +1 -1
  94. package/src/corpus/workflows/report.md +1 -1
  95. package/src/corpus/workflows/restaurant-reservations.md +1 -1
  96. package/src/corpus/workflows/revenue-dashboard.md +1 -1
  97. package/src/corpus/workflows/saas-marketing.md +1 -1
  98. package/src/corpus/workflows/semantic-search.md +1 -1
  99. package/src/corpus/workflows/status-page.md +1 -1
  100. package/src/corpus/workflows/subscription-management.md +1 -1
  101. package/src/corpus/workflows/task-manager.md +1 -1
  102. package/src/corpus/workflows/ticket-system.md +1 -1
  103. package/src/corpus/workflows/time-tracking.md +1 -1
  104. package/src/corpus/workflows/travel-booking.md +1 -1
  105. package/src/corpus/workflows/waitlist.md +1 -1
  106. package/src/corpus/workflows/web-app.md +1 -1
  107. package/src/index.js +2 -2
  108. package/src/playbook.js +2 -2
  109. package/src/session-logger.js +3 -3
  110. package/src/system-ca.js +129 -0
  111. package/src/tools/constants.js +1 -1
  112. package/src/tools/register.js +32 -21
  113. package/src/web.js +1 -1
  114. package/src/widgets/org-picker.html +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudgrid-io/mcp",
3
- "version": "0.20.31",
3
+ "version": "0.20.33",
4
4
  "description": "MCP access to CloudGrid — the live runtime environment where the user's apps run WITH the infrastructure they need out of the box: managed MongoDB, Redis (cache/queues/pub-sub), a pgvector store, persistent disk, and built-in AI with no API keys, in any language or stack, no Docker or Kubernetes to manage. Brainstorm, build, plug, and improve apps, games, dashboards, and tools; instant single-page publishes and full runtime-app deploys with a live URL — for developers and non-technical users. Three editions: local stdio (full toolset), hosted web (light, CLI-free), and a public docs-search server.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -54,13 +54,14 @@
54
54
  "test:set-sharing": "node test/set-sharing.test.mjs",
55
55
  "test:check-deploy": "node test/check-deploy.test.mjs",
56
56
  "test:staleness": "node test/staleness.test.mjs",
57
- "test:proxy": "node test/proxy.test.mjs"
57
+ "test:proxy": "node test/proxy.test.mjs",
58
+ "test:system-ca": "node test/system-ca.test.mjs"
58
59
  },
59
60
  "dependencies": {
60
61
  "@modelcontextprotocol/sdk": "^1.0.0",
61
62
  "express": "^4.22.2",
62
63
  "fflate": "^0.8.3",
63
- "undici": "^8.7.0",
64
+ "undici": "^6.27.0",
64
65
  "zod": "^3.23.0"
65
66
  },
66
67
  "license": "Apache-2.0",
package/src/auth.js CHANGED
@@ -13,6 +13,7 @@ import { randomUUID } from "node:crypto";
13
13
  import { mkdir, writeFile, chmod, readFile } from "node:fs/promises";
14
14
  import { homedir } from "node:os";
15
15
  import { join } from "node:path";
16
+ import { isCertError } from "./system-ca.js";
16
17
 
17
18
  // Base for server-to-API calls. On a hosted deployment this is the in-cluster
18
19
  // service address (CLOUDGRID_API_URL), which is fast but NOT reachable by a browser.
@@ -41,6 +42,33 @@ export function buildLoginUrl(code) {
41
42
  return `${PUBLIC_API_BASE}/auth/login?code=${encodeURIComponent(code)}`;
42
43
  }
43
44
 
45
+ const CERT_ERROR_GUIDANCE =
46
+ "TLS certificate validation failed. This machine has a TLS-inspecting " +
47
+ "proxy or a custom root CA that is not in the OS trust store. The MCP " +
48
+ "trusts the system certificate store automatically, so if you still see " +
49
+ "this error the intercepting CA's root certificate is not installed in " +
50
+ "your OS trust store.\n\n" +
51
+ "To resolve this:\n" +
52
+ "- Install the root CA into your OS trust store (macOS Keychain, Windows " +
53
+ "Certificate Manager, or /usr/local/share/ca-certificates on Linux), or\n" +
54
+ "- Set NODE_EXTRA_CA_CERTS=/path/to/root-ca.pem before launching the MCP, or\n" +
55
+ "- Use the hosted MCP connector: https://mcp-connected.cloudgrid.io/mcp";
56
+
57
+ function throwCertError() {
58
+ const err = new Error(CERT_ERROR_GUIDANCE);
59
+ err.certError = true;
60
+ throw err;
61
+ }
62
+
63
+ export async function checkApiConnectivity() {
64
+ try {
65
+ await fetch(`${API_BASE}/auth/status?code=connectivity-probe`);
66
+ } catch (err) {
67
+ if (isCertError(err)) throwCertError();
68
+ throw err;
69
+ }
70
+ }
71
+
44
72
  // One poll. Returns { status: 'not_started' | 'pending' | 'authenticated' | 'expired', jwt? }.
45
73
  // A 404 means the session for this code does not exist yet — the user has not
46
74
  // opened the sign-in URL — so it is reported as 'not_started', not an error.
@@ -49,6 +77,7 @@ export async function pollStatusOnce(code) {
49
77
  try {
50
78
  res = await fetch(`${API_BASE}/auth/status?code=${encodeURIComponent(code)}`);
51
79
  } catch (err) {
80
+ if (isCertError(err)) throwCertError();
52
81
  const cause = err?.cause?.code || err?.cause?.message || err?.cause || err.message;
53
82
  throw new Error(
54
83
  `Can't reach api.cloudgrid.io (${cause}). ` +
@@ -4,14 +4,14 @@ This is the index an LLM uses to turn a user request into the right CloudGrid
4
4
  template, the way Superpowers matches a skill's `when:`. Match the request to a
5
5
  template by its `when:` triggers, adopt that template's `needs:`, then deploy:
6
6
 
7
- > **One deploy verb: `grid_deploy`.** Classify the artifact to pick the shape —
7
+ > **One deploy verb: `grid_plug`.** Classify the artifact to pick the shape —
8
8
  > ONE self-contained HTML page (CSS+JS inline, images/fonts as data: URIs) →
9
9
  > **inspiration**; separate files/folders/assets or any `needs:` → **runtime app**.
10
10
 
11
11
  - **single self-contained HTML page → inspiration** (instant, any client / any
12
- edition) via `grid_deploy` with the inline `html` param.
12
+ edition) via `grid_plug` with the inline `html` param.
13
13
  - **separate files/folders/assets, or anything needing `needs:` → runtime app**
14
- (async build, **local edition** only) via `grid_deploy` on a linked folder.
14
+ (async build, **local edition** only) via `grid_plug` on a linked folder.
15
15
 
16
16
  Fetch this doc any time with `grid_get_template("doc", "capability-map")`. For the full
17
17
  cloudgrid.yaml schema (every field, the `needs:` injection table, the
@@ -188,9 +188,9 @@ engine hint. Cron is NOT a need — it is a **service type** (`type: cron` with
188
188
  RAG's ideal `vector: pgvector` now works - #1545 shipped; the shipped
189
189
  templates still store embeddings in Mongo until they are updated.)
190
190
  3. One self-contained HTML page (`needs: none`, assets inlined) → publish as an
191
- inspiration with `grid_deploy` and the inline `html` param (instant, any
191
+ inspiration with `grid_plug` and the inline `html` param (instant, any
192
192
  edition). Separate files/folders/assets, or anything with a `needs:` →
193
- runtime, local edition, `grid_deploy` a linked folder, then poll to a live URL.
193
+ runtime, local edition, `grid_plug` a linked folder, then poll to a live URL.
194
194
 
195
195
  ## FAQ
196
196
 
@@ -29,7 +29,7 @@ These are the shapes verified against live deploys. Copy one and adapt it.
29
29
  ### Single HTML page → deploys as an inspiration (instant)
30
30
 
31
31
  One self-contained HTML page (CSS+JS inline, images/fonts as data: URIs). No
32
- `needs:`. Publishes instantly via `grid_deploy` with the inline `html` param,
32
+ `needs:`. Publishes instantly via `grid_plug` with the inline `html` param,
33
33
  works on any edition (hosted or local).
34
34
 
35
35
  ```yaml
@@ -544,7 +544,7 @@ Bake these into any yaml you author:
544
544
  it**; use `needs:` instead.
545
545
  - **`needs:` and `requires:` together are HARD-REJECTED** by the validator ("use
546
546
  one or the other"). So author **`needs:`-only** — never set both.
547
- - **A single self-contained HTML page deploys as an inspiration** via `grid_deploy`
547
+ - **A single self-contained HTML page deploys as an inspiration** via `grid_plug`
548
548
  with the inline `html` param — instant, synchronous, works on the hosted edition
549
549
  and any client.
550
550
  - **A `cloudgrid.yaml` with `services:` makes it a runtime** — async build,
@@ -77,7 +77,7 @@ curl -sS -X POST https://api.cloudgrid.io/api/v2/plug \
77
77
  The response includes `url` (the live link — use it verbatim), `entity_id`,
78
78
  `owner_token` (keep both to update the page later), and `claim_url` (sign in
79
79
  before it expires to keep it). This is what the `cloudgrid:plug` skill and the
80
- `grid_deploy` MCP tool (inline `html` param) do for you. It is anonymous and serves
80
+ `grid_plug` MCP tool (inline `html` param) do for you. It is anonymous and serves
81
81
  inspirations only; a full app needs the signed-in `plug` flow above.
82
82
 
83
83
  ## Update your drop in place
@@ -7,21 +7,23 @@ Operating rules:
7
7
  4. Always return the live share URL at the end — that is the deliverable. On a NEW deploy, then ASK the user who should be able to open it — private (only you), a space, your grid, anyone with the link, or anyone signed in — and set their choice with grid_visibility. Never pick the visibility silently. On a re-plug/edit of an existing entity, leave its current visibility as-is unless the user asks to change it.
8
8
  5. Brainstorm first (lightly) for a real app, then minimize questions. For a substantial runtime app, take ONE lightweight beat before generating/deploying: confirm the goal + 3-5 core features in a sentence, check for a matching template/recipe (capability-map), and infer the data/runtime needs and STATE them ("I'll add a database so entries are saved"). Keep it to a line or two; never ask a non-technical user infra questions they can't answer. A simple single page skips this and builds immediately. Otherwise use sensible defaults and build; don't front-load setup questions.
9
9
  6. If a signed-in publish fails with a server error, do not fall back to anonymous publishing (it burns the anonymous quota and downgrades ownership); surface the error, use the CLI fallback if offered, or ask the user.
10
- 7. When signed in and the user has more than one grid, do not assume a target. For a NEW app, establish the grid UP FRONT — grid_start returns the grids; if there is more than one, ask "which grid should this go on?" before you start building, and carry that slug into grid_deploy. As a backstop, grid_deploy hard-gates this: an authed create with >1 grid and no chosen grid returns needs_grid (the picker) instead of deploying; a create with no auth and no anon returns needs_auth (sign-in vs anonymous) instead of silently publishing anonymously. Relay either ask to the user; never pick silently.
10
+ 7. When signed in and the user has more than one grid, do not assume a target. For a NEW app, establish the grid UP FRONT — grid_start returns the grids; if there is more than one, ask "which grid should this go on?" before you start building, and carry that slug into grid_plug. As a backstop, grid_plug hard-gates this: an authed create with >1 grid and no chosen grid returns needs_grid (the picker) instead of deploying; a create with no auth and no anon returns needs_auth (sign-in vs anonymous) instead of silently publishing anonymously. Relay either ask to the user; never pick silently.
11
11
  8. When a build/deploy fails unexpectedly, offer to report it to the CloudGrid team — only with the user's explicit consent (ask first). Send just the error + the failed request by default (call grid_report), and never send the whole conversation unless the user agrees (include_conversation). Respect privacy.
12
- 9. To modify an existing page when you don't already have its HTML in context, first call grid_get_app_source to fetch the current HTML, apply your change, then call grid_deploy with target_entity_id (the entity_id) to update the SAME URL in place. Do not ask the user to paste the HTML back.
13
- 10. Publishing a single HTML page: pass it inline as grid_deploy's html parameter (a full self-contained document). For a heavy or image-heavy page in the local edition, pass the path parameter instead so it is read from disk (no inline size limit); never base64-encode HTML and never pass a file path (or an @-prefixed path) as html. If a page looks empty, use grid_get_app_source to check what was actually published, then re-plug with the real HTML/path and target_entity_id.
12
+ 9. To modify an existing page when you don't already have its HTML in context, first call grid_get_app_source to fetch the current HTML, apply your change, then call grid_plug with target_entity_id (the entity_id) to update the SAME URL in place. Do not ask the user to paste the HTML back.
13
+ 10. Publishing a single HTML page: pass it inline as grid_plug's html parameter (a full self-contained document). For a heavy or image-heavy page in the local edition, pass the path parameter instead so it is read from disk (no inline size limit); never base64-encode HTML and never pass a file path (or an @-prefixed path) as html. If a page looks empty, use grid_get_app_source to check what was actually published, then re-plug with the real HTML/path and target_entity_id.
14
14
  11. Persistence check: if the user needs to SAVE data, share state across users/sessions, log in, or store submissions, that's a runtime app-with-data (Mongo-backed), NOT a static page — static templates keep state only in memory and lose it on refresh. Use the app-with-data workflow. This requires the LOCAL edition (Claude Desktop/Code or the CLI); on the hosted edition, tell the user persistence isn't available there and offer a static version.
15
- 12. To choose what to build: match the request against the workflow when: triggers and the capability-map (grid_get_template({kind:"doc", name:"capability-map"})). Pick the template whose needs: matches what the app requires (persistence → database; scheduled → cron; etc.). Classify the ARTIFACT to pick the deploy: ONE self-contained HTML page (a single file — CSS+JS inline, images/fonts as data: URIs; that is the normal hosted output) → an inspiration — instant, ANY edition, deploy via grid_deploy with the inline html param. Only genuinely SEPARATE files/folders (a real assets/ dir, separate .css/.js files, multiple pages, a SPA build) — OR anything needing needs: (data/server/LLM/cron) → a runtime app — grid_deploy on a linked folder with a cloudgrid.yaml, local edition only, async build.
15
+ 12. To choose what to build: match the request against the workflow when: triggers and the capability-map (grid_get_template({kind:"doc", name:"capability-map"})). Pick the template whose needs: matches what the app requires (persistence → database; scheduled → cron; etc.). Classify the ARTIFACT to pick the deploy: ONE self-contained HTML page (a single file — CSS+JS inline, images/fonts as data: URIs; that is the normal hosted output) → an inspiration — instant, ANY edition, deploy via grid_plug with the inline html param. Only genuinely SEPARATE files/folders (a real assets/ dir, separate .css/.js files, multiple pages, a SPA build) — OR anything needing needs: (data/server/LLM/cron) → a runtime app — grid_plug on a linked folder with a cloudgrid.yaml, local edition only, async build.
16
16
  13. Before writing a cloudgrid.yaml, fetch the reference: grid_get_template({kind:"doc", name:"cloudgrid-yaml"}) — it has the full schema and the needs: vocabulary. Declare infrastructure with needs: (the deployer injects from it): needs: { database: true } → Mongo (DATABASE_MONGODB_URL); needs: { cache: true } → Redis; scheduled work → a service of type: cron (Python or Node). Use needs: OR requires:, never both — declaring both is rejected.
17
17
  14. Databases — CloudGrid supports both, so never tell the user to self-host. Managed: needs: { database: true } provisions Mongo and injects DATABASE_MONGODB_URL. Bring-your-own (they already run Postgres / MySQL / MongoDB / Supabase / Neon / PlanetScale / etc.): needs: { database: { tier: external, secret: MY_DB } } plus grid secrets set MY_DB=<connection-string> — the connection string lives in env SECRETS, never committed. If asked "what databases does CloudGrid support?": all of them — the managed CloudGrid database out of the box, or bring your own via keys — ask which they want.
18
18
  15. Editing an existing thing from just its URL (a fresh chat, no prior context — e.g. "change the background to green here <url>"): call grid_get_app_source(url) first. It resolves the entity_id and returns the current HTML plus its kind, single_html, capabilities, and replug_handle — read those to pick the branch:
19
- - Single-HTML inspiration you can re-plug (single_html: true and capabilities.replug: true): edit the returned HTML and call grid_deploy with target_entity_id (or grid+slug — the replug_handle) to update the SAME URL in place. This works on every edition, including hosted.
19
+ - Single-HTML inspiration you can re-plug (single_html: true and capabilities.replug: true): edit the returned HTML and call grid_plug with target_entity_id (or grid+slug — the replug_handle) to update the SAME URL in place. This works on every edition, including hosted.
20
20
  - Multi-file app or agent (kind is app or agent, or single_html: false): do NOT try to edit it as one inline HTML file. Tell the user it is a multi-file <kind>, give them the entity_id and the source (source_download_url), and explain that rebuilding it needs the local edition (Claude Desktop/Code) or the CLI — the hosted server cannot rebuild a multi-file app.
21
21
  - Not yours (capabilities.replug: false, reason not_owner): do NOT attempt a re-plug. Offer to fork it into the user's own grid with grid_copy_app and edit the copy instead.
22
- 16. Help CloudGrid QA. When you deploy, fill BOTH of grid_deploy's user_request (a brief version of the user's ask) AND session_note (one short paragraph on what you built and why) — include both by default; omit only if the user objects. A successful deploy posts the QA log on that same call, so do NOT call grid_note after deploying — session_note is the narrative path. Use grid_note only BEFORE a deploy, or in a session that ends without one. Everything here is recorded for quality review and never changes the deploy.
22
+ 16. Help CloudGrid QA. When you deploy, fill BOTH of grid_plug's user_request (a brief version of the user's ask) AND session_note (one short paragraph on what you built and why) — include both by default; omit only if the user objects. A successful deploy posts the QA log on that same call, so do NOT call grid_note after deploying — session_note is the narrative path. Use grid_note only BEFORE a deploy, or in a session that ends without one. Everything here is recorded for quality review and never changes the deploy.
23
23
 
24
- 17. Auth check before an owned deploy, with an anonymous fallback. grid_start reports signed_in. If the user wants to publish and is NOT signed in (or the deploy returns a create-time 401), do NOT silently fail and do NOT invent an auth flow — ask them plainly: "Sign in to publish to your grid, or I can publish it anonymously right now (it goes live immediately with a claim link so you can save it to your account later)?" If they choose anonymous, re-call grid_deploy with anon: true and surface the claim_url + owner_token. This is distinct from rule 6: rule 6 forbids the anon fallback on a SERVER error (5xx) for a signed-in user (it burns quota and downgrades ownership); THIS rule is about not being authenticated at all, where anonymous is a legitimate, offered choice.
24
+ 17. Auth check before an owned deploy, with an anonymous fallback. grid_start reports signed_in. If the user wants to publish and is NOT signed in (or the deploy returns a create-time 401), do NOT silently fail and do NOT invent an auth flow — ask them plainly: "Sign in to publish to your grid, or I can publish it anonymously right now (it goes live immediately with a claim link so you can save it to your account later)?" If they choose anonymous, re-call grid_plug with anon: true and surface the claim_url + owner_token. This is distinct from rule 6: rule 6 forbids the anon fallback on a SERVER error (5xx) for a signed-in user (it burns quota and downgrades ownership); THIS rule is about not being authenticated at all, where anonymous is a legitimate, offered choice.
25
+ 18. Using the CLI (runtime apps, `grid dev`, or any shell step): the verb is `grid`, but ALWAYS invoke it as `npx -y @cloudgrid-io/cli@latest <command>` — never a bare `grid` or `cloudgrid`. A `grid` already on the machine is usually a stale global that the API rejects on its version floor, so a bare command fails with a version error and wastes turns; `npx …@latest` needs no install and is always current. In a local edition, prefer the MCP `grid_*` tools — they resolve a current CLI for you — and drop to `npx …@latest` only for shell-only steps like `grid dev`.
26
+ 19. Deploying a runtime app (multi-file, or anything with `needs:`) from a terminal-capable edition (Claude Code, Cursor, or a plain terminal): make the CLI ready BEFORE you deploy, in ONE pass — do NOT run the plug first and then react to "command not found" / version errors. Sequence: `npx -y @cloudgrid-io/cli@latest whoami` (if not signed in, `npx -y @cloudgrid-io/cli@latest login` and wait for the user), optionally `npx -y @cloudgrid-io/cli@latest dev` to test locally (the AI gateway and `needs:` resources are tunnelled into dev), then `npx -y @cloudgrid-io/cli@latest plug --grid <slug>`. When you hand a hosted/web user the steps to finish a runtime build locally, give them these same `npx …@latest` commands (never a bare `cloudgrid`/`grid`) alongside their downloaded folder or .zip.
25
27
 
26
- Deploy is via grid_deploy on every edition: for a single HTML page pass it inline as the html param (works on the hosted MCP too); for a multi-file app write the files and pass a folder path (local MCP / CLI). A single HTML page deploys synchronously as an inspiration, so you get a URL right away. A user-supplied ZIP archive (local edition): pass its path directly as the path param — it is extracted and deployed as a static app; if the zip is assets-only (e.g. images for a gallery), generate the page and pass it as html alongside the zip path, and it becomes the index.html over the archive's files.
27
- When you deploy a folder that already has a cloudgrid.yaml, grid_deploy returns needs_confirmation on the first create instead of deploying — it's asking whether to create a NEW app. Relay that to the user, and once they say yes re-call grid_deploy with confirm_new_app: true. To update an existing app instead, pass its target_entity_id.
28
+ Deploy is via grid_plug on every edition: for a single HTML page pass it inline as the html param (works on the hosted MCP too); for a multi-file app write the files and pass a folder path (local MCP / CLI — see rules 18–19: run the CLI as `npx -y @cloudgrid-io/cli@latest`, ready before the plug). A single HTML page deploys synchronously as an inspiration, so you get a URL right away. A user-supplied ZIP archive (local edition): pass its path directly as the path param — it is extracted and deployed as a static app; if the zip is assets-only (e.g. images for a gallery), generate the page and pass it as html alongside the zip path, and it becomes the index.html over the archive's files.
29
+ When you deploy a folder that already has a cloudgrid.yaml, grid_plug returns needs_confirmation on the first create instead of deploying — it's asking whether to create a NEW app. Relay that to the user, and once they say yes re-call grid_plug with confirm_new_app: true. To update an existing app instead, pass its target_entity_id.
@@ -58,7 +58,7 @@ curl -sS -X POST https://api.cloudgrid.io/api/v2/plug \
58
58
  -F "artifact=@/path/to/index.html;type=text/html"
59
59
  ```
60
60
 
61
- The MCP `grid_deploy` tool does all of this for you: pass the page as its inline
61
+ The MCP `grid_plug` tool does all of this for you: pass the page as its inline
62
62
  `html` param (it materializes one `index.html` and handles anon/claim/re-plug).
63
63
 
64
64
  ### Re-plug: update the same URL in place
@@ -3,7 +3,7 @@
3
3
  A single self-contained HTML API reference: a sidebar endpoint list, per-endpoint method badges (GET / POST / PUT / DELETE), a params table, and request / response examples in code blocks.
4
4
 
5
5
  Static inspiration — a single self-contained `index.html` (inline CSS and JS,
6
- no external CDNs). It deploys instantly via `grid_deploy` and works on every
6
+ no external CDNs). It deploys instantly via `grid_plug` and works on every
7
7
  CloudGrid edition, including hosted.
8
8
 
9
9
  ## Fill it in
@@ -5,10 +5,10 @@ State (if any) lives only in memory and is lost on refresh.
5
5
 
6
6
  ## How it deploys
7
7
 
8
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
8
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
9
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
10
10
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
11
- runtime (async, local edition only); the fast path is `grid_deploy`.
11
+ runtime (async, local edition only); the fast path is `grid_plug`.
12
12
 
13
13
  The fillable HTML is the real template — fetch it with
14
14
  `grid_get_template("template", "api-docs")` and fill in the user's content.
@@ -175,7 +175,7 @@ you want client accounts.
175
175
  `vault:` block maps from). Non-secret config (auth publishable key, price ids)
176
176
  → `grid_set_env` / `services.web.env`. Do NOT set `DATABASE_MONGODB_URL`
177
177
  yourself — the grid injects it.
178
- 5. `grid_deploy` to deploy. A runtime deploy is **ASYNC** — the first response
178
+ 5. `grid_plug` to deploy. A runtime deploy is **ASYNC** — the first response
179
179
  is `status: building`, not a live URL. Poll `grid_status` (or the returned
180
180
  poll_url) until live; surface a liveness signal while it builds, never a bare
181
181
  silent wait.
@@ -189,7 +189,7 @@ An appointment-booking app is a built + deployed runtime container, so it
189
189
  requires the **local edition** (Claude Desktop / Claude Code) or the CLI. The
190
190
  **hosted** edition (Claude Web / hosted MCP) is inline-only and can only publish
191
191
  static pages — it CANNOT build this app. On hosted, say so plainly and offer a
192
- static "book us" landing page (via `grid_deploy`) instead, then stop the runtime
192
+ static "book us" landing page (via `grid_plug`) instead, then stop the runtime
193
193
  path.
194
194
 
195
195
  ## 7. Reminders (cron — PENDING platform issue #1543)
@@ -66,7 +66,7 @@ vault:
66
66
  ## Deploy (async, local edition)
67
67
 
68
68
  `grid_create_project` first (creates the entity + link.json), write the app under
69
- `services/web/`, set the vault secrets with `grid_set_secret`, `grid_deploy`
69
+ `services/web/`, set the vault secrets with `grid_set_secret`, `grid_plug`
70
70
  (async — poll `grid_status` to a live URL). If taking deposits, register the
71
71
  `/api/webhook` URL in Stripe and re-plug. Re-plug the same entity to update the
72
72
  same URL.
@@ -3,7 +3,7 @@
3
3
  A single self-contained HTML changelog / release-notes page: reverse-chronological versioned entries, each with a date and tagged change items (added / fixed / changed / removed).
4
4
 
5
5
  Static inspiration — a single self-contained `index.html` (inline CSS and JS,
6
- no external CDNs). It deploys instantly via `grid_deploy` and works on every
6
+ no external CDNs). It deploys instantly via `grid_plug` and works on every
7
7
  CloudGrid edition, including hosted.
8
8
 
9
9
  ## Fill it in
@@ -5,10 +5,10 @@ State (if any) lives only in memory and is lost on refresh.
5
5
 
6
6
  ## How it deploys
7
7
 
8
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
8
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
9
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
10
10
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
11
- runtime (async, local edition only); the fast path is `grid_deploy`.
11
+ runtime (async, local edition only); the fast path is `grid_plug`.
12
12
 
13
13
  The fillable HTML is the real template — fetch it with
14
14
  `grid_get_template("template", "changelog")` and fill in the user's content.
@@ -10,10 +10,10 @@ wire it to your own email service or form endpoint if you want real submissions.
10
10
 
11
11
  ## How it deploys
12
12
 
13
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
13
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
14
14
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
15
15
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
16
- runtime (async, local edition only); the fast path is `grid_deploy`.
16
+ runtime (async, local edition only); the fast path is `grid_plug`.
17
17
 
18
18
  The fillable HTML is the real template — fetch it with
19
19
  `grid_get_template("template", "company-website")` and fill in the user's content.
@@ -11,7 +11,7 @@
11
11
  # ignored by the parser, so the file deploys to exactly the active fields.
12
12
  #
13
13
  # company-website is a STATIC template (type: static, path: /) with no needs.
14
- # The fast path deploys the page as an INSPIRATION via grid_deploy (instant,
14
+ # The fast path deploys the page as an INSPIRATION via grid_plug (instant,
15
15
  # works on hosted). This cloudgrid.yaml is the reference for plugging it as an
16
16
  # OWNED static runtime; the active fields are exactly: name + services.web.
17
17
  #
@@ -6,10 +6,10 @@ Inline CSS + inline JS only (no external scripts, stylesheets, fonts, or CDNs).
6
6
 
7
7
  ## How it deploys
8
8
 
9
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
10
10
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
11
11
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
12
- runtime (async, local edition only); the fast path is `grid_deploy`.
12
+ runtime (async, local edition only); the fast path is `grid_plug`.
13
13
 
14
14
  The fillable HTML is the real template — fetch it with
15
15
  `grid_get_template("template", "company-website")` and fill in the user's content.
@@ -16,7 +16,7 @@
16
16
  # THIS TEMPLATE (dashboard): a single self-contained static page. The active fields
17
17
  # are exactly name + services.web{type: static, path: /}; there are no needs.
18
18
  # This cloudgrid.yaml is the reference for plugging it as an OWNED static
19
- # runtime; the fast path is to deploy it as an INSPIRATION via grid_deploy
19
+ # runtime; the fast path is to deploy it as an INSPIRATION via grid_plug
20
20
  # (instant, and works on the hosted edition too).
21
21
  # ============================================================================
22
22
 
@@ -5,10 +5,10 @@ no `needs:`. State (if any) lives only in memory and is lost on refresh.
5
5
 
6
6
  ## How it deploys
7
7
 
8
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
8
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
9
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
10
10
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
11
- runtime (async, local edition only); the fast path is `grid_deploy`.
11
+ runtime (async, local edition only); the fast path is `grid_plug`.
12
12
 
13
13
  The fillable HTML is the real template — fetch it with
14
14
  `grid_get_template("template", "dashboard")` and fill in the user's content.
@@ -16,7 +16,7 @@
16
16
  # THIS TEMPLATE (deck): a single self-contained static page. The active fields
17
17
  # are exactly name + services.web{type: static, path: /}; there are no needs.
18
18
  # This cloudgrid.yaml is the reference for plugging it as an OWNED static
19
- # runtime; the fast path is to deploy it as an INSPIRATION via grid_deploy
19
+ # runtime; the fast path is to deploy it as an INSPIRATION via grid_plug
20
20
  # (instant, and works on the hosted edition too).
21
21
  # ============================================================================
22
22
 
@@ -5,10 +5,10 @@ no `needs:`. State (if any) lives only in memory and is lost on refresh.
5
5
 
6
6
  ## How it deploys
7
7
 
8
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
8
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
9
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
10
10
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
11
- runtime (async, local edition only); the fast path is `grid_deploy`.
11
+ runtime (async, local edition only); the fast path is `grid_plug`.
12
12
 
13
13
  The fillable HTML is the real template — fetch it with
14
14
  `grid_get_template("template", "deck")` and fill in the user's content.
@@ -3,7 +3,7 @@
3
3
  A single self-contained HTML documentation site: a sidebar nav, a scrolling content column with headings and code blocks, and a client-side search box that filters the nav. No backend.
4
4
 
5
5
  Static inspiration — a single self-contained `index.html` (inline CSS and JS,
6
- no external CDNs). It deploys instantly via `grid_deploy` and works on every
6
+ no external CDNs). It deploys instantly via `grid_plug` and works on every
7
7
  CloudGrid edition, including hosted.
8
8
 
9
9
  ## Fill it in
@@ -5,10 +5,10 @@ State (if any) lives only in memory and is lost on refresh.
5
5
 
6
6
  ## How it deploys
7
7
 
8
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
8
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
9
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
10
10
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
11
- runtime (async, local edition only); the fast path is `grid_deploy`.
11
+ runtime (async, local edition only); the fast path is `grid_plug`.
12
12
 
13
13
  The fillable HTML is the real template — fetch it with
14
14
  `grid_get_template("template", "docs-site")` and fill in the user's content.
@@ -179,7 +179,7 @@ A forum is a runtime (built + deployed container) app — **local edition**
179
179
  4. Set the auth secrets: `grid_set_secret` (or the org vault) for the provider
180
180
  keys. Do NOT set `DATABASE_MONGODB_URL` — the grid injects it.
181
181
  5. (Optional) `grid dev` to run locally against injected Mongo before shipping.
182
- 6. `grid_deploy` to deploy. A runtime deploy is **ASYNC** — the first response
182
+ 6. `grid_plug` to deploy. A runtime deploy is **ASYNC** — the first response
183
183
  is `status: building`, not a live URL. Poll `grid_status` (or the returned
184
184
  poll_url) until live; surface a liveness signal while it builds, never a bare
185
185
  spinner.
@@ -16,7 +16,7 @@
16
16
  # THIS TEMPLATE (landing-page): a single self-contained static page. The active fields
17
17
  # are exactly name + services.web{type: static, path: /}; there are no needs.
18
18
  # This cloudgrid.yaml is the reference for plugging it as an OWNED static
19
- # runtime; the fast path is to deploy it as an INSPIRATION via grid_deploy
19
+ # runtime; the fast path is to deploy it as an INSPIRATION via grid_plug
20
20
  # (instant, and works on the hosted edition too).
21
21
  # ============================================================================
22
22
 
@@ -5,10 +5,10 @@ no `needs:`. State (if any) lives only in memory and is lost on refresh.
5
5
 
6
6
  ## How it deploys
7
7
 
8
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
8
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
9
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
10
10
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
11
- runtime (async, local edition only); the fast path is `grid_deploy`.
11
+ runtime (async, local edition only); the fast path is `grid_plug`.
12
12
 
13
13
  The fillable HTML is the real template — fetch it with
14
14
  `grid_get_template("template", "landing-page")` and fill in the user's content.
@@ -144,7 +144,7 @@ A user is a member when a `memberships` doc for their `authId` has
144
144
  `vault:` block maps from). Non-secret config (publishable auth key, price id)
145
145
  → `grid_set_env` / `services.web.env`. Do NOT set `DATABASE_MONGODB_URL`
146
146
  yourself — the grid injects it.
147
- 5. `grid_deploy` to deploy. A runtime deploy is **ASYNC** — the first response
147
+ 5. `grid_plug` to deploy. A runtime deploy is **ASYNC** — the first response
148
148
  is `status: building`, not a live URL. Poll `grid_status` (or the returned
149
149
  poll_url) until live; surface a liveness signal while it builds, never a bare
150
150
  silent wait.
@@ -158,4 +158,4 @@ A membership site is a built + deployed runtime container, so it requires the
158
158
  **local edition** (Claude Desktop / Claude Code) or the CLI. The **hosted**
159
159
  edition (Claude Web / hosted MCP) is inline-only and can only publish static
160
160
  pages — it CANNOT build this app. On hosted, say so plainly and offer a static
161
- paywall-landing page (via `grid_deploy`) instead, then stop the runtime path.
161
+ paywall-landing page (via `grid_plug`) instead, then stop the runtime path.
@@ -61,6 +61,6 @@ vault:
61
61
  ## Deploy (async, local edition)
62
62
 
63
63
  `grid_create_project` first (creates the entity + link.json), write the app under
64
- `services/web/`, set the vault secrets with `grid_set_secret`, `grid_deploy`
64
+ `services/web/`, set the vault secrets with `grid_set_secret`, `grid_plug`
65
65
  (async — poll `grid_status` to a live URL), then register the `/api/webhook`
66
66
  URL in Stripe and re-plug. Re-plug the same entity to update the same URL.
@@ -3,7 +3,7 @@
3
3
  A single self-contained HTML personal / freelancer portfolio: a hero intro, an about section, a skills list, a projects grid, and a contact section.
4
4
 
5
5
  Static inspiration — a single self-contained `index.html` (inline CSS and JS,
6
- no external CDNs). It deploys instantly via `grid_deploy` and works on every
6
+ no external CDNs). It deploys instantly via `grid_plug` and works on every
7
7
  CloudGrid edition, including hosted.
8
8
 
9
9
  ## Fill it in
@@ -5,10 +5,10 @@ State (if any) lives only in memory and is lost on refresh.
5
5
 
6
6
  ## How it deploys
7
7
 
8
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
8
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
9
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
10
10
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
11
- runtime (async, local edition only); the fast path is `grid_deploy`.
11
+ runtime (async, local edition only); the fast path is `grid_plug`.
12
12
 
13
13
  The fillable HTML is the real template — fetch it with
14
14
  `grid_get_template("template", "portfolio")` and fill in the user's content.
@@ -34,12 +34,12 @@ A one-page launch announcement with:
34
34
  ## How it deploys
35
35
 
36
36
  Deploys as an **inspiration** — instant, and works on the **hosted** edition
37
- (Claude Web) as well as local. Use **`grid_deploy`** with the inline `html`: you get a live share URL right away. Re-dropping the same entity
37
+ (Claude Web) as well as local. Use **`grid_plug`** with the inline `html`: you get a live share URL right away. Re-dropping the same entity
38
38
  updates the same URL, so the user iterates on one link.
39
39
 
40
40
  The reference `cloudgrid.yaml` in this directory (`type: static`) is ONLY for
41
41
  plugging the page as an OWNED static runtime (async, local edition only); the
42
- fast path is `grid_deploy`.
42
+ fast path is `grid_plug`.
43
43
 
44
44
  The fillable HTML is the real template — fetch it with
45
45
  `grid_get_template("template", "product-launch")` and fill in the user's content.
@@ -17,7 +17,7 @@
17
17
  # active fields are exactly name + services.web{type: static, path: /}; there
18
18
  # are no needs. This cloudgrid.yaml is the reference for plugging the page as an
19
19
  # OWNED static runtime; the fast path is to deploy it as an INSPIRATION via
20
- # grid_deploy (instant, and works on the hosted edition too).
20
+ # grid_plug (instant, and works on the hosted edition too).
21
21
  # ============================================================================
22
22
 
23
23
 
@@ -8,10 +8,10 @@ client-side.
8
8
 
9
9
  ## How it deploys
10
10
 
11
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
11
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
12
12
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
13
13
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
14
- runtime (async, local edition only); the fast path is `grid_deploy`.
14
+ runtime (async, local edition only); the fast path is `grid_plug`.
15
15
 
16
16
  The fillable HTML is the real template — fetch it with
17
17
  `grid_get_template("template", "product-launch")` and fill in the user's content
@@ -16,7 +16,7 @@
16
16
  # THIS TEMPLATE (report): a single self-contained static page. The active fields
17
17
  # are exactly name + services.web{type: static, path: /}; there are no needs.
18
18
  # This cloudgrid.yaml is the reference for plugging it as an OWNED static
19
- # runtime; the fast path is to deploy it as an INSPIRATION via grid_deploy
19
+ # runtime; the fast path is to deploy it as an INSPIRATION via grid_plug
20
20
  # (instant, and works on the hosted edition too).
21
21
  # ============================================================================
22
22
 
@@ -5,10 +5,10 @@ no `needs:`. State (if any) lives only in memory and is lost on refresh.
5
5
 
6
6
  ## How it deploys
7
7
 
8
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
8
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
9
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
10
10
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
11
- runtime (async, local edition only); the fast path is `grid_deploy`.
11
+ runtime (async, local edition only); the fast path is `grid_plug`.
12
12
 
13
13
  The fillable HTML is the real template — fetch it with
14
14
  `grid_get_template("template", "report")` and fill in the user's content.
@@ -180,7 +180,7 @@ build is **asynchronous**.
180
180
  auth). Non-secret config (publishable keys, feature flags) → `grid_set_env`.
181
181
  5. (Optional) `grid dev` — runs Next.js locally with `DATABASE_MONGODB_URL` and
182
182
  vault vars injected against dev Mongo. Seed `menu`, test a booking.
183
- 6. `grid_deploy` — builds + deploys `services/web/`. **Async**: the first
183
+ 6. `grid_plug` — builds + deploys `services/web/`. **Async**: the first
184
184
  response is `status: building`, not a URL. Poll `grid_status` (or the
185
185
  returned poll URL) until live; surface a liveness signal while it builds
186
186
  (never a bare silent wait). Only then return the **live app URL** (not the
@@ -3,7 +3,7 @@
3
3
  A single self-contained HTML SaaS marketing site (hero, features, pricing tiers, testimonials, FAQ, and a closing call to action). Richer than the landing-page template.
4
4
 
5
5
  Static inspiration — a single self-contained `index.html` (inline CSS and JS,
6
- no external CDNs). It deploys instantly via `grid_deploy` and works on every
6
+ no external CDNs). It deploys instantly via `grid_plug` and works on every
7
7
  CloudGrid edition, including hosted.
8
8
 
9
9
  ## Fill it in
@@ -5,10 +5,10 @@ State (if any) lives only in memory and is lost on refresh.
5
5
 
6
6
  ## How it deploys
7
7
 
8
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
8
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
9
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
10
10
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
11
- runtime (async, local edition only); the fast path is `grid_deploy`.
11
+ runtime (async, local edition only); the fast path is `grid_plug`.
12
12
 
13
13
  The fillable HTML is the real template — fetch it with
14
14
  `grid_get_template("template", "saas-marketing")` and fill in the user's content.
@@ -3,7 +3,7 @@
3
3
  A single self-contained HTML service status page: an overall banner, a component list with up / degraded / down pills, per-component uptime bars, and an incident history log. Status is baked into the page.
4
4
 
5
5
  Static inspiration — a single self-contained `index.html` (inline CSS and JS,
6
- no external CDNs). It deploys instantly via `grid_deploy` and works on every
6
+ no external CDNs). It deploys instantly via `grid_plug` and works on every
7
7
  CloudGrid edition, including hosted.
8
8
 
9
9
  ## Fill it in
@@ -5,10 +5,10 @@ State (if any) lives only in memory and is lost on refresh.
5
5
 
6
6
  ## How it deploys
7
7
 
8
- To publish this page, use **`grid_deploy`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
8
+ To publish this page, use **`grid_plug`** with the inline `html`: it deploys as an **inspiration** — instant, and works on the **hosted**
9
9
  edition (Claude Web) as well as local. The reference `cloudgrid.yaml` in this
10
10
  directory (`type: static`) is ONLY for plugging the page as an OWNED static
11
- runtime (async, local edition only); the fast path is `grid_deploy`.
11
+ runtime (async, local edition only); the fast path is `grid_plug`.
12
12
 
13
13
  The fillable HTML is the real template — fetch it with
14
14
  `grid_get_template("template", "status-page")` and fill in the user's content.