@cloudgrid-io/mcp 0.12.0 → 0.13.0

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 (80) hide show
  1. package/package.json +1 -1
  2. package/src/corpus/capability-map.md +21 -2
  3. package/src/corpus/examples/crm/index.md +273 -0
  4. package/src/corpus/examples/kanban/index.md +256 -0
  5. package/src/corpus/templates/admin-dashboard/README.md +75 -0
  6. package/src/corpus/templates/admin-dashboard/cloudgrid.yaml +15 -0
  7. package/src/corpus/templates/admin-dashboard/index.md +78 -0
  8. package/src/corpus/templates/admin-dashboard/services/web/app/api/orders/route.js +64 -0
  9. package/src/corpus/templates/admin-dashboard/services/web/app/api/users/route.js +63 -0
  10. package/src/corpus/templates/admin-dashboard/services/web/app/layout.js +39 -0
  11. package/src/corpus/templates/admin-dashboard/services/web/app/page.js +73 -0
  12. package/src/corpus/templates/admin-dashboard/services/web/app/resource-table.js +94 -0
  13. package/src/corpus/templates/admin-dashboard/services/web/lib/db.js +32 -0
  14. package/src/corpus/templates/admin-dashboard/services/web/package.json +16 -0
  15. package/src/corpus/templates/api-docs/README.md +28 -0
  16. package/src/corpus/templates/api-docs/cloudgrid.yaml +10 -0
  17. package/src/corpus/templates/api-docs/index.html +136 -0
  18. package/src/corpus/templates/api-docs/index.md +30 -0
  19. package/src/corpus/templates/changelog/README.md +27 -0
  20. package/src/corpus/templates/changelog/cloudgrid.yaml +10 -0
  21. package/src/corpus/templates/changelog/index.html +80 -0
  22. package/src/corpus/templates/changelog/index.md +30 -0
  23. package/src/corpus/templates/crm/README.md +72 -0
  24. package/src/corpus/templates/crm/cloudgrid.yaml +15 -0
  25. package/src/corpus/templates/crm/index.md +68 -0
  26. package/src/corpus/templates/crm/services/web/app/api/contacts/route.js +80 -0
  27. package/src/corpus/templates/crm/services/web/app/contact-manager.js +102 -0
  28. package/src/corpus/templates/crm/services/web/app/layout.js +35 -0
  29. package/src/corpus/templates/crm/services/web/app/page.js +34 -0
  30. package/src/corpus/templates/crm/services/web/lib/db.js +32 -0
  31. package/src/corpus/templates/crm/services/web/package.json +16 -0
  32. package/src/corpus/templates/docs-site/README.md +28 -0
  33. package/src/corpus/templates/docs-site/cloudgrid.yaml +10 -0
  34. package/src/corpus/templates/docs-site/index.html +122 -0
  35. package/src/corpus/templates/docs-site/index.md +30 -0
  36. package/src/corpus/templates/kanban/README.md +72 -0
  37. package/src/corpus/templates/kanban/cloudgrid.yaml +15 -0
  38. package/src/corpus/templates/kanban/index.md +68 -0
  39. package/src/corpus/templates/kanban/services/web/app/api/cards/route.js +70 -0
  40. package/src/corpus/templates/kanban/services/web/app/board.js +93 -0
  41. package/src/corpus/templates/kanban/services/web/app/layout.js +37 -0
  42. package/src/corpus/templates/kanban/services/web/app/page.js +32 -0
  43. package/src/corpus/templates/kanban/services/web/lib/db.js +32 -0
  44. package/src/corpus/templates/kanban/services/web/package.json +16 -0
  45. package/src/corpus/templates/portfolio/README.md +29 -0
  46. package/src/corpus/templates/portfolio/cloudgrid.yaml +10 -0
  47. package/src/corpus/templates/portfolio/index.html +126 -0
  48. package/src/corpus/templates/portfolio/index.md +30 -0
  49. package/src/corpus/templates/saas-marketing/README.md +30 -0
  50. package/src/corpus/templates/saas-marketing/cloudgrid.yaml +10 -0
  51. package/src/corpus/templates/saas-marketing/index.html +212 -0
  52. package/src/corpus/templates/saas-marketing/index.md +30 -0
  53. package/src/corpus/templates/status-page/README.md +28 -0
  54. package/src/corpus/templates/status-page/cloudgrid.yaml +10 -0
  55. package/src/corpus/templates/status-page/index.html +117 -0
  56. package/src/corpus/templates/status-page/index.md +30 -0
  57. package/src/corpus/templates/task-manager/README.md +72 -0
  58. package/src/corpus/templates/task-manager/cloudgrid.yaml +15 -0
  59. package/src/corpus/templates/task-manager/index.md +68 -0
  60. package/src/corpus/templates/task-manager/services/web/app/api/tasks/route.js +77 -0
  61. package/src/corpus/templates/task-manager/services/web/app/layout.js +39 -0
  62. package/src/corpus/templates/task-manager/services/web/app/page.js +33 -0
  63. package/src/corpus/templates/task-manager/services/web/app/task-list.js +110 -0
  64. package/src/corpus/templates/task-manager/services/web/lib/db.js +32 -0
  65. package/src/corpus/templates/task-manager/services/web/package.json +16 -0
  66. package/src/corpus/templates/waitlist/README.md +38 -0
  67. package/src/corpus/templates/waitlist/cloudgrid.yaml +10 -0
  68. package/src/corpus/templates/waitlist/index.html +69 -0
  69. package/src/corpus/templates/waitlist/index.md +41 -0
  70. package/src/corpus/workflows/admin-dashboard.md +102 -0
  71. package/src/corpus/workflows/api-docs.md +36 -0
  72. package/src/corpus/workflows/changelog.md +33 -0
  73. package/src/corpus/workflows/crm.md +101 -0
  74. package/src/corpus/workflows/docs-site.md +35 -0
  75. package/src/corpus/workflows/kanban.md +102 -0
  76. package/src/corpus/workflows/portfolio.md +35 -0
  77. package/src/corpus/workflows/saas-marketing.md +37 -0
  78. package/src/corpus/workflows/status-page.md +35 -0
  79. package/src/corpus/workflows/task-manager.md +101 -0
  80. package/src/corpus/workflows/waitlist.md +42 -0
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: admin-dashboard
3
+ when: admin dashboard, admin panel, back-office, CRUD admin, manage records — a persistent admin over one or two Mongo collections with a metrics header + management table. Needs a database → runtime → local edition.
4
+ needs: database
5
+ deploy: runtime
6
+ editions: local
7
+ capabilities_note: persistent — needs a database (Mongo). Runtime app, async build, local edition only. Declare the canonical `needs: { database: true }`; the deployer injects DATABASE_MONGODB_URL (+legacy MONGODB_URL).
8
+ summary: Build a persistent Next.js + Mongo admin panel on the grid — a couple of resource collections (e.g. users, orders) with a metrics header (counts + revenue) and a management table (add/delete). Edition-gate first, scaffold, put the app under services/web/, wire process.env.DATABASE_MONGODB_URL (legacy MONGODB_URL fallback) lazily, declare needs:{database:true} (not requires:), deploy async, poll to a live URL.
9
+ ---
10
+
11
+ # Workflow: admin-dashboard
12
+
13
+ The user wants an admin panel / back-office to **manage records** — a couple of
14
+ resources (e.g. users and orders) with a metrics header (counts, revenue) and a
15
+ management table (add / delete), all persisted across refresh and shared across
16
+ sessions. That is a **runtime app** backed by the grid's shared Mongo, not a
17
+ static dashboard page. It is the same proven shape as `app-with-data`, generalised
18
+ over one or two Mongo collections. (For a display-only metrics page with baked-in
19
+ data, use the static `dashboard` template instead.)
20
+
21
+ Follow this recipe. Be honest that a runtime deploy is async (not instant like a
22
+ static drop) and that it needs the local edition.
23
+
24
+ ## 1. Edition check FIRST (hard gate)
25
+
26
+ A persistent app is a built + deployed container. It requires the **local
27
+ edition** (Claude Desktop / Claude Code) or the CLI.
28
+
29
+ - **Hosted edition (Claude Web / hosted MCP):** you CANNOT build a runtime app —
30
+ hosted is inline-only and can only publish static pages. Tell the user
31
+ plainly, offer a **static version** instead, and STOP the runtime path here.
32
+ - **Local edition:** continue.
33
+
34
+ ## 2. Auth + grid
35
+
36
+ 1. Ensure signed in: `gridctl_login_status`; if not, `gridctl_login`.
37
+ 2. A grid is required. Respect the grid picker: if the user has more than one
38
+ grid, ask which to use; do not assume a target.
39
+
40
+ ## 3. Scaffold
41
+
42
+ `gridctl_init` an app `<name>`. `init` creates the entity + `.cloudgrid/link.json`
43
+ and writes a `cloudgrid.yaml` with an EMPTY `services: {}`. `plug` needs a linked
44
+ directory, so run `init` FIRST. Then (a) write the app under **`services/web/`**,
45
+ and (b) fill `cloudgrid.yaml` to the shape below (`services.web` + `needs:
46
+ { database: true }`).
47
+
48
+ ## 4. Add the datastore + wire Mongo
49
+
50
+ 1. Set `cloudgrid.yaml`. **App code MUST live under `services/<name>/`** —
51
+ `path:` is the URL mount, NOT the filesystem path.
52
+ ```yaml
53
+ name: my-admin
54
+ services:
55
+ web:
56
+ type: nextjs
57
+ path: /
58
+ needs:
59
+ database: true
60
+ ```
61
+ **Declare the datastore with `needs: { database: true }`** — the canonical
62
+ shape. The deployer provisions Mongo and injects `DATABASE_MONGODB_URL` (plus
63
+ the legacy `MONGODB_URL` alias). `requires:` is the deprecated v1 alias; don't
64
+ author new yaml with it, and never set `needs:` and `requires:` together (the
65
+ validator rejects it).
66
+ 2. Fetch the template for the Mongo wiring + CRUD shape:
67
+ `gridctl_fetch("template", "admin-dashboard")`. It is a minimal, real Next.js
68
+ + `mongodb`-driver admin panel under `services/web/`: a lazy client in
69
+ `services/web/lib/db.js`, two App-Router GET/POST/DELETE routes (`users` and
70
+ `orders`), a server-component page that computes a metrics header, and a
71
+ reusable client management table.
72
+ 3. Adapt it (rename or replace the resource collections, change fields, adjust
73
+ the metrics). **Read the DB from `process.env.DATABASE_MONGODB_URL`** (legacy
74
+ `process.env.MONGODB_URL` fallback) — the grid injects it at dev-time and
75
+ runtime.
76
+ - **Put the DB connection behind a lazy getter — never read the connection
77
+ string at module top level, or `next build` fails.**
78
+
79
+ ## 5. (Optional) Run locally
80
+
81
+ Mention that the user can `grid dev` to run locally against the injected Mongo
82
+ before deploying. Don't require it.
83
+
84
+ ## 6. Config
85
+
86
+ - API keys / secrets → `gridctl_secrets`. Non-secret config → `gridctl_env`.
87
+ - Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` or the
88
+ legacy `MONGODB_URL`) — the grid injects them.
89
+
90
+ ## 7. Deploy (async)
91
+
92
+ Deploy the folder with `gridctl_plug`. A **runtime deploy is ASYNC**: the first
93
+ response is `status: "building"`, NOT a live URL yet.
94
+ - Poll `gridctl_status` (or the returned poll_url) until the entity is live.
95
+ - Surface a liveness signal while it builds — never a bare silent wait.
96
+ - Only once it is live, return the deployed app URL (NOT the build/log link).
97
+
98
+ ## 8. Return the live URL + iterate
99
+
100
+ Give the user the live app URL — that is the deliverable. To iterate, re-plug the
101
+ SAME entity so it updates the same URL. Keep it honest: async build, local-edition
102
+ only, credentials injected by the grid.
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: api-docs
3
+ when: API documentation, API reference, endpoint docs, REST API docs, method/params/response reference. For prose developer guides or a knowledge base, use docs-site instead.
4
+ needs: none
5
+ deploy: inspiration
6
+ editions: all
7
+ capabilities_note: static — no infrastructure. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
8
+ summary: Fetch the api-docs template, fill it with the user's endpoints, deploy it, and return the live share URL.
9
+ ---
10
+
11
+ # Workflow: api-docs
12
+
13
+ Detect the intent ("build me API docs / a REST API reference for X") and follow
14
+ this recipe. For prose guides or a general docs site, use `docs-site`; use this
15
+ one when the content is an endpoint reference. Do not ask setup questions first;
16
+ use sensible defaults and build.
17
+
18
+ 1. **Fetch the template.** Call `gridctl_fetch("template", "api-docs")` to load
19
+ the self-contained HTML API reference (sidebar endpoint list, method badges,
20
+ params tables, request/response code blocks, client-side filter).
21
+ 2. **Fill the template.** Replace the placeholders with the user's content:
22
+ - The API name, base URL, and auth note.
23
+ - One section per endpoint: method badge (GET/POST/PUT/DELETE), path,
24
+ description, a params table, and request/response example blocks.
25
+ - The sidebar links jump to each endpoint anchor; keep ids matching.
26
+ - The code blocks are plain `<pre><code>` — no external highlighter or CDN.
27
+ - Keep it a single self-contained HTML file. Do not add external scripts,
28
+ stylesheets, fonts, or large embedded media.
29
+ 3. **Deploy.** Deploy the filled HTML:
30
+ - Hosted MCP edition: call the drop tool with the HTML.
31
+ - Local MCP / CLI edition: write the HTML to a file and run `gridctl plug`.
32
+ It is an inspiration and deploys synchronously, so you get a URL right away.
33
+ 4. **Return the live share URL.** For revisions, re-deploy with the entity id
34
+ from the first deploy — it updates the same share URL.
35
+
36
+ Keep the whole flow tight: fetch, fill, deploy, share.
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: changelog
3
+ when: changelog, release notes, what's new, product updates page, version history. Reverse-chronological entries with added/fixed/changed/removed tags.
4
+ needs: none
5
+ deploy: inspiration
6
+ editions: all
7
+ capabilities_note: static — no infrastructure. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
8
+ summary: Fetch the changelog template, fill it with the user's release entries, deploy it, and return the live share URL.
9
+ ---
10
+
11
+ # Workflow: changelog
12
+
13
+ Detect the intent ("build me a changelog / release notes page for X") and follow
14
+ this recipe. Do not ask setup questions first; use sensible defaults and build.
15
+
16
+ 1. **Fetch the template.** Call `gridctl_fetch("template", "changelog")` to load
17
+ the self-contained HTML changelog (reverse-chronological versioned entries with
18
+ tagged change items).
19
+ 2. **Fill the template.** Replace the placeholders with the user's content:
20
+ - The product name and a short intro line.
21
+ - One entry per release, newest first: version, date, and a list of changes.
22
+ - Each change item carries a tag — set its class to `added`, `fixed`,
23
+ `changed`, or `removed`.
24
+ - Keep it a single self-contained HTML file. Do not add external scripts,
25
+ stylesheets, fonts, or large embedded media.
26
+ 3. **Deploy.** Deploy the filled HTML:
27
+ - Hosted MCP edition: call the drop tool with the HTML.
28
+ - Local MCP / CLI edition: write the HTML to a file and run `gridctl plug`.
29
+ It is an inspiration and deploys synchronously, so you get a URL right away.
30
+ 4. **Return the live share URL.** For revisions, re-deploy with the entity id
31
+ from the first deploy — it updates the same share URL.
32
+
33
+ Keep the whole flow tight: fetch, fill, deploy, share.
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: crm
3
+ when: CRM, contacts, leads, sales pipeline, customer manager, deal tracker — a persistent app that stores and manages contacts/leads/customers by stage. Needs a database → runtime → local edition.
4
+ needs: database
5
+ deploy: runtime
6
+ editions: local
7
+ capabilities_note: persistent — needs a database (Mongo). Runtime app, async build, local edition only. Declare the canonical `needs: { database: true }`; the deployer injects DATABASE_MONGODB_URL (+legacy MONGODB_URL).
8
+ summary: Build a persistent Next.js + Mongo CRM on the grid — a `contacts` collection (name, email, company, stage, note) with add / restage / delete. Edition-gate first, scaffold, put the app under services/web/, wire process.env.DATABASE_MONGODB_URL (legacy MONGODB_URL fallback) lazily, declare needs:{database:true} (not requires:), deploy async, poll to a live URL.
9
+ ---
10
+
11
+ # Workflow: crm
12
+
13
+ The user wants a contact manager / sales pipeline that **remembers** its
14
+ contacts — a CRM whose records survive refresh and are shared across sessions.
15
+ That is a **runtime app** backed by the grid's shared Mongo, not a static page.
16
+ It is the same proven shape as `app-with-data`, with a `contacts` domain
17
+ (name, email, company, stage of lead/qualified/customer, note) and a table view
18
+ with per-row stage changes.
19
+
20
+ Follow this recipe. Be honest that a runtime deploy is async (not instant like a
21
+ static drop) and that it needs the local edition.
22
+
23
+ ## 1. Edition check FIRST (hard gate)
24
+
25
+ A persistent app is a built + deployed container. It requires the **local
26
+ edition** (Claude Desktop / Claude Code) or the CLI.
27
+
28
+ - **Hosted edition (Claude Web / hosted MCP):** you CANNOT build a runtime app —
29
+ hosted is inline-only and can only publish static pages. Tell the user
30
+ plainly, offer a **static version** instead, and STOP the runtime path here.
31
+ - **Local edition:** continue.
32
+
33
+ ## 2. Auth + grid
34
+
35
+ 1. Ensure signed in: `gridctl_login_status`; if not, `gridctl_login`.
36
+ 2. A grid is required. Respect the grid picker: if the user has more than one
37
+ grid, ask which to use; do not assume a target.
38
+
39
+ ## 3. Scaffold
40
+
41
+ `gridctl_init` an app `<name>`. `init` creates the entity + `.cloudgrid/link.json`
42
+ and writes a `cloudgrid.yaml` with an EMPTY `services: {}`. `plug` needs a linked
43
+ directory, so run `init` FIRST. Then (a) write the app under **`services/web/`**,
44
+ and (b) fill `cloudgrid.yaml` to the shape below (`services.web` + `needs:
45
+ { database: true }`).
46
+
47
+ ## 4. Add the datastore + wire Mongo
48
+
49
+ 1. Set `cloudgrid.yaml`. **App code MUST live under `services/<name>/`** —
50
+ `path:` is the URL mount, NOT the filesystem path.
51
+ ```yaml
52
+ name: my-crm
53
+ services:
54
+ web:
55
+ type: nextjs
56
+ path: /
57
+ needs:
58
+ database: true
59
+ ```
60
+ **Declare the datastore with `needs: { database: true }`** — the canonical
61
+ shape. The deployer provisions Mongo and injects `DATABASE_MONGODB_URL` (plus
62
+ the legacy `MONGODB_URL` alias). `requires:` is the deprecated v1 alias; don't
63
+ author new yaml with it, and never set `needs:` and `requires:` together (the
64
+ validator rejects it).
65
+ 2. Fetch the template for the Mongo wiring + CRUD shape:
66
+ `gridctl_fetch("template", "crm")`. It is a minimal, real Next.js +
67
+ `mongodb`-driver contact manager under `services/web/`: a lazy client in
68
+ `services/web/lib/db.js`, an App-Router GET/POST/PATCH/DELETE route on a
69
+ `contacts` collection, a server-component page, and a client table.
70
+ 3. Adapt it (rename the collection, change fields, adjust the UI). **Read the DB
71
+ from `process.env.DATABASE_MONGODB_URL`** (legacy `process.env.MONGODB_URL`
72
+ fallback) — the grid injects it at dev-time and runtime.
73
+ - **Put the DB connection behind a lazy getter — never read the connection
74
+ string at module top level, or `next build` fails.**
75
+ - (Optional) fetch `gridctl_fetch("example", "crm")` for a richer filled
76
+ reference to imitate.
77
+
78
+ ## 5. (Optional) Run locally
79
+
80
+ Mention that the user can `grid dev` to run locally against the injected Mongo
81
+ before deploying. Don't require it.
82
+
83
+ ## 6. Config
84
+
85
+ - API keys / secrets → `gridctl_secrets`. Non-secret config → `gridctl_env`.
86
+ - Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` or the
87
+ legacy `MONGODB_URL`) — the grid injects them.
88
+
89
+ ## 7. Deploy (async)
90
+
91
+ Deploy the folder with `gridctl_plug`. A **runtime deploy is ASYNC**: the first
92
+ response is `status: "building"`, NOT a live URL yet.
93
+ - Poll `gridctl_status` (or the returned poll_url) until the entity is live.
94
+ - Surface a liveness signal while it builds — never a bare silent wait.
95
+ - Only once it is live, return the deployed app URL (NOT the build/log link).
96
+
97
+ ## 8. Return the live URL + iterate
98
+
99
+ Give the user the live app URL — that is the deliverable. To iterate, re-plug the
100
+ SAME entity so it updates the same URL. Keep it honest: async build, local-edition
101
+ only, credentials injected by the grid.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: docs-site
3
+ when: documentation site, docs, developer docs, guide, manual, knowledge base, help center (static, content baked in). For an interactive API endpoint reference, use api-docs instead.
4
+ needs: none
5
+ deploy: inspiration
6
+ editions: all
7
+ capabilities_note: static — no infrastructure, content baked into the page. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
8
+ summary: Fetch the docs-site template, fill it with the user's documentation, deploy it, and return the live share URL.
9
+ ---
10
+
11
+ # Workflow: docs-site
12
+
13
+ Detect the intent ("build me a docs site / documentation for X") and follow this
14
+ recipe. For a REST API endpoint reference specifically, use `api-docs`. Do not
15
+ ask setup questions first; use sensible defaults and build.
16
+
17
+ 1. **Fetch the template.** Call `gridctl_fetch("template", "docs-site")` to load
18
+ the self-contained HTML docs layout (sidebar nav, content column, code blocks,
19
+ client-side search box).
20
+ 2. **Fill the template.** Replace the placeholders with the user's content:
21
+ - The project/doc name and the sidebar section links.
22
+ - One content section per topic (heading + prose + optional code block). Keep
23
+ each section id matching its sidebar anchor.
24
+ - The code blocks are plain `<pre><code>` — no external highlighter or CDN.
25
+ - Leave the inline search script as-is; it filters the sidebar client-side.
26
+ - Keep it a single self-contained HTML file. Do not add external scripts,
27
+ stylesheets, fonts, or large embedded media.
28
+ 3. **Deploy.** Deploy the filled HTML:
29
+ - Hosted MCP edition: call the drop tool with the HTML.
30
+ - Local MCP / CLI edition: write the HTML to a file and run `gridctl plug`.
31
+ It is an inspiration and deploys synchronously, so you get a URL right away.
32
+ 4. **Return the live share URL.** For revisions, re-deploy with the entity id
33
+ from the first deploy — it updates the same share URL.
34
+
35
+ Keep the whole flow tight: fetch, fill, deploy, share.
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: kanban
3
+ when: kanban board, task board, trello-style board, workflow columns — a persistent board whose cards move between columns and stick across refresh. Needs a database → runtime → local edition.
4
+ needs: database
5
+ deploy: runtime
6
+ editions: local
7
+ capabilities_note: persistent — needs a database (Mongo). Runtime app, async build, local edition only. Declare the canonical `needs: { database: true }`; the deployer injects DATABASE_MONGODB_URL (+legacy MONGODB_URL).
8
+ summary: Build a persistent Next.js + Mongo kanban board on the grid — a `cards` collection (title, column, order) with three columns and move-between-columns + add/delete. Edition-gate first, scaffold, put the app under services/web/, wire process.env.DATABASE_MONGODB_URL (legacy MONGODB_URL fallback) lazily, declare needs:{database:true} (not requires:), deploy async, poll to a live URL.
9
+ ---
10
+
11
+ # Workflow: kanban
12
+
13
+ The user wants a kanban / trello-style board that **remembers** its cards — cards
14
+ that move between columns and survive refresh, shared across sessions. That is a
15
+ **runtime app** backed by the grid's shared Mongo, not a static page. It is the
16
+ same proven shape as `app-with-data`, with a `cards` domain (title, column of
17
+ todo/doing/done, order) and three columns with move-between-columns.
18
+
19
+ Follow this recipe. Be honest that a runtime deploy is async (not instant like a
20
+ static drop) and that it needs the local edition.
21
+
22
+ ## 1. Edition check FIRST (hard gate)
23
+
24
+ A persistent app is a built + deployed container. It requires the **local
25
+ edition** (Claude Desktop / Claude Code) or the CLI.
26
+
27
+ - **Hosted edition (Claude Web / hosted MCP):** you CANNOT build a runtime app —
28
+ hosted is inline-only and can only publish static pages. Tell the user
29
+ plainly, offer a **static version** instead, and STOP the runtime path here.
30
+ - **Local edition:** continue.
31
+
32
+ ## 2. Auth + grid
33
+
34
+ 1. Ensure signed in: `gridctl_login_status`; if not, `gridctl_login`.
35
+ 2. A grid is required. Respect the grid picker: if the user has more than one
36
+ grid, ask which to use; do not assume a target.
37
+
38
+ ## 3. Scaffold
39
+
40
+ `gridctl_init` an app `<name>`. `init` creates the entity + `.cloudgrid/link.json`
41
+ and writes a `cloudgrid.yaml` with an EMPTY `services: {}`. `plug` needs a linked
42
+ directory, so run `init` FIRST. Then (a) write the app under **`services/web/`**,
43
+ and (b) fill `cloudgrid.yaml` to the shape below (`services.web` + `needs:
44
+ { database: true }`).
45
+
46
+ ## 4. Add the datastore + wire Mongo
47
+
48
+ 1. Set `cloudgrid.yaml`. **App code MUST live under `services/<name>/`** —
49
+ `path:` is the URL mount, NOT the filesystem path.
50
+ ```yaml
51
+ name: my-board
52
+ services:
53
+ web:
54
+ type: nextjs
55
+ path: /
56
+ needs:
57
+ database: true
58
+ ```
59
+ **Declare the datastore with `needs: { database: true }`** — the canonical
60
+ shape. The deployer provisions Mongo and injects `DATABASE_MONGODB_URL` (plus
61
+ the legacy `MONGODB_URL` alias). `requires:` is the deprecated v1 alias; don't
62
+ author new yaml with it, and never set `needs:` and `requires:` together (the
63
+ validator rejects it).
64
+ 2. Fetch the template for the Mongo wiring + CRUD shape:
65
+ `gridctl_fetch("template", "kanban")`. It is a minimal, real Next.js +
66
+ `mongodb`-driver board under `services/web/`: a lazy client in
67
+ `services/web/lib/db.js`, an App-Router GET/POST/PATCH/DELETE route on a
68
+ `cards` collection (PATCH moves a card between columns), a server-component
69
+ page, and a client board.
70
+ 3. Adapt it (rename the collection, change the columns/fields, adjust the UI).
71
+ **Read the DB from `process.env.DATABASE_MONGODB_URL`** (legacy
72
+ `process.env.MONGODB_URL` fallback) — the grid injects it at dev-time and
73
+ runtime.
74
+ - **Put the DB connection behind a lazy getter — never read the connection
75
+ string at module top level, or `next build` fails.**
76
+ - (Optional) fetch `gridctl_fetch("example", "kanban")` for a richer filled
77
+ reference to imitate.
78
+
79
+ ## 5. (Optional) Run locally
80
+
81
+ Mention that the user can `grid dev` to run locally against the injected Mongo
82
+ before deploying. Don't require it.
83
+
84
+ ## 6. Config
85
+
86
+ - API keys / secrets → `gridctl_secrets`. Non-secret config → `gridctl_env`.
87
+ - Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` or the
88
+ legacy `MONGODB_URL`) — the grid injects them.
89
+
90
+ ## 7. Deploy (async)
91
+
92
+ Deploy the folder with `gridctl_plug`. A **runtime deploy is ASYNC**: the first
93
+ response is `status: "building"`, NOT a live URL yet.
94
+ - Poll `gridctl_status` (or the returned poll_url) until the entity is live.
95
+ - Surface a liveness signal while it builds — never a bare silent wait.
96
+ - Only once it is live, return the deployed app URL (NOT the build/log link).
97
+
98
+ ## 8. Return the live URL + iterate
99
+
100
+ Give the user the live app URL — that is the deliverable. To iterate, re-plug the
101
+ SAME entity so it updates the same URL. Keep it honest: async build, local-edition
102
+ only, credentials injected by the grid.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: portfolio
3
+ when: portfolio, personal site, freelancer site, my work, showcase, resume site, developer/designer portfolio with a projects grid, about, skills, and contact. For a plain single-section link-in-bio, landing-page also works.
4
+ needs: none
5
+ deploy: inspiration
6
+ editions: all
7
+ capabilities_note: static — no infrastructure. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
8
+ summary: Fetch the portfolio template, fill it with the user's projects and bio, deploy it, and return the live share URL.
9
+ ---
10
+
11
+ # Workflow: portfolio
12
+
13
+ Detect the intent ("build me a portfolio / personal site to show my work") and
14
+ follow this recipe. Reach for this over `landing-page` when the request is about
15
+ showcasing projects with an about, skills, and contact. Do not ask setup
16
+ questions first; use sensible defaults and build.
17
+
18
+ 1. **Fetch the template.** Call `gridctl_fetch("template", "portfolio")` to load
19
+ the self-contained HTML portfolio (hero, about, skills, projects grid,
20
+ contact).
21
+ 2. **Fill the template.** Replace the placeholders with the user's content:
22
+ - The person's name, role/title, and short intro.
23
+ - The about paragraph and the skills (one pill each).
24
+ - One card per project: title, short description, tags, optional link.
25
+ - The contact links (email as a `mailto:`, plus optional profile links).
26
+ - Keep it a single self-contained HTML file. Do not add external scripts,
27
+ stylesheets, fonts, or large embedded media.
28
+ 3. **Deploy.** Deploy the filled HTML:
29
+ - Hosted MCP edition: call the drop tool with the HTML.
30
+ - Local MCP / CLI edition: write the HTML to a file and run `gridctl plug`.
31
+ It is an inspiration and deploys synchronously, so you get a URL right away.
32
+ 4. **Return the live share URL.** For revisions, re-deploy with the entity id
33
+ from the first deploy — it updates the same share URL.
34
+
35
+ Keep the whole flow tight: fetch, fill, deploy, share.
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: saas-marketing
3
+ when: SaaS marketing site, product marketing page, features and pricing page, multi-section product site with pricing tiers, testimonials, and FAQ. For a simpler single-message page, use landing-page instead.
4
+ needs: none
5
+ deploy: inspiration
6
+ editions: all
7
+ capabilities_note: static — no infrastructure. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
8
+ summary: Fetch the saas-marketing template, fill it with the user's product content, deploy it, and return the live share URL.
9
+ ---
10
+
11
+ # Workflow: saas-marketing
12
+
13
+ Detect the intent ("build me a SaaS marketing site / product page with pricing")
14
+ and follow this recipe. This is the richer sibling of `landing-page` — reach for
15
+ it when the request calls for pricing tiers, testimonials, and an FAQ, not just a
16
+ hero. For a plain single-section landing page, use `landing-page`. Do not ask
17
+ setup questions first; use sensible defaults and build.
18
+
19
+ 1. **Fetch the template.** Call `gridctl_fetch("template", "saas-marketing")` to
20
+ load the self-contained HTML marketing site.
21
+ 2. **Fill the template.** Replace the placeholders with the user's content:
22
+ - The product name, tagline, and hero eyebrow/headline/subheadline.
23
+ - The call-to-action label and (optional) target.
24
+ - One block per feature (title + short description).
25
+ - The three pricing plans (name, price, period, feature list). The middle
26
+ plan is marked "Most popular".
27
+ - The testimonial quotes and the FAQ question/answer pairs.
28
+ - Keep it a single self-contained HTML file. Do not add external scripts,
29
+ stylesheets, fonts, or large embedded media.
30
+ 3. **Deploy.** Deploy the filled HTML:
31
+ - Hosted MCP edition: call the drop tool with the HTML.
32
+ - Local MCP / CLI edition: write the HTML to a file and run `gridctl plug`.
33
+ It is an inspiration and deploys synchronously, so you get a URL right away.
34
+ 4. **Return the live share URL.** For revisions, re-deploy with the entity id
35
+ from the first deploy — it updates the same share URL.
36
+
37
+ Keep the whole flow tight: fetch, fill, deploy, share.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: status-page
3
+ when: status page, service status, uptime page, incident history, is-it-down page, system status board. Display-only — status is baked into the page, no live monitoring.
4
+ needs: none
5
+ deploy: inspiration
6
+ editions: all
7
+ capabilities_note: static — no infrastructure, status baked into the page. Publishes as an inspiration (instant, works on hosted) via gridctl_drop.
8
+ summary: Fetch the status-page template, fill it with the user's components and incidents, deploy it, and return the live share URL.
9
+ ---
10
+
11
+ # Workflow: status-page
12
+
13
+ Detect the intent ("build me a status page / uptime page for X") and follow this
14
+ recipe. This is a display-only static page — the status is baked into the markup,
15
+ there is no live polling. Do not ask setup questions first; use sensible defaults
16
+ and build.
17
+
18
+ 1. **Fetch the template.** Call `gridctl_fetch("template", "status-page")` to load
19
+ the self-contained HTML status page (overall banner, component list with
20
+ up/degraded/down pills, per-component uptime bars, incident history).
21
+ 2. **Fill the template.** Replace the placeholders with the user's content:
22
+ - The overall banner text and its state class (`ok` / `degraded` / `down`).
23
+ - One row per component: name, a status pill, and the 90-day uptime bar. Mark
24
+ any non-ok bar segments with class `degraded` or `down`.
25
+ - The incident history entries: date, title, state, and a short note.
26
+ - Keep it a single self-contained HTML file. Do not add external scripts,
27
+ stylesheets, fonts, or large embedded media.
28
+ 3. **Deploy.** Deploy the filled HTML:
29
+ - Hosted MCP edition: call the drop tool with the HTML.
30
+ - Local MCP / CLI edition: write the HTML to a file and run `gridctl plug`.
31
+ It is an inspiration and deploys synchronously, so you get a URL right away.
32
+ 4. **Return the live share URL.** For revisions, re-deploy with the entity id
33
+ from the first deploy — it updates the same share URL.
34
+
35
+ Keep the whole flow tight: fetch, fill, deploy, share.
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: task-manager
3
+ when: task manager, to-do app (richer than the app-with-data starter), task list with due dates/priorities, complete-toggle + filter — a persistent task app that sticks across refresh. Needs a database → runtime → local edition.
4
+ needs: database
5
+ deploy: runtime
6
+ editions: local
7
+ capabilities_note: persistent — needs a database (Mongo). Runtime app, async build, local edition only. Declare the canonical `needs: { database: true }`; the deployer injects DATABASE_MONGODB_URL (+legacy MONGODB_URL).
8
+ summary: Build a persistent Next.js + Mongo task manager on the grid — a `tasks` collection (title, done, due, priority) with a complete-toggle, active/done filter, add/delete. Richer than the bare app-with-data to-do. Edition-gate first, scaffold, put the app under services/web/, wire process.env.DATABASE_MONGODB_URL (legacy MONGODB_URL fallback) lazily, declare needs:{database:true} (not requires:), deploy async, poll to a live URL.
9
+ ---
10
+
11
+ # Workflow: task-manager
12
+
13
+ The user wants a task manager richer than the bare `app-with-data` to-do starter
14
+ — tasks with due dates and priorities, a complete-toggle, and an active/done
15
+ filter, all of which **stick** across refresh and are shared across sessions.
16
+ That is a **runtime app** backed by the grid's shared Mongo, not a static page.
17
+ It is the same proven shape as `app-with-data`, with a `tasks` domain (title,
18
+ done, due, priority of low/medium/high). (For the bare-minimum in-memory to-do,
19
+ use `app-with-data` instead.)
20
+
21
+ Follow this recipe. Be honest that a runtime deploy is async (not instant like a
22
+ static drop) and that it needs the local edition.
23
+
24
+ ## 1. Edition check FIRST (hard gate)
25
+
26
+ A persistent app is a built + deployed container. It requires the **local
27
+ edition** (Claude Desktop / Claude Code) or the CLI.
28
+
29
+ - **Hosted edition (Claude Web / hosted MCP):** you CANNOT build a runtime app —
30
+ hosted is inline-only and can only publish static pages. Tell the user
31
+ plainly, offer a **static version** instead, and STOP the runtime path here.
32
+ - **Local edition:** continue.
33
+
34
+ ## 2. Auth + grid
35
+
36
+ 1. Ensure signed in: `gridctl_login_status`; if not, `gridctl_login`.
37
+ 2. A grid is required. Respect the grid picker: if the user has more than one
38
+ grid, ask which to use; do not assume a target.
39
+
40
+ ## 3. Scaffold
41
+
42
+ `gridctl_init` an app `<name>`. `init` creates the entity + `.cloudgrid/link.json`
43
+ and writes a `cloudgrid.yaml` with an EMPTY `services: {}`. `plug` needs a linked
44
+ directory, so run `init` FIRST. Then (a) write the app under **`services/web/`**,
45
+ and (b) fill `cloudgrid.yaml` to the shape below (`services.web` + `needs:
46
+ { database: true }`).
47
+
48
+ ## 4. Add the datastore + wire Mongo
49
+
50
+ 1. Set `cloudgrid.yaml`. **App code MUST live under `services/<name>/`** —
51
+ `path:` is the URL mount, NOT the filesystem path.
52
+ ```yaml
53
+ name: my-tasks
54
+ services:
55
+ web:
56
+ type: nextjs
57
+ path: /
58
+ needs:
59
+ database: true
60
+ ```
61
+ **Declare the datastore with `needs: { database: true }`** — the canonical
62
+ shape. The deployer provisions Mongo and injects `DATABASE_MONGODB_URL` (plus
63
+ the legacy `MONGODB_URL` alias). `requires:` is the deprecated v1 alias; don't
64
+ author new yaml with it, and never set `needs:` and `requires:` together (the
65
+ validator rejects it).
66
+ 2. Fetch the template for the Mongo wiring + CRUD shape:
67
+ `gridctl_fetch("template", "task-manager")`. It is a minimal, real Next.js +
68
+ `mongodb`-driver task manager under `services/web/`: a lazy client in
69
+ `services/web/lib/db.js`, an App-Router GET/POST/PATCH/DELETE route on a
70
+ `tasks` collection (PATCH toggles done), a server-component page, and a client
71
+ list with an active/done filter.
72
+ 3. Adapt it (rename the collection, change fields, adjust the UI). **Read the DB
73
+ from `process.env.DATABASE_MONGODB_URL`** (legacy `process.env.MONGODB_URL`
74
+ fallback) — the grid injects it at dev-time and runtime.
75
+ - **Put the DB connection behind a lazy getter — never read the connection
76
+ string at module top level, or `next build` fails.**
77
+
78
+ ## 5. (Optional) Run locally
79
+
80
+ Mention that the user can `grid dev` to run locally against the injected Mongo
81
+ before deploying. Don't require it.
82
+
83
+ ## 6. Config
84
+
85
+ - API keys / secrets → `gridctl_secrets`. Non-secret config → `gridctl_env`.
86
+ - Do **NOT** set the DB connection vars yourself (`DATABASE_MONGODB_URL` or the
87
+ legacy `MONGODB_URL`) — the grid injects them.
88
+
89
+ ## 7. Deploy (async)
90
+
91
+ Deploy the folder with `gridctl_plug`. A **runtime deploy is ASYNC**: the first
92
+ response is `status: "building"`, NOT a live URL yet.
93
+ - Poll `gridctl_status` (or the returned poll_url) until the entity is live.
94
+ - Surface a liveness signal while it builds — never a bare silent wait.
95
+ - Only once it is live, return the deployed app URL (NOT the build/log link).
96
+
97
+ ## 8. Return the live URL + iterate
98
+
99
+ Give the user the live app URL — that is the deliverable. To iterate, re-plug the
100
+ SAME entity so it updates the same URL. Keep it honest: async build, local-edition
101
+ only, credentials injected by the grid.