Skip to content
Conduit

mcp server

civic-awareness-mcp

An MCP server for US federal and state legislative data. Pulls from OpenStates and Congress.gov with a cross-jurisdiction entity graph.

julianken/civic-awareness-mcpcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

Before you start

  • Node.js 20 or newer
~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "civic-awareness-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "civic-awareness-mcp"
      ]
    }
  }
}

same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12

Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs

README

synced Oct 23, 2026

Civic Awareness MCP

Two MCP servers for US civic data — one for Congress + federal campaign finance, one for 50-state legislatures.

License: MIT Node 22+ Nightly drift

Servers

ServerSourceJurisdictionsPackage
civic-federal-mcpCongress.gov + OpenFECUS federalnpx civic-federal-mcp
civic-state-mcpOpenStates50 states + DCnpx civic-state-mcp

Each server reads/writes-through to a local SQLite store as a TTL cache. Every response includes a sources: { name, url }[] array for provenance. No tool synthesizes summaries — that is the LLM's job.

Tools

civic-federal-mcp (9 tools)

ToolKindWhat it answers
recent_billsfeedBills introduced or acted on in the last N days (Congress.gov)
recent_votesfeedRoll-call votes in the last N days, yea/nay/present tallies
recent_contributionsfeedFederal campaign contributions in a date window (OpenFEC)
search_civic_documentssearchTitle search across cached federal bills, votes, contributions
search_entitiesentityName search across Members of Congress + FEC candidates/committees
get_entityentityEntity detail + role history + recent documents
resolve_personentityDisambiguate a name into one or more Person entity IDs
entity_connectionsentityCo-occurrence graph via bills, votes, contributions (depth 1–2)
get_votedetailFull roll-call vote with per-legislator positions

civic-state-mcp (8 tools)

ToolKindWhat it answers
recent_billsfeedBills by jurisdiction; filters for sponsor, subject, classification, session, dates
recent_votesfeedRoll-call votes in the last N days, chamber + tally (OpenStates, per jurisdiction)
get_billdetailFull bill detail: actions, versions, sponsors, subjects
search_civic_documentssearchTitle search across cached state bills
search_entitiesentityName search across state legislators (OpenStates)
get_entityentityEntity detail + role history + recent documents
resolve_personentityDisambiguate a name into one or more Person entity IDs
entity_connectionsentityCo-occurrence graph via shared sponsored bills (depth 1–2)

Installation

Prerequisites

Build + run

npm install
npm run build

# federal server
npm run bootstrap:federal
npm run start:federal

# state server
npm run bootstrap:state
npm run start:state

For development (no build step):

npm run dev:federal
npm run dev:state

Data hydration

The server fetches data automatically on cache miss. For bulk pre-population:

# federal
npm run refresh:federal -- --source=congress --max-pages=1
npm run refresh:federal -- --source=openfec --max-pages=1

# state (one jurisdiction)
npm run refresh:state -- --source=openstates --jurisdictions=tx --max-pages=1

To prune stale fetch-log rows (recommended monthly):

npm run evict-fetch-log

Development

npm test              # mocked unit + integration suite (MSW)
npm run test:watch    # rerun on change
npm run test:drift    # live-API drift tests (requires .env.local)
npm run typecheck     # tsc --noEmit
npm run lint          # eslint
npm run format        # prettier --write

Claude Desktop config

To run both servers locally, add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "civic-federal-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/civic-awareness-mcp/dist/federal/index.js"],
      "env": {
        "API_DATA_GOV_KEY": "your-key",
        "CIVIC_FEDERAL_DB_PATH": "/absolute/path/to/federal.db"
      }
    },
    "civic-state-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/civic-awareness-mcp/dist/state/index.js"],
      "env": {
        "OPENSTATES_API_KEY": "your-key",
        "CIVIC_STATE_DB_PATH": "/absolute/path/to/state.db"
      }
    }
  }
}

Environment variables

VariableServerDescription
API_DATA_GOV_KEYfederalapi.data.gov key (Congress.gov + OpenFEC)
OPENSTATES_API_KEYstateOpenStates v3 API key
CIVIC_FEDERAL_DB_PATHfederalSQLite path (default ./data/federal.db)
CIVIC_STATE_DB_PATHstateSQLite path (default ./data/state.db)
CIVIC_AWARENESS_DAILY_BUDGETbothOptional daily API spend cap (unused by default)
LOG_LEVELbothdebug / info / warn / error (default info, JSON to stderr)

CI

Four workflows in .github/workflows/:

  • ci.yml — format, lint, typecheck, tests, build, MCP stdio smoke. Matrix on Node 22/24. Runs on push to main and on every PR.
  • codeql.yml — CodeQL static analysis. Runs on push/PR/weekly.
  • scorecard.yml — OpenSSF Scorecard. Runs on push/weekly.
  • nightly-drift.yml — live-API shape checks against OpenStates, Congress.gov, OpenFEC. Runs daily at 09:00 UTC and on-demand via workflow_dispatch.

The drift workflow requires repo secrets OPENSTATES_API_KEY and API_DATA_GOV_KEY (separate from user keys — those are configured locally via .env.local).

Security

See SECURITY.md. Highlights:

  • Never writes to upstream APIs
  • All sources are sanctioned free-tier APIs with documented rate limits
  • Rate-limited fetch with per-host token bucket; Retry-After honoured
  • Zod-validated inputs; parameterized SQLite queries
  • No contributor PII in responses

License

MIT — see LICENSE.

↑↓ navigate openesc close