Nonprofit Explorer Mcp Server

io.github.cyanheadsPublished by GitHub account cyanheadsv0.3.0Updated Nov 3, 2026

MCP server for nonprofit financials via ProPublica: IRS Form 990 data for 1.8M+ nonprofits.

VerifiedStreamable HTTPWeb executableFinanceData & Analytics

Overview

Nonprofit Explorer's hosted MCP server (nonprofit-explorer.caseyjhand.com); no sign-in required; Streamable HTTP; 3 tools.

No AI overview yet: these facts come from the registry entry and the server itself.

Endpoint
nonprofit-explorer.caseyjhand.com
Last checked

Installation

In SourceWeft

  1. Open Nonprofit Explorer Mcp Server in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.cyanheads%2Fnonprofit-explorer-mcp-server/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "nonprofit-explorer": {
      "type": "http",
      "url": "https://nonprofit-explorer.caseyjhand.com/mcp"
    }
  }
}

README

@cyanheads/nonprofit-explorer-mcp-server

Search and explore 1.8M+ US nonprofits, fetch Form 990 financials, and access IRS filing history via MCP. STDIO or Streamable HTTP.

3 Tools


Overview

IRS Form 990 data for 1.8M+ tax-exempt organizations, via the ProPublica Nonprofit Explorer API. Search by name, fetch an org's financial snapshot, and pull its full filing history.

Tools

ToolDescription
nonprofit_search_organizationsSearch 1.8M+ IRS-recognized tax-exempt organizations by name, keyword, city, or phrase with optional state, NTEE sector, and 501(c) filters
nonprofit_get_organizationFull profile by EIN: legal identity, IRS classification, filing requirements, newest-return metadata, and latest extracted financial snapshot
nonprofit_get_filingsForm 990 history by EIN, optionally filtered by fiscal year: financials, fundraising figures, executive compensation, and source PDF links

Capability reference

nonprofit_search_organizations tool

  • Full-text query — supports quoted phrases ("Red Cross"), required terms (+evanston), excluded terms (-dental)
  • Optional filters: state/territory name or postal code (including military codes and ZZ for foreign entities), NTEE major sector (1–10 or a case-insensitive major letter), and 501(c) subsection code (3 covers both public charities and private foundations — see foundation_type on nonprofit_get_organization to tell them apart). Names and letters normalize to the upstream codes shown in active_filters; unrecognized states are rejected before a request
  • sub_name is the upstream legal name with an optional secondary line; it can repeat name or be null
  • Paginated at 25 per page (page, zero-indexed); num_pages, per_page, and page_offset track position
  • API caps total results at 10,000 — total_results === 10000 means the actual count may be higher, and a page whose offset reaches that ceiling is refused (pagination_ceiling)
  • Zero matches and a page past the last one both succeed with an empty organizations array and a notice explaining which case it is
  • Returns EINs — pass to nonprofit_get_organization or nonprofit_get_filings for details

nonprofit_get_organization tool

  • Accepts EIN as integer (530196605) or string with or without hyphen ("53-0196605"); use nonprofit_search_organizations first if you only have an org name
  • Returns legal identity, address, NTEE code, 501(c) type, and IRS ruling date
  • IRS Business Master File standing: deductibility (including the deductible-by-treaty case), exemption status, and public-charity vs. private-foundation classification — each decoded from its IRS code with the raw code retained
  • latest_filing is the latest extracted financial snapshot: revenue, expenses, assets, liabilities, net assets, and source PDF link. latest_return separately identifies the newest return across extracted and PDF-only histories; a newer return need not have extracted figures
  • Filing requirements, private-foundation filing requirements, affiliation, and group exemption number come from the IRS Business Master File. Empty-history guidance uses these codes without claiming why a particular filing is absent
  • filing_count counts filings with extracted data; filing_count_pdf_only separately counts PDFs without financial extracts. Use nonprofit_get_filings for those links; PDF-only histories have no financial snapshot
  • Data lags 1–2 years — tax_prd_yr in the snapshot is the fiscal year of the filing, not the current year

nonprofit_get_filings tool

  • All Form 990 filings with extracted data, sorted by full tax period newest first — per filing: revenue, expenses, assets, liabilities, net assets, revenue breakdown (contributions, program service, investment income), and the source PDF link
  • Optional inclusive from_year / to_year bounds apply to both extracted and PDF-only histories. Totals remain unfiltered; an empty selected interval does not mean the organization has no history
  • Financial fields follow each return's form type. For 990-PF, investment income is savings interest plus dividends and securities interest (Part I column (a), lines 3–4); both components must be extracted. It excludes capital gains, rents, and net investment income
  • 990-PF filings include grants_paid, distributable_amount, fair_market_value_assets, and net_investment_income. The distributable amount is a payout requirement, not actual payments or a compliance measure
  • program_expense_ratio is always null — ProPublica returns no Form 990 Part IX program-service expense total, so the program/management/fundraising split is only in the source PDF
  • Form 990 includes other salaries and wages, payroll taxes, professional fundraising fees, and fundraising event gross, direct expenses, and net income. For 990-EZ, event gross is separate from combined gaming/fundraising expenses and net income; the combined figures cannot establish event-only results
  • Executive compensation includes the source field for 990 and 990-PF. The 990-EZ extract has no compensation source: amount and field name are null, with guidance to Part IV of the PDF
  • filings_pdf_only retains fiscal years and tax periods for returns without extracted data, including returns newer than the financial snapshots
  • An EIN that resolves to a real org with no 990 on record returns an empty filings array plus a notice, not an error
  • Data lags 1–2 years — always cite tax_prd_yr (fiscal year) when presenting figures

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.

ProPublica Nonprofit Explorer / IRS-specific:

  • Keyless access — ProPublica Nonprofit Explorer API requires no API key
  • Covers 1.8M+ IRS-recognized tax-exempt organizations
  • IRS Form 990 data: annual filings for public charities (990), small orgs (990-EZ), and private foundations (990-PF)
  • Source filing PDF link on every filing record, except where IRS PDF processing lags the extracted data and pdf_url is still null
  • Data sourced from ProPublica Nonprofit Explorer, derived from IRS Form 990 filings; data lags 1–2 years

Agent-friendly output:

  • Provenance on every response — data_source attribution on all tool outputs, ProPublica URL for direct verification
  • Filing-year clarity — tax_prd_yr prominently labeled as fiscal year with explicit lag caveat in every financial response
  • Null values are rendered, not dropped — the formatted text names why a value is absent (never recorded by the IRS, not extracted from the filing, not carried by that form type), and structuredContent keeps an explicit null rather than omitting the key
  • Field-name transparency on compensation — field_name and form_type exposed so agents know exactly which IRS field was read

The published nonprofit-explorer-guide covers diligence, financial comparisons, and when to inspect the source return. It is included in npm, Docker, and desktop bundles and served through MCP skill resources.

Getting started

Public Hosted Instance

A public instance is available at https://nonprofit-explorer.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP, with this client config:

json
{  "mcpServers": {    "nonprofit-explorer-mcp-server": {      "type": "streamable-http",      "url": "https://nonprofit-explorer.caseyjhand.com/mcp"    }  }}

Self-Hosted / Local

Add the following to your MCP client configuration file.

json
{  "mcpServers": {    "nonprofit-explorer-mcp-server": {      "type": "stdio",      "command": "bunx",      "args": ["@cyanheads/nonprofit-explorer-mcp-server@latest"],      "env": {        "MCP_TRANSPORT_TYPE": "stdio",        "MCP_LOG_LEVEL": "info"      }    }  }}

Or with npx (no Bun required):

json
{  "mcpServers": {    "nonprofit-explorer-mcp-server": {      "type": "stdio",      "command": "npx",      "args": ["-y", "@cyanheads/nonprofit-explorer-mcp-server@latest"],      "env": {        "MCP_TRANSPORT_TYPE": "stdio",        "MCP_LOG_LEVEL": "info"      }    }  }}

Or with Docker:

json
{  "mcpServers": {    "nonprofit-explorer-mcp-server": {      "type": "stdio",      "command": "docker",      "args": [        "run", "-i", "--rm",        "-e", "MCP_TRANSPORT_TYPE=stdio",        "ghcr.io/cyanheads/nonprofit-explorer-mcp-server:latest"      ]    }  }}

For Streamable HTTP, set the transport and start the server:

sh
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http# Server listens at http://localhost:3010/mcp

Prerequisites

  • Bun v1.4.0 or higher (or Node.js v24+).
  • No API key required — ProPublica Nonprofit Explorer is a keyless public API.

Installation

  1. Clone the repository:
sh
git clone https://github.com/cyanheads/nonprofit-explorer-mcp-server.git
  1. Navigate into the directory:
sh
cd nonprofit-explorer-mcp-server
  1. Install dependencies:
sh
bun install
  1. Configure environment:
sh
cp .env.example .env# edit .env as needed (no required vars — server works out of the box)

Configuration

All configuration is validated at startup. Key environment variables:

VariableDescriptionDefault
MCP_TRANSPORT_TYPETransport: stdio or httpstdio
MCP_HTTP_PORTHTTP server port3010
MCP_HTTP_HOSTHTTP server hostname127.0.0.1
MCP_HTTP_ENDPOINT_PATHHTTP endpoint path/mcp
MCP_PUBLIC_URLPublic origin override for TLS-terminating reverse-proxy deployments—
MCP_AUTH_MODEAuthentication: none, jwt, or oauthnone
MCP_LOG_LEVELLog level (debug, info, warning, error, etc.)info
LOGS_DIRDirectory for log files (Node.js only)<project-root>/logs
LOG_TOOL_FAILURE_PAYLOADSLog each failed tool call's arguments and result, redacted by key name and capped at LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES (default 16384). A secret inside a free-form value is not redacted.false
STORAGE_PROVIDER_TYPEStorage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1in-memory
OTEL_ENABLEDEnable OpenTelemetry instrumentationfalse

No server-specific required variables. ProPublica Nonprofit Explorer is a keyless public API.

See .env.example for the full list of optional overrides.

Running the server

Local development

  • Build and run:

    sh
    # One-time buildbun run rebuild
    # Run the built serverbun run start:stdio# orbun run start:http
  • Run checks and tests:

    sh
    bun run devcheck   # Lint, format, typecheck, securitybun run test       # Vitest test suitebun run lint:mcp   # Validate MCP definitions against spec

Docker

sh
docker build -t nonprofit-explorer-mcp-server .docker run --rm -p 3010:3010 nonprofit-explorer-mcp-server

The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/nonprofit-explorer-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools and inits the service.
src/mcp-server/toolsTool definitions (*.tool.ts). Three tools for search and financial data.
src/services/nonprofit-explorerProPublica Nonprofit Explorer API client and domain types.
skills/Published agent guidance for diligence and financial interpretation.
tests/Unit and integration tests mirroring src/.

Development guide

See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage
  • Register new tools via the arrays in createApp() in src/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:

sh
bun run devcheckbun run test

License

Apache-2.0 — see LICENSE for details.

Source: README.md at commit 3ada760

Tools

3

nonprofit_search_organizations

Search Nonprofits

Search 1.8M+ IRS-recognized tax-exempt organizations by name, keyword, city, or phrase. Optionally narrow by US state, NTEE major sector (1–10), or 501(c) subsection type. Returns EINs — pass them to nonprofit_get_organization or nonprofit_get_filings for details. Results are paginated at 25 per page; use the page parameter and num_pages to paginate. Total results cap at 10,000 in the API; if total_results === 10000 the actual count may be higher. A zero-match query and a page past the last one both return an empty organizations array with a notice rather than an error; only a page whose offset reaches that 10,000 cap is refused. Supports quoted phrases ("Red Cross"), required terms (+evanston), excluded terms (-dental). Data from ProPublica Nonprofit Explorer, sourced from IRS Form 990 filings.

Parameterspagequeryrequiredstatentee_categorysubsection_code

nonprofit_get_organization

Get Nonprofit Organization

Full profile for a tax-exempt org by EIN: legal identity, IRS classification and BMF filing requirements, latest extracted financial snapshot, and latest return metadata across extracted and PDF-only histories. Use nonprofit_search_organizations first to resolve a name to an EIN. latest_filing is the latest extracted snapshot; latest_return may be newer. Data lags 1–2 years; always cite the fiscal year. Data from ProPublica Nonprofit Explorer and IRS Form 990 filings.

Parameterseinrequired

nonprofit_get_filings

Get Nonprofit Filings

Form 990 history by EIN with extracted financials, form-specific compensation, and PDF-only returns. Optional inclusive from_year/to_year bounds select fiscal years across both histories; omitted bounds return full history. Unfiltered totals remain available. Records are sorted by full tax period without amendment precedence. Empty dataset history succeeds with BMF context; an empty selected window does not imply no history. Data lags 1–2 years; always cite tax_prd_yr. Data from ProPublica Nonprofit Explorer and IRS Form 990 filings.

Parameterseinrequiredto_yearfrom_year

Version history

5
  1. v0.3.0LatestNov 3, 2026
  2. v0.2.0Oct 22, 2026
  3. v0.1.10Oct 9, 2026
  4. v0.1.9Sep 20, 2026
  5. v0.1.8Sep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts