@cloudgrid-io/mcp 0.20.45 → 0.20.47

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 (70) hide show
  1. package/package.json +2 -1
  2. package/src/auth.js +18 -4
  3. package/src/corpus/playbook.md +5 -5
  4. package/src/corpus/templates/ai-knowledge-base/AGENTS.md +1 -1
  5. package/src/corpus/templates/appointment-booking/AGENTS.md +5 -5
  6. package/src/corpus/templates/appointment-booking/index.md +4 -4
  7. package/src/corpus/templates/approval-workflow/AGENTS.md +1 -1
  8. package/src/corpus/templates/calendar-scheduler/AGENTS.md +1 -1
  9. package/src/corpus/templates/forum/AGENTS.md +4 -4
  10. package/src/corpus/templates/marketplace/AGENTS.md +1 -1
  11. package/src/corpus/templates/membership-site/AGENTS.md +5 -5
  12. package/src/corpus/templates/membership-site/index.md +4 -4
  13. package/src/corpus/templates/restaurant-reservations/AGENTS.md +7 -7
  14. package/src/corpus/templates/restaurant-reservations/index.md +1 -1
  15. package/src/corpus/templates/subscription-management/AGENTS.md +5 -5
  16. package/src/corpus/templates/subscription-management/index.md +4 -4
  17. package/src/corpus/troubleshooting/persistent-apps.md +1 -1
  18. package/src/corpus/workflows/admin-dashboard.md +3 -3
  19. package/src/corpus/workflows/ai-app.md +4 -4
  20. package/src/corpus/workflows/ai-knowledge-base.md +3 -3
  21. package/src/corpus/workflows/analytics-dashboard.md +3 -3
  22. package/src/corpus/workflows/api-dashboard.md +3 -3
  23. package/src/corpus/workflows/api-service.md +4 -4
  24. package/src/corpus/workflows/app-with-data.md +4 -4
  25. package/src/corpus/workflows/appointment-booking.md +4 -4
  26. package/src/corpus/workflows/approval-workflow.md +2 -2
  27. package/src/corpus/workflows/billing-dashboard.md +4 -4
  28. package/src/corpus/workflows/blog-cms.md +3 -3
  29. package/src/corpus/workflows/booking-system.md +4 -4
  30. package/src/corpus/workflows/calendar-scheduler.md +3 -3
  31. package/src/corpus/workflows/course-platform.md +4 -4
  32. package/src/corpus/workflows/crm.md +3 -3
  33. package/src/corpus/workflows/directory.md +3 -3
  34. package/src/corpus/workflows/docs-app.md +2 -2
  35. package/src/corpus/workflows/erp.md +4 -4
  36. package/src/corpus/workflows/event-board.md +3 -3
  37. package/src/corpus/workflows/expense-tracker.md +3 -3
  38. package/src/corpus/workflows/feature-request-board.md +3 -3
  39. package/src/corpus/workflows/financial-dashboard.md +3 -3
  40. package/src/corpus/workflows/forum.md +4 -4
  41. package/src/corpus/workflows/hr-portal.md +4 -4
  42. package/src/corpus/workflows/internal-tools-portal.md +4 -4
  43. package/src/corpus/workflows/inventory.md +3 -3
  44. package/src/corpus/workflows/invoice.md +3 -3
  45. package/src/corpus/workflows/job-board.md +3 -3
  46. package/src/corpus/workflows/kanban.md +3 -3
  47. package/src/corpus/workflows/lms.md +4 -4
  48. package/src/corpus/workflows/marketplace.md +3 -3
  49. package/src/corpus/workflows/membership-site.md +4 -4
  50. package/src/corpus/workflows/monitoring-dashboard.md +3 -3
  51. package/src/corpus/workflows/multi-service.md +2 -2
  52. package/src/corpus/workflows/online-store.md +4 -4
  53. package/src/corpus/workflows/product-catalog.md +3 -3
  54. package/src/corpus/workflows/project-management.md +3 -3
  55. package/src/corpus/workflows/property-listings.md +3 -3
  56. package/src/corpus/workflows/quiz-platform.md +3 -3
  57. package/src/corpus/workflows/restaurant-reservations.md +4 -4
  58. package/src/corpus/workflows/revenue-dashboard.md +3 -3
  59. package/src/corpus/workflows/semantic-search.md +4 -4
  60. package/src/corpus/workflows/subscription-management.md +4 -4
  61. package/src/corpus/workflows/task-manager.md +3 -3
  62. package/src/corpus/workflows/ticket-system.md +3 -3
  63. package/src/corpus/workflows/time-tracking.md +3 -3
  64. package/src/corpus/workflows/travel-booking.md +4 -4
  65. package/src/index.js +2 -0
  66. package/src/tools/cli.js +4 -3
  67. package/src/tools/constants.js +1 -1
  68. package/src/tools/deploy.js +17 -7
  69. package/src/tools/register.js +70 -36
  70. package/src/web.js +52 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudgrid-io/mcp",
3
- "version": "0.20.45",
3
+ "version": "0.20.47",
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": {
@@ -43,6 +43,7 @@
43
43
  "smoke:redrop": "node test/smoke-redrop.mjs",
44
44
  "smoke:oauth": "node test/smoke-oauth.mjs",
45
45
  "test:auth": "node test/auth.test.mjs",
46
+ "test:auth-strictness": "node test/auth-strictness.test.mjs",
46
47
  "test:win-cli": "node test/windows-cli-resolution.test.mjs",
47
48
  "test:electron-env": "node test/electron-spawn-env.test.mjs",
48
49
  "smoke:docs": "node test/smoke-docs.mjs",
package/src/auth.js CHANGED
@@ -94,14 +94,28 @@ export async function pollStatusOnce(code) {
94
94
  return res.json();
95
95
  }
96
96
 
97
- // Read the stored credentials, or null if absent/unreadable. Same file the CLI
98
- // writes, so an MCP can reuse a CLI login (and vice versa).
97
+ // Read the stored credentials, or null if absent/unreadable/expired. Same file
98
+ // the CLI writes, so an MCP can reuse a CLI login (and vice versa).
99
+ // Returns { jwt, email, ... } when valid, null otherwise.
99
100
  export async function readCredentials() {
101
+ const result = await readCredentialsStatus();
102
+ if (result.expired || !result.creds) return null;
103
+ return result.creds;
104
+ }
105
+
106
+ // Like readCredentials, but distinguishes "expired" from "absent" so callers
107
+ // (grid_start) can surface a targeted message.
108
+ export async function readCredentialsStatus() {
100
109
  try {
101
110
  const creds = JSON.parse(await readFile(credentialsPath(), "utf8"));
102
- return creds && creds.jwt ? creds : null;
111
+ if (!creds || !creds.jwt) return { creds: null, expired: false };
112
+ const claims = decodeJwt(creds.jwt);
113
+ if (claims.exp && claims.exp * 1000 <= Date.now()) {
114
+ return { creds: null, expired: true };
115
+ }
116
+ return { creds, expired: false };
103
117
  } catch {
104
- return null;
118
+ return { creds: null, expired: false };
105
119
  }
106
120
  }
107
121
 
@@ -29,12 +29,12 @@ Operating rules:
29
29
  Plug 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 plugs 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 plugged 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.
30
30
  When you plug a folder that already has a cloudgrid.yaml, grid_plug returns needs_confirmation on the first create instead of plugging — 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.
31
31
 
32
- After a plug: a single HTML page plugs synchronously — the URL is live immediately. A runtime app (folder-based, anything with needs:) builds asynchronously: grid_plug returns status "building". When that happens, call grid_check_deploy every ~15 seconds until it reports "success" or "failed". Do NOT tell the user the app is live until grid_check_deploy confirms success. If it reports "failed", read the build log with grid_view_logs, fix the cause, and re-plug.
32
+ After a plug: a single HTML page plugs synchronously — the URL is live immediately. A runtime app (folder-based, anything with needs:) builds asynchronously: grid_plug returns status "building". When that happens, call grid_check_deploy every ~15 seconds until it reports "success" or "failed". Do NOT tell the user the app is live until grid_check_deploy confirms success. If it reports "failed", read the build log with `grid logs`, fix the cause, and re-plug.
33
33
 
34
34
  Iteration: when the user asks for changes to something already plugged, edit the source and re-call grid_plug with the same target_entity_id to update in place — the URL stays the same. For a single-HTML page, fetch the current HTML with grid_get_app_source, apply the change, and re-plug inline. For a runtime app, edit the files in the folder and re-plug; the build is async, so poll grid_check_deploy the same way as on the first plug.
35
35
 
36
36
  When something goes wrong:
37
- - Build failed or app returning errors: call grid_view_logs to read the build or runtime log. Fix the cause and re-plug.
38
- - Need to see what is running: call grid_status for the current state of an entity (build status, URL, services, needs).
39
- - Bad plug, need to revert: call grid_rollback_deploy to roll back to the previous working version.
40
- - Check what was plugged before: call grid_list_versions to see the version history of an entity.
37
+ - Build failed or app returning errors: run `grid logs` to read the build or runtime log. Fix the cause and re-plug.
38
+ - Need to see what is running: run `grid status` for the current state of an entity (build status, URL, services, needs).
39
+ - Bad plug, need to revert: run `grid rollback` to roll back to the previous working version.
40
+ - Check what was plugged before: run `grid versions` to see the version history of an entity.
@@ -211,7 +211,7 @@ hosted edition cannot build a runtime container.
211
211
  2. The first `grid plug` auto-creates the entity from the manifest (honors its
212
212
  `name:`) and writes `.cloudgrid/link.json`. To register without deploying —
213
213
  e.g. to set secrets first — use `grid plug --no-deploy` (the
214
- `grid_create_project` MCP tool does the same).
214
+ `grid new` CLI command does the same).
215
215
  3. (If you added auth/payments) store the vault secrets with `grid secrets set`;
216
216
  non-secret public config → `grid env`. The AI Gateway and Mongo need no secrets
217
217
  — they are injected by `needs`.
@@ -102,7 +102,7 @@ clients racing for the same slot cannot both win.
102
102
  STRIPE_KEY: stripe-live-key # only if you take deposits
103
103
  STRIPE_WEBHOOK_SECRET: stripe-webhook-secret # only if you take deposits
104
104
  ```
105
- Set the vault items ONCE with `grid_set_secret` (or `grid secrets set`), then
105
+ Set the vault items ONCE with `grid secrets set` (or `grid secrets set`), then
106
106
  the deployer injects each as the named env var (`process.env.AUTH_PROVIDER_KEY`,
107
107
  `process.env.STRIPE_KEY`, …) at runtime and under `grid dev`. Do NOT commit
108
108
  keys; do NOT set secrets in `services.web.env` (that block is for non-secret
@@ -163,20 +163,20 @@ you want client accounts.
163
163
 
164
164
  1. `grid_login_status` → `grid_login` if needed. Respect the grid picker
165
165
  (ask which grid if the user has more than one).
166
- 2. `grid_create_project` an app `<name>` — it scaffolds the project folder and
166
+ 2. `grid new <name>` — it scaffolds the project folder and
167
167
  a `cloudgrid.yaml` with empty `services: {}`. No server entity exists yet —
168
168
  the first plug auto-creates it from the manifest (honoring its `name:`) and
169
169
  writes `.cloudgrid/link.json`.
170
170
  3. Write the app under `services/web/` and set `cloudgrid.yaml` to the active
171
171
  shape: `name` + `services.web{type: nextjs, path: /}` + `needs:{database:true}`
172
172
  + the `vault:` block. (Leave the `reminders` cron service COMMENTED — see §7.)
173
- 4. Set the secrets: `grid_set_secret` for `auth-provider-key` (and, if taking
173
+ 4. Set the secrets: `grid secrets set` for `auth-provider-key` (and, if taking
174
174
  deposits, `stripe-live-key`, `stripe-webhook-secret` — the vault item keys the
175
175
  `vault:` block maps from). Non-secret config (auth publishable key, price ids)
176
- → `grid_set_env` / `services.web.env`. Do NOT set `DATABASE_MONGODB_URL`
176
+ → `grid env set` / `services.web.env`. Do NOT set `DATABASE_MONGODB_URL`
177
177
  yourself — the grid injects it.
178
178
  5. `grid_plug` to deploy. A runtime deploy is **ASYNC** — the first response
179
- is `status: building`, not a live URL. Poll `grid_status` (or the returned
179
+ is `status: building`, not a live URL. Poll `grid_check_deploy` (or the returned
180
180
  poll_url) until live; surface a liveness signal while it builds, never a bare
181
181
  silent wait.
182
182
  6. If taking deposits, once live add the `/api/webhook` URL as the Stripe webhook
@@ -26,7 +26,7 @@ Local edition only.
26
26
  the getter, never at module top level (top-level read fails `next build`).
27
27
  4. **Secrets via the `vault:` block** → env vars. `AUTH_PROVIDER_KEY` (and, for
28
28
  deposits, `STRIPE_KEY` / `STRIPE_WEBHOOK_SECRET`) map to vault items; set them
29
- with `grid_set_secret`, and the deployer injects them at runtime. Read lazily;
29
+ with `grid secrets set`, and the deployer injects them at runtime. Read lazily;
30
30
  do not commit keys or put secrets in `services.web.env`.
31
31
  5. **No double-booking.** `appointments` is the source of truth for "taken";
32
32
  compute open slots as availability minus booked, re-check at write time, and
@@ -65,8 +65,8 @@ vault:
65
65
 
66
66
  ## Deploy (async, local edition)
67
67
 
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_plug`
70
- (async — poll `grid_status` to a live URL). If taking deposits, register the
68
+ `grid new` first (creates the entity + link.json), write the app under
69
+ `services/web/`, set the vault secrets with `grid secrets set`, `grid_plug`
70
+ (async — poll `grid_check_deploy` 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.
@@ -146,7 +146,7 @@ routes and the UI agree on what is legal.
146
146
 
147
147
  ## 6. Deploy steps
148
148
 
149
- 1. `grid_create_project` an app `<name>` — scaffolds the project folder and a
149
+ 1. `grid new <name>` — scaffolds the project folder and a
150
150
  `cloudgrid.yaml` with an empty `services: {}`. No server entity exists yet —
151
151
  the first `grid plug` auto-creates it from the manifest (honoring its
152
152
  `name:`) and writes `.cloudgrid/link.json`.
@@ -205,7 +205,7 @@ hosted edition cannot build a runtime container.
205
205
  2. The first `grid plug` auto-creates the entity from the manifest (honors its
206
206
  `name:`) and writes `.cloudgrid/link.json`. To register without deploying —
207
207
  e.g. to set secrets first — use `grid plug --no-deploy` (the
208
- `grid_create_project` MCP tool does the same).
208
+ `grid new` CLI command does the same).
209
209
  3. (If you mapped vault items) store the values:
210
210
  `grid secrets set <vault-item-key> <value>`. Non-secret public config → `grid env`.
211
211
  Do NOT set `DATABASE_MONGODB_URL` / `MONGODB_URL` yourself — the grid injects them.
@@ -104,7 +104,7 @@ dev` and runtime.
104
104
  injects that vault item as `process.env.ENV_VAR`. This blueprint maps
105
105
  `AUTH_PROVIDER_SECRET_KEY` and `AUTH_PROVIDER_PUBLISHABLE_KEY`. Rename the env
106
106
  keys to whatever the provider SDK expects (see §4) and set the vault items with
107
- `grid_set_secret` / the org vault — do not commit keys.
107
+ `grid secrets set` / the org vault — do not commit keys.
108
108
  - **AI (optional)** — if you add `needs: { ai: true }` (e.g. auto-moderation or
109
109
  summarize-thread), the grid injects **`RUNTIME_GATEWAY_URL`**; call it via
110
110
  `@cloudgrid-io/runtime`. Not required for the base forum.
@@ -169,18 +169,18 @@ A forum is a runtime (built + deployed container) app — **local edition**
169
169
 
170
170
  1. `grid_login_status` → `grid_login` if needed. Respect the grid picker
171
171
  (ask which grid if the user has more than one).
172
- 2. `grid_create_project` an app `<name>` — scaffolds the project folder and a
172
+ 2. `grid new <name>` — scaffolds the project folder and a
173
173
  `cloudgrid.yaml` with empty `services: {}`. No server entity exists yet — the
174
174
  first plug auto-creates it from the manifest (honoring its `name:`) and
175
175
  writes `.cloudgrid/link.json`.
176
176
  3. Write the app under `services/web/` per §1, then fill `cloudgrid.yaml` to the
177
177
  active shape: `name`, `services.web { type: nextjs, path: / }`, `needs:
178
178
  { database: true }`, and the `vault:` mappings for the auth keys.
179
- 4. Set the auth secrets: `grid_set_secret` (or the org vault) for the provider
179
+ 4. Set the auth secrets: `grid secrets set` (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
182
  6. `grid_plug` to deploy. A runtime deploy is **ASYNC** — the first response
183
- is `status: building`, not a live URL. Poll `grid_status` (or the returned
183
+ is `status: building`, not a live URL. Poll `grid_check_deploy` (or the returned
184
184
  poll_url) until live; surface a liveness signal while it builds, never a bare
185
185
  spinner.
186
186
  7. Only once live, return the deployed app URL. Re-plug the SAME entity to update
@@ -185,7 +185,7 @@ hosted edition cannot build a runtime container.
185
185
  the `vault:` block).
186
186
  2. `grid plug --no-deploy` — registers the entity from the manifest (honors its
187
187
  `name:`) and writes `.cloudgrid/link.json`, without building yet (the
188
- `grid_create_project` MCP tool does the same).
188
+ `grid new` CLI command does the same).
189
189
  3. Store the secrets the vault block maps:
190
190
  `grid secrets set stripe-live-key sk_live_…`,
191
191
  `grid secrets set stripe-webhook-secret whsec_…`,
@@ -78,7 +78,7 @@ A user is a member when a `memberships` doc for their `authId` has
78
78
  STRIPE_WEBHOOK_SECRET: stripe-webhook-secret
79
79
  AUTH_PROVIDER_KEY: auth-provider-key
80
80
  ```
81
- Set the vault items ONCE with `grid_set_secret` (or `grid secrets set`), then
81
+ Set the vault items ONCE with `grid secrets set` (or `grid secrets set`), then
82
82
  the deployer injects each as the named env var (`process.env.STRIPE_KEY`, etc.)
83
83
  at runtime and under `grid dev`. Do NOT commit keys; do NOT set them in
84
84
  `services.web.env` (that block is for non-secret config only). Read them
@@ -132,20 +132,20 @@ A user is a member when a `memberships` doc for their `authId` has
132
132
 
133
133
  1. `grid_login_status` → `grid_login` if needed. Respect the grid picker
134
134
  (ask which grid if the user has more than one).
135
- 2. `grid_create_project` an app `<name>` — it scaffolds the project folder and
135
+ 2. `grid new <name>` — it scaffolds the project folder and
136
136
  a `cloudgrid.yaml` with empty `services: {}`. No server entity exists yet —
137
137
  the first plug auto-creates it from the manifest (honoring its `name:`) and
138
138
  writes `.cloudgrid/link.json`.
139
139
  3. Write the app under `services/web/` and set `cloudgrid.yaml` to the active
140
140
  shape: `name` + `services.web{type: nextjs, path: /}` + `needs:{database:true}`
141
141
  + the `vault:` block.
142
- 4. Set the secrets: `grid_set_secret` for `stripe-live-key`,
142
+ 4. Set the secrets: `grid secrets set` for `stripe-live-key`,
143
143
  `stripe-webhook-secret`, `auth-provider-key` (the vault item keys the
144
144
  `vault:` block maps from). Non-secret config (publishable auth key, price id)
145
- → `grid_set_env` / `services.web.env`. Do NOT set `DATABASE_MONGODB_URL`
145
+ → `grid env set` / `services.web.env`. Do NOT set `DATABASE_MONGODB_URL`
146
146
  yourself — the grid injects it.
147
147
  5. `grid_plug` to deploy. A runtime deploy is **ASYNC** — the first response
148
- is `status: building`, not a live URL. Poll `grid_status` (or the returned
148
+ is `status: building`, not a live URL. Poll `grid_check_deploy` (or the returned
149
149
  poll_url) until live; surface a liveness signal while it builds, never a bare
150
150
  silent wait.
151
151
  6. Once live, add the `/api/webhook` URL as the Stripe webhook endpoint and copy
@@ -24,7 +24,7 @@ edition only.
24
24
  the getter, never at module top level (top-level read fails `next build`).
25
25
  4. **Secrets via the `vault:` block** → env vars. `STRIPE_KEY`,
26
26
  `STRIPE_WEBHOOK_SECRET`, `AUTH_PROVIDER_KEY` map to vault items; set them with
27
- `grid_set_secret`, and the deployer injects them at runtime. Read lazily; do
27
+ `grid secrets set`, and the deployer injects them at runtime. Read lazily; do
28
28
  not commit keys or put secrets in `services.web.env`.
29
29
  5. **Gate server-side.** Auth answers "who are you"; the `memberships`
30
30
  collection answers "have you paid". `app/members/layout.js` checks membership
@@ -60,7 +60,7 @@ vault:
60
60
 
61
61
  ## Deploy (async, local edition)
62
62
 
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_plug`
65
- (async — poll `grid_status` to a live URL), then register the `/api/webhook`
63
+ `grid new` first (creates the entity + link.json), write the app under
64
+ `services/web/`, set the vault secrets with `grid secrets set`, `grid_plug`
65
+ (async — poll `grid_check_deploy` 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.
@@ -115,9 +115,9 @@ You never provision infra or set connection strings by hand. Declare intent in
115
115
  `STRIPE_KEY: stripe-live-key`, `SENDGRID_API_KEY: sendgrid-key`,
116
116
  `AUTH_PROVIDER_KEY: auth-provider-secret`. The platform reads the named item
117
117
  from the org vault and injects it as that env var at runtime. Store the actual
118
- secret value with `grid_set_secret` (or the org vault UI) — never commit it. In
118
+ secret value with `grid secrets set` (or the org vault UI) — never commit it. In
119
119
  code read `process.env.STRIPE_KEY`, `process.env.SENDGRID_API_KEY`, etc. Vault
120
- is the CloudGrid-correct path for third-party keys; `grid_set_env` is for
120
+ is the CloudGrid-correct path for third-party keys; `grid env set` is for
121
121
  non-secret config only.
122
122
 
123
123
  - **AI (optional).** If you add AI (e.g. menu-copy generation, natural-language
@@ -154,7 +154,7 @@ Reserved env var names you must NOT set: `PORT`, `APP_NAME`, `SERVICE_NAME`,
154
154
  provider; leave `/`, `/reserve`, `/api/menu`, `/api/reservations` (POST),
155
155
  `/api/webhooks/stripe` public.
156
156
  3. Initialize the SDK from `process.env.AUTH_PROVIDER_KEY` (+ any public
157
- publishable key via `grid_set_env`). The public booking flow needs no login.
157
+ publishable key via `grid env set`). The public booking flow needs no login.
158
158
 
159
159
  Keep the public reservation POST open; only staff read/mutate endpoints
160
160
  (`GET /api/reservations`, `PATCH/DELETE /api/reservations/[id]`, `/staff/*`) sit
@@ -169,19 +169,19 @@ build is **asynchronous**.
169
169
 
170
170
  1. `grid_login_status` (→ `grid_login` if needed). Pick the grid if the
171
171
  user has more than one.
172
- 2. `grid_create_project` an app `<name>` — scaffolds the project folder and a
172
+ 2. `grid new <name>` — scaffolds the project folder and a
173
173
  `cloudgrid.yaml` with empty `services: {}`. No server entity exists yet — the
174
174
  first plug auto-creates it from the manifest (honoring its `name:`) and
175
175
  writes `.cloudgrid/link.json`.
176
176
  3. **Fill** — write the app under `services/web/`, then set `cloudgrid.yaml` to
177
177
  this blueprint's active fields: `name`, `services.web { type: nextjs, path: / }`,
178
178
  `needs: { database: true }`, and the `vault:` mappings you actually use.
179
- 4. Store secrets: `grid_set_secret` for the vault item values (Stripe/SendGrid/
180
- auth). Non-secret config (publishable keys, feature flags) → `grid_set_env`.
179
+ 4. Store secrets: `grid secrets set` for the vault item values (Stripe/SendGrid/
180
+ auth). Non-secret config (publishable keys, feature flags) → `grid env set`.
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
183
  6. `grid_plug` — builds + deploys `services/web/`. **Async**: the first
184
- response is `status: building`, not a URL. Poll `grid_status` (or the
184
+ response is `status: building`, not a URL. Poll `grid_check_deploy` (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
187
187
  build/log link).
@@ -20,7 +20,7 @@ app under `services/web/` following it — the proven `app-with-data` shape with
20
20
  `MONGODB_URL` fallback — the grid injects it; never hardcode, never commit.
21
21
  3. **Third-party secrets go through the `vault:` block** (Stripe `STRIPE_KEY`,
22
22
  email `SENDGRID_API_KEY`, optional `AUTH_PROVIDER_KEY`) → injected env vars;
23
- store values with `grid_set_secret`.
23
+ store values with `grid secrets set`.
24
24
  4. **Declare `needs: { database: true }`** (canonical) — never mix `needs:` and
25
25
  `requires:`.
26
26
  5. **Cron reminder service is documented but NOT deployable yet** (platform issue
@@ -89,7 +89,7 @@ client for plan/status — read this (kept current by the webhook).
89
89
  STRIPE_KEY: stripe-live-key
90
90
  STRIPE_WEBHOOK_SECRET: stripe-webhook-secret
91
91
  ```
92
- Set the vault items ONCE with `grid_set_secret` (or `grid secrets set`), then
92
+ Set the vault items ONCE with `grid secrets set` (or `grid secrets set`), then
93
93
  the deployer injects each as the named env var (`process.env.STRIPE_KEY`, etc.)
94
94
  at runtime and under `grid dev`. Do NOT commit keys; do NOT set them in
95
95
  `services.web.env` (that block is for non-secret config only). Read them lazily
@@ -160,21 +160,21 @@ known user — otherwise anyone could change anyone's plan.
160
160
 
161
161
  1. `grid_login_status` → `grid_login` if needed. Respect the grid picker
162
162
  (ask which grid if the user has more than one).
163
- 2. `grid_create_project` an app `<name>` — it scaffolds the project folder and
163
+ 2. `grid new <name>` — it scaffolds the project folder and
164
164
  a `cloudgrid.yaml` with empty `services: {}`. No server entity exists yet —
165
165
  the first plug auto-creates it from the manifest (honoring its `name:`) and
166
166
  writes `.cloudgrid/link.json`.
167
167
  3. Write the app under `services/web/` and set `cloudgrid.yaml` to the active
168
168
  shape: `name` + `services.web{type: nextjs, path: /}` + `needs:{database:true}`
169
169
  + the `vault:` block.
170
- 4. Set the secrets: `grid_set_secret` for `stripe-live-key`,
170
+ 4. Set the secrets: `grid secrets set` for `stripe-live-key`,
171
171
  `stripe-webhook-secret` (and `auth-provider-key` if you use an auth SDK) — the
172
172
  vault item keys the `vault:` block maps from. Non-secret config (Stripe
173
- publishable key, price ids, auth publishable key) → `grid_set_env` /
173
+ publishable key, price ids, auth publishable key) → `grid env set` /
174
174
  `services.web.env`. Do NOT set `DATABASE_MONGODB_URL` yourself — the grid
175
175
  injects it.
176
176
  5. `grid_plug` to deploy. A runtime deploy is **ASYNC** — the first response
177
- is `status: building`, not a live URL. Poll `grid_status` (or the returned
177
+ is `status: building`, not a live URL. Poll `grid_check_deploy` (or the returned
178
178
  poll_url) until live; surface a liveness signal while it builds, never a bare
179
179
  silent wait.
180
180
  6. Once live, add the `/api/webhook` URL as the Stripe webhook endpoint, copy
@@ -30,7 +30,7 @@ wiring.
30
30
  `DATABASE_MONGODB_URL` (legacy `MONGODB_URL` fallback). Read it LAZILY inside
31
31
  the getter, never at module top level (top-level read fails `next build`).
32
32
  4. **Secrets via the `vault:` block** → env vars. `STRIPE_KEY` and
33
- `STRIPE_WEBHOOK_SECRET` map to vault items; set them with `grid_set_secret`,
33
+ `STRIPE_WEBHOOK_SECRET` map to vault items; set them with `grid secrets set`,
34
34
  and the deployer injects them at runtime. Read lazily; do not commit keys or
35
35
  put secrets in `services.web.env` (publishable key + price ids go there).
36
36
  5. **The webhook is the source of truth.** Change-plan / cancel APIs call Stripe;
@@ -66,8 +66,8 @@ vault:
66
66
 
67
67
  ## Deploy (async, local edition)
68
68
 
69
- `grid_create_project` first (creates the entity + link.json), write the app under
70
- `services/web/`, set the vault secrets with `grid_set_secret`, `grid_plug`
71
- (async — poll `grid_status` to a live URL), then register the `/api/webhook`
69
+ `grid new` first (creates the entity + link.json), write the app under
70
+ `services/web/`, set the vault secrets with `grid secrets set`, `grid_plug`
71
+ (async — poll `grid_check_deploy` to a live URL), then register the `/api/webhook`
72
72
  URL in Stripe, configure the Billing Portal, and re-plug. Re-plug the same entity
73
73
  to update the same URL.
@@ -15,7 +15,7 @@ Match the symptom to the row, apply the fix, and stop.
15
15
  | `next build` fails / DB connection error at build time | The DB env var is read at module top level; `next build` imports the module for route analysis before the grid injects the var | Read `process.env.DATABASE_MONGODB_URL` (with a legacy `MONGODB_URL` fallback) LAZILY inside the getter (e.g. inside `getDb`), never at module load. Moving the check into the function lets the build pass. |
16
16
  | App builds + deploys but every request 500s with `DATABASE_MONGODB_URL not set` | The datastore isn't declared, or you declared the deprecated `requires:` instead of `needs:` | Declare `needs: { database: true }` in `cloudgrid.yaml`. The deployer provisions Mongo and injects `DATABASE_MONGODB_URL` (plus the legacy `MONGODB_URL` alias). Never set `needs:` and `requires:` together (the validator rejects it). |
17
17
  | `DATABASE_MONGODB_URL is undefined` (or the db.js guard throws) | The env var isn't present because you're not running under the grid | Run locally with `grid dev`, or deploy with `grid plug` — the grid injects `DATABASE_MONGODB_URL` (+legacy `MONGODB_URL`) at dev-time and runtime. Do NOT set it yourself and never hardcode a connection string. |
18
- | Deploy seems stuck / no URL returned | Runtime deploys are asynchronous | `plug` returns `status: building`, not a URL. Poll `grid_status` (or the poll_url) until the app is live, then return the live URL. Don't treat the build/log link as the deliverable. |
18
+ | Deploy seems stuck / no URL returned | Runtime deploys are asynchronous | `plug` returns `status: building`, not a URL. Poll `grid_check_deploy` (or the poll_url) until the app is live, then return the live URL. Don't treat the build/log link as the deliverable. |
19
19
  | It won't build on the hosted edition | Hosted MCP is inline-only — it can't run the CLI or folder-plug | Runtime apps need the LOCAL edition (Claude Desktop/Code) or the CLI. On hosted, tell the user persistence isn't available there and offer a static version instead. |
20
20
  | Redis not available | `cache` wasn't declared | Add `cache: true` to `needs:` in `cloudgrid.yaml`; the grid then injects `CACHE_REDIS_URL` (plus the legacy `REDIS_URL` alias). Only add it if the app actually needs Redis. |
21
21
 
@@ -39,7 +39,7 @@ edition** (Claude Desktop / Claude Code) or the CLI.
39
39
 
40
40
  ## 3. Scaffold
41
41
 
42
- `grid_create_project` an app `<name>`. It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
42
+ `grid new <name>`. It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
43
43
  `services: {}`. No server entity exists yet — the first `grid plug` auto-creates
44
44
  it from the manifest (honoring its `name:`) and writes `.cloudgrid/link.json`.
45
45
  Then (a) write the app under **`services/web/`**,
@@ -84,7 +84,7 @@ before deploying. Don't require it.
84
84
 
85
85
  ## 6. Config
86
86
 
87
- - API keys / secrets → `grid_set_secret`. Non-secret config → `grid_set_env`.
87
+ - API keys / secrets → `grid secrets set`. Non-secret config → `grid env set`.
88
88
  - Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` or the
89
89
  legacy `MONGODB_URL`) — the grid injects them.
90
90
 
@@ -92,7 +92,7 @@ before deploying. Don't require it.
92
92
 
93
93
  Deploy the folder with `grid_plug`. A **runtime deploy is ASYNC**: the first
94
94
  response is `status: "building"`, NOT a live URL yet.
95
- - Poll `grid_status` (or the returned poll_url) until the entity is live.
95
+ - Poll `grid_check_deploy` (or the returned poll_url) until the entity is live.
96
96
  - Surface a liveness signal while it builds — never a bare silent wait.
97
97
  - Only once it is live, return the deployed app URL (NOT the build/log link).
98
98
 
@@ -41,7 +41,7 @@ Persistent apps are owned entities.
41
41
 
42
42
  ## 3. Scaffold
43
43
 
44
- `grid_create_project` an app `<name>`. It scaffolds the project folder, a
44
+ `grid new <name>`. It scaffolds the project folder, a
45
45
  `cloudgrid.yaml`, and a starter `web` service. No server entity exists yet — the
46
46
  first `grid plug` auto-creates it from the manifest (honoring its `name:`) and
47
47
  writes `.cloudgrid/link.json`.
@@ -117,8 +117,8 @@ are wired in dev too — and send a test message before deploying. Don't require
117
117
 
118
118
  ## 6. Config
119
119
 
120
- - Extra API keys / secrets (only if the app needs its own) → `grid_set_secret`.
121
- - Non-secret config → `grid_set_env`.
120
+ - Extra API keys / secrets (only if the app needs its own) → `grid secrets set`.
121
+ - Non-secret config → `grid env set`.
122
122
  - Do **NOT** set the DB connection var yourself (`DATABASE_MONGODB_URL` / legacy
123
123
  `MONGODB_URL`) and do **NOT** set an AI key — the grid injects the DB var and
124
124
  the AI SDK auto-detects the in-grid identity.
@@ -127,7 +127,7 @@ are wired in dev too — and send a test message before deploying. Don't require
127
127
 
128
128
  Deploy the folder with `grid_plug`. A **runtime deploy is ASYNC**: the first
129
129
  response is `status: "building"` with a `poll_url` / entity, NOT a live URL yet.
130
- - Poll `grid_status` (or the returned poll_url) until the entity is live.
130
+ - Poll `grid_check_deploy` (or the returned poll_url) until the entity is live.
131
131
  - Surface a liveness signal while it builds — never a bare silent wait.
132
132
  - Only once it is live, return the deployed URL (the app URL, NOT the build/log
133
133
  link).
@@ -65,7 +65,7 @@ There is no app code to copy — you generate it from the guide.
65
65
 
66
66
  ## 4. Scaffold + fill cloudgrid.yaml
67
67
 
68
- `grid_create_project` an app `<name>` — it scaffolds the project folder and a
68
+ `grid new <name>` — it scaffolds the project folder and a
69
69
  starter `cloudgrid.yaml` with empty `services:{}` (no server entity yet; the
70
70
  first `grid plug` auto-creates it from the manifest, honoring its `name:`, and
71
71
  writes `.cloudgrid/link.json`). Then put the app under **`services/web/`** and
@@ -120,7 +120,7 @@ Generate the files under `services/web/` per the guide:
120
120
  yourself; the grid injects them.
121
121
  - Only if you add auth/payments: map the secret in the `vault:` block
122
122
  (`AUTH_PROVIDER_KEY` and/or `STRIPE_KEY`) and store the value with
123
- `grid secrets set <vault-item-key> …`. Non-secret public config → `grid_set_env`.
123
+ `grid secrets set <vault-item-key> …`. Non-secret public config → `grid env set`.
124
124
 
125
125
  ## 7. (Optional) Run locally
126
126
 
@@ -131,7 +131,7 @@ Gateway before deploying. Don't require it.
131
131
 
132
132
  Deploy the folder with `grid_plug`. A **runtime deploy is ASYNC**: the first
133
133
  response is `status: "building"`, NOT a live URL yet.
134
- - Poll `grid_status` (or the returned poll_url) until the entity is live.
134
+ - Poll `grid_check_deploy` (or the returned poll_url) until the entity is live.
135
135
  - Surface a liveness signal while it builds — never a bare silent wait.
136
136
  - Only once it is live, return the deployed app URL (NOT the build/log link).
137
137
 
@@ -40,7 +40,7 @@ edition** (Claude Desktop / Claude Code) or the CLI.
40
40
 
41
41
  ## 3. Scaffold
42
42
 
43
- `grid_create_project` an app `<name>`. It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
43
+ `grid new <name>`. It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
44
44
  `services: {}`. No server entity exists yet — the first `grid plug` auto-creates
45
45
  it from the manifest (honoring its `name:`) and writes `.cloudgrid/link.json`.
46
46
  Then (a) write the app under **`services/web/`**,
@@ -86,7 +86,7 @@ before deploying. Don't require it.
86
86
 
87
87
  ## 6. Config
88
88
 
89
- - API keys / secrets → `grid_set_secret`. Non-secret config → `grid_set_env`.
89
+ - API keys / secrets → `grid secrets set`. Non-secret config → `grid env set`.
90
90
  - Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` or the
91
91
  legacy `MONGODB_URL`) — the grid injects them.
92
92
 
@@ -94,7 +94,7 @@ before deploying. Don't require it.
94
94
 
95
95
  Deploy the folder with `grid_plug`. A **runtime deploy is ASYNC**: the first
96
96
  response is `status: "building"`, NOT a live URL yet.
97
- - Poll `grid_status` (or the returned poll_url) until the entity is live.
97
+ - Poll `grid_check_deploy` (or the returned poll_url) until the entity is live.
98
98
  - Surface a liveness signal while it builds — never a bare silent wait.
99
99
  - Only once it is live, return the deployed app URL (NOT the build/log link).
100
100
 
@@ -39,7 +39,7 @@ edition** (Claude Desktop / Claude Code) or the CLI.
39
39
 
40
40
  ## 3. Scaffold
41
41
 
42
- `grid_create_project` an app `<name>`. It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
42
+ `grid new <name>`. It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
43
43
  `services: {}`. No server entity exists yet — the first `grid plug` auto-creates
44
44
  it from the manifest (honoring its `name:`) and writes `.cloudgrid/link.json`.
45
45
  Then (a) write the app under **`services/web/`**,
@@ -84,7 +84,7 @@ before deploying. Don't require it.
84
84
 
85
85
  ## 6. Config
86
86
 
87
- - API keys / secrets → `grid_set_secret`. Non-secret config → `grid_set_env`.
87
+ - API keys / secrets → `grid secrets set`. Non-secret config → `grid env set`.
88
88
  - Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` or the
89
89
  legacy `MONGODB_URL`) — the grid injects them.
90
90
 
@@ -92,7 +92,7 @@ before deploying. Don't require it.
92
92
 
93
93
  Deploy the folder with `grid_plug`. A **runtime deploy is ASYNC**: the first
94
94
  response is `status: "building"`, NOT a live URL yet.
95
- - Poll `grid_status` (or the returned poll_url) until the entity is live.
95
+ - Poll `grid_check_deploy` (or the returned poll_url) until the entity is live.
96
96
  - Surface a liveness signal while it builds — never a bare silent wait.
97
97
  - Only once it is live, return the deployed app URL (NOT the build/log link).
98
98
 
@@ -42,7 +42,7 @@ Persistent services are owned entities.
42
42
 
43
43
  ## 3. Scaffold
44
44
 
45
- `grid_create_project` an app `<name>`. It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
45
+ `grid new <name>`. It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
46
46
  `services: {}`. No server entity exists yet — the first `grid plug` auto-creates
47
47
  it from the manifest (honoring its `name:`) and writes `.cloudgrid/link.json`.
48
48
 
@@ -95,8 +95,8 @@ and hit the endpoints before deploying. Don't require it.
95
95
 
96
96
  ## 6. Config
97
97
 
98
- - API keys / secrets → `grid_set_secret`.
99
- - Non-secret config → `grid_set_env`.
98
+ - API keys / secrets → `grid secrets set`.
99
+ - Non-secret config → `grid env set`.
100
100
  - Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL`, or the
101
101
  legacy `MONGODB_URL` alias) — the grid injects them.
102
102
 
@@ -104,7 +104,7 @@ and hit the endpoints before deploying. Don't require it.
104
104
 
105
105
  Deploy the folder with `grid_plug`. A **runtime deploy is ASYNC**: the first
106
106
  response is `status: "building"` with a `poll_url` / entity, NOT a live URL yet.
107
- - Poll `grid_status` (or the returned poll_url) until the entity is live.
107
+ - Poll `grid_check_deploy` (or the returned poll_url) until the entity is live.
108
108
  - Surface a liveness signal while it builds — never a bare silent wait.
109
109
  - Only once it is live, return the deployed URL (the API base URL, NOT the
110
110
  build/log link).
@@ -43,7 +43,7 @@ Persistent apps are owned entities.
43
43
 
44
44
  ## 3. Scaffold
45
45
 
46
- `grid_create_project` an app `<name>` (the default `--type` is fine). It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
46
+ `grid new <name>` (the default `--type` is fine). It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
47
47
  `services: {}`. No server entity exists yet — the first `grid plug` auto-creates
48
48
  it from the manifest (honoring its `name:`) and writes `.cloudgrid/link.json`.
49
49
 
@@ -95,8 +95,8 @@ and sanity-check before deploying. Don't require it.
95
95
 
96
96
  ## 6. Config
97
97
 
98
- - API keys / secrets → `grid_set_secret`.
99
- - Non-secret config → `grid_set_env`.
98
+ - API keys / secrets → `grid secrets set`.
99
+ - Non-secret config → `grid env set`.
100
100
  - Do **NOT** set the DB/cache connection vars yourself (`DATABASE_MONGODB_URL`,
101
101
  `CACHE_REDIS_URL`, or their legacy `MONGODB_URL` / `REDIS_URL` aliases) — the
102
102
  grid injects them.
@@ -105,7 +105,7 @@ and sanity-check before deploying. Don't require it.
105
105
 
106
106
  Deploy the folder with `grid_plug`. A **runtime deploy is ASYNC**: the first
107
107
  response is `status: "building"` with a `poll_url` / entity, NOT a live URL yet.
108
- - Poll `grid_status` (or the returned poll_url) until the entity is live.
108
+ - Poll `grid_check_deploy` (or the returned poll_url) until the entity is live.
109
109
  - Surface a liveness signal while it builds — keep the user informed, never a
110
110
  bare silent wait.
111
111
  - Only once it is live, return the deployed URL (the app URL, NOT the build/log
@@ -54,7 +54,7 @@ workflow:
54
54
 
55
55
  ## 4. Scaffold
56
56
 
57
- `grid_create_project` an app `<name>`. It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
57
+ `grid new <name>`. It scaffolds the project folder and writes a `cloudgrid.yaml` with an EMPTY
58
58
  `services: {}`. No server entity exists yet — the first `grid plug` auto-creates
59
59
  it from the manifest (honoring its `name:`) and writes `.cloudgrid/link.json`.
60
60
  Then write the app under **`services/web/`** and
@@ -102,12 +102,12 @@ never set `needs:` and `requires:` together (the validator rejects it).
102
102
 
103
103
  ## 6. Config / secrets
104
104
 
105
- - Auth + Stripe secrets → `grid_set_secret` (set the vault items `auth-provider-key`,
105
+ - Auth + Stripe secrets → `grid secrets set` (set the vault items `auth-provider-key`,
106
106
  and if taking deposits `stripe-live-key`, `stripe-webhook-secret`, that the
107
107
  `vault:` block maps from). The deployer injects each as its env var at runtime
108
108
  and under `grid dev`.
109
109
  - Non-secret config (auth publishable key `NEXT_PUBLIC_...`, Stripe price ids) →
110
- `grid_set_env` / `services.web.env`.
110
+ `grid env set` / `services.web.env`.
111
111
  - Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` / legacy
112
112
  `MONGODB_URL`) — the grid injects them.
113
113
 
@@ -130,7 +130,7 @@ claim reminders are live.
130
130
 
131
131
  Deploy the folder with `grid_plug`. A **runtime deploy is ASYNC**: the first
132
132
  response is `status: "building"`, NOT a live URL yet.
133
- - Poll `grid_status` (or the returned poll_url) until the entity is live.
133
+ - Poll `grid_check_deploy` (or the returned poll_url) until the entity is live.
134
134
  - Surface a liveness signal while it builds — never a bare silent wait.
135
135
  - If taking deposits, once live register the `/api/webhook` URL as the Stripe
136
136
  webhook endpoint, copy the signing secret into the `stripe-webhook-secret`