---
summary: "Three new tools — openfec_get_committee_totals, openfec_search_coordinated_expenditures, openfec_get_legal_document (9 → 12) — closing #14 and #1; the outbound parameter guard now checks path-parameterized endpoints, and a genuine upstream miss is distinguished from an edge routing failure"
breaking: false
security: false
---

# 0.7.0 — 2026-07-26

## Added

- **`openfec_get_committee_totals`** — mode-dispatched: `single` (default) fetches one committee's per-cycle totals via `/committee/{committee_id}/totals/`; `by_entity_type` ranks or screens committees of one type via `/totals/{entity_type}/`. Four declared error reasons: `committee_id_required_for_single_mode`, `entity_type_required_for_group_mode`, `inputs_not_applicable_to_mode`, `committee_totals_not_found`. ([#1](https://github.com/cyanheads/openfec-mcp-server/issues/1))
- **`openfec_search_coordinated_expenditures`** — searches Schedule F (`/schedules/schedule_f/`), page-based pagination (no keyset, unlike Schedules A/B/E), hoists the shared spending `committee` when scoped to one `committee_id`, and drops `subordinate_committee`. ([#1](https://github.com/cyanheads/openfec-mcp-server/issues/1))
- **`openfec_get_legal_document`** — fetches one legal document in full (`/legal/docs/{doc_type}/{no}`), returning the untouched `documents`, `commission_votes`, and `dispositions` arrays that `openfec_search_legal` trims. One declared error reason: `legal_document_not_found`. ([#14](https://github.com/cyanheads/openfec-mcp-server/issues/14))
- **`openfec_search_legal` gains a `retrievalHint` enrichment field** on every non-empty response, naming what was trimmed and how to retrieve the full record with `openfec_get_legal_document`. ([#14](https://github.com/cyanheads/openfec-mcp-server/issues/14))

## Changed

- **Schedule F rows drop `subordinate_committee`.** Not always a duplicate of the spender: across a 100-row sample it was null on 39 rows, the spender again on 60, and a different committee on 1 — but the row's own `subordinate_committee_id` matched the embedded object in all 100, so the row description tells callers the ID can name a different committee, resolvable with `openfec_search_committees`.

## Fixed

- **`assertKnownParams` now resolves an interpolated request path back to its spec template before the allowlist lookup.** `buildUrl` receives paths with the identifier already substituted, so every path-parameterized endpoint (`/committee/{committee_id}/totals/`, `/totals/{entity_type}/`, `/legal/docs/{doc_type}/{no}`) previously skipped the outbound parameter guard entirely. `/totals/{entity_type}/` is anchored to its six enum values so a different `/totals/…` path isn't checked against the wrong allowlist.
- **A 404 whose body is OpenFEC's own JSON error object now normalizes to an empty or not-found result** instead of a generic failure — `getCommitteeTotals` and `getLegalDocument` raise their own actionable not-found errors. Any other 404 body, including the api.data.gov edge's plain-text routing error seen during an outage, still propagates as a failure rather than being reported as "no such record."
