DEV Community

Loomwise
Loomwise

Posted on

Give Your AI Agent Live Federal Contract Data with the Apify MCP Server

By Loomwise

Language models don't know what SAM.gov posted this morning. Ask one for "open small-business set-asides for janitorial work in Virginia" and you'll get a confident guess or a request to go look yourself. The Model Context Protocol (MCP) fixes this by giving the agent a tool it can call for live data.

This tutorial connects an MCP client to the Apify MCP server, loads a single tool that reads SAM.gov's public daily opportunities extract, and covers prompts, cost limits and scheduling. The setup follows Apify's MCP documentation as of October 2026 (docs.apify.com/mcp).

What you need

  • An MCP client that supports remote servers, such as an AI coding assistant, an IDE with MCP support, or a desktop chat app. Apify keeps client-specific instructions in its docs and has a configurator at https://mcp.apify.com/.
  • An Apify account, so the agent can run tools. Discovery works without one (see Step 4).

Step 1: Connect with only the tools you need

The hosted server lives at https://mcp.apify.com and uses Streamable HTTP. The recommended sign-in is OAuth: on first connect your browser opens, you sign in to Apify and approve access, and no token is stored in the client config.

Load only what the agent needs instead of the default tool set. Apify's docs recommend listing tools explicitly in production, so behavior doesn't change when defaults do.

{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com/?tools=fetch-actor-details,loomwise/federal-opportunities"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The tools query parameter does the work here:

  • loomwise/federal-opportunities exposes that one Actor as a callable tool.
  • fetch-actor-details lets the agent read the tool's input schema, output schema, README and pricing before it calls the tool.
  • When an Actor tool is loaded, the server automatically adds get-actor-run, get-dataset-items, get-key-value-store-record and abort-actor-run, so the agent can read results and stop a runaway run.

Other ways to connect (all from Apify's docs):

  • Bearer token instead of OAuth: add "headers": { "Authorization": "Bearer <APIFY_TOKEN>" }, using a token from Settings → API & Integrations in Apify Console. Treat it like a password.
  • Apify CLI: apify mcp install <client> (e.g. apify mcp install cursor) writes the config for you.
  • Desktop chat apps that don't accept a remote URL in their config file: add https://mcp.apify.com as a custom connector in the app instead.
  • Local stdio for clients without remote support: npx -y @apify/actors-mcp-server with APIFY_TOKEN in the environment. It needs Node.js 18+. Note that inferred output schemas are only available on the hosted server.

Restart the client and confirm the tools appear.

Step 2: Ask a real question

Try a prompt that maps cleanly onto the tool's filters:

Find open SAM.gov solicitations posted in the last 7 days for NAICS 238220 (plumbing/HVAC contractors) with a Service-Disabled Veteran-Owned Small Business set-aside, performed in Texas or Oklahoma. Keep it to 50 results. Show title, agency, response deadline (with timezone) and the SAM.gov link, sorted by deadline.

A well-behaved agent will:

  1. Call fetch-actor-details and read the input schema.
  2. Call the Actor tool with an input like this:
{
  "naicsCodes": ["238220"],
  "setAsideTypes": ["SDVOSBC"],
  "placeOfPerformanceStates": ["TX", "OK"],
  "noticeTypes": ["Solicitation", "Combined Synopsis/Solicitation"],
  "postedWithinDays": 7,
  "excludeExpired": true,
  "maxResults": 50
}
Enter fullscreen mode Exit fullscreen mode
  1. Read the rows with get-dataset-items and give you a table.

Each row has the same fields you'd get in a spreadsheet export: id, source, title, solicitationNumber, agency/subAgency/office, noticeType, naicsCode, classificationCode, setAsideCode/setAside, postedDate, responseDeadline (with timezone offset), archiveDate, popCity/popState/popZip/popCountry, link, and a descriptionSnippet with emails and phone numbers removed. Contact names aren't included. Grant-only fields (fundingInstrument, assistanceListings, awardCeiling, awardFloor) are null for contracts.

Prompts that work well

  • Give codes, not vibes. "NAICS 5415 prefix" beats "IT stuff". naicsCodes accepts prefixes, so 5415 matches every 5415xx code. If you don't know your codes, ask the agent to suggest some, then you confirm them.
  • Use the set-aside codes from the schema: SBA (total small business), 8A, HZC (HUBZone), SDVOSBC, WOSB, EDWOSB, VSA, or NONE for unrestricted. The agent can read the full list via fetch-actor-details.
  • Ask for early signals: add "Sources Sought" and "Presolicitation" to the notice types.
  • De-duplicate amendments: ask for dedupeBySolicitation: true if you only want the latest notice per solicitation number.
  • Include grants when relevant: includeGrants: true adds Grants.gov opportunities in the same schema. NAICS, set-aside, state and notice-type filters don't apply to grants, so tell the agent to filter grants by keyword or agency.
  • Watch the state filter: with placeOfPerformanceStates set, notices without a listed place of performance are excluded. Tell the agent if you want those too.

Step 3: Put guardrails on cost

This Actor is pay-per-event: $2 per 1,000 results plus Apify's small Actor-start fee. A 50-row answer costs about ten cents. To keep an agent from running up a bill:

  • Cap results in the input. maxResults stops the run at that many rows, and it's the most direct limit for this tool.
  • Cap the run itself. If your agent uses the generic call-actor tool (in the actors category), pass maxTotalChargeUsd, maxItems, timeout or memory in callOptions, not in the Actor input. Apify's docs note that fields with those names inside the input don't cap the run.
  • Tell the agent the rule. Add to your system prompt: "Before any paid tool call, state the expected maximum cost and wait for confirmation if it's over $0.50." Apify's own agent quickstart says to state the cost before the first paid run.

Step 4: Discovery without an account (optional)

If you only want an agent to find the right Actor and explain its inputs, without running anything, connect with only the discovery tools:

https://mcp.apify.com?tools=search-actors,fetch-actor-details,search-apify-docs,fetch-apify-docs
Enter fullscreen mode Exit fullscreen mode

According to Apify's docs, this works with no API token. Running Actors and reading storage always need authentication. search-actors ranking follows factors similar to Apify's Actor quality score, so a search like "SAM.gov contract opportunities" may return several options. Have the agent compare them with fetch-actor-details.

Step 5: Make it recurring

A chat answer is a one-off. To get the same answer every morning, either:

  • Create a task and schedule in Apify Console (e.g. cron 0 8 * * * in your timezone, with postedWithinDays: 2 and de-duplication on id downstream). SAM.gov regenerates the extract once a day, overnight US time, so morning runs pick up the previous day's notices. Or:
  • Let the agent do it. Add the tasks and schedules tool categories to the URL (?tools=fetch-actor-details,loomwise/federal-opportunities,tasks,schedules) and ask it to "save this search as a task and schedule it daily at 8:00 America/New_York." Those tools can create, change and delete schedules, so review what the agent creates.

Production notes

  • Pin your tool list in the URL, as above, so default changes don't surprise you.
  • Rate limit: the hosted server allows up to 30 requests per second per user and returns 429 above that. Add retries if you fan out.
  • Telemetry: the hosted server collects anonymous tool-usage telemetry by default. Append telemetry-enabled=false to the URL to opt out.
  • Freshness: each run reads the latest daily extract. The run's RUN_SUMMARY record shows the source file's timestamp, so ask the agent to report it if freshness matters.
  • Keep a human in the loop for bid decisions. The agent summarizes a ~300-character snippet. Always open link and read the full notice and attachments before deciding to bid.

Disclosure: we built the tool used here, the SAM.gov Contract Opportunities Scraper & Feed on Apify ($2 per 1,000 results). The MCP setup above works the same way for any Actor in Apify Store.

Top comments (0)