Skip to content

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-envRELAY_DATABASE_URL, DATABASE_URL, general config - civicos-attestationCIVICOS_ATTESTATION_PRIVATE_KEY - civic-anthropicANTHROPIC_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:

postgresql://postgres:[password]@db.[project-ref].supabase.co:5432/postgres

If your password contains special characters (!, @, $), wrap the entire URL in single quotes when exporting:

export RELAY_DATABASE_URL='postgresql://postgres:p@ss!word@db.xxx.supabase.co:5432/postgres'

Relay schema: After creating the relay database, apply the schema:

psql $RELAY_DATABASE_URL -f packages/civicos-relay/schema.sql

Anti-patterns

  • Shared databases — Never point DATABASE_URL and RELAY_DATABASE_URL at 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). Only service_role keys should access the database.