Configuration
For most deployments, only three variables are required: MESHOPTIXIQ_LICENSE_KEY, NEO4J_PASSWORD, and API_KEY. Everything else has a working default. See Appendix A for the complete variable reference.
4.1 Environment Variables
All configuration is driven by environment variables. No configuration files are required. See Appendix A for the complete reference; the most critical variables are listed below.
| Variable | Required | Default | Description |
|---|---|---|---|
MESHOPTIXIQ_LICENSE_KEY | Required | — | License key from the customer portal |
GRAPH_BACKEND | Optional | neo4j | neo4j or postgres |
NEO4J_URI | If Neo4j | bolt://localhost:7687 | Neo4j Bolt connection URI |
NEO4J_USER | If Neo4j | neo4j | Neo4j username |
NEO4J_PASSWORD | Required | — | Neo4j password |
POSTGRES_DSN | Pro+ | — | Full PostgreSQL DSN (if using postgres backend) |
API_KEY | Optional | — | Shared secret for API authentication. When unset, the server runs in open-access mode. |
CORS_ORIGINS | Optional | — | Comma-separated list of allowed CORS origins. |
UI_DIR | Optional | /app/static | Path to the compiled React app |
MCP_MAX_RESULT_ROWS | Optional | 1000 | Global row cap per MCP tool call |
REDIS_URL | Pro+ | — | Redis URL; enables clustered mode when set (e.g. redis://redis:6379) |
4.2 Neo4j Backend Configuration
Connection String Formats
# Local bolt (default)
NEO4J_URI=bolt://localhost:7687
# TLS-encrypted bolt
NEO4J_URI=bolt+s://neo4j.internal:7687
# Aura cloud (always TLS)
NEO4J_URI=neo4j+s://xxxxxxxx.databases.neo4j.io
Schema Initialisation
On first ingest, MeshOptixIQ creates uniqueness constraints and indexes automatically. To apply constraints manually (recommended before bulk ingest):
meshq ingest --init-schema
Performance Tuning
For networks with more than 200 devices, increase Neo4j heap allocation in neo4j.conf:
dbms.memory.heap.initial_size=1G
dbms.memory.heap.max_size=4G
dbms.memory.pagecache.size=2G
4.3 PostgreSQL Backend Configuration
The PostgreSQL backend stores topology data in relational tables with array columns for multi-value fields (zones, addresses, services in firewall rules). It is functionally equivalent to the Neo4j backend for all 109 queries.
export GRAPH_BACKEND=postgres
export POSTGRES_DSN="postgresql://meshoptixiq:password@db.internal:5432/meshoptixiq"
Connection Pooling
The PostgreSQL provider uses psycopg_pool.ConnectionPool for efficient connection reuse. Pool size is controlled by environment variables:
| Variable | Default | Description |
|---|---|---|
POSTGRES_POOL_MIN | 2 | Minimum idle connections in the pool |
POSTGRES_POOL_MAX | 10 | Maximum connections in the pool |
The GET /health/ready endpoint returns pool_available in the response body when the PostgreSQL backend is active. Pool statistics are also included in GET /admin/config.
Schema Creation
The schema is applied automatically on first ingest. Tables created include: devices, interfaces, ip_addresses, subnets, vlans, mac_addresses, endpoints, firewall_rules, address_objects, service_objects.
4.4 API Authentication
API_KEY is optional. When not set, the API runs in open-access mode — all requests are admitted as the local admin user. This is the default for community self-hosted deployments. Set API_KEY to require authentication. The web UI auto-detects this and connects without prompting for a key.
# Optional: set a strong random key (32+ characters) to require authentication
export API_KEY=$(openssl rand -hex 32)
# When API_KEY is set, include it in all API requests
curl -H "X-API-Key: $API_KEY" http://localhost:8000/queries/
# Without API_KEY set, requests are accepted without authentication
curl http://localhost:8000/queries/
# SSE EventSource clients can pass the key as a query parameter
# (browsers cannot set custom headers on EventSource)
curl "http://localhost:8000/events?api_key=$API_KEY"
CORS Configuration
Restrict CORS to your specific UI origin in production:
export CORS_ORIGINS="https://meshoptixiq.yourdomain.com,https://admin.yourdomain.com"
4.5 Personal Access Tokens (PAT)
Personal Access Tokens allow individual users to authenticate against the API without sharing the global API_KEY. PATs are user-scoped and can be revoked independently. They are generated in the web UI at Admin → API Tokens or via the REST API at POST /auth/tokens/me.
Storing a Token with the CLI
# Store a PAT in ~/.meshoptixiq/credentials
meshq login --token <your-pat-here>
# Verify the stored token
meshq status
# Remove the stored token
meshq logout
The credentials file is stored at ~/.meshoptixiq/credentials with permissions 600. The CLI reads this file automatically when no API_KEY environment variable is set.
Generating a PAT via the API
# Generate a new PAT (requires an existing valid API key or session)
curl -X POST http://localhost:8000/auth/tokens/me \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"description": "CI pipeline", "expires_in_days": 90}'
# Response
{
"token": "mq-pat-xxxxxxxxxxxxxxxxxxxx",
"description": "CI pipeline",
"expires_at": "2026-06-03T00:00:00Z"
}
EventSource / SSE Clients
Browser-based EventSource connections cannot set custom HTTP headers. Pass the API key or PAT as a query parameter instead:
const es = new EventSource('/events?api_key=' + encodeURIComponent(token));