Admin Console
The operator UI compiled into the CortexDB binary — served at / on the API port, zero-dependency and air-gap-friendly.
CortexDB ships a full operations console built into the binary. There's nothing to install or host
separately: it's served at / on the API port (so http://localhost:3141/ on a default
self-hosted instance), it's compiled into the binary with no CDN or external assets, and it works
air-gapped.
# With the server running, just open it in a browser:
open http://localhost:3141/ # macOS (xdg-open on Linux, start on Windows)The page returns 200 text/html with title "CortexDB — local"; its JavaScript and CSS are served from
/assets/* on the same origin (app.css, app.js, pages.js, pages-ops.js, pages-code.js,
pages-usage.js), each versioned to the running server (?v=<server version>), so the console always matches the
binary you're running.
The console matches the server
The console is served by the server itself, so it always matches the version you run. This page describes the current console, including its confirmation dialogs (Restart, Repair the search index, Repair vector hygiene, Dismiss conflict) and the Data & scopes event counts.
What's in it
The console is a single-page app with a live bento Overview, interactive charts, KPI tiles, and a
command palette bound to Ctrl/Cmd + K (type a page name, press Enter). Its sidebar has
14 pages in three sections — Memory, Operate, and System — plus a link to these docs. The
scope box in the top bar sets which scope the memory pages work in.
The readiness pill beside it reads /v1/admin/ready: ready, not ready, or degraded (…) with
the reason — mock embeddings, or embedding calls failing (for example an expired key answering
401) — and the server's own detail when you hover over it.
Memory
| Page | What it's for |
|---|---|
| Overview | The state of the instance at a glance — health, capacity, pipelines, AI wiring (the AI roles table shows which model each stage uses and whether it is configured), and a month-to-date spend strip. |
| Memories | Capture experiences and browse every layer they derive — events, facts, beliefs, episodes, concepts. |
| Console | Ask (an answer with citations and per-query telemetry: recall time, model time, model, tokens), Compose, and Recall (raw) — the exact evidence pack and context block an answer would see. |
| Artifacts | The structured memory plane — compiled sessions, dossiers, story arcs, rollups, and certified computations. Shows how to enable it when it's off. |
| Conflicts | Claims where the store holds two competing values and needs a human call (backed by /v1/conflicts). The sidebar entry shows the count of open conflicts. |
| Code memory | Registered repositories indexed into a code graph — coverage, capability matrix, imports, and GC. |
Operate
| Page | What it's for |
|---|---|
| Observability | Throughput, latency, errors, queues, storage, and provider health, live while the page is open (/v1/admin/metrics), plus a Tokens & cost block from the durable usage ledger: month-to-date / since-inception, cost and tokens by role and by model, and CSV export. Unmeasured or unpriced lanes are labelled as such, never shown as $0.00. A 503 from a lane that isn't configured (for example ANSWER_UNAVAILABLE) is listed by error code but doesn't count toward the error rate. |
| Logs | Live server log stream — filter by level, search text, pause and resume. |
| Features | Switch capabilities (enrichment, artifacts, code memory, knowledge graph, re-ranking, and more) on and off in plain English. See Feature switches and restarts. |
| Data & scopes | Every scope, what's stored in it (events are counted once each), how much it's recalled, per-layer record counts with the reason a layer is empty — plus JSONL export. |
| Audit & access | Who you are (caller, tenant, capabilities), the audit log, and the tamper-evident hash chain with a Verify button. Requests in no-auth mode aren't audited. |
| Maintenance | Readiness checks (the same as /v1/admin/ready), snapshot persist, restart, index integrity audit (dry run, or audit and repair), and vector hygiene. |
System
| Page | What it's for |
|---|---|
| Settings | Connect the AI models and content processors that power search, enrichment, answers, and file understanding. Each card shows whether that role is connected or not configured. Changes apply on restart. |
| Updates | This build's version, commit and build time; an update check; and the bundled release notes. The update check reads the latest release on GitHub (cortexdbai/cortexdb-releases). CORTEX_UPDATE_FEED_URL overrides the feed, for example on an air-gapped network. |
Everything the console shows comes from the same v1 API these docs describe, plus a few console-only
routes under /internal/ui/* (features, logs, updates, restart) that follow the same auth.
Feature switches and restarts
Most switches on Features are marked restart: the change is saved immediately to
<data_dir>/feature_overrides.json (so it survives container restarts on the same volume) and takes effect
the next time the server starts. At startup the log shows each one being applied, and the configuration
dump names its origin — for example CORTEX_CODE_PLANE = 1 (persisted admin-UI override; launch env: unset).
Restart server (on Features and Maintenance) persists snapshots and then exits with code 75. Your process supervisor has to start it again:
- Docker: run with
--restart unless-stopped(oralways/on-failure); the server is back in a few seconds. - Docker Compose:
restart: unless-stopped. systemd:Restart=on-failureorRestart=always. - With no restart policy (a plain
docker run, or a server started by hand in a terminal) the server simply stops, and you start it again yourself.
If you'd rather not depend on the button, docker restart <container> does the same job.
Fast bulk upload and large documents
Fast bulk upload (CORTEX_BULK_DEFER_VECTORS=1) acknowledges bulk imports before embedding them and
embeds them later in the background. Use it for short items only: with OpenAI embeddings, large
documents (about 20 KB and up) can be left without vectors, so they are keyword-searchable but not found
by semantic recall. Leave the switch off for document-sized content. If it was on, turn it off and run
POST /v1/admin/index-audit {"repair": true, "vectors": true} to embed any missing events, then check
that a dry run ({"vectors": true}) reports missing_vectors_total: 0.
Access & security
The console lives on the API port, on the same origin and under the same auth as the v1 API:
- Under
CORTEX_INSECURE_NO_AUTH=1(local dev) it's open. Publish the port on loopback only (-p 127.0.0.1:3141:3141). - On a server with
CORTEX_API_KEYset (or OIDC), the page itself loads, but every data route — including the console's feature switches and restart — answers401 MISSING_TOKENuntil you paste a key into the API key box in the top bar. The Overview says "API key required" until then. - The key is kept in the browser tab's memory only, never stored, so you paste it again after a page reload.
Don't expose the console without auth + TLS
Because it's served on the API port, publishing that port publishes the console too. Never expose it to
a network in no-auth mode: set CORTEX_API_KEY (or your IdP), terminate TLS in front, and restrict
access — same posture as the API itself.
Recall timings
Recall (raw) in the Console shows the round trip it measured. It doesn't ask the server for
diagnostics, and /v1/recall reports its own timings (diagnostics.time_ms) only when the request sets
diagnostics to "summary" or "full", so the server's total isn't shown there. Ask shows the
server's timings.
See also
- Admin endpoints — the API the console is built on
- Self-Hosting Quickstart · Configuration