About grantsgov-mcp-server
grantsgov-mcp-server provides access to U.S. federal funding opportunities listed by Grants.gov. It supports opportunity searches, detailed record review, and lookup of filter reference codes without an API key.
Key features
- 01Search opportunities by keywords and filters
- 02Read eligibility, funding, dates, and attachments
- 03Look up agencies and filter reference codes
- 04Review forecasted, posted, closed, and archived notices
Use cases
- 01Find grants matching an agency or applicant type
- 02Review eligibility and award details before applying
- 03Track opportunities nearing their closing dates
MCP support
Exposes Grants.gov opportunity search, full-record retrieval, and reference-code lookup tools to MCP clients. The `grantsgov-guide` skill is also available as an MCP resource.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://grantsgov.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-grantsgov https://grantsgov.caseyjhand.com/mcp{"mcpServers":{"cyanheads-grantsgov":{"type":"http","url":"https://grantsgov.caseyjhand.com/mcp"}}}Open in Cursor{"servers":{"cyanheads-grantsgov":{"type":"http","url":"https://grantsgov.caseyjhand.com/mcp"}}}Open in VS Code{"mcpServers":{"cyanheads-grantsgov":{"type":"http","url":"https://grantsgov.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-grantsgov":{"serverUrl":"https://grantsgov.caseyjhand.com/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
Tools
3| Parameter | Type | Required | Description |
|---|---|---|---|
| sort | enum | No | Result order: relevance (best keyword match; needs keyword, otherwise the order is arbitrary), open_date_desc/open_date_asc (posting date), close_date_asc/close_date_desc (close date; no close date sorts last on asc), opportunity_number_asc/_desc, agency_asc/_desc. Default: relevance with a keyword, else open_date_desc.relevance | open_date_desc | open_date_asc | close_date_asc | close_date_desc | opportunity_number_asc | opportunity_number_desc | agency_asc | agency_desc |
| limit | integer | No | Rows per page (1-100). |
| offset | integer | No | Zero-based row offset for paging; use next_offset from the previous page. |
| keyword | string | No | Full-text search over title, description, opportunity number, and agency. Bare terms are all required (rural broadband = rural AND broadband); join alternatives with OR, quote phrases ("mental health"), exclude with NOT or -term, and use a trailing * for prefixes (broad*). OR mixed with AND or with bare terms must be grouped in parentheses, e.g. (rural OR tribal) broadband; an ungrouped mix is rejected. A word with an internal hyphen or period (COVID-19, K-12) is matched as a phrase. Field prefixes (agency:NSF, cfda:93.866) are rejected: use the agencies, assistance_listing, or other filter instead. See grantsgov_list_reference topic keyword_syntax. |
| agencies | array | No | Agency codes from grantsgov_list_reference topic agencies (e.g. HHS, HHS-NIH11, NSF). A code includes its sub-agencies. Case-insensitive. Any listed agency matches. |
| statuses | array | No | Lifecycle statuses to include: forecasted, posted, closed, archived. Default: forecasted and posted. |
| eligibilities | array | No | Two-digit applicant-type codes from grantsgov_list_reference topic eligibilities (e.g. 12 = nonprofits with 501(c)(3) status, 07 = federally recognized tribal governments), as strings or numbers. A single digit is zero-padded (7 = 07). Any listed type matches. |
| include_facets | boolean | No | Include facet counts per filter value. Set false when paging to save space. |
| assistance_listing | string | No | One assistance listing number (ALN, formerly CFDA), e.g. 93.866 or 93866, in any case. Only one value is supported. |
| funding_categories | array | No | Funding category codes from grantsgov_list_reference topic funding_categories (e.g. HL = Health, ED = Education). Case-insensitive. Any listed category matches. |
| opportunity_number | string | No | Exact agency-assigned opportunity number (e.g. HRSA-27-005), matched case-insensitively; one pair of surrounding double quotes is removed. Numbers are not unique across agencies, so several rows can match. To look up a number across every status, prefer grantsgov_get_opportunity with opportunity_numbers. |
| posted_within_days | integer | No | Only opportunities posted in the last N days (1-3650). Works only with the forecasted and posted statuses. |
| closing_within_days | integer | No | Only posted opportunities closing between today and N days from today, US Eastern (0-365; 0 = closing today). Searches posted opportunities in close-date order, so statuses may only be posted and sort only close_date_asc. |
| funding_instruments | array | No | Funding instruments: G (grant), CA (cooperative agreement), PC (procurement contract), O (other). Any listed instrument matches. |
| include_unrestricted | boolean | No | When eligibilities is set, also match opportunities open to any applicant type (code 99), which the specific codes do not cover. Set false to see only opportunities targeted at the listed types. |
Details
From the project README@cyanheads/grantsgov-mcp-server
Search Grants.gov federal funding opportunities, read full records (eligibility, awards, deadlines, attachments), and decode filter codes via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://grantsgov.caseyjhand.com/mcp
Overview
US federal funding opportunities from Grants.gov, covering every agency's forecasted, posted, closed, and archived notices. Search by keyword, agency, applicant type, funding category, assistance listing, or deadline window, then read a full record: award range, eligibility, key dates, agency contact, and NOFO attachments. No API key required.
Tools
| Tool | Description |
|---|---|
grantsgov_search_opportunities | Search opportunities by keyword and filters; each row leads with its close date and days left, plus facet counts for narrowing |
grantsgov_get_opportunity | Read full records for up to 5 opportunities by numeric id or opportunity number |
grantsgov_list_reference | List the codes the search filters take (agencies, applicant types, funding categories and instruments), plus statuses, sort options, and keyword syntax |
The grantsgov-guide skill covers funding shortlists, eligibility and deadline review, and application requirements. It ships with the package and plugins and is available over MCP as skill://grantsgov-guide/SKILL.md.
Capability reference
grantsgov_search_opportunities tool
- Filters:
keyword,statuses(defaultforecastedandposted),agencies(a code includes its sub-agencies),eligibilities,funding_categories,funding_instruments,assistance_listing(one ALN),opportunity_number(exact match),posted_within_days,closing_within_days eligibilitiesalso matches opportunities open to any applicant type (code99) unlessinclude_unrestrictedisfalse- Keyword terms are all required; join alternatives with
OR, quote phrases, exclude withNOTor-term, and use a trailing*for prefixes. An ungrouped AND/OR mix or a field prefix (agency:NSF) fails asinvalid_keyword closing_within_days(0–365) scans posted opportunities by close date; it allows only thepostedstatus and theclose_date_ascsort, andposted_within_daysrejectsclosedandarchived(filter_conflict).total_count_kinddistinguishes exact counts from lower bounds when the scan is incomplete;next_offsetreaches only remaining scanned matches- Up to 100 rows per page (default 25);
limitaccepts 1–1,000 and values above 100 are capped with a notice. Offset paging usesnext_offset;effective_keywordandapplied_filtersecho what was sent. Sub-agency facets count each subtree under the current upstream query;include_facets: falsedrops the facet counts - Rows carry
close_date_kind(fixed,none_listed,placeholder) anddays_until_close, but no award amounts. Unknown codes fail asunknown_agency,unknown_eligibility, orunknown_funding_category
grantsgov_get_opportunity tool
- Accept up to 50 nonblank entries per identifier list and 50 normalized unique identifiers combined. Read the first 5 identifiers, ids before numbers;
deferred_ids,deferred_numbers, and an executablecontinuationcarry the remaining queue with the original section offsets. Numbers resolve across all four statuses; selected aliases fetch a record once per call - A miss or a number shared by several opportunities comes back in
unresolved[]asnot_foundorambiguous(withcandidates), not as an error - Records carry the close date (an estimate on forecasts, flagged by
close_date_is_estimate), award ceiling and floor, total funding, expected awards, cost sharing, applicant types with the eligibility narrative, assistance listings, and the agency contact - Funding and eligibility fields come from the synopsis or forecast block matching
doc_type, named inmoney_source; forecasts addforecast_estimates - Independent pages: description 12,000 characters, eligibility narrative 6,000, funding-category explanation 2,000, attachments 30, application packages 10, and related opportunities 10. The six zero-based inputs are
description_offset,eligibility_offset,funding_category_explanation_offset,attachment_offset,application_package_offset, andrelated_opportunity_offset(default 0). Each record'spagessupplies full totals and executable single-opportunity continuations; partial narratives retain*_truncated, and past-end pages are empty. Attachments includedownload_urland the unchanged upstreamcreated_datewhen listed last_revision_noteandlast_revision_changedsummarize the active synopsis or forecast's latest revision when listed. Changed names map to public fields; unknown names keep anupstream:prefix. Missing metadata does not mean nothing changed
grantsgov_list_reference tool
topic:agencies,eligibilities,funding_categories,funding_instruments,statuses,sort_options, orkeyword_syntax- Codes come from a live Grants.gov snapshot, cached for 24 hours and dated by
snapshot_date, withopen_count(forecasted and posted) andtotal_countper code (statusescarriestotal_countonly);sort_optionsandkeyword_syntaxare static - Up to 100 entries per page (default 50);
limitaccepts 1–1,000 and values above 100 are capped with a notice. Filters apply before paging;continuationpreserves the complete next-call arguments - A failed refresh can serve expired data with
reference_cachedisclosing stale status, the failure reason, and retry time. Searches using that vocabulary disclose the same degradation and snapshot timestamp agencieslists the top level by default;parent_codelists every code under one agency, andname_containsmatches labels and codes on any topic (for agencies, at every level)parent_codewith another topic fails asfilter_not_applicable; an unknown code fails asunknown_parent_code
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
Grants.gov-specific:
- List inputs accept one whole string or an array; blank values and members read as unset. Strings are never split on commas, spaces, or line breaks
- Keyless client for the Grants.gov REST API (
search2,fetchOpportunity), with retries and at most 4 concurrent upstream requests per process - Inputs mapped to the form Grants.gov reads as intended: bare keyword terms joined with
AND, hyphenated tokens (COVID-19,K-12) matched as phrases, agency codes expanded to their sub-agency subtree, opportunity numbers matched literally, and filter codes checked against the live vocabulary - Deadlines counted from today in US Eastern Time, the zone Grants.gov publishes in; far-future stand-in close dates are flagged
placeholderrather than reported as deadlines - HTML5 entities decoded in human-readable fields; narrative HTML converted to plain text with table cell and row boundaries preserved. In
content[], agency prose renders as literal text, identifiers retain code styling, multi-line fields render as blockquotes, and inline text is flattened to one line
Agent-friendly output:
- Echo of what ran:
effective_keywordandapplied_filters, including defaulted statuses, the expanded agency filter, and the added code99 - Discriminated fields:
close_date_kind,doc_type,money_source, andunresolved[].outcomelet callers branch on data - Empty-result and paging notices that name the next call, such as counts of closed and archived matches when the default statuses found nothing, or the next close date when a closing window is empty
- Typed failure reasons with recovery hints, including
upstream_unavailable,rate_limited, andupstream_route_unavailablefor Grants.gov outages
Getting started
Connect to the hosted instance, no install:
claude mcp add --transport http grantsgov-mcp-server https://grantsgov.caseyjhand.com/mcp
Or run it locally:
claude mcp add grantsgov-mcp-server -- npx -y @cyanheads/grantsgov-mcp-server
For other clients, add this to the MCP config file:
{
"mcpServers": {
"grantsgov-mcp-server": {
"command": "npx",
"args": ["-y", "@cyanheads/grantsgov-mcp-server"]
}
}
}
No API key is required. For Docker or a source build, see Running the server.
Configuration
The server reads no configuration of its own: the Grants.gov API is keyless and its endpoints are fixed. These framework variables control transport, auth, and logging.
| Variable | Description | Default |
|---|---|---|
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | HTTP server port. | 3010 |
MCP_SESSION_MODE | HTTP session mode: stateless, stateful, or auto. The server declares stateless; set this only to override it. | stateless |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (debug, info, warning, error, etc.). | info |
LOGS_DIR | Directory for log files (Node.js only). | <app-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry. | false |
See .env.example for the full list of optional overrides.
Running the server
Local development
Requires Bun v1.4.0 or higher (or Node.js v24+) and network access to api.grants.gov.
-
Clone and install:
git clone https://github.com/cyanheads/grantsgov-mcp-server.git cd grantsgov-mcp-server && bun install cp .env.example .env # optional framework overrides -
Build and run the production version:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdio -
Run checks and tests:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
Docker
docker run --rm -p 3010:3010 ghcr.io/cyanheads/grantsgov-mcp-server:latest
The image defaults to HTTP transport, stateless session mode, and logs to /var/log/grantsgov-mcp-server. To run over stdio from an MCP client, use "command": "docker" with "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/grantsgov-mcp-server:latest"]. To build locally, docker build -t grantsgov-mcp-server .; OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point: registers the tools and published skill, and starts and disposes the Grants.gov service. |
src/mcp-server/tools/definitions | Tool definitions (*.tool.ts). |
src/mcp-server/tools | Shared input schemas (input-schemas.ts) and format() rendering helpers (render.ts). |
src/services/grants-gov | Grants.gov API client, keyword compiler, reference snapshot, date and money normalization, HTML-to-text. |
tests/ | Unit and tool tests mirroring src/, with trimmed Grants.gov response fixtures. |
skills/ | Published guidance for agents reviewing federal funding opportunities. |
docs/design.md | Design notes: probed API behavior and the decisions behind the tool surface. |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
- Handlers throw, framework catches — no
try/catchin tool logic - Use
ctx.logfor logging andctx.failwith the tool's declared error reasons - Register new tools in
src/mcp-server/tools/definitions/index.ts - Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Data source
Opportunity data comes from Grants.gov, where federal agencies post their funding opportunities. The records are US government works. This project is not affiliated with or endorsed by Grants.gov or any federal agency.
License
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.