Skip to main content
Glama
briancasteel

Charity MCP Server

by briancasteel

charity-lookup

Retrieve detailed IRS nonprofit information including tax status, organization classification, and current standing using an EIN (Employer Identification Number).

Instructions

Look up detailed information about a charity or nonprofit organization using their EIN (Employer Identification Number). This tool retrieves comprehensive information from the IRS database including: - Official organization name and location - Tax deductibility status and codes - Organization classification and activity codes - Current status with the IRS - Foundation type and ruling information

Use this tool when you need complete details about a specific charity.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
einYesThe charity's EIN (Tax ID) in format XX-XXXXXXX or XXXXXXXXX (e.g., '13-1837418' or '131837418')

Implementation Reference

  • The primary handler function for the 'charity-lookup' tool. It handles input sanitization, validation, rate limiting, API calls to retrieve charity data by EIN, response validation and transformation, formatting, and comprehensive error handling.
    export async function handleCharityLookup(args: unknown): Promise<CallToolResult> {
      const startTime = Date.now();
      
      try {
        logger.debug("Charity lookup requested", { args });
    
        // Extract and sanitize input
        const rawInput = args as any;
        const sanitizedEIN = InputSanitizer.sanitizeEIN(rawInput?.ein || '');
        
        if (!sanitizedEIN) {
          throw new ValidationError("EIN is required", "ein");
        }
    
        // Validate EIN format and business rules
        const validatedEIN = EINValidator.validate(sanitizedEIN);
        
        logger.debug("Input validated", { originalEIN: rawInput?.ein, validatedEIN });
    
        // Check rate limit
        if (!(await rateLimiter.checkRateLimit('charity_lookup'))) {
          const resetTime = rateLimiter.getResetTime('charity_lookup');
          const resetDate = new Date(resetTime).toISOString();
          
          return {
            content: [
              {
                type: "text",
                text: `⏱️ Rate limit exceeded for charity lookup. Please try again after ${resetDate}.`,
              } as TextContent,
            ],
            isError: true,
          };
        }
    
        // Make API call
        logger.info("Looking up charity", { ein: validatedEIN });
        const apiResponse = await charityAPIClient.getOrganizationByEIN(validatedEIN);
        
        // Validate API response
        const validatedResponse = ResponseValidator.validateGetOrgResponse(apiResponse);
        
        // Transform to standardized format
        const transformedCharity = CharityTransformer.transformCharityLookup(validatedResponse, validatedEIN);
        
        // Format for display
        const formattedText = ResponseFormatter.formatCharityLookup(transformedCharity);
        
        const processingTime = Date.now() - startTime;
        logger.info("Charity lookup completed successfully", { 
          ein: validatedEIN, 
          name: transformedCharity.name,
          processingTime 
        });
    
        return {
          content: [
            {
              type: "text",
              text: formattedText,
            } as TextContent,
          ],
        };
    
      } catch (error) {
        const processingTime = Date.now() - startTime;
        logger.error("Charity lookup failed", { args, error, processingTime });
        
        let formattedError;
        let errorText: string;
    
        if (error instanceof ValidationError) {
          formattedError = ErrorFormatter.formatValidationError(error);
          errorText = ErrorFormatter.toUserMessage(formattedError);
        } else {
          const mcpError = handleMCPError(error);
          errorText = mcpError.message;
        }
    
        return {
          content: [
            {
              type: "text",
              text: errorText,
            } as TextContent,
          ],
          isError: true,
        };
      }
    }
  • The tool definition object including name, description, and input schema for validating the EIN parameter.
    export const CHARITY_LOOKUP_TOOL = {
      name: "charity-lookup",
      description: `
        Look up detailed information about a charity or nonprofit organization using their EIN (Employer Identification Number).
        This tool retrieves comprehensive information from the IRS database including:
        - Official organization name and location
        - Tax deductibility status and codes
        - Organization classification and activity codes
        - Current status with the IRS
        - Foundation type and ruling information
        
        Use this tool when you need complete details about a specific charity.
      `.trim(),
      inputSchema: {
        type: "object" as const,
        properties: {
          ein: {
            type: "string",
            description: "The charity's EIN (Tax ID) in format XX-XXXXXXX or XXXXXXXXX (e.g., '13-1837418' or '131837418')",
            pattern: "^\\d{2}-?\\d{7}$",
          },
        },
        required: ["ein"],
      },
    };
  • Registration of the 'charity-lookup' tool in the MCP list tools handler, making it discoverable.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        CHARITY_LOOKUP_TOOL,
        PUBLIC_CHARITY_CHECK_TOOL,
        CHARITY_SEARCH_TOOL,
        LIST_ORGANIZATIONS_TOOL,
      ],
    }));
  • Registration of the 'charity-lookup' tool handler in the MCP call tool request switch statement.
    case CHARITY_LOOKUP_TOOL.name:
      return await handleCharityLookup(args);
  • The registerAllTools function that sets up both list and call handlers for all tools including charity-lookup.
    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;
      }
    }

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