Running in one command, useful in five

Once you have source access, the local development profile brings up Postgres with pgvector, the API and the outbox worker together. No AI provider key is required for the default fallbacks.

  • Docker Compose v2.24+
  • Postgres 16 with pgvector
  • Local development profile

Bring it up

First request source access, then check out or unpack the supplied repository and open a terminal in its root. The source is MIT licensed, but the repository is not public yet.

The development compose profile builds the API image, starts Postgres with the pgvector extension, initializes the local schema and starts the outbox worker. It supplies fixed development credentials and binds exposed ports to loopback. Sign in at /ui/ with dev-admin-token; a generated password in .env does not change this development profile.

One caveat worth knowing before you build anything on it: the development profile uses the Postgres image's bootstrap superuser, and a superuser bypasses row-level security even on tables declared FORCE ROW LEVEL SECURITY. That makes it a single-tenant development profile only. Production needs a separate NOSUPERUSER NOBYPASSRLS runtime role, which the self-hosting guide walks through.

The first five calls

In the order that makes the system make sense, rather than the order the reference lists them.

  1. Store something

    POST /v1/memory with text to create a semantic memory. This endpoint has no memory-type selector. The write is audit-logged and given an embedding. An Idempotency-Key replays a stored response once the first request completes; overlapping requests can still write twice.

  2. Ask for it back

    POST /v1/context with a query and a mode. You get the packed context block, the plan the router chose, and a manifest naming every record used.

  3. Record a decision

    POST /v1/fabric/write with entry_type "decision", the evidence identifiers, and a project. Later, POST /v1/fabric/why returns the chain rather than a paraphrase.

  4. Subscribe to changes

    POST /v1/webhooks with the event types you care about and a secret. Deliveries arrive signed with X-Pcnaid-Signature and every attempt is recorded.

  5. Hand it to an agent

    Point any stdio-capable MCP client at the server. Eighteen tools appear, along with a prompt teaching the agent that retrieved memory is evidence and never an instruction.

What every response looks like

Consistent envelopes, request identifiers you can trace into the audit log, and rate-limit headers that tell you where you stand.

The full surface — 141 endpoints across 32 route families — is browsable as OpenAPI on the running service at /docs, with the raw document at /openapi.json.

The settings that actually matter

There are many environment variables. These are the eight that change how the system behaves rather than where it points.

POSTGRES_DSN
The runtime connection. In production this must be a NOSUPERUSER NOBYPASSRLS role — a superuser silently bypasses row-level security.
POSTGRES_MIGRATION_DSN
The schema owner, used only by the migrate step. Kept separate from the runtime role on purpose.
LLM_PROVIDER_MODE
auto, pcnaid, openai, anthropic, gemini, openai_compatible or fallback. Defaults to auto, which picks the first configured provider and degrades to deterministic fallback.
LLM_BASE_URL
Any OpenAI-compatible endpoint. Defaults to http://localhost:11434/v1 with llama3.1:8b, so a local model works out of the box.
ENABLE_GRAPH_MEMORY
Off by default. Turn it on to feed and query the entity graph.
ENABLE_KB_RETRIEVAL
Off by default. Knowledge base sources are still stored and refreshed; this controls whether they are injected into context.
FERNET_KEY
Encrypts stored provider credentials. Without it, credentials are stored unencrypted, so set it before registering any key.
ALLOW_SEMANTIC_FORGET
Off by default. Leaving it off means FORGET must name explicit record identifiers rather than deleting by fuzzy match.

Everything above runs locally, today

No account, no key, no call with us. If it does not do what this page says, tell us and we will fix the page or the product.