Command Palette

Search for a command to run...

UnylyUnyly
Browse all

Civic Ai Mcp Toolkit

FreeNot checked

The shared shape behind every MCP server in the civic-AI portfolio. Server factory + @traced + structured logging + error envelopes + fixture loader + scaffolde

GitHubEmbed

About

The shared shape behind every MCP server in the civic-AI portfolio. Server factory + @traced + structured logging + error envelopes + fixture loader + scaffolder CLI. M1 of the Digital Democracy Studio.

README

The shared shape behind every MCP server in the civic-AI portfolio. Server factory, @traced decorator, structured logging, error envelopes, fixture loader, and a civic-ai-mcp init CLI scaffolder — all distilled from six production MCPs.

Tests License: MIT MCP


Why it exists

After building six MCP servers (gitlaw, safevoice, grailsense, judge-mcp, pmm-mcp, elterngeld-mcp) in one weekend, the same ~50 lines kept repeating in every server.py:

  • FastMCP construction with env-based host/port
  • A @traced decorator that wraps every tool with request-id + latency + structured-JSON logging
  • A /health endpoint for hosted-deploy probes
  • Clean error envelopes that never raise to the MCP transport
  • A main() that picks stdio vs SSE from MCP_TRANSPORT
  • A fixture-loader that caches JSON files from data/

This package extracts that shape once so future MCPs are a one-day build, not a one-weekend build.

It's the first "machine that builds machines" from the Digital Democracy Studio thesis — M1 in the studio's missing-machines list.


Minimum example

from civic_ai_mcp import configure_logging, create_mcp_server, run_main, traced

mcp = create_mcp_server("my-cool-mcp", default_port=8010)


@mcp.tool()
@traced("hello")
def hello(name: str = "world") -> dict:
    """Greet someone."""
    return {"greeting": f"Hello, {name}!"}


def main() -> None:
    configure_logging(logger_name="my_cool_mcp")
    run_main(mcp)


if __name__ == "__main__":
    main()

That's the full server. You get for free:

  • /health returning {"status": "ok", "service": "my-cool-mcp"}
  • Per-tool JSON log lines: {"ts": "...", "tool": "hello", "request_id": "abc12345", "latency_ms": 1.2, "status": "ok"}
  • hello returning a structured error envelope instead of raising if anything goes wrong inside
  • stdio mode for Claude Desktop (default) + SSE mode if MCP_TRANSPORT=sse
  • Host bound to 0.0.0.0 so hosted health probes can reach it

CLI: scaffold a new MCP project

pip install civic-ai-mcp-toolkit
civic-ai-mcp init flight-rights --description "EU261 flight compensation calculator" --port 8011
cd flight-rights-mcp
pip install -e .
pytest

You get a complete project layout:

flight-rights-mcp/
├── flight_rights_mcp/
│   ├── __init__.py
│   ├── data/
│   └── server.py          # sample tool, uses civic_ai_mcp helpers
├── tests/
│   └── test_flight_rights_mcp.py
├── pyproject.toml         # standard portfolio shape
├── README.md              # stub with install instructions
├── LICENSE                # MIT
└── .gitignore

Replace the sample tool, add data fixtures to data/, ship.


Public surface

from civic_ai_mcp import (
    create_mcp_server,    # build a FastMCP with portfolio defaults
    run_main,             # standard entry-point (stdio | SSE from env)
    traced,               # @traced("tool_name") decorator
    configure_logging,    # stderr JSON logging setup
    log_json,             # emit one structured log line
    load_fixture,         # cached JSON loader from <pkg>/data/<file>
    error_envelope,       # build {"error": ..., "message": ...}
)

Plus convenience envelope shorthands (from civic_ai_mcp.envelope import not_found, invalid_input, internal_error).


Test coverage

19 passed in ~2s

Hermetic — no MCP transport, no network, no LLM. Covers:

  • 6 envelope tests (basic, extras, empty-message handling, shorthands, internal_error with exception info)
  • 2 logging tests (logger setup, structured-line emission)
  • 5 @traced tests (success pass-through, exception → envelope, metadata preservation, log shape on ok + error)
  • 3 fixture-loader tests (caching, force-reload, missing-file raises loudly)
  • 2 server-factory tests (FastMCP instance, env-port respected)
  • 1 end-to-end CLI scaffolder test (subprocess civic-ai-mcp init, asserts the generated layout is correct)

Part of an MCP-server portfolio

civic-ai-mcp-toolkit is the foundation under six production MCPs. Same architectural shape, six different domains:

  • gitlaw-mcp — German federal law (5,942 statutes), anti-hallucination citation verification, live drift detection
  • safevoice-mcp — Digital-harassment victim tooling (DE/AT/CH/UK)
  • grailsense — NFT collector intelligence over Blockscout
  • judge-mcp — Domain-agnostic judge + iterate engine (MCP-for-MCPs)
  • pmm-mcp — Public Money Mirror: Bundeshaushalt + Bundesrechnungshof
  • elterngeld-mcp — German parental-benefit calculator + Elterngeldstelle lookup

Future MCPs in the portfolio will use this toolkit from day one rather than copy-paste.


Roadmap

  • Migrate the six existing MCPs to use civic-ai-mcp-toolkit (incremental, behind compatibility, one PR per server)
  • Eval-harness sub-package — extract the gitlaw-mcp eval/run.py pattern as a reusable harness for any MCP
  • Freshness-pattern sub-package — extract the gitlaw-mcp freshness/ scaffold (manifest + drift detection) as a reusable trust layer
  • TRUST.md template generatorcivic-ai-mcp trust init scaffolds an honest trust-statement document
  • Cross-MCP composition examples — show how judge-mcp can score outputs from gitlaw-mcp etc. (the MCP-on-MCP pattern, made discoverable)

License

MIT. Built by extracting the shared shape from six MCP servers in the civic-AI portfolio. The toolkit and the servers are all MIT — fork, compose, contribute, ship your own.

from github.com/mikelninh/civic-ai-mcp-toolkit

Installing Civic Ai Mcp Toolkit

This server has no published package — it is built from source. Open the repository and follow its README.

▸ github.com/mikelninh/civic-ai-mcp-toolkit

FAQ

Is Civic Ai Mcp Toolkit MCP free?

Yes, Civic Ai Mcp Toolkit MCP is free — one-click install via Unyly at no cost.

Does Civic Ai Mcp Toolkit need an API key?

No, Civic Ai Mcp Toolkit runs without API keys or environment variables.

Is Civic Ai Mcp Toolkit hosted or self-hosted?

Self-hosted: the server runs locally on your machine via the install command above.

How do I install Civic Ai Mcp Toolkit in Claude Desktop, Claude Code or Cursor?

Open Civic Ai Mcp Toolkit on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

Compare Civic Ai Mcp Toolkit with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All ai MCPs