New app
Loading connection settings…
← All docs

optional: customize ports / keys / model

Part of the ContextMemory docs. Back to README.

Quick start — self-host

Run the open-source gateway yourself — the path for on-prem or fully local deployments. Unlike Cloud (where the dashboard wires up your LLM for you), here you point the gateway at your own LLM backend — endpoint and model — in config. Same OpenAI-compatible chat body and choices[] response as Cloud; you supply the X-App-Id and use a cm_live_ key.

Fastest: one-liner from GHCR (API)

Public images (published on every push to main):

Image Package
ghcr.io/kortexio/contextmemory API
ghcr.io/kortexio/contextmemory-admin Admin UI

API only (needs Docker + Ollama on the host):

docker run --rm -p 5100:8080 \
  --add-host=host.docker.internal:host-gateway \
  -v contextmemory-data:/app/data \
  -e ContextMemory__OllamaEndpoint=http://host.docker.internal:11434 \
  -e ContextMemory__MasterKey=cm_master_dev_key_change_me \
  -e ContextMemory__Apps__demo-dev__ApiKey=cm_live_dev_key_change_me \
  -e ContextMemory__Apps__demo-dev__LlmModel=qwen3.5:9b \
  ghcr.io/kortexio/contextmemory:latest

Then: http://localhost:5100/health

API + Admin from GHCR (no local build):

docker compose -f docker-compose.ghcr.yml up -d

Or the helper scripts:

./scripts/docker-run.sh --with-admin          # pull from GHCR
./scripts/docker-run.sh --build --with-admin  # build locally instead
.\scripts\docker-run.ps1 -WithAdmin
.\scripts\docker-run.ps1 -Build -WithAdmin

Build from source: Docker Compose

Builds and starts the API (:5100), Admin (:5200), mcp-runtime (stdio MCP host), and sandbox-runtime (shell/python/node) locally. Requires Docker and an LLM reachable from the containers (Ollama on the host by default).

git clone https://github.com/Kortexio/ContextMemory.git
cd ContextMemory

# optional: customize ports / keys / model
cp .env.example .env

# build + run (File persistence — no Postgres required)
docker compose up --build

Then open http://localhost:5200 — Settings are pre-filled for the Compose network (API base URL = http://api:8080, demo Master Key). Click Test connection.

Service URL / value
API http://localhost:5100
Admin http://localhost:5200
Health http://localhost:5100/health
mcp-runtime internal http://mcp-runtime:8080 (ContextMemory__McpRuntimeUrl)
sandbox-runtime internal self-hosted sandbox for shell_execute / python_execute / node_execute
Demo app X-App-Id: demo-dev / Bearer cm_live_dev_key_change_me
Master key cm_master_dev_key_change_me

For a Postgres-backed network overlay (shared Docker network, extra tenants), see docker-compose.network.yml.

Ollama on the host

ollama pull qwen3.5:9b
# Compose default: ContextMemory__OllamaEndpoint=http://host.docker.internal:11434

Useful Compose env vars (see .env.example):

Variable Default Meaning
API_PORT / ADMIN_PORT 5100 / 5200 Host ports
OLLAMA_ENDPOINT http://host.docker.internal:11434 LLM from inside the API container
DEFAULT_LLM_MODEL qwen3.5:9b Seed + default model
MASTER_KEY cm_master_dev_key_change_me Admin Master Key
DEMO_APP_API_KEY cm_live_dev_key_change_me Seed app API key
PERSISTENCE_PROVIDER File File or Postgres

Stop with Ctrl+C, or docker compose down. Data for File mode lives in the cm_data Docker volume.

Chat smoke test against the containerized API (preferred OpenAI route):

curl -X POST http://localhost:5100/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "X-App-Id: demo-dev" \
  -H "X-User-Id: user-123" \
  -H "Authorization: Bearer cm_live_dev_key_change_me" \
  -d '{"model":"qwen3.5:9b","messages":[{"role":"user","content":"Hello"}]}'

Prerequisites (dotnet run)

  • .NET 9 SDK
  • Ollama (or another configured backend) reachable on the network
  • Optional: PostgreSQL 14+ for production / multi-instance HA

1. Configure

The committed appsettings.json uses safe placeholders and PersistenceProvider: File (no database required). Seed app id: demo-dev with key cm_live_dev_key_change_me (change before any real use).

Local secrets — choose one approach (never commit real values):

Method How
User Secrets (recommended) cd src/ContextMemory.Api then dotnet user-secrets set "ContextMemory:MasterKey" "your-key"
Environment variables See .env.example for the __ naming convention
Development file Create src/ContextMemory.Api/appsettings.Development.json (gitignored) with local overrides

For PostgreSQL in production or multi-instance HA:

{
  "ConnectionStrings": {
    "ContextMemory": "Host=localhost;Port=5432;Database=contextmemory;Username=...;Password=..."
  },
  "ContextMemory": {
    "PersistenceProvider": "Postgres",
    "DataPath": "../../data",
    "OllamaEndpoint": "http://localhost:11434",
    "MasterKey": "your-master-key",
    "Apps": {
      "my-app": {
        "ApiKey": "cm_live_...",
        "SystemPrompt": "You are a helpful assistant.",
        "LlmModel": "qwen3.5:9b"
      }
    }
  }
}

Use "Postgres" exactly (not Postgresql). Relative DataPath values resolve from the API content root.

appsettings.json field reference

Field Meaning
ConnectionStrings:ContextMemory PostgreSQL connection string when PersistenceProvider is Postgres
ContextMemory:PersistenceProvider File (default) or Postgres
ContextMemory:DataPath Root for file-based persistence (apps, sessions, wiki)
ContextMemory:OllamaEndpoint Default Ollama (or Ollama-compatible) backend base URL
ContextMemory:DefaultLlmModel Fallback model when an app has no LlmModel
ContextMemory:MasterKey Secret for Admin API / admin dashboard
ContextMemory:AdminCorsOrigins Allowed browser origins for Admin UI CORS
ContextMemory:WebSearch:* Tavily/Brave keys, default provider, timeout
ContextMemory:Apps Seed map of tenant apps; each key is the app id (X-App-Id)

Per-app runtime settings (agentic tools, wiki schema, web-search toggles, guardrails) are managed via the admin API or Admin UI host, not only this seed section.

2. Start the API

cd src/ContextMemory.Api
dotnet run

API defaults to http://localhost:5100 (Swagger in Development at /swagger).

3. First chat request

curl -X POST http://localhost:5100/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "X-App-Id: demo-dev" \
  -H "X-User-Id: user-123" \
  -H "X-Session-Id: sess-abc" \
  -H "Authorization: Bearer cm_live_dev_key_change_me" \
  -d '{
    "model": "qwen3.5:9b",
    "messages": [{ "role": "user", "content": "Hi, do you remember my name?" }]
  }'

Response (OpenAI schema — identical to Cloud):

{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "model": "qwen3.5:9b",
  "choices": [{
    "index": 0,
    "message": { "role": "assistant", "content": "..." },
    "finish_reason": "stop"
  }]
}

Legacy POST /api/chat still returns the Ollama message / done shape (deprecated).

Required headers: X-App-Id, X-User-Id, Authorization: Bearer {API_KEY}
Optional: X-Session-Id (generated by the API if omitted).

4. Admin UI and Chat Lab

Prefer Docker Compose above, or run the Admin host locally against a local API:

cd src/ContextMemory.Admin.Web
dotnet run

Open http://localhost:5200Settings → set API URL http://localhost:5100 and your Master Key (ContextMemory:MasterKey) → Test connection.

Full walkthrough of every screen: Admin UI guide.

The API also serves a short HTML pointer at http://localhost:5100/admin. Admin HTTP APIs still require the Master Key bearer token.