Scope and stack#
What scrap sets out not to be, and what it is built from. The design describes the principles and how it works; the decision records give the reasons.
Non-goals#
No Obsidian vault and no git sync: the database and a folder of files are the store. An export of every page as Markdown (
scrap export, or Settings, Export everything) opens as an Obsidian vault, but nothing is kept in step with it.No login code of its own and no user management. Access is the network: Tailscale (Serve supplies the identity header) or an authenticating proxy such as Cloudflare Access, with an optional bearer token on
/mcponly (7. Tailscale Serve is the only way in; no login code, 23. Bearer token on /mcp and an identity-header setting).No collection of microservices or paid-API integration layers.
Not multi-user: one store for one person, or a few people who trust each other.
Stack#
Part |
Choice |
|---|---|
Service |
One Python process: FastAPI serving the PWA, a JSON API and an MCP server (13. The MCP server is part of the app: streamable HTTP, add-only writes) |
Storage |
SQLite, plus a folder of content-addressed files |
Search |
SQLite FTS5 (BM25, prefix matching) with a filter syntax shared by the PWA and MCP; embeddings deferred (8. Search is SQLite FTS5 with a shared query syntax; embeddings are deferred) |
Frontend |
TypeScript PWA with the Excalidraw component |
Access |
No login. Bind loopback or a Unix socket and publish with Tailscale Serve (7. Tailscale Serve is the only way in; no login code, 18. Single-server installs listen on a Unix socket, reached only through Tailscale Serve), or put an authenticating proxy in front on Kubernetes, with an optional |
Deployment |
Multi-arch (amd64, arm64) container image: a plain container to try it, rootless podman and systemd on one server, or the Helm chart on Kubernetes (16. Deployment: rootless podman units for one server, a Helm chart for Kubernetes) |