Skip to main content
The repository ships a complete self-hosted deployment in examples/docker: one container image, two services, one database file.
  • web (port 8080) — the authoring app: the widget, theme, schema and action designers over the published authoring surface (@widgentic/mcp/authoring), plus write-only secrets and API keys.
  • mcp (port 8081) — the Streamable HTTP MCP endpoint at /mcp. Mint a key under Keys and connect any MCP host with an x-api-key header (or ?key= where the host cannot send headers).
An entry you save in the app is served on the MCP endpoint’s next tool call — same file, no cache, no restart. The store is createSqliteStore: SQLite compiled into the Node runtime, so the whole deployment has no runtime dependency to operate.

The trust shape

The two services mirror the hosted product’s split:

Identity without an identity provider

By default the deployment serves one principal with no sign-in. That mode belongs on localhost or a trusted network — treat the app like any admin panel without a login. Multi-user comes from the auth proxy you already run, not from widgentic:
Each verified header value (from oauth2-proxy, Cloudflare Access, Authelia, Tailscale Serve, …) becomes its own account, stable across restarts. The header is never read while the variable is unset, so a spoofed header changes nothing; once set the app fails closed — a request without the header is refused rather than served the default account. Your proxy must strip the header from inbound client requests.

Secrets and key custody

Secret values are envelope-encrypted at rest; the database file holds ciphertext and key digests only. The key-encryption key is yours to supply — generated once, handed to both services as a mounted file (WIDGENTIC_KEK_FILE, the compose file uses a docker secret) or the WIDGENTIC_KEK variable, and never generated at boot: a per-boot key would write records nothing can read back. With no KEK the Secrets section is off and everything else works. Name the trade honestly: here the KEK lives in the process, which is weaker custody than the hosted product’s, where the key sits in a managed vault and no process ever holds it. Whoever can read your KEK material can decrypt every secret this deployment stores, and losing it makes them unreadable with no recovery. If your threat model needs vault custody, the same cipher port takes createKeyVaultCipher from @widgentic/mcp/secrets/keyvault.

Configuration

What this deployment is not

A single node. The SQLite adapter is deliberately a one-machine design — two local processes share the file through WAL, but there is no multi-replica story, no migration path to one, and no high availability. When you outgrow it, the store port is the seam: the same deployment shape runs against the Cosmos adapter, and the hosted product is the same assembly operated for you.