One process
The server is a single Fastify app. It serves the JSON API under/api/*, the MCP endpoint at /mcp, the
web app, better-auth login, and the connection gateway on loopback. A production install is one binary
supervising itself.
The database is embedded
Postgres runs inside the app process as PGlite, against a directory underCRAFTSPACE_HOME. There is no
separate database container, which is what makes an install one thing rather than two.
Migrations run as one transaction, so a failed migration changes nothing and the previous version keeps
serving. That is the property that makes rolling an image back safe, and it is also the constraint on
every release: a release may only add what the previous one reads, never remove it.
The gateway is a module, not a service
Connection credentials are sealed at rest, and only the gateway can open them. It used to be a separate container, and it is not any more, because a second machine was the only thing that boundary actually bought. What survives is the shape: one module, importing nothing else in the app, holding the key.Module layout
packages/app/server/src groups by subject rather than by layer:
A group folder carries no code of its own, which
npm run check:structure enforces. A module grows
subfolders once it passes ten files.
Reading further
CONTEXT.md in the repository is the domain language: what a space, a page, a connection and an errand
each mean here, in the words the code uses.