A self-hosted MCP server that provides access to live US federal funding opportunities from grants.gov. Exposes tools for searching grants, checking eligibility, ranking opportunities by fit, and monitoring deadlines. Designed for voice integration with Alexa+.
Opportunity Radar demonstrates solid tool design with clear, action-oriented naming (find_, check_, rank_) and comprehensive parameter descriptions. All 6 tools have documented input schemas with types and descriptions. Descriptions are well-crafted (100-250 chars), explaining WHEN to use each tool and what it returns. Error handling via _guard() pattern is present but generic. Output schemas are partially documented in code but not formally exposed. Main gaps: no tool annotations (readOnlyHint/destructiveHint), no pagination support despite potential for large result sets, and output field naming could be more consistent (e.g., 'opportunities' vs 'closing_soon' vs 'top').
Check whether a given kind of applicant is actually allowed to apply. `applicant_type` is plain language: "individual", "small business", "nonprofit", "city government", "university". This reads the official applicant list published with the notice — it does not guess.
List matching opportunities whose deadline falls inside the next N days. This answers "what do I have to act on this week". Opportunities with no published close date are counted separately rather than silently dropped.
Find currently open funding opportunities matching a plain-language interest. Use this for questions like "any grants for a small AI company?" or "what's open for rural health right now?". `interest` is free text and is matched against opportunity titles and descriptions.
Get the full picture for one opportunity: award size, who may apply, dates. Call this after `find_opportunities` when the person asks about a specific one, e.g. "tell me more about the second one".
Rank live opportunities by how well they fit YOU, with a reason for each. `profile` is one sentence about the applicant: "solo developer building AI tools for small clinics". `interest` narrows the search first; leave it empty to reuse the profile as the search term. Fit scores are judged by a model on Amazon Bedrock; every deadline and dollar figure attached to a result still comes from grants.gov.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). All tools are read-only but this is not formally declared in the MCP schema, forcing LLMs to infer safety from descriptions alone.
Output schemas not formally documented in MCP tool registration. Code shows return structures (dicts with 'error', 'opportunities', 'eligible', etc.) but these are not exposed as JSON Schema in the tool definition, limiting LLM planning.
No pagination support. find_opportunities and deadline_watch return up to 60 items but lack offset/limit or cursor parameters. Large result sets risk context window exhaustion.
Inferred effective spec: 2025-06-18+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | 2025-06-18+ | v2 |
Build this week's radar sweep across several interests at once. `interests` is a comma-separated list such as "ai, small business, clean energy". This is what the scheduled background run calls; it returns the raw material for a spoken summary, already filtered to things still open.
Error handling is generic. _guard() catches SourceError and returns a fixed 'source_unavailable' message. No guidance on retry strategy, partial results, or recovery steps for LLM.
Inconsistent output field naming. find_opportunities returns 'opportunities' array; deadline_watch returns 'closing_soon'; weekly_briefing returns raw material. No consistent naming convention for result lists.