@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/AGENTS.md +16 -4
- package/README.md +33 -18
- package/dist/mcp/server.js +6 -5
- package/docs/ai-manifest.json +15 -1
- package/docs/ai.md +15 -6
- package/docs/changelog.md +20 -0
- package/docs/from-install-to-deploy.md +157 -0
- package/docs/getting-started.md +19 -27
- package/docs/keel-cloud.md +180 -0
- package/docs/starter-kits.md +2 -1
- package/llms-full.txt +495 -142
- package/llms.txt +2 -0
- package/package.json +1 -1
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
-
|
|
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()`.
|
|
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
|
|
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
|
|
86
|
-
npm run
|
|
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.
|
|
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:
|
|
4673
|
-
|
|
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
|
|
4730
|
-
|
|
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 }`
|
|
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 -->
|