Skip to main content
Glama

search-grants

Search for government grants using keywords to find funding opportunities, eligibility details, and deadlines.

Instructions

Search for government grants based on keywords

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query for grants (e.g., 'Artificial intelligence', 'Climate change')
pageNoPage number for pagination (default: 1)
grantsPerPageNoNumber of grants per page (default: 3)

Implementation Reference

  • Executes the 'search-grants' tool: parses arguments, queries the grants.gov API via POST request with filters and pagination, handles responses, errors, and formats output using helper functions.
    if (request.params.name === "search-grants") { try { const args = request.params.arguments as { query?: string; page?: number; grantsPerPage?: number } | undefined; const searchQuery = args?.query ? String(args.query).trim() : "Artificial intelligence"; const page = args?.page || 1; const grantsPerPage = args?.grantsPerPage || 3; console.error(`Debug: Starting search with query: ${searchQuery}, page: ${page}, grantsPerPage: ${grantsPerPage}`); const url = 'https://api.simpler.grants.gov/v1/opportunities/search'; const searchData = { filters: { opportunity_status: { one_of: ["forecasted", "posted"] } }, pagination: { order_by: "opportunity_id", page_offset: page, page_size: grantsPerPage, sort_direction: "descending" }, query: searchQuery }; const response = await axios.post<GrantsAPIResponse>(url, searchData, { headers: { 'accept': 'application/json', 'X-Auth': API_KEY, 'Content-Type': 'application/json' } }); if (!response.data?.data) { return { content: [{ type: "text", text: "No results found or invalid response format" }] }; } const grants = response.data.data; if (grants.length === 0) { return { content: [{ type: "text", text: `No grants found matching "${searchQuery}"` }] }; } const summaryText = createSummary(grants, searchQuery, page, grantsPerPage); return { content: [{ type: "text", text: summaryText }] }; } catch (error) { console.error('Debug: Error occurred:', error); if (axios.isAxiosError(error)) { console.error('Debug: Axios error response:', error.response?.data); return { content: [{ type: "text", text: `API Error: ${error.response?.data?.message || error.message}` }] }; } return { content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}` }] }; } }
  • Input schema definition for the 'search-grants' tool, specifying query (required), page, and grantsPerPage parameters.
    inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query for grants (e.g., 'Artificial intelligence', 'Climate change')" }, page: { type: "number", description: "Page number for pagination (default: 1)" }, grantsPerPage: { type: "number", description: "Number of grants per page (default: 3)" } }, required: ["query"] }
  • src/index.ts:121-146 (registration)
    Registers the 'search-grants' tool in the MCP server's listTools handler, including its name, description, and input schema.
    server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [{ name: "search-grants", description: "Search for government grants based on keywords", inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query for grants (e.g., 'Artificial intelligence', 'Climate change')" }, page: { type: "number", description: "Page number for pagination (default: 1)" }, grantsPerPage: { type: "number", description: "Number of grants per page (default: 3)" } }, required: ["query"] } }] }; });
  • Helper function to format detailed information for a single grant into a structured text block.
    const formatGrantDetails = (grant: Grant) => { return ` OPPORTUNITY DETAILS ------------------ Title: ${grant.opportunity_title} Opportunity Number: ${grant.opportunity_number} Agency: ${grant.agency_name} (${grant.agency_code}) Status: ${grant.opportunity_status} FUNDING INFORMATION ------------------ Award Floor: ${grant.summary.award_floor ? `$${grant.summary.award_floor.toLocaleString()}` : 'Not specified'} Award Ceiling: ${grant.summary.award_ceiling ? `$${grant.summary.award_ceiling.toLocaleString()}` : 'Not specified'} Category: ${grant.category} DATES AND DEADLINES ------------------ Posted Date: ${grant.summary.post_date || 'N/A'} Close Date: ${grant.summary.close_date || 'N/A'} CONTACT INFORMATION ------------------ Agency Contact: ${grant.summary.agency_contact_description || 'Not provided'} Email: ${grant.summary.agency_email_address || 'Not provided'} Phone: ${grant.summary.agency_phone_number || 'Not provided'} ELIGIBILITY ------------------ ${grant.summary.applicant_eligibility_description ? grant.summary.applicant_eligibility_description.replace(/<[^>]*>/g, '').trim() : 'Eligibility information not provided'} ADDITIONAL INFORMATION ------------------ More Details URL: ${grant.summary.additional_info_url || 'Not available'} Description: ${grant.summary.summary_description ? grant.summary.summary_description.replace(/<[^>]*>/g, '').trim() : 'No description available'} ========================================================================== `; };
  • Helper function to create a paginated summary of grant search results, using formatGrantDetails for each grant.
    const createSummary = (grants: Grant[], searchQuery: string, page: number = 1, grantsPerPage: number = 3) => { const startIdx = (page - 1) * grantsPerPage; const endIdx = startIdx + grantsPerPage; const displayedGrants = grants.slice(startIdx, endIdx); const totalPages = Math.ceil(grants.length / grantsPerPage); return `Search Results for "${searchQuery}": OVERVIEW -------- Total Grants Found: ${grants.length} Showing grants ${startIdx + 1} to ${Math.min(endIdx, grants.length)} of ${grants.length} Page ${page} of ${totalPages} DETAILED GRANT LISTINGS ---------------------- ${displayedGrants.map(formatGrantDetails).join("\n")} Note: Showing ${grantsPerPage} grants per page. Total grants available: ${grants.length} `; };
Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Tar-ive/grants-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server