Operator Environment Variable Reference¶
Consolidated reference for all environment variables that operators need to configure when running CivicOS services. Distilled from the full .env.example (~80 variables) to the ~30 that matter for operators.
MCP Server¶
The MCP server serves read-only civic data (meetings, decisions, legislation, transcripts) to AI assistants and REST API clients.
| Variable | Required | Default | Purpose |
|---|---|---|---|
CIVICOS_JURISDICTION | Yes | city-san-rafael | Jurisdiction code (e.g., city-berkeley, state-california) |
DATABASE_URL | Yes | SQLite fallback | PostgreSQL connection string for civic data |
OPENAI_API_KEY | Yes | — | Embeddings and AI features |
CIVICOS_ENV | No | development | Environment: development, staging, production |
CIVICOS_API_PORT | No | 8001 | API server port |
CIVICOS_WEB_KEY | Prod | dev_key_local | Authentication token for web interface |
CIVICOS_CORS_ORIGINS | Prod | — | Comma-separated allowed CORS origins |
CIVICOS_EMBEDDING_PROVIDER | No | local | local (free, MiniLM) or openai (better quality) |
GOOGLE_MAPS_API_KEY | No | — | Address geocoding (city-level servers) |
BLOB_STORAGE_URL | No | local://data/blobs | Blob storage for PDFs, audio (r2:// for production) |
MCP on Modal¶
When deploying to Modal, environment variables are stored in Modal Secrets. The naming convention:
| Jurisdiction | Modal Secret | Modal App |
|---|---|---|
city-san-rafael | civicos-env | civicos-san-rafael |
state-california | civicos-california-env | civicos-california |
country-united-states | civicos-federal-env | civicos-federal |
City-level servers also use civic-google (for GOOGLE_MAPS_API_KEY) and civicos-attestation secrets.
Relay¶
The relay handles bidirectional coordination — voices, actions, subscriptions, attestation, and AI proxy.
| Variable | Required | Default | Purpose |
|---|---|---|---|
RELAY_DATABASE_URL | Yes | — | PostgreSQL connection string for relay data (separate DB from MCP) |
RELAY_ID | No | relay.local | Unique relay identifier (e.g., relay.civicos.org/san-rafael) |
RELAY_NAMESPACES | No | * | Comma-separated entity namespaces to host (e.g., city-san-rafael:*) |
RELAY_PEERS | No | — | Comma-separated peer relay URLs for federation |
RELAY_HOST | No | 0.0.0.0 | Bind address |
RELAY_PORT | No | 8003 | Listen port |
RELAY_SYNC_ENABLED | No | true | Enable peer-to-peer voice sync |
RELAY_ACCEPTANCE_POLICY | No | false | Enable rate limiting on write endpoints |
CIVICOS_JURISDICTION | No | city-san-rafael | Jurisdiction for AI proxy routing |
CIVICOS_MCP_URL | No | — | MCP server URL for AI proxy tool calls |
CIVICOS_ATTESTATION_PRIVATE_KEY | No | — | Relay's own attestation signing key (hex) |
ANTHROPIC_API_KEY | No | — | Required for AI proxy (/api/ai/chat, /api/ai/draft) |
Relay on Modal¶
The relay deployment uses three Modal Secrets: - civicos-env — RELAY_DATABASE_URL, DATABASE_URL, general config - civicos-attestation — CIVICOS_ATTESTATION_PRIVATE_KEY - civic-anthropic — ANTHROPIC_API_KEY
Signer¶
The signer is a standalone attestation signing service for organizations. Full configuration docs: civicos-signer package.
| Variable | Required | Default | Purpose |
|---|---|---|---|
CIVICOS_SIGNER_PRIVATE_KEY | Yes | — | Issuer private key (hex, generated by keygen) |
CIVICOS_SIGNER_JURISDICTION | Yes | — | Jurisdiction code |
CIVICOS_SIGNER_ORGANIZATION | Yes | — | Organization display name |
CIVICOS_SIGNER_BEARER_TOKEN | Yes | — | Shared secret with the relay |
CIVICOS_SIGNER_ALLOWED_TYPES | No | physical | Comma-separated attestation types |
CIVICOS_SIGNER_PORT | No | 8850 | Server port |
Generate all signer config with one command: civicos-signer keygen --jurisdiction city-your-city --organization "Your Org" → writes .env.signer.
Database Setup Notes¶
Use separate databases. The MCP server (DATABASE_URL) and relay (RELAY_DATABASE_URL) must use different databases. This is a deliberate architectural boundary — civic data and coordination data are isolated.
Free PostgreSQL options: - Supabase — 500MB free, pgvector included - Neon — 512MB free, serverless - Fly.io — shared instance
Connection string format:
If your password contains special characters (!, @, $), wrap the entire URL in single quotes when exporting:
Relay schema: After creating the relay database, apply the schema:
Anti-patterns¶
- Shared databases — Never point
DATABASE_URLandRELAY_DATABASE_URLat the same database. Civic data and coordination data have different ownership and federation models. - Signer key in relay env — The relay should never hold a signer's private key. The signer is a separate service with its own process and credentials.
- Skipping RLS — Production PostgreSQL databases should have Row Level Security enabled (
scripts/sql/enable_rls.sql). Onlyservice_rolekeys should access the database.