Grants Qualification MCP Server
Pricing
from $50.00 / 1,000 tool calls
Grants Qualification MCP Server
Report what a US federal grant agency actually states about who may apply, and screen an applicant type against it. Three outcomes, and 'qualified' is not one of them.
Pricing
from $50.00 / 1,000 tool calls
Rating
0.0
(0)
Developer
NexGen Watch
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
2 days ago
Last modified
Share
🧰 Grants Qualification MCP Server
An MCP server that puts US federal grant eligibility on Grants.gov in front of an AI agent. Connect it to your assistant and it can search current grant opportunities, pull everything an agency states about who may apply, and screen an applicant type against that opportunity — reporting exactly what the agency says, and nothing it doesn't.
What it does not do: it does not tell you that you qualify, that you will be funded, or that an application will be approved, and it is not legal advice. It reports the agency's own words and can rule an applicant out on the agency's coded list. The final eligibility decision always lives in the official opportunity notice.
This is a standby MCP server: it stays warm on Apify and answers tool calls from any MCP client (Claude Desktop, Cursor, an agent framework) at https://nexgenwatch--grants-qualification-mcp.apify.actor/mcp. Billing is pay-per-event: $0.05 when the server starts, then $0.05 per tool call (mcp-tool-call). Source: api.grants.gov.
No login, no source API key and no CAPTCHA solving are involved: the source is read logged-out.
Who it's for
- Grant consultants monitoring newly posted opportunities for their clients each week.
- Nonprofits screening which federal programs are worth a closer look before investing staff time.
- Universities and research teams tracking funding relevant to a department or PI.
- Vendors and market teams watching government-funded markets open up.
- Economic-development teams following what federal money is flowing into their sector or region.
It's built to be reconnected on a schedule, not used once. New opportunities post continuously and agencies edit eligibility language often, so the useful pattern is a recurring check — a weekly sweep for new opportunities and approaching deadlines — rather than a one-time lookup.
📊 Sample Output
A standby server answers tool calls rather than writing a dataset, so the sample is the server's own live health answer (GET https://nexgenwatch--grants-qualification-mcp.apify.actor/, HTTP 200, read on 2026-09-17) followed by its tool table:
{"server": "grants-qualification","billing_gate": true,"declared_events": ["apify-actor-start","mcp-tool-call"],"scope": "US federal discretionary grants published on Grants.gov. One jurisdiction -- UK Find a Grant was probed and its documented API paths 404, so it is not covered and this server does not imply otherwise.","rate_limit_per_sec": 5.0,"rate_waits": 0,"ready": true}
| Tool | Arguments | What it returns |
|---|---|---|
find_opportunities | `keyword: str | None = None, agency_code: str |
get_eligibility | opportunity_id: int | Everything the agency states about who may apply to one opportunity: the coded applicant types, the free-text eligibility narrative, cost-sharing, award range and close date. Critically, it reports whether the coded list |
screen_applicant | opportunity_id: int, applicant_type_id: str | Screen one applicant type against one opportunity. Returns one of three outcomes — CLEAR_MISMATCH, NOT_EXCLUDED_BY_THE_CODED_LIST, or CANNOT_DETERMINE. It never returns 'qualified': the narrative carries conditions no co |
explain_outcomes | `` | What each screening outcome means, and why this server will not say 'qualified'. Read this before acting on a screen_applicant result. |
✅ What you get
4 tools, each returning a JSON object built only from what the source answered, with a scope and note field stating what the source does and does not cover. A lookup the source answers with 'not found' is a sourced answer (charged); malformed input or a source failure returns a notice that is NOT charged; nothing is ever fabricated.
Connect the server
This Actor runs in Apify Standby mode as an MCP server over Streamable HTTP. You connect an
MCP client to the server's URL with the path /mcp and authenticate with your Apify API token as a
Bearer token.
Server URL
https://nexgenwatch--grants-qualification-mcp.apify.actor/mcp
Confirm the exact hostname on the Actor's Standby tab in Apify Console — that tab shows the authoritative URL and endpoint for your account. Get your API token from Apify Console → Settings → Integrations.
Client configuration (Claude Desktop, Cursor, and other clients that support a remote Streamable-HTTP MCP server with headers):
{"mcpServers": {"grants-qualification": {"url": "https://nexgenwatch--grants-qualification-mcp.apify.actor/mcp","headers": {"Authorization": "Bearer YOUR_APIFY_API_TOKEN"}}}}
Replace YOUR_APIFY_API_TOKEN with your own token. Keep the token private — treat it like a
password: don't paste it into shared files, screenshots, or a URL query string, and don't commit it to
source control. Prefer the Authorization header shown above over putting the token in the URL, so it
doesn't end up in logs.
Clients differ in how they add a remote MCP server (some read the JSON above directly; others have a form where you paste the URL and the header). If your client only speaks a different transport, use one that supports Streamable HTTP with request headers.
Tools
The server exposes four tools. A successful tool call is billed once (see Pricing); calls that
fail on bad input, a missing opportunity, or a Grants.gov error return a short notice and are not
billed.
find_opportunities
Find currently posted US federal grant opportunities.
| argument | type | required | default | notes |
|---|---|---|---|---|
keyword | string | no | (none) | free-text search |
agency_code | string | no | (none) | e.g. an agency's Grants.gov code |
limit | integer | no | 20 | clamped to the range 1–100 |
Example call
{ "keyword": "journalist training", "limit": 5 }
Example response (shape)
{"query": { "keyword": "journalist training", "agency_code": null },"total_matching": 42,"returned": 1,"opportunities": [{"opportunity_id": "363318","opportunity_number": "PAS-JAKARTA-FY26-09","title": "National Disaster Coverage Training for Indonesian Journalists","agency": "Department of State","agency_code": "DOS-JAK","open_date": "07/20/2026","close_date": "08/28/2026","status": "posted","opportunity_url": "https://www.grants.gov/search-results-detail/363318"}],"scope": "US federal discretionary grants published on Grants.gov. One jurisdiction ...","note": "This server reports what the agency states ... It CANNOT determine that you qualify ..."}
total_matching is the full count on Grants.gov; returned is how many this call brought back, so you
can see when results were capped by limit. A search that finds nothing returns returned: 0 and is
still a billed answer (it's a sourced "none"). Take an opportunity_id from here into the next tools.
get_eligibility
Everything the agency states about who may apply to one opportunity.
| argument | type | required | notes |
|---|---|---|---|
opportunity_id | integer | yes | the numeric id from find_opportunities |
Example call
{ "opportunity_id": 363318 }
Example response (shape)
{"opportunity_id": "363318","opportunity_number": "PAS-JAKARTA-FY26-09","title": "National Disaster Coverage Training","opportunity_url": "https://www.grants.gov/search-results-detail/363318","applicant_types": [{ "id": "25", "description": "Others (see text field entitled \"Additional Information on Eligibility\")" }],"applicant_type_ids": ["25"],"eligibility_narrative": "The following organizations are eligible to apply:- Indonesia-based non-profit organizations","structured_list_defers_to_narrative": true,"deferral_reason": "the agency's coded applicant-type list points at the free-text eligibility field ...","cost_sharing_required": false,"award_ceiling": "25000","award_floor": "15000","expected_number_of_awards": "1","close_date": "2026-08-28-00-00-00","posted_date": "2026-07-20-00-00-00","cfda": [ { "number": "19.040", "program": "Public Diplomacy Programs" } ],"category": "Discretionary"}
The key field is structured_list_defers_to_narrative. When it's true, the agency's coded list
points at the free-text narrative — so the coded list is not the operative rule, and you must read
eligibility_narrative.
screen_applicant
Screen one applicant type against one opportunity. Returns one of three outcomes — and "qualified" is never one of them (see Outcomes).
| argument | type | required | notes |
|---|---|---|---|
opportunity_id | integer | yes | the numeric id from find_opportunities |
applicant_type_id | string | yes | a Grants.gov coded applicant-type id, e.g. "12" |
Example call
{ "opportunity_id": 363318, "applicant_type_id": "25" }
Example response (shape)
{"opportunity_id": "363318","opportunity_number": "PAS-JAKARTA-FY26-09","opportunity_url": "https://www.grants.gov/search-results-detail/363318","applicant_type_id": "25","screening": {"outcome": "CANNOT_DETERMINE","because": "the agency's coded applicant-type list points at the free-text eligibility field ...","read_this": "The following organizations are eligible to apply:- Indonesia-based non-profit organizations","coded_list": [ { "id": "25", "description": "Others (see text field ...)" } ]},"close_date": "2026-08-28-00-00-00","cost_sharing_required": false,"is_a_determination": false,"note": "This server reports what the agency states ... It CANNOT determine that you qualify ..."}
is_a_determination is always false — a deliberate, standing reminder that this is research help,
not an eligibility ruling.
explain_outcomes
What each screening outcome means and why there is no "qualified" outcome. Takes no arguments. Useful
to call once so your agent interprets screen_applicant results correctly. Note: like any
completed tool call, this one is billed at the standard tool-call rate — its content is also
reproduced in the Outcomes section below, which you can read here for free.
{}
Outcomes
Grants.gov states eligibility in two places that are not equivalent: a coded applicantTypes list
and a free-text narrative. The narrative routinely carries geography, sector, prior-award, and
partnership conditions that no coded list can express. screen_applicant therefore returns one of:
| outcome | meaning |
|---|---|
CLEAR_MISMATCH | the applicant type is not in the agency's coded list — the one clear negative the coded list supports |
NOT_EXCLUDED_BY_THE_CODED_LIST | the type appears in the list. Not a determination that you qualify — the narrative may add conditions |
CANNOT_DETERMINE | the coded list defers to the prose, states no types at all, or no type was supplied — read the narrative |
Why there is no "qualified". When an opportunity's coded type is, for example, "Others (see text
field)" while the prose restricts it to a specific group, screening on the coded list alone would tell
the wrong applicant it's eligible. So when the coded list defers to prose, the server returns
CANNOT_DETERMINE and hands back the narrative to read. In every case, verify eligibility in the
official opportunity notice before applying.
Source & freshness
All data comes from Grants.gov, the official US federal government grants system, through its public API — no key required:
- Search2 API — https://grants.gov/api/common/search2
- fetchOpportunity API — https://grants.gov/api/common/fetchopportunity
- API guide — https://grants.gov/api/api-guide
Every result includes the original opportunity_url on Grants.gov so you can open the authoritative
notice. Each opportunity reflects Grants.gov at the moment of the call; opportunities post and change
continuously, which is why a recurring check is the intended use.
Scope: US federal discretionary grants on Grants.gov — one jurisdiction. Requests are paced to Grants.gov at a steady rate on every call.
⚙️ Sample inputs
1. Connect an MCP client (Claude Desktop / Cursor style config; your Apify API token goes in the header):
{"mcpServers": {"grants-qualification-mcp": {"url": "https://nexgenwatch--grants-qualification-mcp.apify.actor/mcp","headers": {"Authorization": "Bearer <YOUR_APIFY_TOKEN>"}}}}
2. One tool call over JSON-RPC (what the client sends to /mcp; each call is one mcp-tool-call event):
{"jsonrpc": "2.0","id": 1,"method": "tools/call","params": {"name": "find_opportunities","arguments": {"keyword": "<keyword>","agency_code": "<agency_code>","limit": 20}}}
3. Health check from a shell (free — no tool call is charged):
$curl -H "Authorization: Bearer $APIFY_TOKEN" https://nexgenwatch--grants-qualification-mcp.apify.actor/
🧾 JSON sample record
The live health record above is the server's own answer; a tool result carries the fields listed in the tool table plus scope and note.
🔧 How it works
Source. api.grants.gov — endpoints: https://api.grants.gov/v1/api/fetchOpportunity, https://api.grants.gov/v1/api/search2. Public, logged-out reads only.
Standby. Apify keeps one server process warm; each MCP session is served by that process and idle servers are stopped by the platform. Nothing is cached between calls except what the source itself caches.
Charging. Every tool call charges one mcp-tool-call at $0.05 through Apify's pay-per-event billing before the answer is returned; the declared events are asserted against the live pricing at startup (billing_gate in the health answer).
What is not done. No login, no CAPTCHA bypass, no private data, no scraping of pages the source does not publish to any visitor.
💰 Pricing example
| Event | Free | Bronze | Silver | Gold |
|---|---|---|---|---|
Actor Start (apify-actor-start) | $0.05 | $0.05 | $0.05 | $0.05 |
Tool call (mcp-tool-call) | $0.05 | $0.05 | $0.05 | $0.05 |
- 10 tool calls in one session: $0.05 start + 10 × $0.05 = $0.55
- 100 tool calls in one session: $0.05 start + 100 × $0.05 = $5.05
- 1000 tool calls in one session: $0.05 start + 1000 × $0.05 = $50.05
A health check or a connection that makes no tool call charges only the $0.05 start fee. A sourced 'not found' answer is a completed tool call and is charged; a notice for malformed input or a source failure is not charged (settle() charges only chargeable outcomes).
⚖️ Legal & ToS
The server reads public data published by api.grants.gov to any visitor, identifies itself, and does not access accounts or private data. Use the answers in line with the source's terms and your local law; the intended use is B2B research and agent tooling.
❓ FAQ
Q: Do I need a source API key?
A: No. api.grants.gov is read logged-out. You need only your Apify API token to connect to the server.
Q: Which MCP clients work?
A: Any client that speaks the MCP HTTP transport: Claude Desktop, Cursor, Windsurf, LangChain/LlamaIndex MCP adapters and Apify's own MCP client. Point it at the /mcp URL above.
Q: What happens when the source has no answer?
A: A sourced 'not found' (for example a 404 for an unknown identifier) comes back as an answer with scope and note explaining what was checked (where the server carries those fields), and is charged as a completed call; malformed input or a source outage returns a notice that is not charged. Nothing is invented.
Q: How is a call billed?
A: One mcp-tool-call event per tool call at $0.05, plus $0.05 when the server starts. Idle time is not billed to you.
Q: Is it rate limited?
A: The server paces requests to the source (RATE_PER_SEC=5.0) and answers calls in the order they arrive.
Q: Can I call it without an MCP client?
A: Yes — the /mcp endpoint is plain JSON-RPC over HTTP (sample input 2), and GET / is a free health check.
🆘 Troubleshooting
- 401 / 403 from the server → the Authorization header is missing or the token is wrong → use
Bearer <your Apify API token>. - 400
Missing session ID→ the client hit/mcpwithout initialising an MCP session → let the MCP client connect (it performs the handshake); raw JSON-RPC needs the session header the initialise call returns. - Tool returns a notice instead of data → the input was malformed or empty, or the source failed → the call was not charged; check the
note/reasonfield, fix the input and call again. - First call is slow → the standby server was cold and Apify started it → later calls in the same session are fast.
🔗 Related Actors
- FDIC Bank Diligence MCP Server — Answer questions about US banks from the FDIC's public data: institution details, structural history, current status, closures and failures - for vet…
- Federal Award Counterparty MCP Server — Answer questions about US federal award recipients from USAspending.gov: who won awards from an agency, one organisation's award history, and who tha…
- Federal Rule Impact MCP Server — Answer 'what regulations changed for this industry' from the US Federal Register: search and retrieve rules, proposed rules and notices by CFR title,…
- Official Travel Advice MCP Server — MCP server for UK FCDO foreign travel advice from the official GOV.UK Content API — safety warnings, entry and health requirements, and update histor…
- Procurement Evidence MCP Server — Locate the public procurement record behind a claim across the UK, EU and US. Every row carries the awarding body's own record id and a direct public…
- Research Funding Landscape MCP Server — Answer 'who funds research on this topic' across two public government registers: US National Science Foundation awards and UK Research and Innovatio…
- 🏢 About NexGenData — NexGen Watch is NexGenData's fleet of 256 public monitoring and lookup actors built on official sources, pay-per-result. Browse the catalog at apify.com/nexgenwatch.
⭐ Found this useful?
If this server answered a question your agent could not, a quick review on the Apify Store helps other teams find it. Feature request or a source that changed? Open it from the Issues tab — every one is read.
