Skip to main content
Glama
cstillick

guardian-contributions-mcp

by cstillick

Guardian Contributions — MCP + API

⚠️ Archived — this is the original open-source prototype (v0.1.0, MIT). Active development has moved to a maintained commercial edition with a hosted API + MCP, monitored data freshness (SLA), automated backups, and broader coverage. This repository is frozen at v0.1.0 and will not receive updates. For a demo or licensing, contact cooperstillick@icloud.com.

A reusable service for Oklahoma Ethics Commission "Guardian" campaign-finance data. It pulls and normalizes the data, then answers narrow questions through a REST API and an MCP server (so Claude — or any MCP host — can use it as tools).

It automates a workflow that's otherwise done by hand: for a roster of candidates, combine each one's Pre-Primary report (Beginning, Raised, Loans, Expended, Ending) with all their Continuing contributions layered on top, and flag things like self-dealing loans. The business rules come from a manual workflow distilled into 14 hard rules — each is enforced as a service invariant (table below) and backed by a test.

Status: v0.1.0. 51 tests pass; the combined figures reproduce a known-good deliverable to the penny (HD-42 Cynthia Roe: $29,863.66 + $42,750.00 − $4,278.24 = $68,335.42), and an opt-in live test verifies the whole pipeline against guardian.ok.gov end-to-end.


Get started (about 2 minutes)

Prerequisites: Python 3.11+ and uv (curl -LsSf https://astral.sh/uv/install.sh | sh). No API key needed for local use.

git clone https://github.com/cstillick/guardian-contributions-mcp.git
cd guardian-contributions-mcp
uv sync                       # create the env + install the package

# 1) run the tests (offline; proves the rules against known-good fixtures)
uv run --extra dev pytest -q

# 2) load real data from Guardian
uv run guardian-ingest --no-reports     # fast: bulk contributions only (~5s)
#   or the full load (also fetches Pre-Primary report PDFs for the roster,
#   ~1–2 min because it walks Guardian's report pages one at a time):
# uv run guardian-ingest

# 3) start the server — web dashboard + REST API + interactive docs
uv run guardian-api           # dashboard: http://localhost:8000   ·   API docs: /docs

Then ask it things:

# the cycle's reporting calendar (computed, not hardcoded)
curl localhost:8000/v1/calendar

# one candidate's combined Pre-Primary + Continuing figures
curl "localhost:8000/v1/committees/11932/combined"
# -> {"beginning":"29863.66","raised":"42750.00","ending":"68335.42", ...}

# every candidate in a district
curl "localhost:8000/v1/districts/HD-42/combined"

# computed alerts (large loans, sub-$1,000 receipts, ...)
curl "localhost:8000/v1/flags?district=HD-42"

guardian-ingest needs outbound access to guardian.ok.gov. Reads come entirely from the local database — Guardian is never touched on the request path.


Related MCP server: USAspending MCP Server

Web dashboard

guardian-api also serves a browsable "Public Ledger" UI at / — for people who just want to open a link and read the numbers, no API knowledge needed:

  • / — the roster as a sortable, filterable ledger (combined Beginning / Raised / Loan / Expended / Ending, flags, freshness dateline) plus money-over-time and "who's raised the most" charts.

  • /c/{org_id} — a candidate dossier: the balance as an equation, the per-reporting-period balance chain (every Quarterly / Pre-Primary / Pre-General report via the layering model) with an itemized vs unitemized split, itemized contributions, filings, flags, and animated charts (money over time, funding sources, top donors).

  • /flags — every computed alert across the roster, grouped by severity.

  • /search — find any committee on file (candidates, PACs, parties) by name.

Editorial broadsheet design; server-rendered (Jinja2 + bespoke CSS), no build step.


Use it from Claude (MCP)

Point any MCP host at the server. For Claude Desktop / Claude Code, add to your MCP config:

{
  "mcpServers": {
    "guardian-contributions": {
      "command": "uv",
      "args": ["run", "guardian-mcp"],
      "cwd": "/absolute/path/to/guardian-contributions-mcp"
    }
  }
}

Then ask in plain language — "combined Pre-Primary + Continuing for HD-42 Cynthia Roe," "which candidates in HD-99 took loans larger than they raised?" The model picks from 13 focused tools plus a flexible query tool.


What you're selecting between (the two axes)

A request = who/where × what:

Axis A — who / where

Axis B — what

candidate · committee (Org ID) · district · office · party · cycle

summary · combined · continuing_total · contributions · loans · report · filing_history · flags

How it works

guardian.ok.gov ──▶ ingestion (bulk CSV + report-PDF postback chain) ──▶ store
                                                                           │
                              REST API  ◀── service layer (the 14 rules) ◀─┘
                              MCP tools  ◀──┘

Two halves hinged on the database: a write path (the only code that touches Guardian — scrapes and normalizes on a schedule) and a read path (API + MCP, serving fast from the store). Ingestion downloads one bulk extract for all committees, then walks Guardian's ASP.NET report pages to fetch each Pre-Primary PDF, parses the Schedule Summary, and stores it. Reads layer the stored Pre-Primary figures on top of deduped continuing-window receipts.

API surface (/v1, JSON, optional X-API-Key)

Endpoint

Returns

GET /candidates?name=&district=&office=&party=

resolve candidates → committees

GET /committees/{org_id} · /{org_id}/filings · /{org_id}/summary

committee, filings, Pre-Primary figures

GET /committees/{org_id}/continuing · /{org_id}/combined

deduped continuing total · the headline number

GET /districts/{d}/candidates · /districts/{d}/combined

whole-race rollups

GET /contributions?org_id=&district=&from=&to=&type=&min_amount=

itemized receipts

GET /reports/{filing_id} · /flags · /calendar · /status

one report · alerts · windows · freshness

POST /query

flexible Axis A × Axis B selector

POST /refresh

trigger ingestion (background)

Full interactive docs at /docs when the API is running.


Deployment

One always-on host (recommended) — Postgres + API + nightly scheduler, no code changes:

cd deploy
GUARDIAN_API_KEYS=staff-key-1,staff-key-2 docker compose up -d --build
docker compose run --rm api guardian-ingest      # initial load

Set GUARDIAN_DATABASE_URL to a Postgres DSN for production (SQLite is the local default — same schema). Pass X-API-Key on every request once keys are set.

Serverless split (Vercel) — the read API + web UI deploy fine to Vercel, but the ingestion is a long, stateful scrape that doesn't fit serverless. The repo ships a ready split: Vercel (UI + /v1) + a GitHub Actions cron (the scraper) + managed Postgres. Files: vercel.json, api/index.py, requirements.txt, .github/workflows/ingest.yml. Step-by-step in DEPLOY.md.


The 14 Hard Rules → enforced invariants

#

Rule

Where it's enforced

1

Windows computed, never hardcoded

reporting_calendar (3rd-Tue-of-June); /calendar

2

Continuing reports are incremental → dedup receipts

compute.continuing (dedup by Receipt ID)

3

Pre-Primary can't be rebuilt from bulk

get_summary serves only parsed-PDF figures

4

Report PDFs are retrievable

guardian_client.fetch_report (postback chain, sequential)

5

Match by Org ID, confirm district

roster.resolve_org_id (never fuzzy)

6

One person, multiple committees

committee_detail.is_regular_cycle (lblElection)

7

Confirm year + committee

ingester rejects a report whose year ≠ cycle

8

Use the amended version

postback takes the last lnkView

9

Sub-$1,000 not on continuing reports

flags.sub_threshold

10

Data is a moving target

as_of on every response; scheduler

11

Version everything

runs append-only; builder archives, never overwrites

12

Full verification before delivery

combined.identity_ok; test suite

13

Freshness gate

Run.changed_since_prev; /status reports "no change"

14

Drop blank-Org-ID rows before dedup

bulk.iter_receipts


Project layout

src/guardian_contrib/
  ingest/      bulk CSV + report-PDF postback chain + run orchestration
  compute/     continuing-sum · combined-layering · flags  (the rules)
  service.py   the one place rules are applied on read (API + MCP call this)
  api/         FastAPI app          mcp_server/  MCP server (stdio)
  builder/     Book(Sheet1) xlsx    scheduler.py nightly/election refresh
tests/         51 tests + fixtures (incl. opt-in live e2e: GUARDIAN_LIVE=1)
deploy/        Dockerfile + docker-compose (Postgres + API + scheduler)

Troubleshooting

  • guardian-ingest hangs or errors: confirm outbound access to guardian.ok.gov. Try uv run guardian-ingest --no-reports first (bulk only).

  • API returns empty/null data: you haven't ingested yet — run guardian-ingest, then check /v1/status for the extract as-of date.

  • Imports fail in a checkout under a path with spaces: prefix commands with PYTHONPATH=src (the editable install can be flaky there); a normal path needs nothing.

License

MIT — see LICENSE.

Available Tools

13 tools
get_calendarB

The cycle's reporting calendar: primary date (3rd Tue of June), Pre-Primary period, and continuing window — computed, not hardcoded (Rule 1).

ParametersJSON Schema
NameRequiredDescriptionDefault
yearNo

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Describes that the calendar is computed according to Rule 1, indicating dynamic behavior. However, no explicit read-only or side-effect declaration, and no annotations to supplement. The description adds some behavioral context but is not comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, concise and front-loaded. No unnecessary words, every part adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Describes what the tool returns (key dates) but lacks details on the response structure or how the data is represented. Given no output schema, additional description of return format would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description does not explain the 'year' parameter's purpose, format, or behavior when null. With 0% schema description coverage, the description should compensate but fails to do so.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns the reporting calendar with specific dates (primary date, pre-primary period, continuing window) and notes it's computed, not hardcoded. It distinguishes from sibling tools by being about calendar, not committees, candidates, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives like get_combined, get_committee, etc. No mention of prerequisites or context for selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_combinedA

The headline number: Pre-Primary base + Continuing layered on top, for one committee (org_id) or every candidate in a district. Recomputes Ending = Beginning + Raised + Loans − Expended; note: Ending omits continuing-period spend.

ParametersJSON Schema
NameRequiredDescriptionDefault
org_idNo
districtNo
yearNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It discloses that Ending excludes continuing-period spend and that the tool recomputes values, but does not state whether it is read-only, requires authentication, or has side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences long and front-loaded with key information. However, the second sentence is somewhat technical, and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description should explain return values; it does not. It also omits the year parameter explanation. The tool is moderately complex with three parameters, and the description only partially covers them, making it incomplete for intelligent selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description should explain all parameters. It mentions org_id and district in context, clarifying their roles, but fails to mention the 'year' parameter, leaving one of three parameters undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool computes a headline number combining pre-primary and continuing totals for a committee or district. It explains the formula and distinguishes from siblings like get_continuing by specifying the combination.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for one committee (org_id) or every candidate in a district, but does not provide explicit guidance on when to use versus alternatives like get_continuing or list_district_candidates. No exclusions or when-not scenarios are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_committeeA

Committee detail by Org ID (Ethics #), including any OTHER committees the same candidate has (surfaces Special-vs-General — Rule 6).

ParametersJSON Schema
NameRequiredDescriptionDefault
org_idYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the burden. It discloses that the tool surfaces other committees of the same candidate and Rule 6 classification, which are key behaviors. However, it does not confirm read-only nature, required permissions, or any side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with two sentences, front-loading the primary purpose and adding a valuable detail about cross-referencing. No unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should explain what 'Committee detail' includes, but it only hints at returning other committees. It lacks field descriptions, return structure, and practical examples, leaving gaps for the agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description explains that 'org_id' is an 'Ethics #', adding context beyond the schema's minimal 'Org Id'. However, it provides no format, validation, or examples.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it retrieves committee detail by Org ID, and explicitly mentions it also includes other committees of the same candidate, distinguishing it from sibling tools like get_continuing. The reference to 'Rule 6' adds specificity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for looking up committees by an Ethics number, but does not explicitly state when to use this tool over alternatives like get_continuing or when not to use it. No exclusions or prerequisites are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_continuingA

Deduped continuing-window total (Raised vs Loans split), counting each receipt once across however many continuing reports were filed (Appendix C / Rule 2). Defaults to the cycle's computed continuing window.

ParametersJSON Schema
NameRequiredDescriptionDefault
org_idYes
date_fromNo
date_toNo
yearNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the dedup logic and default window, but lacks details on permissions, side effects, or output format. For a read-only tool, this is adequate but not comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with two sentences, front-loading the main purpose. Every sentence adds value, though it could be more structured with separate parameter explanations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's specificity, the description covers core behavior but omits output format, error conditions, and permissions. No output schema or annotations exist, leaving gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain parameters. It only vaguely relates date parameters to the cycle's computed window and does not explain org_id or year. Significantly deficient in parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns a deduped continuing-window total split by Raised vs Loans, counting each receipt once across multiple reports. This is specific and distinguishes it from sibling tools like get_summary or get_contributions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for deduped continuing totals but does not explicitly state when to use this tool versus alternatives or provide exclusions. No guidance on prerequisites or when not to use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_contributionsC

Itemized receipts + totals for a committee or a whole district. Optional window (date_from/date_to ISO), receipt_type, and min_amount filters.

ParametersJSON Schema
NameRequiredDescriptionDefault
org_idNo
districtNo
date_fromNo
date_toNo
receipt_typeNo
min_amountNo
dedupNo
yearNo

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It states it returns 'itemized receipts + totals' and supports filtering, but does not disclose any behavioral traits such as pagination, rate limits, or whether the operation is read-only or destructive. This is insufficient for understanding the tool's side effects or constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the core purpose and then lists key filters. It is concise with no wasted words, though it could be structured slightly better to include the omitted parameters. For a short description, it is efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of 8 parameters, no output schema, and no annotations, the description is incomplete. It does not explain the return format, how dedup works, what receipt_type values are valid, or how org_id and district relate to one another. The agent lacks sufficient context to invoke the tool confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It only explains 4 of 8 parameters (date_from, date_to, receipt_type, min_amount) and fails to mention org_id, district, dedup, and year, which are significant. The description adds some value but leaves half the parameters unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool returns 'itemized receipts + totals for a committee or a whole district'. It uses a specific verb ('get') and resource ('contributions'), and the scope (committee/district) helps distinguish it from sibling tools like get_committee (which likely focuses on committee info) and get_summary (which might return aggregated totals).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description mentions optional filters (date window, receipt_type, min_amount) but does not provide explicit guidance on when to use this tool versus alternatives like get_committee or get_summary. No 'when not to use' or alternative tool names are given, leaving the agent to infer usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_flagsC

Computed alerts: large-loan self-dealing (loan ≥ raised), sub-$1,000 continuing receipts, amended-report-used, multiple committees, no Pre-Primary, no committee found, identity mismatches.

ParametersJSON Schema
NameRequiredDescriptionDefault
districtNo
org_idNo
yearNo

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries full burden. It mentions 'computed alerts' but does not state if the tool is read-only, whether it requires specific authentication, or what side effects occur. The list of alert types gives some output context but no behavioral traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise (one line with a colon-separated list) but lacks structure. It front-loads 'Computed alerts:' then enumerates types, but no sentences or logical flow. It is appropriately short but could be better organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema, no annotations, and 0% parameter coverage, the description is severely incomplete. It fails to explain what the tool returns, how parameters affect results, or any fundamental behavior, making it nearly unusable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description must explain parameters. It does not mention 'district', 'org_id', or 'year' at all, leaving the agent without any understanding of how to use these optional parameters to filter results.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description lists specific types of alerts (e.g., 'large-loan self-dealing', 'amended-report-used'), which clarifies that the tool returns computed flags. The verb is implied ('get') but missing the resource object; however, the list of alert types provides a clear purpose and distinguishes from sibling tools that fetch different data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. There is no indication of prerequisites, filtering logic, or scenarios where this tool is appropriate, leaving the agent to guess.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_reportC

One filed report's parsed Schedule Summary (Reporting-Period column).

ParametersJSON Schema
NameRequiredDescriptionDefault
filing_idYes

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided; the description does not disclose behavioral traits like read-only, authentication needs, or rate limits. For a tool with no annotations, the description should provide more context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very concise (one short sentence), but lacks important details about the output and parameter. It is not optimally informative for its brevity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of output schema and minimal description, the tool is incomplete for an agent to understand what the 'parsed Schedule Summary' contains or how to interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description fails to explain what 'filing_id' represents or how to obtain it. The single parameter is critical but entirely undocumented beyond its name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description specifies it returns a 'parsed Schedule Summary' for one filed report, indicating a specific verb and resource. It distinguishes from sibling tools like get_summary and get_contributions, though the term 'Schedule Summary' could be clearer.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus sibling tools like get_summary or list_filings. The context hints are insufficient for an agent to decide appropriate usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_summaryB

Pre-Primary / periodic figures (Beginning, Raised excl-loans, Loans, Expended, Ending). ALWAYS from the parsed report PDF — never re-summed from bulk (Rule 3).

ParametersJSON Schema
NameRequiredDescriptionDefault
org_idYes

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the transparency burden. It discloses the data source (parsed PDF) and a rule about not re-summing from bulk, but does not discuss side effects, authentication, or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is only two sentences, with no redundant words. Key information is front-loaded: the type of figures and the source rule.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a simple input schema and no output schema, the description should cover return format and parameter details. It omits both, leaving the agent without guidance on what to expect or how to use org_id.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one required parameter (org_id) with no description. The tool description does not mention org_id or its purpose, so it adds no meaning beyond the schema. Schema coverage is 0%, yet the description fails to compensate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it retrieves summary figures from parsed report PDF, specifying the fields (Beginning, Raised excl-loans, etc.). It provides a specific verb-resource combination but does not directly distinguish from sibling tools like get_combined or get_report, though the source is unique.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description indicates it should always be used from the parsed report PDF and never re-summed from bulk, implying a specific context. However, it does not explicitly state when to use this tool versus alternatives or when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_district_candidatesC

Every candidate/committee in a House/Senate district (whole-race rollup).

ParametersJSON Schema
NameRequiredDescriptionDefault
districtYes
yearNo

TDQS

C2.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden but only mentions 'whole-race rollup' as a behavioral hint. It does not disclose read-only status, pagination, response structure, or any side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence with no redundancy. Every word is meaningful and front-loaded. However, conciseness sacrifices substance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, no output schema, and 0% parameter coverage, the description is far from complete. It omits essential information for correct agent invocation, such as parameter details and behavioral expectations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the description adds no meaning to the parameters (district, year). It does not explain district format, year filter behavior, or defaults. Agent cannot infer parameter usage from description alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the subject (every candidate/committee) and scope (House/Senate district, whole-race rollup), but the verb 'list' is implied rather than explicit. It differentiates from sibling tools like search_candidates by indicating a broader listing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives such as search_candidates or get_committee. The description does not specify prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_filingsB

All reports a committee filed (type, period, amended), newest-first.

ParametersJSON Schema
NameRequiredDescriptionDefault
org_idYes

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so the description carries full burden. It discloses the sorting (newest-first) but fails to mention other behavioral traits like read-only nature, authentication needs, or rate limits. For a tool with no annotations, this is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with one sentence that front-loads the core purpose. No extraneous words; every part adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description partially covers return values by listing fields, but omits details like possible values, pagination, or error conditions. For a simple list tool with one param, it is adequate but not complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, yet the description does not explain the sole parameter 'org_id' beyond implying it identifies a committee. It lists output fields (type, period, amended) but provides no definitions or context for those, leaving meaning unclear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists all reports for a committee, including details like type, period, and amendment status, sorted newest-first. This distinguishes it from sibling tools like 'get_report' which fetch individual reports, though it does not explicitly name the verb.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when needing a list of filings for a committee, but provides no explicit guidance on when not to use it or alternatives. Siblings like 'get_report' exist for single-record lookups, but this is not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queryA

Flexible category selector — pick {who/where} × {what} in one call.

select: any of candidate, committee (Org ID), district, office, party, cycle. category: summary | combined | continuing_total | contributions | loans | report | filing_history | flags. window: {from, to} ISO dates (optional; defaults to the calendar). options: {dedup, min_amount, include_amended}. Returns a uniform envelope {as_of, selection, category, data, caveats}.

ParametersJSON Schema
NameRequiredDescriptionDefault
selectYes
categoryYes
windowNo
optionsNo
yearNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description adequately discloses behavior: it returns a uniform envelope with specified fields, defaults for window to the calendar, and lists options. It does not mention authorization or rate limits, but for a query tool, the description is sufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured: a single sentence explaining the tool's purpose, followed by bullet-like explanations of each parameter and the return structure. Every part is necessary and earned its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (5 parameters, nested objects, no output schema, many siblings), the description is moderately complete. It explains the main parameters and return envelope but omits the 'year' parameter and does not fully clarify how the 'select' object works (schema says it's an object, description implies specific strings). More detail would be beneficial.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It adds meaning by listing possible values for select and category, describing window as ISO dates with default, and options as a set of flags. However, it fails to mention the 'year' parameter present in the schema, which is a gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool is a flexible category selector that picks combinations of entity and category in one call, listing specific options. It distinguishes itself from sibling tools (e.g., get_summary, get_combined) by implying it can replace multiple specific tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on what the tool does and how to use it (select and category options, window, options). However, it does not explicitly state when to use this tool versus the sibling tools, nor does it mention any exclusions or when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

refresh_statusA

Extract as-of (max Filed/Receipt date) and whether it changed since the prior pull — so an identical re-pull is reported as 'no change' (Rule 13), not a fake update.

ParametersJSON Schema
NameRequiredDescriptionDefault
yearNo

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly states that an identical re-pull is reported as 'no change' (Rule 13), not a fake update. This is a key behavioral trait beyond just extracting data. However, it does not mention side effects, authorization needs, or rate limits, which are minor for a read-only tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the core action and outcome. It is concise and avoids unnecessary words. However, it could be improved by adding the missing parameter information without becoming verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 1 optional parameter, no output schema, and no annotations, the description is incomplete. It does not explain what the 'as-of' date looks like or the format of the change indicator. The mention of 'Rule 13' is cryptic without context. The year parameter is ignored entirely, making the description insufficient for an agent to use the tool correctly without further inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has one optional parameter (year) with no description, and the schema description coverage is 0%. The description does not mention this parameter at all, leaving the agent guessing how year affects the output (e.g., filtering to a specific filing year). This is a severe omission.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool extracts the as-of (max Filed/Receipt date) and whether it changed since the prior pull. This is a specific action (extract) on a specific resource (status change indicator), and the mention of Rule 13 helps distinguish it from sibling tools that retrieve raw data (e.g., get_report, get_summary).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly defines when to use the tool: to check if a re-pull would result in a 'no change' or a real update. This is clear for an agent performing data synchronization. However, it does not explicitly state when not to use it or list alternatives, but the purpose is self-explanatory enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_candidatesA

Resolve candidates to committees (Org IDs). Never fuzzy-matches: returns all matches and flags has_multiple_committees so the caller picks the regular-cycle one. Filter by name, district (HD-42/SD-15), office, party ((D)/(R)), or cycle.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo
districtNo
officeNo
partyNo
cycleNo
yearNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description covers key behaviors: exact matching, returning all matches, and providing a flag (has_multiple_committees) for disambiguation. It does not discuss authorization, rate limits, or error states, but the essential behavior is well-explained.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with purpose and key behavior, followed by filter examples. No extraneous words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description explains the main output feature (returns all matches, flags multiple committees). It does not detail pagination, error handling, or full return structure, but for a search tool this is adequate and consistent with sibling tool descriptions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description partially compensates by listing filterable parameters and giving format examples (e.g., district: 'HD-42/SD-15', party: '(D)/(R)'). However, it omits the 'year' parameter and does not describe each parameter's full semantics or constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly defines the tool's purpose: 'Resolve candidates to committees (Org IDs)' and distinguishes it from siblings by noting it never fuzzy-matches and flags multiple committees. The verb 'resolve' and resource 'candidates to committees' are specific.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description lists filterable attributes (name, district, office, party, cycle) and states the tool never fuzzy-matches, but does not explicitly compare to sibling tools like list_district_candidates or provide guidance on when to choose this over alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 13 tool updatesv0.1.0
    • First observedget_calendar
    • First observedget_combined
    • First observedget_committee
    • First observedget_continuing
    • First observedget_contributions
    • First observedget_flags
    • First observedget_report
    • First observedget_summary
    • First observedlist_district_candidates
    • First observedlist_filings
    • First observedquery
    • First observedrefresh_status
    • First observedsearch_candidates

TDQS

B3.4/5.0
Disambiguation4/5

Each tool has a well-defined purpose, with clear distinctions between similar concepts like get_combined, get_summary, and get_continuing. The query tool is flexible but still distinct as a category-based aggregator.

Naming Consistency4/5

Most tools follow a consistent 'get_' pattern for data retrieval, with 'list_', 'query', 'search_', and 'refresh_' used for different types of operations. The pattern is logical but not perfectly uniform.

Tool Count5/5

13 tools cover the domain of campaign finance data comprehensively without being excessive. Each tool addresses a specific aspect of the system, from calendar to contributions to flags.

Completeness5/5

The tool surface covers all major operations expected for a read-only campaign finance data API: querying committees, candidates, contributions, reports, filings, and computed alerts. The flexible query tool fills any gaps.

Maintenance

ActivityStale
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Read-only MCP server for exploring US federal spending data via the USAspending.gov API, enabling natural language queries on awards, agencies, recipients, and spending trends.
    12
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Enables querying state-level campaign finance data, including donors, expenditures, committees, and candidates, from multiple state disclosure systems via a unified MCP interface.
    9
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cstillick/guardian-contributions-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server