PromptOwl + ContextNest Docs

Self-Hosting (Community Edition)

Updated Open in ChatGPTOpen in Claude

ContextNest Community Edition is a self-hosted context governance server for AI workflows, part of the PromptOwl platform. It stores, versions, and governs markdown-based context documents ("nests") and serves the approved slice to AI agents over MCP or HTTP.

The server is a Node.js backend (the Hono framework) paired with a React frontend, shipped as a single deployable. It runs on your own laptop, a VM, or a container platform — your data stays on infrastructure you control, while your PromptOwl account handles authentication entitlement and license validation.

Commercial software. Community Edition is proprietary, licensed by Promptowl LLC, and requires a (free) PromptOwl account. It is not open source. Redistribution and hosting-as-a-service are prohibited without a commercial agreement — contact hoot@promptowl.ai.

Requirements

  • Node.js 20.x or later
  • A free PromptOwl account (https://app.promptowl.ai/signup) to obtain a Community License key (pk_...)
  • OS: Windows, macOS, or Linux
  • Disk: ~200 MB for the server, plus room for your nests

Deploy

npm / npx (quickest)

# Run the community server
npx @promptowl/contextnest-community

# Then open the UI
#   http://localhost:3838
# On first boot with no license it lands on the License Setup Page.

The server listens on http://localhost:3838 by default. Without a valid license it still boots and serves reads, but every write returns 503 until you activate.

Docker / CI / scripted deploys

Pass configuration as environment variables — set them in your shell, a .env file, a Docker image, or your process manager. The simplest licensed boot:

PROMPTOWL_KEY=pk_... npx @promptowl/contextnest-community

For a built image the production entrypoint is node dist/index.js (or npm start).

Licensing at runtime

A Community License key (pk_...) is created for free from the PromptOwl Overview → Community License menu. Install it one of two ways:

  1. Browser setup page — start the server, open it with no license installed, and paste the pk_... key on the License Setup Page. It is validated against PromptOwl and persisted (see storage note below) — no restart needed.
  2. PROMPTOWL_KEY env var — read at boot and validated on startup.

Runtime behaviour:

  • Unlicensed / setup mode — reads work; every non-GET (write) request returns 503 until a valid key is installed.
  • Live revocation — a long-poll watcher tracks license state against PromptOwl; a revoked key blocks writes within seconds and returns to setup mode, no restart required.
  • Admin identity follows the license — the admin user is whichever PromptOwl account owns the installed key, resolved live. Transferring the license promotes the new owner and demotes the old one.

Authentication modes

Pick one per instance with AUTH_MODE.

Mode Behaviour Use when
key (default) Every request needs Authorization: Bearer cnst_... (or a browser session cookie). Real user accounts, per-user API keys, rate-limited login. Any multi-user or internet-facing deployment.
open No auth — every request is the anonymous admin user; everyone effectively owns every anon-created nest. The server prints a loud startup warning. Local single-user (bind 127.0.0.1), a trusted LAN, or behind a proxy that already authenticates.

Do not use open mode on a publicly reachable port, for multiple isolated users, or where you need audit trails (every write is attributed to "anonymous admin"). See Authentication & API Keys for the cnst_ key model.

Single sign-on (OIDC)

Community Edition supports generic OpenID Connect SSO against any spec-compliant IdP — Microsoft Entra ID and Google are first-class presets, and Okta / Keycloak work as standard issuers. Turn it on with OIDC_ENABLED=true plus OIDC_ISSUER, OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET (all three required before the login button appears), or configure it live from Settings → Single sign-on. Set PUBLIC_BASE_URL so the OIDC redirect URI is derived from your canonical address rather than the incoming Host header. A separate one-click PromptOwl SSO exists only on the official hosted deployment (gated by OFFICIAL_COMMUNITY_SSO_SECRET, which stays unset on self-hosted).

Storage backends

The governance/auth metadata (users, sessions, nests registry, stewards, reviews, version index, comments, telemetry) lives in a relational database; the actual document content and version history live on the filesystem under $DATA_ROOT/nests/.

Backend Selected by Notes
SQLite (default) nothing — it's the default Single file at DATABASE_PATH (defaults to $DATA_ROOT/community.db). Zero-config, ideal for a single box or local use.
PostgreSQL / Cloud SQL DB_DRIVER=postgres, or setting DATABASE_URL / CLOUD_SQL_CONNECTION_NAME For deployments where local disk isn't durable (e.g. Cloud Run). All horizontally-scaled instances share one consistent database.

The server creates its schema automatically on first connect (idempotent); there is no built-in SQLite→Postgres data migration — a new Postgres backend starts empty.

Cloud Run durability warning. Cloud SQL persists only the metadata database. Document content and version history live under $DATA_ROOT/nests/, which on Cloud Run is ephemeral. Put $DATA_ROOT (or NEST_STORAGE_ROOT) on durable shared storage — e.g. a GCS bucket mounted via Cloud Storage FUSE — or documents disappear on redeploy. On a GCS mount, set DRIFT_SCAN_INTERVAL_MS=0 and run a single instance (GCS FUSE has no file locking).

Separating the vault from the DB: NEST_STORAGE_ROOT (default $DATA_ROOT/nests) can point at a different volume (e.g. a GCS mount) while the SQLite DB stays on DATA_ROOT. The app does not relocate existing files — copy them before switching or nests appear empty.

Key environment variables

The full reference lives in REST API Reference's source (CONFIGURATION.md); the essentials:

Var Default Purpose
PORT 3838 HTTP port the server listens on.
DATA_ROOT ./data (relative to cwd) Root for the SQLite DB + nest vaults. Use an absolute path in production.
AUTH_MODE key key or open.
PROMPTOWL_KEY (empty) Community License key (pk_...). Unlicensed instances serve reads only. Can also be set from the browser License Setup Page.
NEST_STORAGE_ROOT $DATA_ROOT/nests Where nest vault files live; override to store nests on a separate/GCS volume.
DATABASE_PATH $DATA_ROOT/community.db Explicit SQLite file location (SQLite backend only).
DB_DRIVER sqlite sqlite or postgres. Inferred postgres if DATABASE_URL / CLOUD_SQL_CONNECTION_NAME is set.
DATABASE_URL (empty) Postgres TCP connection string, e.g. postgres://user:pass@host:5432/db.
CLOUD_SQL_CONNECTION_NAME (empty) Cloud SQL instance name (project:region:instance); connects over the Auth Proxy unix socket.
PUBLIC_BASE_URL (empty) This server's canonical external URL. Set it whenever OIDC is enabled or behind a reverse proxy.
OIDC_ENABLED false Turn on generic OIDC SSO (requires OIDC_ISSUER + OIDC_CLIENT_ID + OIDC_CLIENT_SECRET).
CORS_ORIGINS * (open) / http://localhost:5173,http://localhost:3838 (key) Comma-separated allowlist. * is only safe in open mode.
TELEMETRY_ENABLED true Batched anonymized usage events to PromptOwl; set false to disable.

Changing any env var requires a restart — they are read at boot. Settings you change from the UI (sign-in gate, logo, base URL, feature flags, OIDC, connectors) plus the installed license key persist in the database (server_settings), which survives rebuilds and is shared across instances; the deploy environment still overrides a UI change when its value for that key changes.

Plugins (1.24+)

Nest Plugins connect outside sources — Google Drive, GitHub, transcripts, mail — to nests, raw or summarized, and add live search over those sources. Off by default. See Plugins.

Variable Default Purpose
FEATURE_PLUGINS unset (off) true enables the per-nest Plugins tab, /nests/:id/plugins, /plugin-hooks/:token, and include_live search. Also a superadmin toggle under Settings → Plugins.
PLUGINS empty Comma-separated allowlist of plugin packages to load: npm package names installed on the server (e.g. @promptowl/contextnest-plugin-google-drive) or absolute paths to an ESM module. Nothing outside this list ever loads. Editable live from Settings → Plugins.
PLUGIN_MIN_INTERVAL_MINUTES 5 Floor for a plugin's pull cadence.

Install a plugin the way you would any dependency of the server (npm install @promptowl/contextnest-plugin-google-drive in the deploy, or bake it into the image), then name it in PLUGINS. Secrets a plugin needs are entered per nest and stored write-only in the nest's env store.

Typical deployments

Local dev / single user:

AUTH_MODE=open DATA_ROOT=./my-data npm run dev

Team / multi-user behind a reverse proxy:

AUTH_MODE=key \
CORS_ORIGINS="https://team.example.com" \
DATA_ROOT=/var/lib/contextnest \
PROMPTOWL_KEY=pk_... \
npm start

Terminate TLS at the proxy, forward X-Forwarded-For / X-Real-IP (the rate limiter reads them), and bind the server to 127.0.0.1 so only the proxy can reach it. For a hosted/SaaS-style rollout, run N instances behind a load balancer on the PostgreSQL / Cloud SQL backend with durable shared storage for the vault.

See also

Sources

  • README.md (Community server repo) — what it is, quickstart, license setup, requirements, feature matrix.
  • CONFIGURATION.md (Community server repo) — auth modes, full env var reference, database backends, Cloud Run notes, typical deployments.