Configuration
CntrlNode is configured via environment variables or a YAML config file. Environment variables take precedence over the config file.
Environment variables
| Variable | Default | Description |
|---|---|---|
CNTRLNODE_PORT | 7474 | HTTP/2 server port |
CNTRLNODE_STORAGE | bbolt | Storage backend: bbolt or postgres |
CNTRLNODE_DB_PATH | ./cntrlnode.db | Path to bbolt database file |
CNTRLNODE_DB_URL | (required for postgres) | PostgreSQL connection string |
CNTRLNODE_OLLAMA_HOST | localhost:11434 | Ollama host for embeddings |
CNTRLNODE_EMBED_MODEL | nomic-embed-text | Embedding model name |
CNTRLNODE_AUTH_ENABLED | false | Enable API key authentication |
CNTRLNODE_API_KEYS | (empty) | Comma-separated list of valid API keys |
CNTRLNODE_LOG_LEVEL | info | Log level: debug, info, warn, error |
CNTRLNODE_DEV | false | Dev mode: verbose logging, mock embeddings |
YAML config file
Create config.yaml (or pass --config <path> at startup):
port: 7474
storage: bbolt
dbPath: ./cntrlnode.db
logLevel: info
dev: false
auth:
enabled: false
apiKeys: []
ollama:
host: localhost:11434
embedModel: nomic-embed-text
Startup flags
./cntrlnode start --config ./config.yaml
./cntrlnode start --port 8080
./cntrlnode start --storage postgres --db-url postgres://localhost/cntrlnode
Storage backends
bbolt (default — dev mode)
Zero dependencies. State is persisted to a single file on disk. Suitable for development, single-node deployments, and testing.
CNTRLNODE_STORAGE=bbolt
CNTRLNODE_DB_PATH=./cntrlnode.db
PostgreSQL (production)
Requires PostgreSQL 14+ with the pgvector extension for semantic agent discovery.
CNTRLNODE_STORAGE=postgres
CNTRLNODE_DB_URL=postgres://user:pass@localhost:5432/cntrlnode?sslmode=require
Run migrations on first start (automatic) or manually:
psql $DATABASE_URL -f migrations/001_init.sql
Ollama (semantic discovery)
Semantic agent discovery (/v1/registry/discover with a query field) requires Ollama running locally with the nomic-embed-text model pulled:
ollama pull nomic-embed-text
If Ollama is unavailable, tag-based discovery still works — semantic discovery gracefully falls back.
In dev mode (CNTRLNODE_DEV=true), a mock embedder is used so Ollama is not required.
Log output
CntrlNode logs structured JSON to stdout:
{"level":"info","time":"2024-01-15T10:30:00Z","message":"server started","port":7474,"storage":"bbolt"}
{"level":"info","time":"2024-01-15T10:30:05Z","message":"agent registered","id":"researcher-1","tags":["research","pdf"]}
Pipe through jq for human-readable output in development:
./cntrlnode start | jq .
Complete example
# Production with PostgreSQL and auth
CNTRLNODE_PORT=7474 \
CNTRLNODE_STORAGE=postgres \
CNTRLNODE_DB_URL=postgres://cntrlnode:secret@db:5432/cntrlnode \
CNTRLNODE_AUTH_ENABLED=true \
CNTRLNODE_API_KEYS=key-prod-abc123,key-svc-def456 \
CNTRLNODE_LOG_LEVEL=info \
./cntrlnode start