# GovCon API (pypi · govconapi-mcp)

53 tools over US federal procurement: SAM.gov, FPDS awards, entities, subawards, exclusions.

- Trust score: 76/100 (medium)
- Change this week: +18
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-09-21

## Components

- pypi · `govconapi-mcp`: 76/100 (this document), [markdown](https://verifymcp.io/servers/govconapi-govconapi/govconapi-mcp.md), [page](https://verifymcp.io/servers/govconapi-govconapi/govconapi-mcp)

## Channel facts

- Registry: `pypi`
- Package: `govconapi-mcp`
- Version: `0.2.3`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-09-21.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised native-build step with no shell scripting around it.
  - 0 of 29 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 20 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 65/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 13229 tokens (~249/item across 53 items; 53 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 70/100
  - Stability observed for 21 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 53 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 53 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the GovCon API MCP server?

GovCon API runs locally as a PyPI package, launched with uvx govconapi-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add govconapi-govconapi -- uvx govconapi-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "govconapi-govconapi": {
      "command": "uvx",
      "args": [
        "govconapi-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "govconapi-govconapi": {
      "command": "uvx",
      "args": [
        "govconapi-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add govconapi-govconapi -- uvx govconapi-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "govconapi-govconapi": {
      "type": "local",
      "command": [
        "uvx",
        "govconapi-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add govconapi-govconapi --command uvx --arg govconapi-mcp
```

### Hermes

```yaml
mcp_servers:
  govconapi-govconapi:
    command: "uvx"
    args: ["govconapi-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "govconapi-govconapi": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "govconapi-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add govconapi-govconapi -t stdio -c uvx -a govconapi-mcp
```

### Other

```json
{
  "mcpServers": {
    "govconapi-govconapi": {
      "command": "uvx",
      "args": [
        "govconapi-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-09-20 (score 76, +1)

No change was recorded against any check on this day. Stability & Change Management went from 63 to 67. That category is still filling its 30-day observation window: 19 days of observed history at the previous scan, 20 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-18 (score 75, +1)

No change was recorded against any check on this day. Stability & Change Management went from 57 to 60. That category is still filling its 30-day observation window: 17 days of observed history at the previous scan, 18 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-16 (score 74, +1)

No change was recorded against any check on this day. Stability & Change Management went from 50 to 53. That category is still filling its 30-day observation window: 15 days of observed history at the previous scan, 16 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-15 (score 73, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-09-14 (score 58, −14)

- [security regression] Malware scan: pass → unverified

### 2026-09-11 (score 72, +1)

No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-09 (score 71, +1)

No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-07 (score 70, +4)

- [functional improvement] Stability: unverified → 0.23

## MCP tools (53)

### `search_opportunities` (~736 tokens)

Search Opportunities

Search federal contract opportunities (SAM.gov data) with filters.

At least one filter is required. Use specific values:
\- naics: 6-digit NAICS code, e.g. "541330" (engineering services)
\- psc: 1-4 char Product Service Code, e.g. "D302" (IT services)
\- naics_multiple: comma-separated NAICS codes, e.g. "541511,541512"
\- agency: agency name substring (use full names, e.g. "FEDERAL EMERGENCY MANAGEMENT" not "FEMA"; use lookup_agency tool first)
\- keywords: full-text search across title, agency, description (min 3 chars)
\- state: 2-letter state code (CA, TX) or full name (California)
\- set_aside: a plain term (HUBZone, WOSB, 8(a), Veteran, Small Business, Indian Small
  Business, Buy Indian, ...) or an exact SAM code (SBA, SDVOSBC, HZC, ...). An
  unrecognized value returns 400 WITH THE FULL VALID-TERM LIST in the response body, retry using that list rather than guessing another synonym.
\- notice_type: Solicitation, Combined Synopsis/Solicitation, Presolicitation, Sources
  Sought, Award Notice, Justification, Justification and Approval (J&A), Special
  Notice, Sale of Surplus Property, Modification/Amendment/Cancel, Consolidate/
  (Substantially) Bundle. Comma-separate several to match any. Invalid values 400
  the same way as set_aside, the full list comes back in the error.
\- posted_after / due_before / due_after / date_from / date_to: YYYY-MM-DD. A
  date_from before your plan's history window is not silently dropped, it's
  clamped, and the response's `window` block (`clamped`, `date_from_requested`,
  \`reason`) discloses exactly what happened.
\- value_min / value_max: USD amounts (only Award Notice records have values)
\- has_attachments: true/false
\- sort_by: posted_date, due_date, award_amount, title, agency, relevance (used
  automatically when keywords is set and sort_by is omitted)
\- sort_order: asc | desc (default desc), e.g. sort_by=due_date + sort_order=asc for
  "what's due soonest first"
\- limit: max 1000

Returns JSON with `data` (matching opportunitie…

Input parameters:

- `agency`
- `date_from`
- `date_to`
- `due_after`
- `due_before`
- `has_attachments`
- `keywords`
- `limit` (integer)
- `naics`
- `naics_multiple`
- `notice_type`
- `offset` (integer)
- `posted_after`
- `psc`
- `set_aside`
- `sort_by`
- `sort_order`
- `state`
- `value_max`
- `value_min`

Output parameters:

- `result` (string)

### `get_opportunity` (~53 tokens)

Get Opportunity

Fetch a single contract opportunity by its notice_id.

Returns the full record including agency, contacts, description, attachments,
award data (if applicable), and 50+ structured fields.

Input parameters:

- `notice_id` (string, required)

Output parameters:

- `result` (string)

### `recent_changes` (~130 tokens)

Recent Opportunity Changes

List opportunities added or updated since a timestamp.

Use this for incremental sync instead of paginating through search results.
Keyset-based, so depth doesn't degrade performance.

\- since: ISO 8601 timestamp, e.g. "2026-04-12T00:00:00Z"
\- limit: max 1000 per page

Returns `data` (changed records), `pagination`, and `sync.server_time`, save server_time and pass it as `since` on your next call.

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `since` (string, required)

Output parameters:

- `result` (string)

### `lookup_agency` (~255 tokens)

Lookup Agency

Resolve an agency acronym or partial name to canonical SAM.gov agency strings.

SAM.gov stores agency names like "HOMELAND SECURITY, DEPARTMENT OF.FEDERAL
EMERGENCY MANAGEMENT AGENCY..." not "FEMA". Use this to find the right
substring to use as the `agency` filter on search_opportunities, search_companies,
or most other tools that take an `agency` parameter. EXCEPTION: search_forecasts'
\`agency` filter uses its own natural-language agency names (e.g. "Department of
Health and Human Services"), not this SAM-hierarchy string, this tool's suggestion
will not match there.

\- query: acronym (FEMA, DoD, NASA), partial name, or full agency name

Returns matching agencies grouped by canonical name with the suggested
filter value to use. `suggested_filter_value` is the CANONICAL grouping, which can
be much broader than one component of it (e.g. a sub-agency's contracting office
grouped under its parent's canonical name), if the match count looks too high, use
one of that group's own `raw_variations` entries instead for a narrower filter.

Input parameters:

- `query` (string, required)

Output parameters:

- `result` (string)

### `check_exclusion` (~126 tokens)

Check Exclusions for a Vendor

Check the SAM.gov exclusions list (debarred / suspended entities).

Use this before subcontracting or teaming, and again periodically post-award to
catch a teammate getting excluded mid-performance. Provide at least one of:
\- name: company or individual name (partial match)
\- uei: Unique Entity ID (same identifier search_companies/search_entities return)
\- cage_code: CAGE code

Returns matching exclusion records with the reason, agency, and dates.

Input parameters:

- `cage_code`
- `limit` (integer)
- `name`
- `uei`

Output parameters:

- `result` (string)

### `search_awards` (~253 tokens)

Search SAM Award Notices

Search SAM Award Notices (who won, how much, when), a SPARSE, self-reported
subset of federal awards (~52K notices), NOT the comprehensive federal award record.
\~60% of contractors here have only a single notice; a diversified contractor's real
award book is usually much bigger than what shows here. For the comprehensive,
authoritative award record (10.6M+ FPDS/USAspending transactions), use
search_contracts instead, reach for THIS tool specifically when the question is
about a SAM-noticed award, not the company's overall federal business.

\- awardee: company name (partial match)
\- uei: Unique Entity ID
\- naics: 6-digit NAICS code
\- agency: agency name substring
\- value_min / value_max: USD
\- date_from / date_to: YYYY-MM-DD
\- limit: max 1000

Input parameters:

- `agency`
- `awardee`
- `date_from`
- `date_to`
- `limit` (integer)
- `naics`
- `offset` (integer)
- `uei`
- `value_max`
- `value_min`

Output parameters:

- `result` (string)

### `discover_offices` (~249 tokens)

Discover Offices

Find which contracting offices buy a NAICS code, ranked, each with its own win-facts.

Market Research tool: answers "who actually buys this, not just which department."
Competition and set-aside behavior vary a lot office-to-office even within one agency;
this ranks offices instead of reporting only a department-wide average.

\- naics: 2-6 digit NAICS code, required (e.g. "541512")
\- sort: biggest (total obligations) | most_open (highest full-and-open share) |
  most_setaside (highest set-aside share)
\- limit: max 100

Returns each office's code, name, total obligations, competition rate, and set-aside
share for this NAICS. Pass an office's `office_code` to get_office_profile for the
full picture of how that office buys across ALL NAICS, not just this one.
Free on every plan. No shared identifier (UEI/PIID) links out from this tool to
contract- or company-level tools, office_code is its own namespace.

Input parameters:

- `limit` (integer)
- `naics` (string, required)
- `sort` (string)

Output parameters:

- `result` (string)

### `get_office_profile` (~145 tokens)

Get Office Profile

Get one contracting office's full buying profile: obligations, competition,
set-aside lean, and every NAICS it buys.

Market Research tool. Use this after discover_offices (or when you already have an
office_code from a contract/award record) to see an office's behavior across its
ENTIRE buying pattern, not just one NAICS.

\- office_code: the office's FPDS office code (from discover_offices or a contract record)

Free on every plan. Returns 404 if the office has no FPDS activity on record; 503
briefly if the office index is still building (retry).

Input parameters:

- `office_code` (string, required)

Output parameters:

- `result` (string)

### `list_organizations` (~282 tokens)

List Organizations

Search the federal agency organization tree (~907 departments/agencies/offices).

Market Research tool. Use `search` to resolve a name/acronym to an org, or
\`parent_id` to list an agency's direct sub-units. Free tier.

\- type: DEPARTMENT or AGENCY
\- cgac: Treasury account code (e.g. "097" for DoD), NOT the same code space as
  \`awarding_agency_code` on contract/award tools; there is no shared identifier
  between federal_hierarchy and contract-level data, cgac requires a separate
  lookup, it does not chain directly
\- parent_id: filter to direct children of one organization_id
\- hierarchy_level: 1 = root department
\- search: matches canonical name, short name, or any alternative name (min 2 chars)
\- limit: max 1000

Returns each org's organization_id, pass that to get_organization for the full
record with parent/children/ancestors inline, or to list_organizations again as
parent_id to page through its children.

Input parameters:

- `cgac`
- `hierarchy_level`
- `is_active`
- `limit` (integer)
- `offset` (integer)
- `parent_id`
- `search`
- `type`

Output parameters:

- `result` (string)

### `get_organization` (~136 tokens)

Get Organization

Get one federal organization's full record, with its parent, immediate children,
and full ancestor chain (root department down to immediate parent) all included in
one call.

Market Research tool. This already includes what get_org_relationships would give
you separately, use this first; only call get_org_relationships if you want JUST
the children or JUST the ancestors without the rest of the record (a narrower,
cheaper call for e.g. listing every sub-agency of a department).

\- organization_id: from list_organizations

Free tier. 404 if the organization_id doesn't exist.

Input parameters:

- `organization_id` (integer, required)

Output parameters:

- `result` (string)

### `get_org_relationships` (~157 tokens)

Get Organization Relationships

Get JUST an organization's immediate children or its ancestor chain, without the
rest of the record (get_organization already includes both if you need everything).

Market Research tool, narrow form: e.g. "list every sub-agency under DoD" doesn't
need DoD's own full record, just its children.

\- organization_id: from list_organizations or get_organization
\- direction: "children" (immediate sub-organizations) | "ancestors" (root department
  down to immediate parent; empty if this org is already a root department)

Free tier. 404 (ancestors direction only) if organization_id doesn't exist.

Input parameters:

- `direction` (string)
- `organization_id` (integer, required)

Output parameters:

- `result` (string)

### `search_forecasts` (~452 tokens)

Search Forecasts

Search agency procurement forecasts, the only FORWARD-LOOKING layer in this API.
These are pre-solicitation: work an agency has planned but hasn't posted an
opportunity for yet.

Market Research tool. Use this to find what's coming before it's postable, not what's
live now (for live notices, use search_opportunities instead).

\- source: fco | dhs | hhs (which agency forecast feed)
\- naics: 2-6 digit code, prefix match (e.g. "5415" matches 541511, 541512...)
\- is_recompete: true = only forecasts that name a current incumbent (see below)
\- amount_min/amount_max: USD, matched against the forecast's value range
\- active_only: default true, excludes already-awarded/cancelled forecasts
\- keywords: full-text search over title + description
\- sort_by: est_award_fy | est_solicitation_date | value_high | agency | last_updated_date

Recompete signal: when `is_recompete` is true, each row's `incumbent_piid` is the SAME
identifier `get_contract` and `get_vehicle` take as `piid`, chain into either to see who
currently holds it, its value, and when it expires (Pro accounts get this pre-joined
inline as `incumbent_award`, so check that field before making the extra call).
Direct-line PoC contact fields (poc_email, poc_phone, co_email, sb_specialist_email/phone)
are Pro-gated; poc_name stays visible on every plan.

Input parameters:

- `active_only` (boolean)
- `agency`
- `amount_max`
- `amount_min`
- `est_award_fy`
- `est_award_quarter`
- `is_recompete`
- `keywords`
- `limit` (integer)
- `naics`
- `offset` (integer)
- `set_aside`
- `sort_by`
- `sort_order`
- `source`
- `state`
- `status`

Output parameters:

- `result` (string)

### `find_naics_codes` (~363 tokens)

Find NAICS Codes

Discover NAICS codes by current federal spending and small-business set-aside
leverage, use this when you don't already know which NAICS code to look at.

Market Research tool, the entry point into the NAICS/Market Pulse tools below.

\- sector: 2-digit NAICS sector prefix (e.g. "54")
\- prefix: any-length NAICS prefix (e.g. "5415")
\- min_market: minimum FY2025+ obligated dollars
\- max_competitors: maximum distinct winning firms (a low number = a thin, less-contested market)
\- set_aside_family: total_small_business | 8a | sdvosb | wosb | hubzone | veteran | native
\- keywords: matches the NAICS description text
\- sort_by: market (size) | competitors | setaside_pct (aggregate small-business share
  across ALL families; when set_aside_family is also set, sorts by THAT family's own
  share instead, read each row's `family_share_pct` for the honest per-family number,
  populated only when set_aside_family is set)

Returns each matching code's `naics_code`, pass that to get_naics_market,
get_naics_positioning, get_naics_simplified_acquisition, or get_naics_competition for
the deeper reads below. 503 briefly if the market index is still building.

Input parameters:

- `keywords`
- `limit` (integer)
- `max_competitors`
- `min_market`
- `offset` (integer)
- `prefix`
- `sector`
- `set_aside_family`
- `sort_by` (string)
- `sort_order` (string)

Output parameters:

- `result` (string)

### `get_naics_leaderboard` (~202 tokens)

Get NAICS Leaderboard

Browse curated, ranked NAICS market leaderboards, a fixed set of named rankings,
distinct from find_naics_codes' open filtered search.

Market Research tool.

\- board: the named ranking to view , "biggest" | "least_crowded" | "most_open" |
  "most_locked" | "setaside_total_small_business" | "setaside_8a" | "setaside_sdvosb" |
  "setaside_wosb" | "setaside_hubzone" | "setaside_veteran" | "setaside_native"
\- limit: max 100

Returns each ranked NAICS code's `naics_code`, pass that to get_naics_market or the
other NAICS tools below. 400 if `board` isn't a recognized name; 503 briefly if the
market index is still building.

Input parameters:

- `board` (string, required)
- `limit` (integer)

Output parameters:

- `result` (string)

### `get_naics_market` (~198 tokens)

Get NAICS Market

Get the federal market profile for one NAICS code: spending, competition,
set-aside leverage, top buyers, and top incumbents.

Market Research tool, the AWARD side of a market (who's winning, how much). Pair with
get_naics_positioning for the SOLICITATION side (the language contracting officers
use), get_naics_simplified_acquisition for the small-buy value bands, and
get_naics_competition for the deeper contestability read.

\- code: 2-6 digit NAICS code

\`size_standard` is null (`size_standard_status: "pending_sba_table"`), the SBA
small-business size threshold isn't part of this dataset. Check SBA's table directly
for small-business eligibility rather than relying on this response for it.

Free tier. 404 if there's no FY2025+ federal contract activity for this code.

Input parameters:

- `code` (string, required)

Output parameters:

- `result` (string)

### `get_naics_positioning` (~165 tokens)

Get NAICS Positioning

Get the language and set-aside makeup for a NAICS code's SOLICITATION side: the
phrase vocabulary contracting officers actually use in notices, the set-aside share
of notices, and the top soliciting agencies, over the last 24 months of SAM
opportunities.

Market Research / Capture tool. This is what to put in a SAM/DSBS profile or
capability statement so contracting officers find you. Pair with get_naics_market for
the award side (spending, incumbents, competition) of the same NAICS.

\- code: 2-6 digit NAICS code

Free tier. 404 if there's no SAM opportunity activity for this code in the last 24 months.

Input parameters:

- `code` (string, required)

Output parameters:

- `result` (string)

### `get_naics_simplified_acquisition` (~222 tokens)

Get NAICS Simplified-Acquisition Breakdown

Get the award-value breakdown for a NAICS code over the last 12 months of FPDS
prime awards: counts of micro / simplified-acquisition / above-SAT awards, and which
offices are making simplified-acquisition-band awards, with distinct-firm and
set-aside counts for that band.

Market Research tool, the SMALL-BUY value-band read (FAR Part 13 context: the
$15k-$350k simplified-acquisition band is reserved for small business under FAR
19.502-2(a)'s Rule of Two). Pair with get_naics_positioning (the language) and
get_naics_market (the whole-market picture) for the same code.

\- code: 2-6 digit NAICS code

Free tier. Factual, never scored, the facts only, no recommendation on whether to
pursue this band. 404 if there's no FPDS prime-award activity for this code in the
last 12 months.

Input parameters:

- `code` (string, required)

Output parameters:

- `result` (string)

### `get_naics_competition` (~248 tokens)

Get NAICS Competition

Get how contested a NAICS market is, over the whole FPDS prime-award market: offers
received per award, single-bidder share, top place-of-performance states, award-volume
trend by quarter, the share of recent winners holding only one or two awards (the
long-tail signal that a market ISN'T locked up by incumbents), and the winner-cert
socioeconomic mix (the dollar share going to firms holding each set-aside
certification, e.g. 8(a), SDVOSB, WOSB, HUBZone).

Market Research / Capture tool, the CONTESTABILITY read , the facts a would-be
competitor needs before committing a capture cycle to this market. Distinct from
get_naics_market (size + concentration), get_naics_simplified_acquisition (the
small-buy value bands), and get_naics_positioning (the language).

\- code: 2-6 digit NAICS code

Free tier. Factual, never scored. 404 if there's no FPDS prime-award activity for this
code in the last 12 months.

Input parameters:

- `code` (string, required)

Output parameters:

- `result` (string)

### `search_companies` (~377 tokens)

Search Companies

Search companies that have WON at least one federal award, by name, across both
SAM Award Notices and FPDS prime contracts. For ALL registered SAM firms (won an
award or not), use search_entities instead.

Capture & Teaming tool, Pro only. Case-insensitive substring match on the name.

\- q: name substring, min 2 chars, REQUIRED, naics/agency/naics_small only narrow an
  existing name search, they don't work standalone (for a direct UEI lookup use
  get_company_profile instead)
\- naics: 6-digit code, filters to companies with 1+ award in this NAICS
\- agency: top-level agency name (e.g. "DEPT OF DEFENSE"), filters to companies with
  1+ award from this agency
\- naics_small: exact 6-digit NAICS code (e.g. "236220"), SBA DSBS small-business
  determination for this NAICS (Pro), pairs award history with actual eligibility,
  distinct from SAM's self-reported flag
\- limit: max 100

Returns each company's `uei`, the SAME identifier every other Capture/Teaming tool
takes as `uei` (get_company_profile, get_company_awards, get_company_peers,
check_exclusion, get_company_contact). `total_value`/`total_awards` cover SAM Award
Notices only; `fpds_obligated_total`/`fpds_transaction_count` cover the broader FPDS
prime-contract activity independently, a contractor can show $0 in one and millions
in the other, check both.

Input parameters:

- `agency`
- `limit` (integer)
- `naics`
- `naics_small`
- `offset` (integer)
- `q`

Output parameters:

- `result` (string)

### `get_company_profile` (~209 tokens)

Get Company Profile

Get one company's aggregate profile: SAM registration (legal name, address, NAICS,
PSC, certifications) combined with award-history totals.

Capture & Teaming tool, Pro only. This is the SUMMARY view, for the full paginated
list of individual awards use get_company_awards; for similar/competitor firms use
get_company_peers.

\- uei: 12-character Unique Entity ID (from search_companies, search_opportunities'
  \`award_uei_sam`, or any other tool that returns a `uei` field)

IMPORTANT scope note: `total_awards`/`total_value`/`avg_value` here count SAM Award
Notices ONLY (roughly 10-30% of federal obligations), NOT the company's total
federal contract value. A contractor active only in FPDS shows `total_value: 0` here
by design; check the FPDS-sourced fields for the fuller picture.

Input parameters:

- `uei` (string, required)

Output parameters:

- `result` (string)

### `get_company_awards` (~193 tokens)

Get Company Awards

Get the full paginated award history for one company (every individual award,
not just the summary totals get_company_profile gives you).

Capture & Teaming tool, Pro only.

\- uei: 12-character Unique Entity ID
\- sort_by: award_date | award_amount
\- sort_order: asc | desc
\- limit: max 1000

Each row's `notice_id` is the same identifier get_opportunity takes, for pulling the
full original notice behind an award, but it's `null` on FPDS-sourced rows
(`source: "fpds_prime_contract"`), since those contracts were never posted as SAM
opportunities. Only `source: "sam_award_notice"` rows have one.

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `sort_by`
- `sort_order` (string)
- `uei` (string, required)

Output parameters:

- `result` (string)

### `get_company_peers` (~138 tokens)

Get Company Peers

Find companies similar to this one by NAICS + agency overlap, the competitive
landscape around a firm, not its own history.

Capture & Teaming tool, Pro only. Use this to answer "who else competes where this
company competes," distinct from get_company_profile (this firm's own stats) or
search_companies (open name search).

\- uei: 12-character Unique Entity ID
\- limit: max 50

Returns each peer's `uei`, chain into get_company_profile or check_exclusion for any
of them.

Input parameters:

- `limit` (integer)
- `uei` (string, required)

Output parameters:

- `result` (string)

### `search_entities` (~318 tokens)

Search Entities

Search ALL SAM-registered entities by name (won a federal award or not). For
companies that have actually WON an award, use search_companies instead, it has
richer award-history fields; use this one when you need the full registry, including
firms with no award history yet.

Capture & Teaming tool. `q` alone works on every plan; the other filters are Pro.

\- q: name substring, min 2 chars
\- naics: NAICS code, no Y/N suffix (Pro)
\- state: 2-letter US state (Pro)
\- business_type: SAM business-type code, e.g. "8W" (WOSB), "QF" (SDVOSB), "27"
  (self-cert SDB) (Pro), an unrecognized code returns 400 with the full valid list
\- active_only: only Active registrations (Pro)
\- naics_small: exact 6-digit NAICS code (e.g. "236220"), SBA DSBS small-business
  determination for this NAICS (Pro)
\- limit: max 100

Returns each entity's `uei`, the same identifier get_entity, get_company_profile,
check_exclusion, and get_company_contact all take as `uei`.

Input parameters:

- `active_only` (boolean)
- `business_type`
- `limit` (integer)
- `naics`
- `naics_small`
- `offset` (integer)
- `q`
- `state`

Output parameters:

- `result` (string)

### `get_entities_expiring` (~159 tokens)

Get Expiring SAM Registrations

Find SAM registrations expiring within N days, a monitoring/list question,
distinct from a name lookup. A lapsed registration makes a firm invisible to
contracting officers and ineligible for award, so this is useful both for
self-monitoring and for spotting teammates/subs whose registration needs renewal.

Capture & Teaming tool, Pro only.

\- within_days: 1-365, default 60
\- state / naics: optional narrowing filters
\- limit: max 500

Returns each entity's `uei`, chain into get_entity for the full registration record.

Input parameters:

- `limit` (integer)
- `naics`
- `offset` (integer)
- `state`
- `within_days` (integer)

Output parameters:

- `result` (string)

### `get_entity` (~138 tokens)

Get Entity

Get one SAM entity's full registration record by UEI or CAGE code, the same
question, two different keys, so this is one tool, not two.

Capture & Teaming tool. Provide exactly one of `uei` or `cage_code`.

\- uei: 12-character Unique Entity ID (from search_entities, search_companies, or any
  other tool's `uei` field)
\- cage_code: CAGE code (from a contract/award record's `cage_code` field)

Free tier (Developer). Returns the same shape either way.

Input parameters:

- `cage_code`
- `uei`

Output parameters:

- `result` (string)

### `search_partners` (~308 tokens)

Search Partners

Find teaming/partner firms with REAL past performance, by NAICS + agency + state +
set-aside, who's actually done this kind of work, not just who's registered for it.

Capture & Teaming tool, Pro only. This is the "who could I team with" question,
distinct from search_companies (open name search) or get_company_peers (similar to
ONE specific company).

\- naics: 6-digit code, exact
\- agency: name/acronym, crosswalk-resolved (e.g. "Army", "Navy", "USACE")
\- state: place-of-performance, 2-letter
\- set_aside: sdvosb | vosb | wosb | woman_owned | hubzone | 8a | sdb | minority_owned
\- psc: Product/Service Code, exact
\- keywords: matches the award description
\- limit: max 50

Returns each firm's `uei`, chain into get_company_profile, check_exclusion, or
get_company_contact. NOTE: this tool's `agencies` field is an array of sub-agency
names with no agency CODE, it does not chain into contract-level `awarding_agency_code`
filters directly.

Input parameters:

- `agency`
- `keywords`
- `limit` (integer)
- `naics`
- `offset` (integer)
- `psc`
- `set_aside`
- `state`

Output parameters:

- `result` (string)

### `get_company_contact` (~145 tokens)

Get Company Decision-Maker Contact

Resolve a vendor's REAL decision-maker contact, SAM registration agents
(third-party filing services) are filtered out, so this is the actual point of
contact at the company, not their SAM paperwork filer.

Capture & Teaming tool, Pro only. Distinct from search_contacts (finds a
CONTRACTING OFFICER at an agency, the buyer side), this is the vendor/teammate side.

\- uei: 12-character Unique Entity ID

Rate-limited more tightly than other tools (separate IP + key burst limits), avoid
calling this in a tight loop across many UEIs at once.

Input parameters:

- `uei` (string, required)

Output parameters:

- `result` (string)

### `search_contacts` (~177 tokens)

Search Contracting Officer Contacts

Look up a CONTRACTING OFFICER's contact info, the buyer side, distinct from
get_company_contact (the vendor/teammate side).

Capture & Teaming tool, Pro only (`contacts_access`). A RESOLVER, not a directory, you cannot list/browse all contacts through this tool, only look up a specific one.

Two modes, provide one:
\- name (+ optional agency, state for disambiguation): substring match, returns up to 5
\- email: exact match, returns one record, useful when you already have an email on
  file and want the current name/agency/phone for it

Returns 404 if nothing matches, 402 if the caller's plan doesn't include contacts_access.

Input parameters:

- `agency`
- `email`
- `name`
- `state`

Output parameters:

- `result` (string)

### `search_recompetes` (~521 tokens)

Search Recompetes

Find contracts entering recompete within a window, a market read for NEW business
(who else's contract is about to be up for grabs), and also useful post-award to watch
your OWN contract's expiration (see get_recompete for the single-contract form of that).

Capture & Teaming / Post-Award tool, Pro only, factual, never scored (no win-probability
guess, just the facts: option runway, offer count, incumbent history).

\- naics: exactly 6 digits
\- agency: name substring
\- ends_after_months / ends_within_months: the window, e.g. 0-18 = "ending in the next
  18 months," set ends_after_months higher (e.g. 6) to skip the too-late-to-influence band
\- date_anchor: current_end (next decision point) | potential_end (guaranteed recompete,
  all options used)
\- options_exhausted_only: true = only contracts whose options are ~exhausted (the
  high-confidence "must recompete" subset)
\- incumbent_excluded: true = only recompetes whose incumbent is CURRENTLY on the SAM
  exclusions list (can't legally win the recompete); false = only clean incumbents;
  omit for both
\- sort_by: ends_soonest | value | mod_churn | de_obligated

Returns each row's `agency_code`/`sub_agency_code` alongside the published `agency`/
\`sub_agency` names, and `award_id_piid`, pass that to get_recompete for the full
incumbent-vulnerability read, or to get_contract/get_vehicle for the raw FPDS record.
\`incumbent_uei` is the same identifier every Capture/Teaming tool takes as `uei`. NOTE:
get_recompete (the single-PIID detail form) does not yet carry agency_code/sub_agency_code,
only this search does.

Input parameters:

- `agency`
- `amount_max`
- `amount_min`
- `date_anchor` (string)
- `ends_after_months` (integer)
- `ends_within_months` (integer)
- `incumbent_excluded`
- `limit` (integer)
- `naics`
- `offset` (integer)
- `options_exhausted_only` (boolean)
- `set_aside`
- `sort_by` (string)
- `state`

Output parameters:

- `result` (string)

### `get_recompete` (~154 tokens)

Get Recompete

Get one recompeting/expiring contract by PIID, plus incumbent-vulnerability
signals (cert-lapse, lone-holder, single-agency dependence) composed from the
incumbent's DSBS certifications and FPDS obligation history.

Capture & Teaming / Post-Award tool, Pro only. Factual, signals-not-scores, no
win-probability guess. Not windowed, a direct ID lookup (unlike search_recompetes).

\- piid: from search_recompetes, get_contract, or get_vehicle

\`incumbent_uei` in the response is the same identifier every Capture/Teaming tool
takes as `uei`.

Input parameters:

- `piid` (string, required)

Output parameters:

- `result` (string)

### `get_price_benchmark` (~443 tokens)

Get Price Benchmark

Get the percentile distribution of comparable contract VALUE for a NAICS, broken
out by pricing type. A price-analysis / market-range read for the Negotiate stage,
not a win predictor. Factual, not scored.

Bid & Proposal / Negotiate tool, Pro only. Pair with get_price_position to see where
YOUR specific value sits, or get_labor_rate_benchmark for the labor-cost input.

\- naics: 6-digit code, required
\- set_aside: exact code, e.g. "8A", "SBA", "SDVOSBC", "WOSB", "HZC", "NONE"
\- psc: 1-4 alphanumeric Product/Service Code, finer scope than NAICS
\- pricing_type: pin one, e.g. "FIRM FIXED PRICE", "TIME AND MATERIALS", a rarer
  pricing arrangement can surface as a raw, undecoded single-letter FPDS code
  (e.g. "J", "Y", "Z") instead of a readable name; that's passthrough source data,
  not an error
\- agency: name / acronym / CGAC code, narrows the comparable set to that agency
\- value_basis: current (default) | potential | obligated
\- date_from/date_to: filters on the FPDS transaction's `action_date` (when a
  modification/closeout action was recorded), NOT the award date or period of
  performance, a years-old contract can appear as a "current" comparable via a
  recent action on it

IMPORTANT: pricing type shifts the median 8x-3000x within a NAICS, use the
per-pricing-type blocks (`pricing_types`), not `combined`, for a meaningful
comparable. `combined` is blended context only, not a real number to price against.

Input parameters:

- `agency`
- `date_from`
- `date_to`
- `naics` (string, required)
- `pricing_type`
- `psc`
- `set_aside`
- `value_basis` (string)

Output parameters:

- `result` (string)

### `get_price_position` (~321 tokens)

Get Price Position

Get where YOUR specific contract/bid value sits (percentile rank) against real
comparable contracts, plus a sample of the nearest ones by value.

Bid & Proposal / Negotiate tool, Pro only. This is the "is my number reasonable"
check, distinct from get_price_benchmark, which gives the market range without
placing any one number in it.

\- naics: 6-digit code, required
\- value: YOUR contract/bid value in dollars, e.g. "2200000" or "$2,200,000", required
\- set_aside / psc / pricing_type / agency / value_basis / date_from / date_to: same as
  get_price_benchmark, narrows the comparable set the same way (see its docstring for
  the `pricing_type` raw-code and `date_from`/`date_to` action_date caveats)
\- sample_limit: how many nearest comparable contracts to return, max 25

Each sample contract's `recipient_uei` and `award_id_piid` chain into
get_company_profile / get_contract for a closer look at a specific comparable.
Factual positioning, not a recommendation on what to bid.

Input parameters:

- `agency`
- `date_from`
- `date_to`
- `naics` (string, required)
- `pricing_type`
- `psc`
- `sample_limit` (integer)
- `set_aside`
- `value` (string, required)
- `value_basis` (string)

Output parameters:

- `result` (string)

### `get_labor_rate_benchmark` (~442 tokens)

Get Labor Rate Benchmark

Get the awarded labor-rate (should-cost) benchmark for a labor category, from GSA
CALC, the labor-cost input for a proposal, paired with get_price_benchmark's
contract-value read.

Bid & Proposal / Negotiate tool, Pro only.

\- labor_category: required, e.g. "Senior Software Engineer"
\- match: contains (default, substring) | exact
\- education_level: HS | AA | BA | MA | PHD | OTHER
\- min_experience / max_experience: years, 0-60
\- naics: 6-digit, via the SIN bridge
\- vendor: substring match, use for a competitor's or your own rate-card lookup
\- worksite: Customer | Contractor | Virtual
\- business_size: S (small business) | O (other than small)
\- security_clearance: Yes | No
\- value_basis: current (default) | next_year | second_year, the escalated out-year
  rate directly, a distinct enum from get_price_benchmark's current/potential/obligated
\- sample_limit: how many comparable rates to return, max 25

Use `vendor` with a specific company name (e.g. from search_companies) to check a
known competitor's or teammate's actual awarded rate card.

Response includes `rate_distribution` (hourly percentiles p10-p90 + min/max/avg),
\`escalation` (median year-over-year ceiling-rate growth for next_year and
second_year, the real input for pricing an out-year, not a guessed 2-3% flat
escalator), `category_breakdown`, and `rates_sample` (individual comparable rate rows).

Input parameters:

- `business_size`
- `education_level`
- `labor_category` (string, required)
- `match` (string)
- `max_experience`
- `min_experience`
- `naics`
- `sample_limit` (integer)
- `security_clearance`
- `value_basis` (string)
- `vendor`
- `worksite`

Output parameters:

- `result` (string)

### `search_wage_determinations` (~296 tokens)

Search Wage Determinations

Search Davis-Bacon (DBA), Service Contract Act (SCA), and CBA wage
determinations by jurisdiction, number, or revision date.

Bid & Proposal / Negotiate tool. For "which WDs apply where I'm bidding" use
get_wds_by_location instead (the compliance shortcut); use this one when you need
to browse/filter broadly or track revisions over time.

\- type: DBA | SCA | CBA
\- state: 2-letter US state code
\- county: substring
\- wd_number: substring (e.g. "AK2026", "1994-2371")
\- active_only: only currently-effective WDs
\- date_from/date_to: modified-date window, YYYY-MM-DD
\- construction_type: DBA only, Building | Heavy | Highway | Residential
\- sort_by: modified_date | publish_date | wd_number | revision_number
\- limit: max 100

Returns each WD's identifier, pass to get_wage_determination for the full
classification/rate detail.

Input parameters:

- `active_only` (boolean)
- `construction_type`
- `county`
- `date_from`
- `date_to`
- `limit` (integer)
- `offset` (integer)
- `sort_by`
- `sort_order`
- `state`
- `type`
- `wd_number`

Output parameters:

- `result` (string)

### `get_wds_by_location` (~262 tokens)

Get Wage Determinations by Location

The compliance shortcut: "I'm bidding a contract in this state/county, which
wage determinations apply?" Returns every currently-active DBA, SCA, and CBA record
covering that jurisdiction.

Bid & Proposal / Negotiate tool. Statewide DBAs are included regardless of `county`
(they apply everywhere in the state). No date filter, this answers "what's in
force here right now," not a historical query (use search_wage_determinations for that).

\- state: 2-letter US state code, required
\- county: optional; omit for statewide only
\- type: DBA | SCA | CBA, filter to one type; omit for all. Rows default-sort with
  CBA first alphabetically, which can bury the DBA/SCA coverage a construction or
  services bidder actually wants (e.g. VA/Fairfax is 47 CBA vs 6 SCA vs 5 DBA), use
  this to skip straight to the type you need instead of paging past CBAs.
\- limit: max 100

Input parameters:

- `county`
- `limit` (integer)
- `offset` (integer)
- `state` (string, required)
- `type`

Output parameters:

- `result` (string)

### `get_wage_rates` (~260 tokens)

Query Wage Rates Across Determinations

Query prevailing-wage rates ACROSS wage determinations, by occupation, "what
does a given trade actually pay," distinct from search_wage_determinations /
get_wds_by_location which answer "which WDs apply."

Bid & Proposal / Negotiate tool. Each row is one classification's hourly base wage
plus fringe, tied to the WD it came from. For the aggregated distribution/floor
across many WDs at once, use get_wage_rate_summary instead of paging through this.

\- classification: trade/occupation name substring, e.g. "Electrician"
\- type: DBA | SCA (CBAs have no rate table)
\- occupation_code: SCA 5-digit code, e.g. "23210"
\- wd_number: exact
\- state: 2-letter, via the WD's jurisdictions
\- sort_by: base_rate | classification | wd_number
\- limit: max 100

Input parameters:

- `active_only` (boolean)
- `classification`
- `limit` (integer)
- `occupation_code`
- `offset` (integer)
- `sort_by`
- `sort_order`
- `state`
- `type`
- `wd_number`

Output parameters:

- `result` (string)

### `get_wage_rate_summary` (~323 tokens)

Get Wage Rate Summary

Get the labor-cost FLOOR for one occupation, aggregated across wage
determinations: base hourly percentiles + Health & Welfare fringe + how many WDs
set it, what a services bidder needs to price loaded labor, which on an SCA
contract drives the bid far more than the award value.

Bid & Proposal / Negotiate tool, the DISTRIBUTION view, distinct from get_wage_rates
(individual county rate lines). Pair with get_labor_rate_benchmark for the awarded
(as-bid) rate comparison, this tool gives the regulatory floor instead.

\- occupation_code: SCA 5-digit code, e.g. "11150" (Janitor), "27101" (Guard), the
  precise key, prefer this when known
\- classification: name substring, e.g. "Guard", used when no occupation_code is given
\- type: SCA (default) | DBA (CBAs have no rate table)
\- state: 2-letter, scope to WDs covering that state

Response includes `distinct_classifications` (COUNT DISTINCT of matched titles), a broad `classification` substring can blend several distinct, differently-paid
titles into one distribution (e.g. "Computer" spans 10 titles from $10-$53/hr);
this discloses whether the returned label is one occupation or a blend. Prefer
\`occupation_code` over `classification` whenever the pay spread matters.

Input parameters:

- `classification`
- `occupation_code`
- `state`
- `type` (string)

Output parameters:

- `result` (string)

### `get_wage_determination` (~116 tokens)

Get Wage Determination

Get one wage determination's full record: location array, every classification's
hourly wage + fringe, and (for CBAs) the contractor/union detail block.

Bid & Proposal / Negotiate tool.

\- wd_id: the internal sgs id (e.g. "43309") OR the human-readable WD number (e.g.
  "AK20260001"), from search_wage_determinations, get_wds_by_location, or get_wage_rates

Input parameters:

- `wd_id` (string, required)

Output parameters:

- `result` (string)

### `get_vendor_risk_report` (~277 tokens)

Get Vendor Risk Report

Get a 7-signal vendor risk report for one UEI, screening facts for teaming or
subcontracting due diligence, before you commit to a partner.

Bid & Proposal / Negotiate tool, Pro only. Distinct from check_exclusion (a binary
debarment check), this is a broader risk-signal read.

\- uei: 12-character Unique Entity ID (from search_companies, search_entities,
  search_partners, or any other tool's `uei` field)

The 7 signals (under `signals`): exclusion_status, address_cluster (other entities
registered at the same address), name_variant_cluster, individual_exclusions_at_address,
wave_membership, timing_gap, dual_cage. Check `triage` first, it's a pre-computed
summary (`category`, `label`, `reasons`) so you don't have to interpret all 7 signals
yourself; `category: "clean"` with empty `reasons` means nothing surfaced.

Also includes `contract_exposure` (FPDS obligated total, distinct contracts, top
agencies) and `subaward_exposure` (as-prime/as-sub FFATA payment history), how much
is actually at stake with this vendor, alongside the risk signals themselves.

Input parameters:

- `uei` (string, required)

Output parameters:

- `result` (string)

### `search_contracts` (~437 tokens)

Search FPDS Contract Transactions

Search FPDS prime contract transactions, the comprehensive, authoritative award
record (10.6M+ transactions). For the sparse SAM Award Notice slice specifically, use
search_awards instead (see its docstring for when that's actually the right tool).

Award & Compliance tool.

\- uei / parent_uei: exact 12-char (parent_uei = corporate roll-up)
\- piid: exact award PIID; parent_piid: the vehicle/IDV it was ordered against
\- agency: name substring
\- naics: exactly 6 digits
\- award_type_code: FPDS type A | B | C | D
\- date_from/date_to: action_date window, YYYY-MM-DD
\- amount_min/amount_max: federal_action_obligation
\- sort_by: action_date | current_total_value_of_award | federal_action_obligation |
  recipient_name (default action_date). sort_order: asc | desc.
\- limit: max 250

Data coverage starts FY2025 (~2024-10-01) and cannot go earlier on any plan, a
\`date_from` before that floor is silently clamped, not rejected; the response's
\`window` block (`clamped`, `earliest_searchable`, `reason`) discloses what actually
ran. Contrast search_vehicles, which is NOT floored this way.

Returns each transaction's `award_id_piid`, pass that to get_contract for the full
roll-up, get_contract_modifications for the full history, or get_contract_vehicle for
what vehicle it's under. `recipient_uei` chains into every Capture/Teaming tool.

Input parameters:

- `agency`
- `amount_max`
- `amount_min`
- `award_type_code`
- `date_from`
- `date_to`
- `limit` (integer)
- `naics`
- `offset` (integer)
- `parent_piid`
- `parent_uei`
- `piid`
- `sort_by`
- `sort_order`
- `uei`

Output parameters:

- `result` (string)

### `get_contract` (~212 tokens)

Get Contract

Get one contract's LATEST transaction plus a roll-up of obligation/value totals
across every modification.

Award & Compliance tool. This is the SUMMARY view, for every individual
modification row use get_contract_modifications; for what vehicle it's under use
get_contract_vehicle.

\- piid: award PIID (from search_contracts, search_recompetes, or a company's award
  history)

Top-level keys: `contract` (the latest transaction), `transaction_rollup` (counts +
obligated/value totals across every modification, transaction_count, total_obligated,
max/latest current and potential value, first/latest action date), and `subaward_rollup`
(Pro only; who this prime paid as subs, subaward_count, total_subcontracted,
distinct_sub_vendors, top_subs; a legitimate `subaward_count: 0` means no subs, not
an error). All three are siblings, not nested inside `contract`.

Input parameters:

- `piid` (string, required)

Output parameters:

- `result` (string)

### `get_contract_modifications` (~193 tokens)

Get Contract Modifications

Get EVERY transaction row for a contract, oldest action first, the full
modification trail (amendments, options exercised, partial terminations), not just
the latest snapshot get_contract gives you.

Award & Compliance tool. There's no per-request date filter, but the underlying data
itself only carries FY2025 onward, a contract whose real history predates that floor
will start mid-sequence (e.g. first row `P00026`, not `P00001`), with earlier
modifications simply never ingested, not filtered out. Check the response's `window`
block (`clamped`, `earliest_searchable`, `reason`) before treating the returned rows
as the complete history.

\- piid: award PIID
\- limit: max 500

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `piid` (string, required)

Output parameters:

- `result` (string)

### `get_contract_vehicle` (~167 tokens)

Get the Vehicle Behind a Contract

Get the contract vehicle (IDIQ, GWAC, FSS schedule, or BPA) this order was placed
against.

Award & Compliance tool. Returns the vehicle's own PIID, chain into get_vehicle for
the vehicle's own ceiling/period detail, or get_vehicle_holders to see who else can
compete for orders on it.

\- piid: the ORDER's PIID (not the vehicle's own PIID), from search_contracts or get_contract

If the contract was awarded directly, not against a vehicle, returns
\`{status: "standalone", vehicle: null, message: ...}` instead, check `status` before
reading `vehicle.award_id_piid` or chaining into get_vehicle.

Input parameters:

- `piid` (string, required)

Output parameters:

- `result` (string)

### `search_vehicles` (~333 tokens)

Search Vehicles

Search contract vehicles: IDIQs, GWACs, FSS schedules, BPAs, BOAs.

Award & Compliance tool. Vehicles are long-lived and NOT limited to a rolling
window the way prime-contract search is, a GWAC awarded years ago is still the
vehicle you must hold today to compete for its orders.

\- uei/parent_uei: vehicle holder, exact 12-char
\- piid: vehicle PIID, exact
\- idv_type: IDC | FSS | BPA | GWAC | BOA
\- active_only: only vehicles whose period of performance hasn't ended
\- ceiling_min/ceiling_max: potential_total_value_of_award. A ceiling of `999999999999`
  (or `.99`) is FPDS's own placeholder for "no negotiated ceiling" (typical on GSA
  MAS/GWAC-style vehicles), not a literal dollar figure.
\- limit: max 250

Returns each vehicle's `award_id_piid`, pass to get_vehicle for detail or
get_vehicle_holders (Pro) to see who holds it and who's actually earning through it.

Input parameters:

- `active_only`
- `agency`
- `ceiling_max`
- `ceiling_min`
- `date_from`
- `date_to`
- `idv_type`
- `limit` (integer)
- `naics`
- `offset` (integer)
- `parent_uei`
- `piid`
- `sort_by`
- `sort_order`
- `uei`

Output parameters:

- `result` (string)

### `get_vehicle` (~266 tokens)

Get Vehicle Detail

Get one contract vehicle's detail: ceiling, period, and what's been ordered
through it.

Award & Compliance tool.

\- piid: vehicle's own PIID (from search_vehicles or get_contract_vehicle)

Also returns a `vehicle_family` block (`is_multiple_award`, `piid_count`,
\`solicitation_identifier`, `note`) disclosing whether this PIID is one award among
several placed under the same solicitation, distinct from get_vehicle_holders' own
\`vehicle_family.piids`, which lists every sibling PIID; this one only counts them.
NOTE: `transaction_rollup.distinct_awardees` / `orders_rollup.distinct_holders` above
are scoped to THIS piid only and read `1` even when `vehicle_family.is_multiple_award`
is true (FPDS gives every awardee of a multi-award vehicle its own separate PIID), use get_vehicle_holders for the real family-wide count. A ceiling of `999999999999`
(or `.99`) is FPDS's own placeholder for "no negotiated ceiling" (typical on GSA
MAS/GWAC-style vehicles), treat it as effectively unlimited, not a literal ~$1T figure.

Input parameters:

- `piid` (string, required)

Output parameters:

- `result` (string)

### `get_vehicle_holders` (~266 tokens)

Get Vehicle Holders

Get who holds a vehicle AND who's actually earning through it, two distinct
populations, don't conflate them: a firm can hold a vehicle for years and earn
nothing on it.

Award & Compliance tool, Pro only. The "can I even compete for this work" answer, on a multi-award vehicle, only holders can bid task orders.

\- piid: vehicle's own PIID (from search_vehicles or get_contract_vehicle)
\- limit: max 250

Returns `awardees` (hold the vehicle) and `earners` (have actually been paid through
it) as separate lists with counts (`awardee_count`/`earner_count`), on a real
multi-award vehicle these can be wildly different (e.g. 1,596 awardees, 2 earners),
which is the whole point of the distinction. Each entry's `recipient_uei` chains into
Capture/Teaming tools. Also returns `vehicle_family.piids`: this rolls up EVERY
related PIID under the same vehicle family, not just the one you asked for, so
\`awardee_count` reflects the whole family, not a single order.

Input parameters:

- `limit` (integer)
- `piid` (string, required)

Output parameters:

- `result` (string)

### `search_subawards` (~312 tokens)

Search Subawards

Search FFATA subawards: who primes paid as subcontractors.

Award & Compliance tool. For a single company's subs-paid or primes-that-paid-them
reverse lookups, use get_prime_subawards / get_prime_relationships instead, narrower
and simpler when you already have one UEI.

\- prime_uei / sub_uei: exact 12-char
\- piid: the PRIME contract's PIID
\- naics: exactly 6 digits
\- sub_name: substring, min 3 chars
\- limit: max 250

Data coverage starts FY2025 (~2024-10-01) and cannot go earlier on any plan, a
\`date_from` before that floor is silently clamped, not rejected; the response's
\`window` block (`clamped`, `earliest_searchable`, `reason`) discloses what actually
ran.

NOTE: this table has no `cage_code` field, you cannot CAGE-cross-check a
subawardee through this tool, only by UEI/name.

Input parameters:

- `agency`
- `amount_max`
- `amount_min`
- `date_from`
- `date_to`
- `limit` (integer)
- `naics`
- `offset` (integer)
- `piid`
- `prime_uei`
- `sort_by`
- `sort_order`
- `sub_name`
- `sub_uei`

Output parameters:

- `result` (string)

### `get_subaward` (~61 tokens)

Get Subaward

Get one FFATA subaward report by its SAM report ID.

Award & Compliance tool.

\- subaward_sam_report_id: UUID, from search_subawards or a company's subaward list

Input parameters:

- `subaward_sam_report_id` (string, required)

Output parameters:

- `result` (string)

### `get_prime_subawards` (~182 tokens)

Get Prime Subawards

Get every subaward THIS company (as a prime) paid out, "who did they
subcontract to."

Award & Compliance tool. The opposite direction from get_prime_relationships (who
paid THIS company as a sub), both use the same `uei`, pick based on which
direction you're asking.

\- uei: 12-character Unique Entity ID (the PRIME's UEI)
\- limit: max 250

Includes a `summary` block (total_subaward_amount, distinct_sub_vendors,
distinct_prime_contracts, first/last subaward date) alongside the paginated `data`
rows, read `summary` first rather than summing the page yourself.

Input parameters:

- `date_from`
- `date_to`
- `limit` (integer)
- `offset` (integer)
- `uei` (string, required)

Output parameters:

- `result` (string)

### `get_prime_relationships` (~145 tokens)

Get Prime Relationships

Get every prime that has paid THIS company as a subcontractor, "who
subcontracts to them," the opposite direction from get_prime_subawards.

Award & Compliance tool.

\- uei: 12-character Unique Entity ID (the SUB's UEI)
\- limit: max 250

Includes a `summary` block (total_received, distinct_primes, top_primes, first/last
subaward date) alongside the paginated `data` rows, read `summary` first.

Input parameters:

- `date_from`
- `date_to`
- `limit` (integer)
- `offset` (integer)
- `uei` (string, required)

Output parameters:

- `result` (string)

### `search_protests` (~310 tokens)

Search Protests

Search GAO bid protests: who protested, on which solicitation, when, and the
outcome.

Award & Compliance tool. `status=Open` is the live set (still pending before GAO,
the award may be under a performance stay); filter to `outcome=Sustained` for
protests that actually disturbed an award.

\- protester: the firm that FILED the protest (use this, not `search`, for
  competitor research, `search` also matches the agency column)
\- search: full-text over protester, agency, solicitation number, file number
\- case_number: GAO case, e.g. "B-424433", returns every docket on that case
\- outcome: Denied | Dismissed | Sustained | Withdrawn | Granted
\- status: Open | Closed
\- sort: recent (default) | oldest | filed | due (due = soonest statutory deadline first)
\- limit: max 100

Factual, never scored. Returns each protest's solicitation number, pass to
get_protests_on_solicitation for every protest on that same procurement.

Input parameters:

- `agency`
- `case_number`
- `case_type`
- `filed_from`
- `filed_to`
- `limit` (integer)
- `offset` (integer)
- `outcome`
- `protester`
- `search`
- `sort` (string)
- `status`

Output parameters:

- `result` (string)

### `get_protests_on_solicitation` (~238 tokens)

Get Protests on a Solicitation

Get every protest filed on ONE solicitation, the contestability read for a
specific opportunity or award: any protest pending right now, and the statutory date
GAO must decide by.

Award & Compliance tool, Pro only.

\- solicitation_number: from search_opportunities, search_contracts, or search_protests

Returns `any_open` and `any_sustained` (pre-computed booleans, check these first
before scanning the `protests` list yourself) and `earliest_open_due_date` (the
nearest statutory deadline among any still-pending protest on this solicitation).

Resolves the WHOLE GAO case: if your `solicitation_number` matches any docket of a
case, this returns every docket across all solicitation-number spellings GAO
recorded for that case (GAO sometimes records one case differently across its own
dockets, e.g. an `RFQ-` prefix present on some rows, absent on others), two
different, both-real spellings for the same case return the identical, complete set.

Input parameters:

- `solicitation_number` (string, required)

Output parameters:

- `result` (string)

### `resolve_identifier` (~158 tokens)

Resolve DUNS to UEI

Resolve between legacy DUNS (9 digits, or 13-digit DUNS+4) and current UEI
(12 alphanumeric), accepts either side, returns both plus the entity name.

Free tier.

\- identifier: a DUNS or a UEI

COVERAGE TRUTH: built from FFATA subaward filings since FY2025 where both
identifiers co-exist (~24K firms indexed). A 404 means "not in this FFATA-derived
crosswalk," NOT "not in SAM", the official SAM DUNS↔UEI translator is admin-gated
and not publicly available, so a 404 here is inconclusive, not a negative proof.

Input parameters:

- `identifier` (string, required)

Output parameters:

- `result` (string)

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/govconapi-govconapi/govconapi-mcp#diagnostics

## Score history

- 2026-09-21: 76
- 2026-09-20: 76
- 2026-09-19: 75
- 2026-09-18: 75
- 2026-09-17: 74
- 2026-09-16: 74
- 2026-09-15: 73
- 2026-09-14: 58
- 2026-09-13: 72
- 2026-09-12: 72
- 2026-09-11: 72
- 2026-09-10: 71
- 2026-09-09: 71
- 2026-09-08: 70
- 2026-09-07: 70
- 2026-09-06: 66
- 2026-09-05: 66
- 2026-09-04: 66
- 2026-09-03: 66
- 2026-09-02: 66
- 2026-09-01: 66
- 2026-08-31: 39

## Common questions

### What is the GovCon API MCP server?

GovCon API is an MCP server listed in the public MCP registry as io.github.govconapi/govconapi. 53 tools over US federal procurement: SAM.gov, FPDS awards, entities, subawards, exclusions. This page covers its PyPI package (govconapi-mcp).

### Is the GovCon API MCP server safe to use?

GovCon API scores 76 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 21 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the GovCon API MCP server expose?

GovCon API exposes 53 tools: search_opportunities, get_opportunity, recent_changes, lookup_agency, check_exclusion, and 48 more. Their descriptions and schemas cost roughly 13,229 tokens of context every time the server is loaded.

### Is the GovCon API MCP server still maintained?

GovCon API is still listed as active in the MCP registry. We last reached this channel on 21 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the GovCon API MCP server under?

GovCon API declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/govconapi-mcp/
- Socket report: https://socket.dev/pypi/package/govconapi-mcp
- Repository: https://github.com/govconapi/govconapi-mcp
- Website: https://govconapi.com/mcp
- Changelog RSS feed: https://verifymcp.io/servers/govconapi-govconapi/govconapi-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/govconapi-govconapi/govconapi-mcp.json
- HTML version of this page: https://verifymcp.io/servers/govconapi-govconapi/govconapi-mcp
