@cloudgrid-io/mcp 0.20.6 → 0.20.8

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 (33) hide show
  1. package/README.md +40 -31
  2. package/package.json +2 -1
  3. package/src/corpus/capability-map.md +21 -13
  4. package/src/corpus/cloudgrid-yaml.md +5 -3
  5. package/src/corpus/examples/ai-app/index.md +4 -3
  6. package/src/corpus/examples/docs-app/index.md +113 -0
  7. package/src/corpus/templates/ai-app/README.md +4 -4
  8. package/src/corpus/templates/ai-app/index.md +4 -4
  9. package/src/corpus/templates/ai-knowledge-base/AGENTS.md +17 -17
  10. package/src/corpus/templates/ai-knowledge-base/README.md +5 -4
  11. package/src/corpus/templates/ai-knowledge-base/cloudgrid.yaml +5 -4
  12. package/src/corpus/templates/ai-knowledge-base/index.md +15 -11
  13. package/src/corpus/templates/semantic-search/AGENTS.md +9 -9
  14. package/src/corpus/templates/semantic-search/README.md +4 -3
  15. package/src/corpus/templates/semantic-search/cloudgrid.yaml +6 -5
  16. package/src/corpus/templates/semantic-search/index.md +7 -4
  17. package/src/corpus/templates/simple-semantic-search/README.md +20 -0
  18. package/src/corpus/templates/simple-semantic-search/cloudgrid.yaml +235 -0
  19. package/src/corpus/templates/simple-semantic-search/index.md +353 -0
  20. package/src/corpus/templates/simple-semantic-search/services/web/package.json +15 -0
  21. package/src/corpus/templates/simple-semantic-search/services/web/src/document.txt +40 -0
  22. package/src/corpus/templates/simple-semantic-search/services/web/src/index.js +225 -0
  23. package/src/corpus/workflows/ai-app.md +5 -4
  24. package/src/corpus/workflows/ai-knowledge-base.md +17 -14
  25. package/src/corpus/workflows/semantic-search.md +9 -7
  26. package/src/corpus/workflows/simple-semantic-search.md +64 -0
  27. package/src/playbook.js +135 -0
  28. package/src/tools/cli.js +446 -0
  29. package/src/tools/constants.js +106 -0
  30. package/src/tools/deploy.js +1677 -0
  31. package/src/tools/register.js +1165 -0
  32. package/src/tools/util.js +17 -0
  33. package/src/tools.js +30 -3470
package/README.md CHANGED
@@ -15,10 +15,12 @@ drop, claim, and login tools.
15
15
 
16
16
  ## CLI compatibility
17
17
 
18
- MCP 0.8.0 is tested against CLI 0.12. The lazy-npx fallback pins
19
- `@cloudgrid-io/cli@~0.12` so a future CLI major with renamed verbs cannot
20
- silently break a released MCP. A CI drift guard (`npm run test:drift-guard`)
21
- asserts every wrapped verb exists in the CLI help.
18
+ The MCP uses an installed CLI only when it meets the platform floor
19
+ (`MIN_CLI_VERSION`, currently 0.15.2 - kept in lockstep with the API's live
20
+ `cli_compat` floor, which rejects older CLIs with HTTP 426). Below the floor it
21
+ skips the local/global CLI and lazily fetches `@cloudgrid-io/cli@latest` via
22
+ npx instead. A CI drift guard (`npm run test:drift-guard`) asserts every
23
+ wrapped verb exists in the CLI help.
22
24
 
23
25
  ### `GRID_AUTH_STALE` is out of scope
24
26
 
@@ -71,52 +73,59 @@ posted). `CLOUDGRID_QA_IDLE_MS` overrides the abandoned-idle window (default
71
73
 
72
74
  | Tool | Wraps | Notes |
73
75
  |---|---|---|
74
- | `grid_plug` | `POST /api/v2/plug` | The unified create/re-plug verb: create a new entity, or update the SAME entity in place with `target_entity_id` (same URL). Source via local `path` (local edition) or inline `artifact_files` (both). |
75
- | `grid_drop` | `POST /api/v2/plug` | Artifact drop. Anonymous, or owned if signed in. Re-drops in a session update the same drop in place; anonymous drops return an `entity_id` + `owner_token` re-plug/claim handle. |
76
- | `grid_claim` | `POST /api/v2/entities/:id/pickup` | Claim an anonymous drop into the signed-in account (the claim token IS the drop's owner token). Direct API. |
77
- | `grid_fork` | `POST /api/v2/runtimes/:id/fork` | Start a new entity from an existing runtime (lineage recorded). Needs sign-in. |
78
- | `grid_download` | `GET /api/v2/runtimes/:id/source` | Signed 15-minute source-bundle URLs. Needs sign-in. |
79
- | `grid_login` | `GET /auth/login` | Start a CLI-free sign-in; returns a URL to open. Direct API. |
76
+ | `grid_deploy` | `POST /api/v2/plug` | THE deploy/publish verb (CloudGrid calls it "plug"): create a new entity, or update the SAME entity in place with `target_entity_id` (same URL). Source via inline `html` (single page), local `path` (local edition), or inline `artifact_files` (both). Anonymous drops return an `entity_id` + `owner_token` re-plug/claim handle. |
77
+ | `grid_claim_anonymous_deploy` | `POST /api/v2/entities/:id/pickup` | Claim an anonymous drop into the signed-in account (the claim token IS the drop's owner token). |
78
+ | `grid_copy_app` | `POST /api/v2/runtimes/:id/fork` | Start a new entity from an existing runtime (lineage recorded). Needs sign-in. |
79
+ | `grid_download_source` | `GET /api/v2/runtimes/:id/source` | Signed 15-minute source-bundle URLs. Needs sign-in. |
80
+ | `grid_get_app_source` | `GET /api/v2/.../source` | Fetch a deployed entity's source (resolves entity_id from a URL). Read-only. |
81
+ | `grid_login` | `GET /auth/login` | Start a CLI-free sign-in; returns a URL to open. |
80
82
  | `grid_login_status` | `GET /auth/status` | Finish the sign-in; saves the token to the shared CLI credentials. |
81
- | `grid_visibility` | `PATCH /api/v2/inspirations/<id>` | Change who can see a drop (private, space, authenticated, org, link). Needs sign-in. Direct API; also in the web edition. |
83
+ | `grid_set_sharing` | `PATCH /api/v2/inspirations/<id>` | Change who can see a drop (private, space, authenticated, org, link). Needs sign-in. |
84
+ | `grid_list_grids` | `GET /api/v2/orgs` | List the caller's grids. Read-only. |
85
+ | `grid_start` | corpus | Orientation: the playbook + workflow index + live context. Call FIRST. Read-only. |
86
+ | `grid_get_template` | corpus | Fetch a workflow / template / example / doc from the bundled corpus. Read-only. (`grid_fetch` is a kept deprecated alias.) |
87
+ | `grid_note` / `grid_report` / `grid_feedback` | API | Session notes, consent-gated error reports, feedback feed. |
82
88
 
83
- `grid_drop`, `grid_claim`, `grid_visibility`, and the two
84
- `grid_login` tools do not wrap the CLI -- they call the API directly, so they
85
- also work in the web edition where no CLI exists. `grid_login` writes the same
86
- `~/.cloudgrid/credentials` the CLI uses, so the two share one identity.
89
+ The direct-API tools call the platform without the CLI, so they also work in
90
+ the web edition. `grid_login` writes the same `~/.cloudgrid/credentials` the
91
+ CLI uses, so the two share one identity.
87
92
 
88
93
  ### CLI-wrapping tools (local edition only)
89
94
 
90
95
  | Tool | Wraps | Notes |
91
96
  |---|---|---|
92
- | `grid_init` | `grid init` | Register an app or agent; optionally seed a web service. |
93
- | `grid_logs` | `grid logs` | Snapshot of recent logs. Does not stream. Read-only. |
97
+ | `grid_create_project` | `grid init` | Register an app or agent; optionally seed a web service. |
98
+ | `grid_view_logs` | `grid logs` | Snapshot of recent logs. Does not stream. Read-only. (`grid_logs` is a kept deprecated alias.) |
94
99
  | `grid_share` | `grid visibility set` | Set visibility, default link. |
95
- | `grid_feedback` | `grid feedback list` | Read the org feedback feed. Read-only. |
96
- | `grid_whoami` | `grid whoami` | Show the signed-in user and active org. Read-only. |
97
- | `grid_use` | `grid use` | Switch the active org. |
100
+ | `grid_whoami` | `grid whoami` | Show the signed-in user and active grid. Read-only. |
101
+ | `grid_switch_grid` | `grid use` | Switch the active grid. |
98
102
  | `grid_logout` | `grid logout` | Sign out and clear local credentials. Destructive. |
99
- | `grid_status` | `grid status` | Org dashboard or entity detail. Read-only. |
103
+ | `grid_status` | `grid status` | Grid dashboard or entity detail. Read-only. |
100
104
  | `grid_info` | `grid info` | Entity metadata. Read-only. |
101
105
  | `grid_get` | `grid get grids\|entities\|spaces` | List grids, entities, or spaces. Read-only. |
102
106
  | `grid_describe_grid` | `grid describe grid <slug>` | Grid detail. Read-only. |
103
- | `grid_pickup` | `grid pickup <name>` | Download an entity's source and bind the folder. |
107
+ | `grid_edit_existing_app` | `grid pickup <name>` | Download an entity's source and bind the folder. |
104
108
  | `grid_rename` | `grid rename` | Rename an entity's display name. |
105
- | `grid_unplug` | `grid unplug` | Take an entity off the grid. Destructive; requires confirm. |
109
+ | `grid_take_offline` | `grid unplug` | Take an entity off the grid. Destructive; requires confirm. |
106
110
  | `grid_delete` | `grid delete entity` | Archive an inspiration. Destructive; requires confirm. |
107
- | `grid_rollback` | `grid rollback` | Rollback to a previous version. |
108
- | `grid_versions` | `grid versions` | List published versions. Read-only. |
109
- | `grid_env` | `grid env` | Get, set, or list environment variables. |
110
- | `grid_secrets` | `grid secrets` | Set or list secret names. Never returns secret values. |
111
+ | `grid_rollback_deploy` | `grid rollback` | Rollback to a previous version. |
112
+ | `grid_list_versions` | `grid versions` | List published versions. Read-only. |
113
+ | `grid_set_env` | `grid env` | Get, set, or list environment variables. |
114
+ | `grid_set_secret` | `grid secrets` | Set or list secret names. Never returns secret values. |
111
115
  | `grid_scaffold` | `grid scaffold` | Generate starter files. |
112
- | `grid_doctor` | `grid doctor` | Run local diagnostics. Read-only. |
113
- | `grid_open` | `grid open --print` | Return the public URL. Does not open a browser. Read-only. |
116
+ | `grid_diagnose` | `grid doctor` | Run local diagnostics. Read-only. |
117
+ | `grid_get_url` | `grid open --print` | Return the public URL. Does not open a browser. Read-only. |
114
118
 
115
- `grid_share` and `grid_visibility` overlap on purpose: `grid_share`
116
- wraps the CLI and defaults to `link`; `grid_visibility` is direct API, takes an
119
+ `grid_share` and `grid_set_sharing` overlap on purpose: `grid_share`
120
+ wraps the CLI and defaults to `link`; `grid_set_sharing` is direct API, takes an
117
121
  explicit scope, and defaults its target to the session's last drop -- it is the one
118
122
  the web edition gets.
119
123
 
124
+ 37 tool names are advertised in total: 35 canonical + 2 kept deprecated
125
+ aliases (`grid_fetch`, `grid_logs`). The 0.20.8 alias diet dropped the other 16
126
+ legacy aliases. Per-tool internals (signature, sketch, behavior):
127
+ [docs/TOOL-INTERNALS.md](docs/TOOL-INTERNALS.md).
128
+
120
129
  All tools carry MCP annotations (`readOnlyHint`, `destructiveHint`,
121
130
  `openWorldHint`) for clients that support them.
122
131
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudgrid-io/mcp",
3
- "version": "0.20.6",
3
+ "version": "0.20.8",
4
4
  "description": "Use CloudGrid via MCP to brainstorm, build, deploy, and improve apps, games, websites, dashboards, and tools and get a live URL - templates, recipes, managed databases and AI, instant single-page publish, and full-app deploys, for developers and non-technical users. Three editions: local stdio (full toolset), hosted web (light, CLI-free), and a public docs-search server, over MCP.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,6 +27,7 @@
27
27
  "test:content": "node test/content-handling.test.mjs",
28
28
  "test:self-healing": "node test/self-healing.test.mjs",
29
29
  "test:grid-picker": "node test/grid-picker.test.mjs",
30
+ "test:plug-output-schema": "node test/plug-output-schema.test.mjs",
30
31
  "test:plug-timeout": "node test/plug-timeout.test.mjs",
31
32
  "test:manifest-confirm": "node test/manifest-confirm.test.mjs",
32
33
  "test:qa-courier": "node test/qa-courier.test.mjs",
@@ -18,7 +18,7 @@ cloudgrid.yaml schema (every field, the `needs:` injection table, the
18
18
  requires-vs-needs caveat, validation rules), fetch the companion reference:
19
19
  `grid_get_template("doc", "cloudgrid-yaml")`.
20
20
 
21
- ## The 60 templates
21
+ ## The 61 templates
22
22
 
23
23
  | Intent (match on `when:`) | Template | `needs:` | Deploy | Edition |
24
24
  |---|---|---|---|---|
@@ -63,7 +63,8 @@ requires-vs-needs caveat, validation rules), fetch the companion reference:
63
63
  | revenue dashboard, sales dashboard, MRR/revenue view | `revenue-dashboard` | `database: true` | runtime (async, poll) | local |
64
64
  | property listings, real estate site, rentals/homes listings | `property-listings` | `database: true` | runtime (async, poll) | local |
65
65
  | project management, projects and tasks tracker, team project board | `project-management` | `database: true` | runtime (async, poll) | local |
66
- | search over my documents / PDFs / notes / knowledge base, semantic search, document search, find across my files, searchable archive | `semantic-search` | `database: true` (NO `vector` #1545; active daily refresh cron) | runtime (async, poll) | local |
66
+ | semantic search over a document / article / text, search-by-meaning box, question-answering search over content, embeddings / vector / similarity search — ONE document or small text set, one service | `simple-semantic-search` | `vector: pgvector, ai: true` (native pgvector, verified live 2026-07-16) | runtime (async, poll) | local |
67
+ | search over my documents / PDFs / notes / knowledge base with upload UI and scheduled refresh, document search portfolio, searchable archive (multi-service) | `semantic-search` | `database: true` (template uses Mongo embeddings; `vector: pgvector` now available, #1545 shipped; active daily refresh cron) | runtime (async, poll) | local |
67
68
 
68
69
  **Rule of thumb:** if the app must SAVE/remember data, share state across
69
70
  users/sessions, log in, or store submissions → it is persistent → runtime, local
@@ -86,8 +87,10 @@ real runnable code in a different shape from the Next.js family: a React (Vite)
86
87
  **static** frontend at `/` plus a **Python FastAPI** backend at `/backend`, on the
87
88
  same grid-shared Mongo (`needs: { database: true }`). Hybrid search = Mongo
88
89
  `$text` + in-app NumPy cosine over embedding arrays + metadata filters. It stores
89
- embeddings in the Mongo `chunks` collection (NO `needs: vector` — pgvector is
90
- blocked on **#1545**) and refreshes via a manager endpoint (NO active cron — a
90
+ embeddings in the Mongo `chunks` collection (the template does not declare
91
+ `needs: vector`; `vector: pgvector` is now available — **#1545** shipped, verified
92
+ live 2026-07-16 — but the template code still ranks in-app) and refreshes via a
93
+ manager endpoint (NO active cron — a
91
94
  Python `type: cron` is blocked on **#1585**). Read its `AGENTS.md` for the source
92
95
  adapter (dropbox/local/url) + embeddings wiring and the health-without-secrets /
93
96
  startup-index patterns.
@@ -97,7 +100,7 @@ startup-index patterns.
97
100
  | Intent | Would need | Status |
98
101
  |---|---|---|
99
102
  | scheduled task, cron job, "run every day/hour", periodic worker | a `type: cron` service (`schedule`, `timezone`) | **SUPPORTED** on CLI 0.14.0 — Python and Node `type: cron` services validate, deploy, and fire (platform #1585 fixed). See the semantic-search `refresh` cron for a working Python-job example. |
100
- | RAG chatbot, "answer over my own docs", semantic search, retrieval-augmented Q&A | `ai-app` + `needs: { vector: pgvector }` | **HELD** — platform issue #1545 (pgvector crashes the deploy). Ship the plain `ai-app` (no vector) for now. |
103
+ | RAG chatbot, "answer over my own docs", semantic search, retrieval-augmented Q&A | `ai-app` + `needs: { vector: pgvector }` | AVAILABLE — #1545 shipped (verified live 2026-07-16). `vector: pgvector` deploys and injects `VECTOR_PGVECTOR_URL`; the shipped template still stores embeddings in Mongo until updated. |
101
104
 
102
105
  ## Blueprints (structure + cloudgrid.yaml; adapt the app — some pending platform support)
103
106
 
@@ -129,14 +132,15 @@ runtime, async build, **local edition only**. Auth/payment secrets map through a
129
132
  | appointment booking, clinic/salon booking, appointment scheduler | `appointment-booking` | `database: true` (+ auth/Stripe via `vault:`); reminder cron supported (Python/Node `type: cron`, 0.14.0) | runtime (async, poll) | local |
130
133
  | restaurant website with reservations, table booking, restaurant site | `restaurant-reservations` | `database: true` (+ Stripe/email via `vault:`); reminder cron supported (Python/Node `type: cron`, 0.14.0) | runtime (async, poll) | local |
131
134
  | travel booking portal, trip booking, flights/hotels booking, travel reservations | `travel-booking` | `database: true` (+ Stripe/auth via `vault:`); reminder cron supported (Python/Node `type: cron`, 0.14.0) | runtime (async, poll) | local |
132
- | RAG, ask my docs, knowledge base chatbot, retrieval-augmented search over documents | `ai-knowledge-base` | `ai: true, database: true`; ideal `vector: pgvector` **pending #1545** (store embeddings in Mongo + cosine-rank until it lands) | runtime (async, poll) | local |
135
+ | RAG, ask my docs, knowledge base chatbot, retrieval-augmented search over documents | `ai-knowledge-base` | `ai: true, database: true`; ideal `vector: pgvector` now AVAILABLE (#1545 shipped; the shipped blueprint still uses Mongo embeddings until updated) | runtime (async, poll) | local |
133
136
 
134
137
  The booking family (`booking-system`, `calendar-scheduler`, `appointment-booking`,
135
138
  `restaurant-reservations`, `travel-booking`) is fully buildable today, **including**
136
139
  the reminder cron — Python and Node `type: cron` services work on CLI 0.14.0
137
140
  (platform #1585 fixed). `ai-knowledge-base` builds today on the AI Gateway + Mongo; its
138
- ideal `needs: { vector: pgvector }` embedding store is HELD on **#1545**, so store
139
- chunks in Mongo and cosine-rank in-app until it lands.
141
+ ideal `needs: { vector: pgvector }` embedding store is now AVAILABLE (**#1545**
142
+ shipped, verified live 2026-07-16) — the shipped blueprint still stores chunks in
143
+ Mongo and cosine-ranks in-app until it is updated to pgvector.
140
144
 
141
145
  ## The full `needs:` vocabulary (the whole menu)
142
146
 
@@ -152,8 +156,8 @@ engine hint. Cron is NOT a need — it is a **service type** (`type: cron` with
152
156
  | `kv: true` | Redis, no eviction | `KV_REDIS_URL` | Injects via `needs:` |
153
157
  | `queue: true` | Redis durable job queue | `QUEUE_REDIS_URL` | Injects via `needs:` |
154
158
  | `pubsub: true` | Redis pub/sub broadcast | `PUBSUB_REDIS_URL` | Injects via `needs:` |
155
- | `vector: pgvector` | pgvector embeddings DB | `VECTOR_PGVECTOR_URL` (+legacy `PGVECTOR_URL`) | **Injects via `needs:`** |
156
- | `object_storage: true` | GCS bucket | `OBJECT_STORAGE_GCS_BUCKET`, `OBJECT_STORAGE_GCS_REGION` | Injects via `needs:` |
159
+ | `vector: pgvector` | pgvector embeddings DB | `VECTOR_PGVECTOR_URL` (+legacy `PGVECTOR_URL`) | **Injects via `needs:`** (#1545 shipped, verified live 2026-07-16) |
160
+ | `object_storage: true` | GCS bucket | `OBJECT_STORAGE_GCS_BUCKET`, `OBJECT_STORAGE_GCS_REGION` | **GATED (#1678)** - rejected at plug-time; use `disk` or a BYO bucket via secret |
157
161
  | `disk: true` | Persistent filesystem at `/data` | `DISK_PATH` | Injects via `needs:` |
158
162
  | `ai: true` | AI Gateway access | `AI_GATEWAY_URL` | Injects via `needs:` |
159
163
  | `type: cron` (service) | Scheduled job (`schedule`, `timezone`) | — | Service type, not a need |
@@ -162,8 +166,11 @@ engine hint. Cron is NOT a need — it is a **service type** (`type: cron` with
162
166
 
163
167
  - **`needs:` injects the connection env vars today.** `needs: { database: true }`
164
168
  → `DATABASE_MONGODB_URL` (+legacy `MONGODB_URL`); `needs: { cache: true }` →
165
- `CACHE_REDIS_URL` (+legacy `REDIS_URL`); `needs: { vector: pgvector }` →
166
- `VECTOR_PGVECTOR_URL`; and so on across the nine needs. Author `needs:`.
169
+ `CACHE_REDIS_URL` (+legacy `REDIS_URL`); `needs: { queue: true }` →
170
+ `QUEUE_REDIS_URL`; and so on across the durable needs. Author `needs:`.
171
+ `vector: pgvector` → `VECTOR_PGVECTOR_URL` is now AVAILABLE (#1545 shipped,
172
+ verified live 2026-07-16). (**GATED, do NOT author yet:** `object_storage`
173
+ #1678 - rejected at plug-time, use `disk` or a BYO bucket via secret.)
167
174
  (*Historical note: the deployer once did not inject from `needs:` — platform
168
175
  bug #1527, now fixed and verified live.*)
169
176
  - **`requires:` is the deprecated v1 alias.** Don't author new yaml with it.
@@ -178,7 +185,8 @@ engine hint. Cron is NOT a need — it is a **service type** (`type: cron` with
178
185
  2. Adopt that template's `needs:`. Persistence → `database` (`app-with-data` or
179
186
  `api-service`); talks to an LLM → `ai: true` + `database` (`ai-app`); scheduled
180
187
  work → a `type: cron` service (Python/Node, supported on 0.14.0). (Held for now:
181
- RAG's ideal `vector: pgvector`, #1545 — store embeddings in Mongo until it lands.)
188
+ RAG's ideal `vector: pgvector` now works - #1545 shipped; the shipped
189
+ templates still store embeddings in Mongo until they are updated.)
182
190
  3. One self-contained HTML page (`needs: none`, assets inlined) → publish as an
183
191
  inspiration with `grid_deploy` and the inline `html` param (instant, any
184
192
  edition). Separate files/folders/assets, or anything with a `needs:` →
@@ -152,8 +152,8 @@ needs:
152
152
  kv: true # Redis, no eviction. Injects KV_REDIS_URL.
153
153
  queue: true # Redis for BullMQ etc. Injects QUEUE_REDIS_URL.
154
154
  pubsub: true # Redis pub/sub. Injects PUBSUB_REDIS_URL.
155
- vector: pgvector # pgvector. Injects VECTOR_PGVECTOR_URL.
156
- object_storage: true # GCS bucket. Injects OBJECT_STORAGE_GCS_BUCKET.
155
+ vector: pgvector # pgvector. Injects VECTOR_PGVECTOR_URL. (#1545 shipped, verified live 2026-07-16.)
156
+ object_storage: true # GATED (platform #1678) - rejected at plug-time; use disk: or a BYO bucket via secret.
157
157
  disk: true # Persistent filesystem at /data. Injects DISK_PATH.
158
158
  ai: true # AI Gateway access. Injects AI_GATEWAY_URL.
159
159
 
@@ -404,7 +404,7 @@ service type.**
404
404
  | `queue` | Durable job queue substrate | `QUEUE_REDIS_URL` | Redis |
405
405
  | `pubsub` | Broadcast pub/sub | `PUBSUB_REDIS_URL` | Redis |
406
406
  | `vector` | Vector embeddings DB | `VECTOR_PGVECTOR_URL` (+legacy `PGVECTOR_URL`) | pgvector (Postgres) |
407
- | `object_storage` | Object/blob bucket | `OBJECT_STORAGE_GCS_BUCKET`, `OBJECT_STORAGE_GCS_REGION` | GCS |
407
+ | `object_storage` | Object/blob bucket - **GATED (#1678)**: rejected at plug-time, use `disk` or a BYO bucket via secret | `OBJECT_STORAGE_GCS_BUCKET`, `OBJECT_STORAGE_GCS_REGION` | GCS |
408
408
  | `disk` | Persistent filesystem mount | `DISK_PATH` | PVC |
409
409
  | `ai` | AI Gateway access | `AI_GATEWAY_URL` | CloudGrid AI Gateway |
410
410
 
@@ -424,10 +424,12 @@ needs:
424
424
  cache: true # Platform Redis
425
425
  cache: { engine: external, secret: MY_REDIS } # Bring your own (same forms for kv/queue/pubsub)
426
426
 
427
+ # vector - AVAILABLE (#1545 shipped, verified live 2026-07-16):
427
428
  vector: true # Platform default engine
428
429
  vector: pgvector # pgvector explicitly
429
430
  vector: { engine: pgvector, dim: 1536 } # With dimension hint
430
431
 
432
+ # object_storage - GATED (#1678), rejected at plug-time; use disk: or a BYO bucket:
431
433
  object_storage: true # Default size (100MB)
432
434
  object_storage: { size: 10Gi } # Custom size
433
435
 
@@ -32,8 +32,8 @@ services:
32
32
  needs:
33
33
  ai: true
34
34
  database: true
35
- # RAG over your own docs needs `needs: { vector: pgvector }` — not yet available
36
- # (platform issue #1545).
35
+ # RAG over your own docs needs `needs: { vector: pgvector }` — available now,
36
+ # #1545 shipped (verified live 2026-07-16). This example does not use it.
37
37
  ```
38
38
 
39
39
  ## services/web/package.json
@@ -234,4 +234,5 @@ export default function Chat({ initialHistory }) {
234
234
  - All app code lives under `services/web/`; the connection is read lazily inside
235
235
  `getDb`, never at module top level.
236
236
  - To answer over your own documents (RAG) you'd add `needs: { vector: pgvector }`
237
- — not yet available (platform issue #1545).
237
+ — available now (#1545 shipped); this example ships without it, so you'd also
238
+ write the retrieval code.
@@ -0,0 +1,113 @@
1
+ # Example: docs-app — "Widgets SDK docs"
2
+
3
+ A filled reference imitating the `docs-app` template: a multi-page documentation
4
+ site for a fictional "Widgets SDK", built with [Astro Starlight](https://starlight.astro.build).
5
+ It has sidebar navigation, client-side full-text search, and agent-readable
6
+ `llms.txt` / `llms-full.txt` generated on every build.
7
+
8
+ `docs-app` is the buildable sibling of `docs-site`. Use `docs-app` when the docs
9
+ are more than one page and you will keep editing them; use `docs-site` for a
10
+ quick single page baked into one HTML file (instant, works on the hosted MCP).
11
+
12
+ **The proven rules for a docs-app:** (1) it is served at the entity **root**, so
13
+ there is **no `base`** in `astro.config.mjs`; (2) `cloudgrid.yaml` declares a
14
+ single `static` service with **`source: { path: . }`** (the project is at the
15
+ folder root, not under `services/site/`) plus a **`build:` block** — the platform
16
+ runs `npm run build` for you; (3) it is a multi-file **build**, so it deploys
17
+ **async** (poll to the live URL) and needs the **local edition** (the hosted MCP
18
+ cannot build it); (4) `llms.txt` / `llms-full.txt` are generated automatically at
19
+ the site root by the `starlight-llms-txt` plugin — no extra work.
20
+
21
+ ## cloudgrid.yaml
22
+
23
+ ```yaml
24
+ # Static site with a build step, served at the entity root. source.path: .
25
+ # points the build at the project root; without it the build looks for
26
+ # services/site/ and fails. No needs: — a docs site has no infrastructure.
27
+ name: widgets-sdk-docs
28
+ services:
29
+ site:
30
+ type: static
31
+ path: /
32
+ node_version: "22"
33
+ source:
34
+ path: .
35
+ build:
36
+ command: "npm run build"
37
+ output: "dist"
38
+ ```
39
+
40
+ ## package.json
41
+
42
+ ```json
43
+ {
44
+ "name": "widgets-sdk-docs",
45
+ "type": "module",
46
+ "version": "0.1.0",
47
+ "scripts": { "dev": "astro dev", "build": "astro build", "preview": "astro preview" },
48
+ "dependencies": {
49
+ "@astrojs/starlight": "^0.41.3",
50
+ "astro": "^7.0.2",
51
+ "sharp": "^0.34.5"
52
+ },
53
+ "devDependencies": { "starlight-llms-txt": "^0.11.0" }
54
+ }
55
+ ```
56
+
57
+ ## astro.config.mjs
58
+
59
+ ```js
60
+ import { defineConfig } from 'astro/config';
61
+ import starlight from '@astrojs/starlight';
62
+ import starlightLlmsTxt from 'starlight-llms-txt';
63
+
64
+ export default defineConfig({
65
+ site: 'https://example.com',
66
+ integrations: [
67
+ starlight({
68
+ plugins: [
69
+ starlightLlmsTxt({
70
+ projectName: 'Widgets SDK',
71
+ description: 'Build, style, and ship widgets. The official Widgets SDK docs.',
72
+ }),
73
+ ],
74
+ title: 'Widgets SDK',
75
+ sidebar: [
76
+ { label: 'Start here', items: [
77
+ { label: 'Introduction', slug: 'index' },
78
+ { label: 'Install', slug: 'guides/install' },
79
+ ] },
80
+ { label: 'Reference', items: [{ label: 'Widget API', slug: 'reference/widget-api' }] },
81
+ ],
82
+ }),
83
+ ],
84
+ });
85
+ ```
86
+
87
+ ## src/content/docs/guides/install.md
88
+
89
+ ```md
90
+ ---
91
+ title: Install
92
+ description: Add the Widgets SDK to your project.
93
+ ---
94
+
95
+ npm install @widgets/sdk
96
+
97
+ Then import a widget and render it:
98
+
99
+ import { Button } from '@widgets/sdk';
100
+ ```
101
+
102
+ ## Build + deploy
103
+
104
+ ```sh
105
+ npm install
106
+ npm run build # local check; the platform also builds on plug
107
+ grid plug # async build → poll to the live URL
108
+ ```
109
+
110
+ The live site serves at the entity root — pages at `/`, `/guides/install/`,
111
+ `/reference/widget-api/`, and the agent docs at `/llms.txt` and `/llms-full.txt`.
112
+ On a new deploy, ask the user what visibility they want and set it with
113
+ `grid visibility`.
@@ -87,9 +87,9 @@ services/web/app/api/chat/route.js # POST: createClient().chat(...) -> persis
87
87
  - Change the `messages` collection / fields; add users, sessions, titles.
88
88
  - Restyle the chat UI in `layout.js` / `chat.js`.
89
89
 
90
- ## RAG / retrieval (not yet)
90
+ ## RAG / retrieval (not included)
91
91
 
92
92
  To answer over **your own documents** (retrieval-augmented generation) you need a
93
- vector store — `needs: { vector: pgvector }`. That path is **not yet available**
94
- (platform issue #1545). Ship the plain chatbot now; add retrieval once the vector
95
- need is unblocked.
93
+ vector store — `needs: { vector: pgvector }`. That need is **now available** —
94
+ #1545 shipped (verified live 2026-07-16) — but this template is a plain chatbot:
95
+ declare the need and build the retrieval code on top if you want RAG.
@@ -253,9 +253,9 @@ export default function Chat({ initialHistory }) {
253
253
  - Change the `messages` collection / fields; add users, sessions, titles.
254
254
  - Run `grid dev` to test locally, `grid plug` to deploy (async — poll to live).
255
255
 
256
- ## RAG / retrieval (not yet)
256
+ ## RAG / retrieval (not included)
257
257
 
258
258
  To answer over **your own documents** (retrieval-augmented generation) you need a
259
- vector store — `needs: { vector: pgvector }`. That path is **not yet available**
260
- (platform issue #1545). Ship the plain chatbot now; add retrieval once the vector
261
- need is unblocked.
259
+ vector store — `needs: { vector: pgvector }`. That need is **now available** —
260
+ #1545 shipped (verified live 2026-07-16) — but this template is a plain chatbot:
261
+ declare the need and build the retrieval code on top if you want RAG.
@@ -13,13 +13,13 @@ them (with citations). Both the embedding and the answer step run through
13
13
  CloudGrid's **AI Gateway** (`@cloudgrid-io/ai`, injected via `needs: { ai: true }`).
14
14
 
15
15
  > **Vector-store status (read this first):** the ideal store for embeddings is
16
- > `needs: vector` (pgvector on Postgres, injecting `VECTOR_PGVECTOR_URL`), but it
17
- > is **PENDING platform issue #1545** and not yet provisioned. The **`ai` part
18
- > works today.** Until #1545 ships, store embeddings in **Mongo** (a `chunks`
19
- > collection with an `embedding: number[]` field) and compute cosine similarity in
20
- > the app. This blueprint's `cloudgrid.yaml` therefore declares
21
- > `needs: { ai: true, database: true }` and keeps `vector: pgvector` commented.
22
- > Section 7 describes the drop-in swap once #1545 lands.
16
+ > `needs: vector` (pgvector on Postgres, injecting `VECTOR_PGVECTOR_URL`), and it
17
+ > is **now available** — #1545 shipped (verified live 2026-07-16). This blueprint
18
+ > still stores embeddings in **Mongo** (a `chunks` collection with an
19
+ > `embedding: number[]` field) and computes cosine similarity in the app; its
20
+ > `cloudgrid.yaml` declares `needs: { ai: true, database: true }` and keeps
21
+ > `vector: pgvector` commented. Uncomment it only if you also build the retrieval
22
+ > on pgvector — Section 7 describes the drop-in swap.
23
23
 
24
24
  ---
25
25
 
@@ -72,9 +72,9 @@ collections (`_id` is the Mongo ObjectId on every doc):
72
72
  - `embedding` (number[] — the embedding vector; e.g. length 1536)
73
73
  - `createdAt` (Date)
74
74
 
75
- Until issue #1545 lands, `chunks.embedding` lives in Mongo and you rank in the
76
- app (Section 3). When pgvector ships, the vectors move to Postgres and `chunks`
77
- keeps only the text + a foreign key (Section 7).
75
+ As shipped, `chunks.embedding` lives in Mongo and you rank in the app
76
+ (Section 3). If you swap to pgvector (available — #1545 shipped), the vectors
77
+ move to Postgres and `chunks` keeps only the text + a foreign key (Section 7).
78
78
 
79
79
  ---
80
80
 
@@ -87,7 +87,7 @@ injected as env vars at `grid dev` (local) and at runtime (after `grid plug`):
87
87
  |------|----------------------------|---------------------|--------------|
88
88
  | MongoDB | `needs: { database: true }` | `DATABASE_MONGODB_URL` (+ legacy `MONGODB_URL`) | `lib/db.js` |
89
89
  | AI Gateway | `needs: { ai: true }` | `AI_GATEWAY_URL` | `lib/ai.js` (via `@cloudgrid-io/ai`) |
90
- | Vector store (PENDING #1545) | `needs: { vector: pgvector }` | `VECTOR_PGVECTOR_URL` (+ legacy `PGVECTOR_URL`) | `lib/retrieve.js` — not yet available |
90
+ | Vector store (available — #1545 shipped) | `needs: { vector: pgvector }` | `VECTOR_PGVECTOR_URL` (+ legacy `PGVECTOR_URL`) | `lib/retrieve.js` — not used by this blueprint (Section 7 for the swap) |
91
91
  | Auth key (optional) | `vault: { AUTH_PROVIDER_KEY: auth-provider-key }` | `AUTH_PROVIDER_KEY` | `lib/auth.js` |
92
92
  | Stripe key (optional) | `vault: { STRIPE_KEY: stripe-live-key }` | `STRIPE_KEY` | `lib/stripe.js` |
93
93
 
@@ -149,12 +149,12 @@ export async function chat(messages) {
149
149
 
150
150
  ### Retrieve (`lib/retrieve.js`)
151
151
  1. `embed(question)` -> query vector.
152
- 2. Until pgvector (#1545): load candidate `chunks`, compute cosine similarity in
153
- the app, keep the top-k (e.g. k=5). Keep it a pure, testable ranking function
154
- so it swaps cleanly to a pgvector query later.
152
+ 2. As shipped (Mongo embeddings): load candidate `chunks`, compute cosine
153
+ similarity in the app, keep the top-k (e.g. k=5). Keep it a pure, testable
154
+ ranking function so it swaps cleanly to a pgvector query later.
155
155
 
156
156
  ```js
157
- // lib/retrieve.js — cosine top-k over Mongo-stored embeddings (pre-#1545)
157
+ // lib/retrieve.js — cosine top-k over Mongo-stored embeddings (as shipped)
158
158
  import { getDb } from "./db.js";
159
159
  import { embed } from "./ai.js";
160
160
  const dot = (a, b) => a.reduce((s, x, i) => s + x * b[i], 0);
@@ -224,9 +224,9 @@ linked directory, so `init` first.
224
224
 
225
225
  ---
226
226
 
227
- ## 7. When pgvector (#1545) lands — the swap
227
+ ## 7. The swap to pgvector (now available — #1545 shipped)
228
228
 
229
- Once `needs: vector` is available, migrate off the in-app cosine ranking:
229
+ `needs: vector` is available; to migrate off the in-app cosine ranking:
230
230
 
231
231
  1. Uncomment `vector: pgvector` in `cloudgrid.yaml`'s `needs:` block (dim 1536 to
232
232
  match your embedding model). The grid then injects `VECTOR_PGVECTOR_URL` (+
@@ -6,14 +6,14 @@ and answers questions grounded in the retrieved chunks (with citations) — the
6
6
  `app-with-data` runtime shape with a RAG loop layered on. Embeddings and answers
7
7
  run through CloudGrid's AI Gateway (`@cloudgrid-io/ai`, injected via
8
8
  `needs: { ai: true }` — works today); the ideal vector store `needs: vector`
9
- (pgvector) is **PENDING platform issue #1545**, so embeddings live in Mongo and
10
- similarity is computed in-app until it ships. Because RAG involves choices
9
+ (pgvector) is **now available** — #1545 shipped (verified live 2026-07-16) — but
10
+ this blueprint stores embeddings in Mongo and computes similarity in-app. Because RAG involves choices
11
11
  (chunking, embedding model, retrieval), this template ships the **structure and
12
12
  `cloudgrid.yaml`, not finished app code** — adapt it and build.
13
13
 
14
14
  > **This is a blueprint: structure + cloudgrid.yaml, adapt and build.** Read
15
15
  > `AGENTS.md` for the file tree, Mongo collections, CloudGrid injection table
16
- > (needs + AI Gateway + the pgvector #1545 note), the RAG loop, optional
16
+ > (needs + AI Gateway + the pgvector note), the RAG loop, optional
17
17
  > auth/payments wiring, and the deploy flow — then generate the app under
18
18
  > `services/web/` and `grid plug` it (runtime, local edition, async — poll to a
19
19
  > live URL).
@@ -22,7 +22,8 @@ similarity is computed in-app until it ships. Because RAG involves choices
22
22
 
23
23
  - `cloudgrid.yaml` — active fields: `name`, `services.web` (nextjs, `/`), and
24
24
  `needs: { ai: true, database: true }`. `vector: pgvector` is present but
25
- commented (PENDING #1545); the optional `vault:` block (auth/payments) is
25
+ commented (available now, #1545 shipped — this blueprint uses Mongo
26
+ embeddings); the optional `vault:` block (auth/payments) is
26
27
  commented too.
27
28
  - `AGENTS.md` — the structure guide (read this first).
28
29
  - `index.md` — the fetch-bundle summary + cloudgrid.yaml.
@@ -89,10 +89,11 @@ needs:
89
89
  # pubsub: true
90
90
  # # vector — pgvector on Postgres. Injects VECTOR_PGVECTOR_URL (+ PGVECTOR_URL).
91
91
  # # true | pgvector | { engine: pgvector, dim: 1536 }
92
- # # NOTE: `needs: vector` (pgvector) is the intended store for RAG embeddings but
93
- # # is PENDING platform issue #1545 — not yet provisioned. Until it ships, store
94
- # # embeddings in Mongo (a `chunks` collection with an `embedding: number[]` field)
95
- # # and do cosine similarity in the app. Flip this on once #1545 lands.
92
+ # # NOTE: `needs: vector` (pgvector) is the intended store for RAG embeddings and
93
+ # # is available now (#1545 shipped). This template still stores embeddings in
94
+ # # Mongo (a `chunks` collection with an `embedding: number[]` field) and does
95
+ # # cosine similarity in the app — uncomment `vector: pgvector` only if you also
96
+ # # switch the retrieval code to pgvector.
96
97
  # vector: pgvector
97
98
  # # object_storage — GCS bucket. Injects OBJECT_STORAGE_GCS_BUCKET, _GCS_REGION.
98
99
  # # true | { size: 10Gi }
@@ -13,7 +13,7 @@ the app following it.
13
13
 
14
14
  - **Structure guide:** `grid_get_template("template", "ai-knowledge-base")` → read
15
15
  **`AGENTS.md`** (file tree, Mongo collections, CloudGrid injection table, the
16
- RAG loop, the pgvector #1545 note, optional auth/payments, deploy steps).
16
+ RAG loop, the pgvector note, optional auth/payments, deploy steps).
17
17
 
18
18
  **Key rules (same runtime discipline as `app-with-data`):**
19
19
 
@@ -29,10 +29,11 @@ the app following it.
29
29
  model's parametric memory alone. Keep chunking/retrieval as pure functions.
30
30
 
31
31
  **Vector store:** `needs: vector` (pgvector, injecting `VECTOR_PGVECTOR_URL`) is
32
- the intended embedding store but is **PENDING platform issue #1545**. The `ai`
33
- part works today — until #1545 ships, store embeddings in a Mongo `chunks`
34
- collection and rank by cosine similarity in the app; swap to a pgvector
35
- ORDER-BY-distance query when it lands (see `AGENTS.md` §7).
32
+ the intended embedding store and is **now available** — #1545 shipped (verified
33
+ live 2026-07-16). This blueprint still stores embeddings in a Mongo `chunks`
34
+ collection and ranks by cosine similarity in the app; to use pgvector instead,
35
+ uncomment the need and swap to a pgvector ORDER-BY-distance query (see
36
+ `AGENTS.md` §7).
36
37
 
37
38
  Runtime app → **local edition** only (async build, poll to a live URL).
38
39
 
@@ -42,7 +43,8 @@ Runtime app → **local edition** only (async build, poll to a live URL).
42
43
  # On disk this file is the full-annotated reference (templates/_cloudgrid.yaml.reference) with EVERY
43
44
  # field present as a comment; only the fields below are uncommented, so it
44
45
  # deploys to exactly these active fields. `vector: pgvector` is present but kept
45
- # COMMENTED (PENDING #1545).
46
+ # COMMENTED (available now — #1545 shipped — but this blueprint uses Mongo
47
+ # embeddings; uncomment only if you also build the retrieval on pgvector).
46
48
  name: my-knowledge-base
47
49
  services:
48
50
  web:
@@ -56,15 +58,16 @@ needs:
56
58
  > **Capability:** `needs: { database: true }` → the deployer provisions Mongo and
57
59
  > injects `DATABASE_MONGODB_URL` (plus legacy `MONGODB_URL`). `needs: { ai: true }`
58
60
  > → injects `AI_GATEWAY_URL`; `@cloudgrid-io/ai` routes embeddings + chat through
59
- > it with no API key to manage. `needs: { vector: pgvector }` (would inject
60
- > `VECTOR_PGVECTOR_URL`) is PENDING #1545. See the capability-map for the full
61
+ > it with no API key to manage. `needs: { vector: pgvector }` (injects
62
+ > `VECTOR_PGVECTOR_URL`) is available (#1545 shipped) but not declared here —
63
+ > this blueprint uses Mongo embeddings. See the capability-map for the full
61
64
  > injection table.
62
65
 
63
66
  ## Structure guide
64
67
 
65
68
  The real content of this blueprint is **`AGENTS.md`** — fetch the template bundle
66
69
  and read it. It covers the `services/web/` file tree, the `documents` / `chunks`
67
- collections, the CloudGrid injection table (needs + AI Gateway + the #1545 note),
70
+ collections, the CloudGrid injection table (needs + AI Gateway + the pgvector note),
68
71
  the ingest → retrieve → answer RAG loop with lazy `lib/db.js` / `lib/ai.js` /
69
72
  `lib/retrieve.js`, optional auth/payments via `vault:`, and the
70
73
  `grid init → fill → grid plug → poll` deploy flow.
@@ -75,7 +78,8 @@ the ingest → retrieve → answer RAG loop with lazy `lib/db.js` / `lib/ai.js`
75
78
  `lib/ai.js`; tune retrieval `k`.
76
79
  - Add auth (uncomment `vault: { AUTH_PROVIDER_KEY }`) to gate the KB, or payments
77
80
  (`vault: { STRIPE_KEY }`) to charge for access.
78
- - When pgvector #1545 lands, uncomment `needs: { vector: pgvector }` and swap
79
- `lib/retrieve.js` to an ORDER-BY-distance query (`AGENTS.md` §7).
81
+ - To move to pgvector (now available — #1545 shipped), uncomment
82
+ `needs: { vector: pgvector }` and swap `lib/retrieve.js` to an
83
+ ORDER-BY-distance query (`AGENTS.md` §7).
80
84
  - Build under `services/web/`, then `grid dev` (local) / `grid plug` (async — poll
81
85
  to a live URL).