@shaferllc/keel 0.83.5 → 0.83.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/llms-full.txt CHANGED
@@ -7,6 +7,357 @@ https://github.com/shaferllc/keel/blob/main/docs. Generated by `npm run build:ai
7
7
 
8
8
 
9
9
 
10
+ ---
11
+
12
+ <!-- source: docs/from-install-to-deploy.md -->
13
+
14
+ # From install to deploy
15
+
16
+ One path from zero to a live Keel app — locally, on Cloudflare yourself, or on
17
+ **Keel Cloud** with an AI agent. Pick the track that matches how you want to
18
+ ship; everything else is optional.
19
+
20
+ ```text
21
+ create-keeljs → npm run dev → (optional MCP) → deploy
22
+
23
+ Keel Cloud (optional)
24
+ ```
25
+
26
+ ## Requirements
27
+
28
+ - Node.js **≥ 22**
29
+ - npm
30
+ - For self-hosted edge deploys: a [Cloudflare](https://dash.cloudflare.com) account
31
+ and [Wrangler](https://developers.cloudflare.com/workers/wrangler/) (ships with
32
+ the kits as a devDependency)
33
+ - For Keel Cloud: an invite / allowlisted email at [app.keeljs.cloud](https://app.keeljs.cloud)
34
+ during private alpha
35
+
36
+ ## 1. Create an app
37
+
38
+ ```bash
39
+ npm create keeljs@latest my-app # full-stack "app" preset (default)
40
+ # npm create keeljs@latest my-api -- --preset api
41
+ # npm create keeljs@latest my-saas -- --preset saas
42
+ # npm create keeljs@latest bare -- --preset minimal
43
+ cd my-app
44
+ npm install
45
+ cp .env.example .env # if the kit didn't already
46
+ ```
47
+
48
+ | Preset | Use when |
49
+ |--------|----------|
50
+ | `minimal` | Hello-world / learning — routes, a view, Tailwind. No database. |
51
+ | `api` | JSON API — models, migrations, token auth, OpenAPI, tests. |
52
+ | `app` *(default)* | Product with views, sessions, register/login, password reset, 2FA. |
53
+ | `saas` | Multi-tenant product — teams, roles, invitations, billing. |
54
+
55
+ Templates live **inside** `@shaferllc/keel`, so the kit version matches the
56
+ framework version you just installed. Details: [Starter kits](./starter-kits.md).
57
+
58
+ ## 2. Run it locally
59
+
60
+ ```bash
61
+ npm run migrate # if the preset has a database (api / app / saas)
62
+ npm run dev # http://localhost:3000 — Node + local SQLite
63
+ ```
64
+
65
+ Useful next commands:
66
+
67
+ ```bash
68
+ npm run keel -- routes # what is mounted
69
+ npm run keel -- make:controller Post # scaffold, then wire a route
70
+ npm test
71
+ npm run typecheck
72
+ ```
73
+
74
+ Local tip: `DB_CONNECTION` defaults to a SQLite file. Switching drivers later is
75
+ config only — see [Database](./database.md) and [Starter kits](./starter-kits.md).
76
+
77
+ For a guided first hour inside the codebase (routes, controllers, views, config),
78
+ read [Getting Started](./getting-started.md).
79
+
80
+ ## 3. Optional — AI agents (local)
81
+
82
+ Keel is designed to be written with an agent. Point Cursor / Claude Code at the
83
+ MCP server that ships with the package:
84
+
85
+ ```json
86
+ {
87
+ "mcpServers": {
88
+ "keel": {
89
+ "command": "npx",
90
+ "args": ["-y", "keel-mcp"]
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ Then have the agent call `keel_overview` first. It can search docs, look up the
97
+ public API, and scaffold controllers/jobs/… without inventing imports.
98
+
99
+ Full map: [Building with AI](./ai.md).
100
+
101
+ ## 4. Deploy yourself (Cloudflare Workers)
102
+
103
+ Every kit includes `wrangler.jsonc`, a `worker.ts` entry, and `npm run deploy`.
104
+ You own the Cloudflare account and the hostname.
105
+
106
+ ```bash
107
+ # one-time
108
+ npx wrangler login
109
+ npx wrangler d1 create my-app # paste database_id into wrangler.jsonc
110
+
111
+ # ship
112
+ npm run deploy # css:build + wrangler deploy
113
+ ```
114
+
115
+ Migrations against remote D1 use the HTTP driver from your laptop / CI — the
116
+ binding only exists inside the Worker. Set Cloudflare API credentials as
117
+ documented in [Database](./database.md) (D1 HTTP) and your kit’s README.
118
+
119
+ Edge preview without deploying:
120
+
121
+ ```bash
122
+ npm run dev:edge # wrangler + local D1
123
+ ```
124
+
125
+ Hosting helpers (hostname utils, SQL dump, secrets encryption) live in
126
+ [`@shaferllc/keel/hosting`](./hosting.md) if you build your own control plane.
127
+
128
+ ## 5. Optional — Keel Cloud (`*.keeljs.cloud`)
129
+
130
+ Ship without owning a Cloudflare account: **Keel Cloud** creates the site,
131
+ runs preview/production Workers on `*.keeljs.cloud`, vaults secrets, and lets
132
+ you export git + SQL anytime — driven from the **same `keel-mcp`** you already
133
+ use for docs.
134
+
135
+ **Dedicated guide:** [Keel Cloud (deploy from MCP)](./keel-cloud.md).
136
+
137
+ Quick path:
138
+
139
+ 1. Sign up at [app.keeljs.cloud](https://app.keeljs.cloud) → mint a token at `/tokens`
140
+ 2. Add `KEEL_CLOUD_TOKEN` (+ `KEEL_CLOUD_URL`) to your MCP config
141
+ 3. Agent: `keel_cloud_create_site` → edit `storage_path` → `keel_cloud_preview` →
142
+ `keel_cloud_publish { confirm: true }`
143
+
144
+ Use Cloud when you want the platform to own deploys and hostnames. Skip it when
145
+ you already have Cloudflare / your own pipeline (§4). Don’t mix Cloud and
146
+ self-host for the same app.
147
+
148
+ ## Which path should I pick?
149
+
150
+ | Goal | Path |
151
+ |------|------|
152
+ | Learn Keel / ship a side project on your CF account | §§1–4 |
153
+ | Build with an agent in your IDE, deploy yourself | §§1–4 + §3 |
154
+ | Let the platform host preview/prod on `*.keeljs.cloud` via MCP | [Keel Cloud](./keel-cloud.md) |
155
+ | Multi-tenant SaaS with billing | Preset `saas`, then §4 or §5 |
156
+
157
+ Cloud **create_site** scaffolds a kit the same way `create-keeljs` does — you do
158
+ not need both for the same app. Use `create-keeljs` for apps you own end-to-end;
159
+ use Cloud when you want hosted preview/publish under `*.keeljs.cloud`.
160
+
161
+ ## Where next
162
+
163
+ - [Keel Cloud (deploy from MCP)](./keel-cloud.md) — create / preview / publish
164
+ on `*.keeljs.cloud` from `keel-mcp`
165
+ - [Getting Started](./getting-started.md) — first route, controller, view
166
+ - [Starter kits](./starter-kits.md) — presets and the Node/edge seam
167
+ - [Building with AI](./ai.md) — MCP tools (local + Cloud)
168
+ - [Hosting](./hosting.md) — Cloudflare / dump / secrets primitives
169
+ - [Accounts](./accounts.md) · [Teams](./teams.md) · [Billing](./billing.md) — what
170
+ `app` / `saas` already mount
171
+
172
+
173
+
174
+ ---
175
+
176
+ <!-- source: docs/keel-cloud.md -->
177
+
178
+ # Keel Cloud (deploy from MCP)
179
+
180
+ **Keel Cloud** hosts your Keel apps on `*.keeljs.cloud` — preview and production
181
+ Workers, D1, secrets vault, and full export (git + SQL). You build in your IDE
182
+ with an AI agent; the same `keel-mcp` binary that knows the framework also
183
+ **creates sites and deploys them** when you set a Cloud token.
184
+
185
+ | Host | Role |
186
+ |------|------|
187
+ | [app.keeljs.cloud](https://app.keeljs.cloud) | Control plane (dashboard + `/api/v1`) |
188
+ | `preview-{slug}.keeljs.cloud` | Preview Worker |
189
+ | `{slug}.keeljs.cloud` | Production Worker |
190
+ | [keeljs.com](https://keeljs.com) | Framework docs (this site) |
191
+
192
+ Private alpha: registration needs an invite code or allowlisted email. Free tier
193
+ is limited (typically one site); Pro adds more sites and custom domains.
194
+
195
+ > Prefer owning Cloudflare yourself? Use
196
+ > [From install to deploy](./from-install-to-deploy.md) §4 (`create-keeljs` +
197
+ > `wrangler deploy`). Cloud and self-host are **alternate** paths — don’t mix
198
+ > them for the same app.
199
+
200
+ ## Why deploy from MCP
201
+
202
+ Agents already use `keel-mcp` for docs and scaffolding. With a token they also
203
+ get `keel_cloud_*` tools against the control plane — no separate CLI, no
204
+ copy-pasting wrangler credentials into the agent. The loop is:
205
+
206
+ ```text
207
+ create_site → edit storage_path → set_secret → preview → publish (confirm)
208
+ ```
209
+
210
+ ## 1. Sign up and mint a token
211
+
212
+ 1. Open [app.keeljs.cloud](https://app.keeljs.cloud) and register (invite /
213
+ allowlist during alpha).
214
+ 2. Go to **`/tokens`** → create a personal access token.
215
+ 3. Copy the plaintext once — it looks like `keel_<selector>.<verifier>`.
216
+
217
+ The token binds to your **first team**. Switch teams in the dashboard before
218
+ minting if you need a different team context.
219
+
220
+ ## 2. Wire `keel-mcp` for Cloud
221
+
222
+ Same server as local docs/API — add env so Cloud tools register:
223
+
224
+ **Cursor / `.mcp.json` / Windsurf:**
225
+
226
+ ```json
227
+ {
228
+ "mcpServers": {
229
+ "keel": {
230
+ "command": "npx",
231
+ "args": ["-y", "keel-mcp"],
232
+ "env": {
233
+ "KEEL_CLOUD_TOKEN": "keel_….…",
234
+ "KEEL_CLOUD_URL": "https://app.keeljs.cloud"
235
+ }
236
+ }
237
+ }
238
+ }
239
+ ```
240
+
241
+ **Claude Code:**
242
+
243
+ ```bash
244
+ claude mcp add keel -e KEEL_CLOUD_TOKEN=keel_….… -e KEEL_CLOUD_URL=https://app.keeljs.cloud -- npx -y keel-mcp
245
+ ```
246
+
247
+ Reload the MCP client. Stderr should say `Cloud tools enabled`. Call
248
+ `keel_overview` — it lists the Cloud loop when a token is present.
249
+
250
+ Local-only (docs + scaffold, no deploy): omit the env vars.
251
+ [Building with AI](./ai.md) covers that surface.
252
+
253
+ ## 3. Deploy a site from the agent
254
+
255
+ Tell your agent something like: *“Create an app preset site named Acme on Keel
256
+ Cloud, then preview it.”* Or drive the tools yourself:
257
+
258
+ ### Create
259
+
260
+ ```text
261
+ keel_cloud_create_site { "name": "Acme", "preset": "app" }
262
+ ```
263
+
264
+ Presets: `minimal` | `api` | `app` | `saas` (same kits as
265
+ [`create-keeljs`](./starter-kits.md)).
266
+
267
+ Response includes `storage_path` (real Keel app on disk) and hostnames. Open that
268
+ path in your IDE and edit like any Keel project.
269
+
270
+ ### Secrets (optional, before deploy)
271
+
272
+ ```text
273
+ keel_cloud_set_secret { "site_id": 1, "key": "STRIPE_SECRET_KEY", "value": "sk_…" }
274
+ keel_cloud_list_secrets { "site_id": 1 } # keys only — values never returned
275
+ ```
276
+
277
+ Secrets are vaulted (not in git) and injected on the next preview/publish.
278
+
279
+ ### Preview (safe to repeat)
280
+
281
+ ```text
282
+ keel_cloud_preview { "site_id": 1 }
283
+ ```
284
+
285
+ Deploys the preview Worker → `preview-{slug}.keeljs.cloud`. Iterate freely.
286
+
287
+ ### Publish production (confirm required)
288
+
289
+ ```text
290
+ keel_cloud_publish { "site_id": 1, "confirm": true }
291
+ ```
292
+
293
+ Agents must get your explicit approval before `confirm: true`. Production lands
294
+ on `{slug}.keeljs.cloud`.
295
+
296
+ ### Check status
297
+
298
+ ```text
299
+ keel_cloud_get_site { "site_id": 1 }
300
+ keel_cloud_deploys { "site_id": 1 } # logs + preview/production history
301
+ keel_cloud_me # plan, site_limit, team
302
+ ```
303
+
304
+ ### Custom domain (Pro)
305
+
306
+ ```text
307
+ keel_cloud_set_custom_domain {
308
+ "site_id": 1,
309
+ "hostname": "app.example.com",
310
+ "attach": true
311
+ }
312
+ ```
313
+
314
+ Returns CNAME instructions (point at `{slug}.keeljs.cloud`). The customer zone
315
+ must live on the same Cloudflare account as Keel Cloud. Clear with
316
+ `keel_cloud_clear_custom_domain`.
317
+
318
+ ### Escape hatch
319
+
320
+ ```text
321
+ keel_cloud_export { "site_id": 1 }
322
+ keel_cloud_export_sql { "site_id": 1, "env": "production" }
323
+ ```
324
+
325
+ Always yours: clone `storage_path` / `git_url`, restore the `.sql` dump on a
326
+ self-hosted Keel app anytime.
327
+
328
+ ## Tool cheat sheet
329
+
330
+ | Tool | Deploy role |
331
+ |------|-------------|
332
+ | `keel_cloud_create_site` | Scaffold kit under Cloud storage |
333
+ | `keel_cloud_preview` | Deploy preview Worker |
334
+ | `keel_cloud_publish` | Deploy production (`confirm: true`) |
335
+ | `keel_cloud_set_secret` / `_list_secrets` / `_delete_secret` | Runtime env for Workers |
336
+ | `keel_cloud_set_custom_domain` / `_clear_custom_domain` | Pro hostname |
337
+ | `keel_cloud_deploys` / `_get_site` | Status and logs |
338
+ | `keel_cloud_billing` / `_checkout` / `_portal` | Plan / upgrade (owner) |
339
+ | `keel_cloud_export` / `_export_sql` | Leave with code + data |
340
+ | `keel_cloud_delete_site` / `_restore_site` | Soft-delete / restore |
341
+
342
+ Full API table and local-docs tools: [Building with AI](./ai.md).
343
+
344
+ ## Dashboard parity
345
+
346
+ Everything above is also available in the browser at
347
+ [app.keeljs.cloud](https://app.keeljs.cloud) (`/sites`, `/billing`, `/tokens`).
348
+ MCP is the agent-first path; the UI is the same control plane.
349
+
350
+ ## Related
351
+
352
+ - [From install to deploy](./from-install-to-deploy.md) — full journey including
353
+ self-hosted Cloudflare
354
+ - [Building with AI](./ai.md) — MCP docs + complete `keel_cloud_*` list
355
+ - [Starter kits](./starter-kits.md) — what each preset contains
356
+ - [Hosting](./hosting.md) — primitives Cloud uses under the hood
357
+ - [Gates](./gates.md) — invite / allowlist signup gating
358
+
359
+
360
+
10
361
  ---
11
362
 
12
363
  <!-- source: docs/getting-started.md -->
@@ -28,32 +379,20 @@ Keel targets modern Node and web-standard APIs, so a current runtime matters —
28
379
 
29
380
  ## Install
30
381
 
31
- Keel ships as two repos: the **framework** (`@shaferllc/keel`, published to
32
- npm) and a **starter app** (`shaferllc/keel-app`) you build on. Which path you
33
- take depends on whether you're starting fresh or bolting Keel onto something
34
- that already exists. See [Architecture](./architecture.md#two-repos-library-and-starter)
35
- for why it's split this way.
36
-
37
- ### From the starter (recommended)
38
-
39
- The fastest route to a running app is the starter — a working skeleton with the
40
- folders, config, and scripts already wired:
382
+ The fastest path to a running app is the generator it copies a curated kit
383
+ from the same `@shaferllc/keel` version you install, so the template cannot lag
384
+ the framework:
41
385
 
42
386
  ```bash
43
- git clone https://github.com/shaferllc/keel-app.git my-app
387
+ npm create keeljs@latest my-app
44
388
  cd my-app
45
389
  npm install
390
+ npm run dev # http://localhost:3000
46
391
  ```
47
392
 
48
- The starter depends on `@shaferllc/keel`, so you pick up framework updates with
49
- an ordinary `npm update @shaferllc/keel` your app code in `app/` stays put.
50
-
51
- A fresh checkout ships with a working `.env`. To start from the template
52
- instead:
53
-
54
- ```bash
55
- cp .env.example .env
56
- ```
393
+ For the full journey (presets, Cloudflare deploy, optional Keel Cloud + MCP),
394
+ see **[From install to deploy](./from-install-to-deploy.md)**. Kit details:
395
+ [Starter kits](./starter-kits.md).
57
396
 
58
397
  ### Into an existing app
59
398
 
@@ -70,22 +409,24 @@ import { Application, Router, config } from "@shaferllc/keel/core";
70
409
  ```
71
410
 
72
411
  You supply the four convention folders yourself — `app/`, `config/`, `routes/`,
73
- `bootstrap/` — plus an entry that calls `createApplication()`. The starter's
412
+ `bootstrap/` — plus an entry that calls `createApplication()`. A generated kit’s
74
413
  `bootstrap/app.ts` is the reference; copy it and trim to taste.
75
414
 
76
415
  ### Hacking on the framework itself
77
416
 
78
- To work on Keel proper, clone the framework repo — it carries an example app you
79
- can run directly:
417
+ To work on Keel proper, clone the framework repo:
80
418
 
81
419
  ```bash
82
420
  git clone https://github.com/shaferllc/keel.git
83
421
  cd keel
84
422
  npm install
85
- npm run dev # example app on http://localhost:3000
86
- npm run build # compile the package to dist/
423
+ npm test
424
+ npm run typecheck
87
425
  ```
88
426
 
427
+ Generate a disposable app against your checkout with
428
+ `npm create keeljs@latest …` and point its dependency at `file:../keel`.
429
+
89
430
  ## Run the server
90
431
 
91
432
  ```bash
@@ -280,9 +621,10 @@ unsure what's mounted. [The Console](./console.md) lists every command.
280
621
  ## Where to go next
281
622
 
282
623
  You now have the shape of a Keel app: routes point at controllers, controllers
283
- render views and read config, and the console scaffolds the pieces. The deep
284
- guides pick up from here:
624
+ render views and read config, and the console scaffolds the pieces.
285
625
 
626
+ - **[From install to deploy](./from-install-to-deploy.md)** — presets, Cloudflare,
627
+ optional Keel Cloud + MCP
286
628
  - [Architecture](./architecture.md) — how boot, the container, and the request
287
629
  lifecycle fit together
288
630
  - [The Service Container](./container.md) — how dependency injection works
@@ -297,6 +639,7 @@ guides pick up from here:
297
639
  the active-record layer on top of it
298
640
  - [Configuration](./configuration.md) and [The Console](./console.md) — settings
299
641
  and commands
642
+ - [Building with AI](./ai.md) — MCP docs + Cloud tools
300
643
 
301
644
  When something isn't documented, open the source — the whole framework is a few
302
645
  hundred readable lines in `src/core/`, and [Built on Hono](./hono.md) explains
@@ -304,6 +647,116 @@ what you inherit from the layer underneath.
304
647
 
305
648
 
306
649
 
650
+ ---
651
+
652
+ <!-- source: docs/starter-kits.md -->
653
+
654
+ # Starter kits
655
+
656
+ ```bash
657
+ npm create keeljs@latest my-app -- --preset saas
658
+ ```
659
+
660
+ Four curated applications. Each is a complete, working app — not a scaffold you have
661
+ to finish. For the full path from this command through Cloudflare or Keel Cloud,
662
+ see [From install to deploy](./from-install-to-deploy.md).
663
+
664
+ | Preset | What you get |
665
+ | --- | --- |
666
+ | `minimal` | Routes, a controller, a JSX view, Tailwind. No database. |
667
+ | `api` | JSON only — models, migrations, validation, tests. No views. |
668
+ | `app` *(default)* | Full-stack: views, sessions, register/login, password reset, two-factor. |
669
+ | `saas` | `app` plus teams, roles, invitations, billing, and multi-tenancy. |
670
+
671
+ ## Pick a kit
672
+
673
+ ```bash
674
+ npm create keeljs@latest my-app # app (default)
675
+ npm create keeljs@latest my-api -- --preset api
676
+ npm create keeljs@latest my-saas -- --preset saas
677
+ npm create keeljs@latest bare -- --preset minimal
678
+ cd my-app && npm install && npm run dev
679
+ ```
680
+
681
+ Then open `http://localhost:3000`. The SaaS kit already has a team switcher,
682
+ invites, and a billing stub wired through [teams](./teams.md) and
683
+ [billing](./billing.md) — start by editing `app/Models` and `routes/web.ts`.
684
+
685
+ ## Every database, Cloudflare first
686
+
687
+ Each kit ships with all four drivers wired. Switching is `DB_CONNECTION` and nothing
688
+ else — no model or query changes, because they talk to a `Connection`, not a driver.
689
+
690
+ | | |
691
+ | --- | --- |
692
+ | **D1** | The default for deploys. Inside the Worker Keel uses the binding; migrations and scripts reach the same database over [the HTTP API](./database.md), so `keel migrate` works from your laptop and from CI. |
693
+ | **SQLite** (libSQL) | A local file. What `npm run dev` uses — no account, no wrangler. |
694
+ | **Turso** | libSQL over the network. |
695
+ | **Postgres** | For when you want it. |
696
+
697
+ Local and production are both SQLite dialects, so one schema and one set of
698
+ migrations serve both.
699
+
700
+ ```bash
701
+ npm run dev # Node, SQLite file, no setup
702
+ npm run dev:edge # wrangler, local D1
703
+ npm run deploy # wrangler deploy
704
+ ```
705
+
706
+ To deploy:
707
+
708
+ ```bash
709
+ wrangler d1 create my-app # paste the id into wrangler.jsonc
710
+ npm run deploy
711
+ ```
712
+
713
+ ## What's in the box
714
+
715
+ `app` and `saas` mount [accounts](./accounts.md), so password reset, email
716
+ verification, and two-factor already work — the flows live in the framework, tested
717
+ once, rather than being copy-pasted into each new app. `saas` also mounts
718
+ [teams](./teams.md) and [billing](./billing.md).
719
+
720
+ In `saas`, a tenant-owned model is one word:
721
+
722
+ ```ts
723
+ import { TenantModel } from "@shaferllc/keel/teams";
724
+
725
+ class Project extends TenantModel {
726
+ static table = "projects";
727
+ }
728
+
729
+ await Project.all(); // only the current team's. Always.
730
+ await Project.create({ name: "Hi" }); // stamped with the current team
731
+ ```
732
+
733
+ Another team's project isn't merely hidden from a list — `Project.find(id)` returns
734
+ `null`. You never write `.where("team_id", …)`, which is what makes it impossible to
735
+ forget.
736
+
737
+ ## Why a generator, and not a template repo
738
+
739
+ Because a second repo rots. The old starter sat pinned to `0.78.2` while the
740
+ framework was on `0.79.0`, and nothing noticed.
741
+
742
+ The templates live **inside the framework package**, so the version a kit is
743
+ generated from is, by construction, the version it was written for. And CI generates
744
+ all four on every push, then typechecks, migrates, boots, serves a request, bundles
745
+ the Worker, and runs their tests — so a breaking change fails in the pull request
746
+ that caused it, not in your `npm create` three weeks later.
747
+
748
+ ## The Node/edge seam
749
+
750
+ Each kit has two provider lists. `bootstrap/providers.ts` runs under Node;
751
+ `bootstrap/providers.edge.ts` runs in the Worker and deliberately **omits the
752
+ database provider** — it reaches for `pg`, which needs `net`/`tls`, and wrangler
753
+ cannot bundle a TCP driver for the edge. `worker.ts` binds D1 before the app boots,
754
+ so nothing on the edge needs to open a connection.
755
+
756
+ If you add a provider that touches a Node-only module, add it to the Node list only.
757
+
758
+
759
+
307
760
  ---
308
761
 
309
762
  <!-- source: docs/architecture.md -->
@@ -4669,8 +5122,11 @@ AI-facing surface: an MCP server, machine-readable docs (`llms.txt` /
4669
5122
  `llms-full.txt`), an agent playbook (`AGENTS.md`), and code generators an agent
4670
5123
  can drive directly.
4671
5124
 
4672
- If you only read one thing: point your agent at the [MCP server](#the-mcp-server)
4673
- and have it call `keel_overview` first.
5125
+ If you only read one thing: follow
5126
+ [From install to deploy](./from-install-to-deploy.md). To **deploy on
5127
+ `*.keeljs.cloud` from your IDE**, see [Keel Cloud (deploy from MCP)](./keel-cloud.md).
5128
+ Then point your agent at the [MCP server](#the-mcp-server) and call
5129
+ `keel_overview` first.
4674
5130
 
4675
5131
  ## Why this exists
4676
5132
 
@@ -4726,8 +5182,12 @@ package, so it always matches your installed version.
4726
5182
  | `keel_scaffold` | Generate a controller/provider/middleware/factory/seeder/job/notification/transformer stub. Returns code + target path — it does **not** write to disk. |
4727
5183
 
4728
5184
  When `KEEL_CLOUD_TOKEN` (and optional `KEEL_CLOUD_URL`) is set, Cloud tools are
4729
- also registered. Create a token at `/tokens` on the control plane — the plaintext
4730
- looks like `keel_<selector>.<verifier>`.
5185
+ also registered **create, preview, and publish sites on `*.keeljs.cloud`** from
5186
+ the same MCP server. Step-by-step:
5187
+ **[Keel Cloud (deploy from MCP)](./keel-cloud.md)**.
5188
+
5189
+ Create a token at `/tokens` on [app.keeljs.cloud](https://app.keeljs.cloud) — the
5190
+ plaintext looks like `keel_<selector>.<verifier>`.
4731
5191
 
4732
5192
  | Tool | What it does |
4733
5193
  |------|--------------|
@@ -4777,11 +5237,13 @@ minting a token if you need a different team context.
4777
5237
 
4778
5238
  ### A typical Keel Cloud loop
4779
5239
 
5240
+ Full walkthrough: [Keel Cloud (deploy from MCP)](./keel-cloud.md).
5241
+
4780
5242
  1. `keel_cloud_create_site { name: "Acme", preset: "app" }`
4781
5243
  2. Edit the returned `storage_path` (real Keel app + git)
4782
5244
  3. `keel_cloud_set_secret` for env the Worker needs
4783
- 4. `keel_cloud_preview { site_id }`
4784
- 5. `keel_cloud_publish { site_id, confirm: true }` after the user approves
5245
+ 4. `keel_cloud_preview { site_id }` → `preview-{slug}.keeljs.cloud`
5246
+ 5. `keel_cloud_publish { site_id, confirm: true }` `{slug}.keeljs.cloud`
4785
5247
  6. Optional Pro: `keel_cloud_set_custom_domain { hostname, attach: true }`
4786
5248
  7. Escape hatch anytime: `keel_cloud_export` + `keel_cloud_export_sql`
4787
5249
 
@@ -17957,115 +18419,6 @@ const gitlab = social.driver(
17957
18419
 
17958
18420
 
17959
18421
 
17960
- ---
17961
-
17962
- <!-- source: docs/starter-kits.md -->
17963
-
17964
- # Starter kits
17965
-
17966
- ```bash
17967
- npm create keeljs@latest my-app -- --preset saas
17968
- ```
17969
-
17970
- Four curated applications. Each is a complete, working app — not a scaffold you have
17971
- to finish.
17972
-
17973
- | Preset | What you get |
17974
- | --- | --- |
17975
- | `minimal` | Routes, a controller, a JSX view, Tailwind. No database. |
17976
- | `api` | JSON only — models, migrations, validation, tests. No views. |
17977
- | `app` *(default)* | Full-stack: views, sessions, register/login, password reset, two-factor. |
17978
- | `saas` | `app` plus teams, roles, invitations, billing, and multi-tenancy. |
17979
-
17980
- ## Pick a kit
17981
-
17982
- ```bash
17983
- npm create keeljs@latest my-app # app (default)
17984
- npm create keeljs@latest my-api -- --preset api
17985
- npm create keeljs@latest my-saas -- --preset saas
17986
- npm create keeljs@latest bare -- --preset minimal
17987
- cd my-app && npm install && npm run dev
17988
- ```
17989
-
17990
- Then open `http://localhost:3000`. The SaaS kit already has a team switcher,
17991
- invites, and a billing stub wired through [teams](./teams.md) and
17992
- [billing](./billing.md) — start by editing `app/Models` and `routes/web.ts`.
17993
-
17994
- ## Every database, Cloudflare first
17995
-
17996
- Each kit ships with all four drivers wired. Switching is `DB_CONNECTION` and nothing
17997
- else — no model or query changes, because they talk to a `Connection`, not a driver.
17998
-
17999
- | | |
18000
- | --- | --- |
18001
- | **D1** | The default for deploys. Inside the Worker Keel uses the binding; migrations and scripts reach the same database over [the HTTP API](./database.md), so `keel migrate` works from your laptop and from CI. |
18002
- | **SQLite** (libSQL) | A local file. What `npm run dev` uses — no account, no wrangler. |
18003
- | **Turso** | libSQL over the network. |
18004
- | **Postgres** | For when you want it. |
18005
-
18006
- Local and production are both SQLite dialects, so one schema and one set of
18007
- migrations serve both.
18008
-
18009
- ```bash
18010
- npm run dev # Node, SQLite file, no setup
18011
- npm run dev:edge # wrangler, local D1
18012
- npm run deploy # wrangler deploy
18013
- ```
18014
-
18015
- To deploy:
18016
-
18017
- ```bash
18018
- wrangler d1 create my-app # paste the id into wrangler.jsonc
18019
- npm run deploy
18020
- ```
18021
-
18022
- ## What's in the box
18023
-
18024
- `app` and `saas` mount [accounts](./accounts.md), so password reset, email
18025
- verification, and two-factor already work — the flows live in the framework, tested
18026
- once, rather than being copy-pasted into each new app. `saas` also mounts
18027
- [teams](./teams.md) and [billing](./billing.md).
18028
-
18029
- In `saas`, a tenant-owned model is one word:
18030
-
18031
- ```ts
18032
- import { TenantModel } from "@shaferllc/keel/teams";
18033
-
18034
- class Project extends TenantModel {
18035
- static table = "projects";
18036
- }
18037
-
18038
- await Project.all(); // only the current team's. Always.
18039
- await Project.create({ name: "Hi" }); // stamped with the current team
18040
- ```
18041
-
18042
- Another team's project isn't merely hidden from a list — `Project.find(id)` returns
18043
- `null`. You never write `.where("team_id", …)`, which is what makes it impossible to
18044
- forget.
18045
-
18046
- ## Why a generator, and not a template repo
18047
-
18048
- Because a second repo rots. The old starter sat pinned to `0.78.2` while the
18049
- framework was on `0.79.0`, and nothing noticed.
18050
-
18051
- The templates live **inside the framework package**, so the version a kit is
18052
- generated from is, by construction, the version it was written for. And CI generates
18053
- all four on every push, then typechecks, migrates, boots, serves a request, bundles
18054
- the Worker, and runs their tests — so a breaking change fails in the pull request
18055
- that caused it, not in your `npm create` three weeks later.
18056
-
18057
- ## The Node/edge seam
18058
-
18059
- Each kit has two provider lists. `bootstrap/providers.ts` runs under Node;
18060
- `bootstrap/providers.edge.ts` runs in the Worker and deliberately **omits the
18061
- database provider** — it reaches for `pg`, which needs `net`/`tls`, and wrangler
18062
- cannot bundle a TCP driver for the edge. `worker.ts` binds D1 before the app boots,
18063
- so nothing on the edge needs to open a connection.
18064
-
18065
- If you add a provider that touches a Node-only module, add it to the Node list only.
18066
-
18067
-
18068
-
18069
18422
  ---
18070
18423
 
18071
18424
  <!-- source: docs/static-files.md -->