npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@devessentials/zfy-cli

v0.1.0

Published

Third-party CLI, SDK, and MCP server for the Zeffy API — donation reports for nonprofits and AI agents.

Readme

zfy

CI MIT License

A third-party CLI, TypeScript SDK, and MCP server for the Zeffy API — built so nonprofits can automate donation reporting and AI agents can answer questions like "draft tax receipts for everyone who gave over $250 in 2025."

Not affiliated with Zeffy or Simplyk. Wraps the official free public read-only API (Payments, Contacts, Campaigns) released in 2025.

What you can do with it

  • Pull donations, donors, and campaigns out of Zeffy as JSON — pipe into jq, spreadsheets, or your own code.
  • Generate end-of-year donation reports in JSON, CSV, Markdown, or one PDF receipt per donor.
  • Plug Zeffy into Claude, Claude Desktop, or any MCP-aware agent so it can answer questions about your donation data conversationally.
  • Build custom workflows in TypeScript using the same SDK that powers the CLI.

Read-only by design — zfy cannot modify your Zeffy data, because the official API is read-only.

Contents

Install

npm i -g @devessentials/zfy-cli
# or run without installing:
npx --package=@devessentials/zfy-cli zfy --help

The package is @devessentials/zfy-cli on npm; the binary is zfy and the MCP entry point is zfy-mcp. Node.js 20+ required.

Authenticate

  1. In your Zeffy dashboard, go to Settings → Integrations and generate an API key.
  2. Save it locally:
zfy auth set            # prompts for the key, stores it in ~/.config/zfy/config.json (mode 0600)
zfy auth status         # verifies the key by calling the Zeffy API
zfy auth clear          # removes the stored key

Or pass it inline for CI / one-offs:

ZEFFY_API_KEY=sk_xxx zfy payments list --from 2025-01-01

The ZEFFY_API_KEY env var always takes precedence over the stored key.

CLI usage

Every command outputs JSON to stdout — pipe it into jq, an LLM, a spreadsheet, or further commands.

Quickstart

# Donations in a date range
zfy payments list --from 2025-01-01 --to 2025-12-31

# Total raised in Q4 2025
zfy payments list --from 2025-10-01 --to 2025-12-31 | jq '[.[].amount] | add'

# All gifts to a specific campaign
zfy payments list --campaign cmp_abc --status succeeded

# Donor lookup by email
zfy contacts list --email [email protected]

# Campaigns
zfy campaigns list

End-of-year report

Generate a per-donor annual report in any format. Defaults: excludes refunded payments, uses your system timezone for year boundaries.

# JSON to stdout (default — best for piping to agents)
zfy report eoy --year 2025

# Spreadsheet-friendly CSV
zfy report eoy --year 2025 --format csv --out eoy-2025.csv

# Top-50 donor markdown summary (fits in an LLM context)
zfy report eoy --year 2025 --format md --out eoy-2025.md --top 50

# One PDF receipt per donor
zfy report eoy --year 2025 --format pdf --out ./receipts/ \
               --org "Friends of the Library" \
               --logo ./logo.png --logo-size 64 \
               --timezone America/Los_Angeles

Useful flags (zfy report eoy --help for the full list):

| Flag | Notes | | --- | --- | | --year <year> | Required. Calendar year. | | --format <fmt> | json | csv | md | pdf. Default json. | | --out <path> | Output file (or directory for PDF). Defaults to stdout. | | --timezone <tz> | IANA timezone (e.g. America/Los_Angeles). Boundaries respect DST. | | --currency <code> | Filter to a single currency. | | --include-refunded | Include refunded payments (excluded by default). | | --top <n> | Markdown: limit donor table. | | --org <name> | PDF: organization name in the header. | | --logo <path> | PDF: square PNG/JPEG mark — see spec below. | | --logo-size <pt> | PDF: edge length of the logo slot (default 64 pt). | | --receipt-text <txt> | PDF: override the default tax-receipt boilerplate. |

Logo spec for --logo

The PDF renderer reserves a small square slot for an org mark. To keep batches consistent and prevent multi-gigabyte receipt runs, logos must meet:

| Constraint | Limit | | --- | --- | | Format | PNG or JPEG (sniffed from file bytes — extension is ignored) | | File size | ≤ 2 MB | | Minimum dimensions | 64 × 64 px | | Shape | Square within ±10% (e.g. 512×512, or 500×510 — but not 800×200) |

Recommended: a 512×512 PNG with a transparent or white background. If the file fails any check, zfy prints a single warning to stderr and continues without the logo — a bad asset never blocks a 500-donor receipt run.

MCP server (use from Claude / agents)

zfy-mcp exposes the same operations as MCP tools over stdio. Add to ~/.claude.json (or Claude Desktop's claude_desktop_config.json):

{
  "mcpServers": {
    "zeffy": {
      "command": "zfy-mcp",
      "env": { "ZEFFY_API_KEY": "sk_xxx" }
    }
  }
}

Tools exposed:

| Tool | Description | | --- | --- | | zeffy_list_payments | List donations with date / status / campaign / contact filters | | zeffy_list_contacts | List donors (lookup by email or date range) | | zeffy_list_campaigns | List campaigns | | zeffy_eoy_report | Per-donor annual summary (JSON or Markdown) |

After installing and configuring, ask your agent things like:

  • "How much did we raise in Q4 2025?"
  • "Who were our top 10 donors last year, and what did each give?"
  • "Generate an EOY summary I can paste into our board report."

PDF and CSV output aren't exposed via MCP (binary data is awkward over stdio) — use the CLI for those.

SDK usage

Everything the CLI does is available as a typed library, including the EOY aggregation and the format renderers.

import { Zeffy } from "@devessentials/zfy-cli";

const zeffy = new Zeffy(process.env.ZEFFY_API_KEY!);

// Single page (cursor-paginated under the hood)
const page = await zeffy.payments.list({ created_gte: 1735689600 });

// Auto-paginate across the whole range
for await (const p of zeffy.payments.iterate({ created_gte: 1735689600 })) {
  console.log(p.id, p.amount, p.contact?.email);
}

// Build and render an EOY report yourself
import { buildEoyReport, formatMarkdown, writePdfReceipts } from "@devessentials/zfy-cli";

const report = await buildEoyReport(zeffy, {
  year: 2025,
  timezone: "America/Los_Angeles",
});

console.log(formatMarkdown(report, 25));
await writePdfReceipts(report, "./receipts", { orgName: "Friends of the Library" });

The client handles 429 rate-limit responses (token-bucket capped at 90 req/min, with Retry-After honored on backoff) and validates every response against zod schemas — bad shapes throw with the raw response attached for debugging.

Development

pnpm install
pnpm build         # tsup → dist/
pnpm test          # vitest
pnpm typecheck     # tsc --noEmit

CI runs typecheck, test, and build on every push and PR against Node 20 and 22.

License

MIT — see LICENSE. Not affiliated with Zeffy or Simplyk.

Found a bug or want to contribute? Open an issue or PR.