CivicOS Relay¶
The relay is CivicOS's coordination infrastructure — it stores and serves signed civic events (voices, actions, subscriptions) and provides authenticated AI access for residents.
Relay vs. MCP Server¶
CivicOS operators can run either or both of two independent services:
| Component | Direction | Purpose |
|---|---|---|
| MCP Server | Read-only | Serves civic data queries — meetings, decisions, legislation, transcripts |
| Relay | Bidirectional | Coordinates civic participation — voices, actions, subscriptions, AI drafting |
The MCP server is a data API. It answers questions like "what's on the agenda?" by querying structured civic records. Any AI client (Claude, ChatGPT) or application can connect to it. No identity required.
The relay is coordination infrastructure. It handles the things that require identity and trust: voicing support or opposition on an agenda item, committing to civic actions, subscribing to topics, and using AI to draft testimony. All relay interactions are signed with secp256k1 Schnorr signatures (Nostr-compatible) and most require attestation.
A city government might run only an MCP server to publish authoritative civic data. A neighborhood group might run only a relay to coordinate community voices. A full CivicOS operator runs both.
What the Relay Stores¶
| Data | Nostr Kind | Requires Attestation |
|---|---|---|
| Voices — support, oppose, or watching on a civic entity | 30800 | Yes |
| Actions — commitments and completions on civic actions | 30810-30812 | Yes |
| Subscriptions — topic and event notifications | 30820 | No |
| Attestations — residency proofs issued by the relay | 30850 | N/A (this IS attestation) |
All voice and action records are signed Nostr events. The relay verifies signatures on ingest and serves them to any client. Records are self-verifying — any relay, anywhere, can validate a voice by checking its signature and embedded attestation proof without contacting the original relay.
Services¶
VoiceService¶
Public expression of civic interest on entities (agenda items, decisions, initiatives).
cast_voice(voice)— Submit a signed stance (support/oppose/watching)get_counts(entity)— Aggregate voice counts per entityverify(voice)— Verify signature and attestation proof
One key = one stance per entity. Casting a new stance revokes the previous one.
ActionService¶
Track commitments and completions on civic actions.
record_commitment(action)— Record a commitment to actrecord_completion(action)— Record completionget_counts(entity)— Action counts per entity
RelayService¶
Event routing and subscription management.
subscribe(subscription)— Subscribe to events by topic, geography, or event typeunsubscribe(id)— Remove subscriptionemit(event)— Route event to subscribers
AI Proxy¶
Authenticated AI access for attested residents. See AI Proxy.
ProvenanceService¶
Trust signals for voice quality — tracks which keys have participated in which entities and jurisdictions.
SyncService¶
Voice and event synchronization between peer relays. See Federation.
Cryptography¶
All relay interactions use secp256k1 Schnorr signatures (Nostr-compatible, BIP-340). Not P-256 ECDSA.
- Keys are generated client-side in the browser extension
- Private keys never leave the user's device
- Signatures are verified by the relay on every write operation
- Attestation proofs are embedded on each voice/action record
Storage¶
- Production: PostgreSQL (
RELAY_DATABASE_URL), separate from the civic data database - Development: In-memory storage (fallback when no database URL is set)
The relay uses its own database, separate from the MCP server's civic data store. This is a deliberate architectural boundary — coordination data (who voiced what) is isolated from civic data (what happened at the meeting).
Further Reading¶
- Attestation — How gated attestation prevents spam and ensures genuine participation
- Trust Model — Adversary analysis, commitment logs, operator integrity
- Federation — Multi-operator peering, jurisdiction rollup, data sovereignty
- AI Proxy — Privacy-preserving AI access for residents