Skip to main content
Glama
briancasteel

Charity MCP Server

by briancasteel

list-organizations

Retrieve nonprofit organizations from the IRS database with updated tax-exempt status or filing information since a specified date to track recent changes or access bulk organization data.

Instructions

List nonprofit organizations from the IRS database that have been updated since a specified date. This tool retrieves organizations that have had changes to their tax-exempt status or filing information.

Parameters: - since: ISO date string (required) - Get organizations updated since this date (e.g., "2024-01-01T00:00:00Z") Returns detailed information about organizations including: - Basic information (EIN, name, address) - Tax status and classification details - Financial information (revenue, assets) - Filing requirements and ruling dates Use this tool to get bulk organization data or track recent changes to nonprofit status.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sinceYesISO date string to get organizations updated since this date (e.g., '2024-01-01T00:00:00Z')

Implementation Reference

  • Implements the tool execution: parses input with Zod schema, applies rate limiting, fetches organizations from CharityAPI updated since the given date, maps and formats the response data into markdown, handles errors.
    export async function handleListOrganizations(args: unknown): Promise<CallToolResult> { try { logger.debug("List organizations requested", { args }); // Validate input const input = ListOrganizationsInputSchema.parse(args); logger.debug("Input validated", { input }); // Check rate limit if (!(await rateLimiter.checkRateLimit('list_organizations'))) { const resetTime = rateLimiter.getResetTime('list_organizations'); const resetDate = new Date(resetTime).toISOString(); return { content: [ { type: "text", text: `Rate limit exceeded for list organizations. Please try again after ${resetDate}.`, } as TextContent, ], isError: true, }; } // Make API call logger.info("Listing organizations", { since: input.since.toISOString() }); const response = await charityAPIClient.listOrganizations(input.since); if (!response.data) { throw new CharityAPIError("No data returned from CharityAPI", 404); } // Handle the response data - it should be an array or single organization const organizations = Array.isArray(response.data) ? response.data : [response.data]; // Format response const output: ListOrganizationsOutput = { organizations: organizations.map(org => ({ ein: org.ein, name: org.name, city: org.city, state: org.state, zip: org.zip, street: org.street, status: org.status, classification: org.classification, subsection: org.subsection, foundation: org.foundation, activity: org.activity, organization: org.organization, deductibility: org.deductibility, ruling: org.ruling, taxPeriod: org.tax_period, revenueAmount: org.revenue_amt, incomeAmount: org.income_amt, assetAmount: org.asset_amt, })), since: input.since, }; // Create formatted text response const formattedText = formatListOrganizationsResponse(output, input); logger.info("List organizations completed successfully", { resultCount: output.organizations.length, since: input.since.toISOString() }); return { content: [ { type: "text", text: formattedText, } as TextContent, ], }; } catch (error) { logger.error("List organizations failed", { args, error }); const mcpError = handleMCPError(error); return { content: [ { type: "text", text: mcpError.message, } as TextContent, ], isError: true, }; } }
  • Zod schema for validating and parsing the tool input parameter 'since' as a date.
    export const ListOrganizationsInputSchema = z.object({ since: z.string() .refine((dateStr) => { const date = new Date(dateStr); return !isNaN(date.getTime()); }, "Since must be a valid ISO date string") .transform((dateStr) => new Date(dateStr)), });
  • MCP tool specification including name, description, and input schema for protocol compliance.
    export const LIST_ORGANIZATIONS_TOOL = { name: "list-organizations", description: ` List nonprofit organizations from the IRS database that have been updated since a specified date. This tool retrieves organizations that have had changes to their tax-exempt status or filing information. Parameters: - since: ISO date string (required) - Get organizations updated since this date (e.g., "2024-01-01T00:00:00Z") Returns detailed information about organizations including: - Basic information (EIN, name, address) - Tax status and classification details - Financial information (revenue, assets) - Filing requirements and ruling dates Use this tool to get bulk organization data or track recent changes to nonprofit status. `.trim(), inputSchema: { type: "object" as const, properties: { since: { type: "string", description: "ISO date string to get organizations updated since this date (e.g., '2024-01-01T00:00:00Z')", format: "date-time", }, }, required: ["since"], }, };
  • Registers the tool with the MCP server: adds to listTools response and dispatches calls to the handler via switch statement.
    export function registerAllTools(server: Server) { try { // Register tools list handler server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ CHARITY_LOOKUP_TOOL, PUBLIC_CHARITY_CHECK_TOOL, CHARITY_SEARCH_TOOL, LIST_ORGANIZATIONS_TOOL, ], })); // Register tool call handler server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; switch (name) { case CHARITY_LOOKUP_TOOL.name: return await handleCharityLookup(args); case PUBLIC_CHARITY_CHECK_TOOL.name: return await handlePublicCharityCheck(args); case CHARITY_SEARCH_TOOL.name: return await handleCharitySearch(args); case LIST_ORGANIZATIONS_TOOL.name: return await handleListOrganizations(args); default: throw new Error(`Unknown tool: ${name}`); } }); logger.info("All charity tools registered successfully", { tools: [ CHARITY_LOOKUP_TOOL.name, PUBLIC_CHARITY_CHECK_TOOL.name, CHARITY_SEARCH_TOOL.name, LIST_ORGANIZATIONS_TOOL.name, ], }); } catch (error) { logger.error("Failed to register tools", { error }); throw error; } }
  • Helper function to format the API response into a user-friendly markdown string listing organization details.
    function formatListOrganizationsResponse(output: ListOrganizationsOutput, input: ListOrganizationsInput): string { const { organizations, since } = output; let response = `# Organizations List\n\n`; // Query summary response += `**Updated Since:** ${since.toISOString()}\n`; response += `**Results:** ${organizations.length} organizations found\n\n`; if (organizations.length === 0) { response += `No organizations found that have been updated since ${since.toISOString()}.\n`; response += `Try using an earlier date to see more results.\n`; return response; } // Organizations listing organizations.forEach((org, index) => { response += `## ${index + 1}. ${org.name}\n`; response += `**EIN:** ${org.ein}\n`; // Address information const addressParts = [org.street, org.city, org.state, org.zip].filter(Boolean); if (addressParts.length > 0) { response += `**Address:** ${addressParts.join(', ')}\n`; } // Status and classification if (org.status) { response += `**Status:** ${getStatusDescription(org.status)}\n`; } if (org.subsection) { response += `**Subsection:** 501(c)(${org.subsection})\n`; } if (org.classification) { response += `**Classification:** ${org.classification}\n`; } if (org.foundation) { response += `**Foundation Code:** ${org.foundation}\n`; } // Financial information if (org.revenueAmount && org.revenueAmount !== '0') { response += `**Revenue:** $${formatCurrency(org.revenueAmount)}\n`; } if (org.assetAmount && org.assetAmount !== '0') { response += `**Assets:** $${formatCurrency(org.assetAmount)}\n`; } // Tax information if (org.taxPeriod) { response += `**Tax Period:** ${formatTaxPeriod(org.taxPeriod)}\n`; } if (org.ruling) { response += `**Ruling Date:** ${formatRulingDate(org.ruling)}\n`; } if (org.deductibility) { response += `**Deductible:** ${org.deductibility === '1' ? 'Yes' : 'No'}\n`; } response += `\n`; }); return response; }

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/briancasteel/charity-mcp-server'

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