Skip to main content
Glama
README.md
# fedvendor

SAM.gov is where the US federal vendor world is registered,
excluded, solicited and awarded — and it is spread across
half a dozen public APIs with different habits. fedvendor
wraps them in one client: twenty tools covering entity
registrations, debarment records, live contract
opportunities, award history, the federal org chart, FFATA
subaward reports and product/service codes, all behind a
single SAM.gov API key.

Most tools hand back the upstream JSON exactly as SAM.gov
sent it. The three awards tools are the exception: they
return a normalized `{"awardSummary": [...],
"totalRecords": int}` shape, so modifications, search hits
and deleted records all read the same way.

## Configuration

- `SAM_API_KEY` (required for the nineteen data tools) —
  your SAM.gov public API key, sent on every request as
  the `api_key` query parameter. When it is not set, every
  data tool fails with `SAM_API_KEY is not set` and no
  request is made. SAM.gov keys expire every 90 days; a
  401 or 403 reply says so and points at the regeneration
  page. `get_access_status` works without a key — reporting
  that state is its whole job.
- `SAM_API_BASE_URL` (optional) — API base URL. Defaults
  to `https://api.sam.gov`.

Country codes follow ISO 3166-1 alpha-3, as the underlying
APIs expect.

## Tools

Entities (Entity Management v3):

- `lookup_entity_by_uei` — one entity by `uei`.
  `include_sections` chooses the response sections and
  defaults to `entityRegistration,coreData`.
- `lookup_entity_by_cage` — one entity by `cage`, with
  the same section handling.
- `search_entities` — flexible search by
  `legal_business_name`, `primary_naics`, `state`
  (physical-address state), `business_type_code`,
  `sba_business_type_code` and `registration_status`, with
  `page` and `size`. The API's page size is capped at 10
  and the cap is enforced client-side: a `size` outside
  1–10 fails with `size must be an integer between 1 and
  10` before any request.
- `get_entity_reps_and_certs` — FAR/DFARS representations
  and certifications for a `uei`. These sections are never
  included by an `All` section request, so they have
  their own tool; `entityRegistration` is always included
  alongside.
- `get_entity_integrity_info` — FAPIIS proceedings
  (integrity information) for a `uei`, likewise requested
  explicitly with `entityRegistration`.

Exclusions (v4):

- `check_exclusion_by_uei` — is this `uei` debarred?
- `search_exclusions` — search by `name`,
  `classification` and `agency`, paginated with `page`
  and `size` (this API paginates by `size`, not `limit`).

Contract opportunities (v2):

- `search_opportunities` — search by `keyword` (title),
  `naics_code`, `psc_code`, `notice_type`, `state` and
  `zip`, with posted-date (`posted_from` / `posted_to`)
  and response-deadline (`response_from` / `response_to`)
  ranges in MM/dd/yyyy, plus `limit` and `offset`. The
  `agency_keyword` filter is applied locally after the
  response arrives — the API silently ignores its
  department parameters — by keeping only results whose
  `fullParentPathName` contains the keyword,
  case-insensitively.
- `get_opportunity_description` — the HTML description
  for a `notice_id`.

Contract awards (v1) — all three return the normalized
awards shape described above:

- `search_contract_awards` — search by `agency_id`,
  `naics_code`, `fiscal_year` and `piid`, with an award
  date range (`award_date_from` + `award_date_to`,
  MM/dd/yyyy) sent as one bracket-range parameter.
  Pagination is `limit` (1–100) and `offset`.
- `lookup_award_by_piid` — every modification for one
  `piid`.
- `search_deleted_awards` — deleted award records, for
  audit trails.

Federal Hierarchy (v1):

- `search_federal_organizations` — search the org chart
  by `fh_org_id`, `name`, `org_type` (shorthand values
  such as `DEPARTMENT` and `AGENCY` are accepted),
  `status`, `agency_code` and `cgac`. The response keeps
  the upstream lowercase `totalrecords` / `orglist` keys.
- `get_organization_hierarchy` — the children of one
  organization, by `fh_org_id`.

FFATA subawards — dates are ISO yyyy-MM-dd, pagination is
`page_number` / `page_size`:

- `search_acquisition_subawards` — subcontract reports,
  filtered by `piid`, `referenced_idv_piid`, `agency_id`
  and `status`.
- `search_assistance_subawards` — grant subaward
  reports, filtered by `fain`, `prime_award_key`,
  `agency_code` and `status`.

PSC codes:

- `lookup_psc_code` — the full record for one `psc_code`.
- `search_psc_free_text` — discover codes by free-text
  `query`.

Composite:

- `vendor_responsibility_check` — a one-shot FAR 9.104-1
  responsibility check for a `uei`: the entity lookup and
  the exclusion lookup in a single call, returned as
  `{"uei", "entity", "exclusions", "flags"}`. The flags
  are composed locally — `entity_not_found`,
  `registration_inactive`, `excluded`, or `clear` when
  none of the others apply.
- `get_access_status` — credential readiness: whether
  `SAM_API_KEY` is configured, the 90-day key expiry, and
  the daily request limits by account type (10 for
  non-federal users without a SAM.gov role, 1000 with a
  role or a federal personal account, 10000 for federal
  system accounts). Makes no request.

Validation fails before any request with a specific
message: `<arg> must be a non-empty string` for required
strings, the size/limit range messages above,
`<arg> must use MM/dd/yyyy` for opportunity and award
dates, and `<arg> must use yyyy-MM-dd` for subaward
dates. Other upstream non-2xx replies fail with
`sam.gov error: HTTP <status>` and an unreachable API
with `sam.gov unreachable`.

### Labelled reconstructions

The tool surface, the base URLs and the documented
parameter names come from the SAM.gov API documentation
and the original tool's published description. A few
details are reconstructions, labelled as such:
`get_access_status`'s name follows the vendor family's
published pattern for credential checks; the exclusions
endpoint's `ueiSAM` parameter, the Federal Hierarchy
parameter names, the awards bracket-range parameter
name, the PSC endpoint's `searchby=keyword` value, the
awards wire names for `agency_id` / `naics_code` /
`fiscal_year`, and the composite tool's flag strings are
renderings of the documented behaviour rather than
verbatim-pinned names. MCP argument names are snake_case
renderings of the documented wire names throughout.

## CLI

Each tool is a subcommand taking one JSON argument string:

```bash
export SAM_API_KEY="<your key>"
npx @reneturcios/fedvendor lookup_entity_by_uei '{"uei":"ABC123XYZ"}'
npx @reneturcios/fedvendor lookup_entity_by_cage '{"cage":"1A2B3"}'
npx @reneturcios/fedvendor search_entities '{"legal_business_name":"Acme","size":5}'
npx @reneturcios/fedvendor get_entity_reps_and_certs '{"uei":"ABC123XYZ"}'
npx @reneturcios/fedvendor check_exclusion_by_uei '{"uei":"ABC123XYZ"}'
npx @reneturcios/fedvendor search_opportunities '{"keyword":"software","agency_keyword":"defense"}'
npx @reneturcios/fedvendor search_contract_awards '{"fiscal_year":"2026","limit":10}'
npx @reneturcios/fedvendor lookup_award_by_piid '{"piid":"W91ZLK24P0001"}'
npx @reneturcios/fedvendor search_federal_organizations '{"org_type":"DEPARTMENT"}'
npx @reneturcios/fedvendor lookup_psc_code '{"psc_code":"D399"}'
npx @reneturcios/fedvendor vendor_responsibility_check '{"uei":"ABC123XYZ"}'
npx @reneturcios/fedvendor get_access_status '{}'
npx @reneturcios/fedvendor --version
```

Output is the tool's result text (the upstream JSON on
success). Exit codes: `0` on success, `1` on a runtime
error (including a validation, missing-key or upstream
failure), `2` on a usage error.

## MCP server

```bash
npx -y @reneturcios/fedvendor mcp
```

MCP client config (provide the key through the client's
environment):

```json
{
  "mcpServers": {
    "fedvendor": {
      "command": "npx",
      "args": ["-y", "@reneturcios/fedvendor", "mcp"],
      "env": {
        "SAM_API_KEY": "<your key>"
      }
    }
  }
}
```

## Docker

```bash
docker run -i -e SAM_API_KEY="<your key>" ghcr.io/cloudcorprecords/fedvendor
docker run --rm -e SAM_API_KEY="<your key>" ghcr.io/cloudcorprecords/fedvendor get_access_status '{}'
```

## Development

```bash
npm install
npm run build   # tsc -> dist/
npm test        # tsx --test test/*.test.ts (fake fetch only, no network)
npm run dev     # run the CLI from source
```

## License

MIT — Copyright (c) 2026 Rene Turcios