@pipeworx/gao-protests

Connect: https://gateway.pipeworx.io/gao-protests/mcp · Install: one-click buttons

Tools: 4

GAO bid-protest decisions — government-contract award disputes ruled on by the US Government Accountability Office (“did anyone protest this award”, “how often does this agency lose protests”). Pairs with usaspending and dod-contract-announcements, which cover the award side but not disputes.

Tools

  • gao_protests_recent(days?, outcome?, limit?) — recently decided protests, optionally filtered by outcome (denied|dismissed|sustained).
  • gao_protest(b_number) — a single decision by B-number, with the decision PDF link.
  • gao_protests_search(protester, limit?) — search accumulated decisions by protester/company name.
  • gao_protests_coverage() — total decisions held, earliest/most-recent decided_on, last crawl time.

Auth

Keyless. Reads a Pipeworx-hosted table (gao_bid_protests), ingested daily by workers/data-pipeline (dataset gao-protests) — no operator key needed.

Data sources

Coverage is a rolling accumulation, not GAO’s full protest archive. The filtered search endpoint (gao.gov/search?f[0]=ctype_search:Bid Protest Decision) sits behind an Akamai Bot Manager proof-of-work JS interstitial that cannot be solved from a server — full Chrome headers over HTTP/2 don’t help, this is a JS-execution challenge, not a header fingerprint. The landing page’s own “More” link points at that same blocked endpoint, and there is no other reachable pagination. So this pack can only ever see the decisions GAO has published since it started crawlinggao_protests_recent/_search answer against what has accumulated in gao_bid_protests so far, not against GAO’s complete decision history. gao_protests_coverage reports exactly how far back that goes.

Both hosts need the full Chrome header set (User-Agent, Accept, Accept-Language, sec-ch-ua*, Sec-Fetch-*, Upgrade-Insecure-Requests over HTTP/2) — a plain User-Agent alone gets a 403. This is a header-fingerprint block, not a Cloudflare-egress block; no proxy is needed.

The protested AGENCY is not available. It appears only inside each decision’s PDF text, never in the page HTML, and this pipeline has no PDF text extraction. Rather than guess an agency from context (or from the protester’s history), the field is omitted entirely — presenting a guessed agency as fact would be worse than not having it.

A decision can carry several B-numbers (e.g. B-424484,B-424484.2 for an original protest plus a reconsideration). The table’s primary key is the first number in that string; gao_protest also matches a non-primary number (like the .2 suffix) by searching the raw string.

Outcome is prose, not an enum (“We deny the protest.”, “We dismiss the request for reconsideration.”, “We sustain the protest.”). It’s normalized to denied | dismissed | sustained | other for filtering, and the raw sentence is always kept alongside it.

Tools

  • gao_protests_recent — Recently decided GAO bid-protest decisions — government-contract award disputes ruled on by the Government Accountability Office. Filter by a lookback window (days) and optionally outcome (denied|dism
  • gao_protest — Fetch a single GAO bid-protest decision by its B-number (e.g. “B-424695” or “B-424484.2” for a reconsideration). Returns protester, decided_on, outcome (normalized + the raw prose sentence, e.g. “We d
  • gao_protests_search — Search accumulated GAO bid-protest decisions by protester (company) name, e.g. “has been cited in a bid protest” or “which GAO protests did Boeing file”. Case-insensitive partial match. Only
  • gao_protests_coverage — How much GAO bid-protest data this pack currently holds: total decisions, the earliest and most recent decided_on dates, and when the daily crawl last ran. Use this before relying on gao_protests_rece

Tools

  • gao_protest — Fetch a single GAO bid-protest decision by its B-number (e.g. B-424695 or B-424484.2 for a reconsideration). Returns protester, decided_on, outcome (normalized + the raw prose sentence, e.g. We deny t
  • gao_protests_coverage — How much GAO bid-protest data this pack currently holds: total decisions, the earliest and most recent decided_on dates, and when the daily crawl last ran. Use this before relying on gao_protests_rece
  • gao_protests_recent — Recently decided GAO bid-protest decisions — government-contract award disputes ruled on by the Government Accountability Office. Filter by a lookback window (days) and optionally outcome (denied|dism
  • gao_protests_search — Search accumulated GAO bid-protest decisions by protester (company) name, e.g. has <company> been cited in a bid protest or which GAO protests did Boeing file . Case-insensitive partial match. Only se

Regenerated from source · build August 31, 2026