@devessentials/zfy-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 zfy contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # zfy
2
+
3
+ [![CI](https://github.com/EssentialsDev/zfy-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/EssentialsDev/zfy-cli/actions/workflows/ci.yml)
4
+ [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
5
+
6
+ A third-party CLI, TypeScript SDK, and **MCP server** for the [Zeffy API](https://www.zeffy.com/integration/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."*
7
+
8
+ > **Not affiliated with Zeffy or Simplyk.** Wraps the official free public read-only API (Payments, Contacts, Campaigns) released in 2025.
9
+
10
+ ## What you can do with it
11
+
12
+ - Pull donations, donors, and campaigns out of Zeffy as JSON — pipe into `jq`, spreadsheets, or your own code.
13
+ - Generate **end-of-year donation reports** in JSON, CSV, Markdown, or one PDF receipt per donor.
14
+ - Plug Zeffy into Claude, Claude Desktop, or any MCP-aware agent so it can answer questions about your donation data conversationally.
15
+ - Build custom workflows in TypeScript using the same SDK that powers the CLI.
16
+
17
+ Read-only by design — `zfy` cannot modify your Zeffy data, because the official API is read-only.
18
+
19
+ ## Contents
20
+
21
+ - [Install](#install)
22
+ - [Authenticate](#authenticate)
23
+ - [CLI usage](#cli-usage)
24
+ - [Quickstart](#quickstart)
25
+ - [End-of-year report](#end-of-year-report)
26
+ - [Logo spec for `--logo`](#logo-spec-for---logo)
27
+ - [MCP server](#mcp-server-use-from-claude--agents)
28
+ - [SDK usage](#sdk-usage)
29
+ - [Development](#development)
30
+ - [License](#license)
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ npm i -g @devessentials/zfy-cli
36
+ # or run without installing:
37
+ npx --package=@devessentials/zfy-cli zfy --help
38
+ ```
39
+
40
+ The package is `@devessentials/zfy-cli` on npm; the binary is `zfy` and the MCP entry point is `zfy-mcp`. Node.js 20+ required.
41
+
42
+ ## Authenticate
43
+
44
+ 1. In your Zeffy dashboard, go to **Settings → Integrations** and generate an API key.
45
+ 2. Save it locally:
46
+
47
+ ```bash
48
+ zfy auth set # prompts for the key, stores it in ~/.config/zfy/config.json (mode 0600)
49
+ zfy auth status # verifies the key by calling the Zeffy API
50
+ zfy auth clear # removes the stored key
51
+ ```
52
+
53
+ Or pass it inline for CI / one-offs:
54
+
55
+ ```bash
56
+ ZEFFY_API_KEY=sk_xxx zfy payments list --from 2025-01-01
57
+ ```
58
+
59
+ The `ZEFFY_API_KEY` env var always takes precedence over the stored key.
60
+
61
+ ## CLI usage
62
+
63
+ Every command outputs JSON to stdout — pipe it into `jq`, an LLM, a spreadsheet, or further commands.
64
+
65
+ ### Quickstart
66
+
67
+ ```bash
68
+ # Donations in a date range
69
+ zfy payments list --from 2025-01-01 --to 2025-12-31
70
+
71
+ # Total raised in Q4 2025
72
+ zfy payments list --from 2025-10-01 --to 2025-12-31 | jq '[.[].amount] | add'
73
+
74
+ # All gifts to a specific campaign
75
+ zfy payments list --campaign cmp_abc --status succeeded
76
+
77
+ # Donor lookup by email
78
+ zfy contacts list --email donor@example.com
79
+
80
+ # Campaigns
81
+ zfy campaigns list
82
+ ```
83
+
84
+ ### End-of-year report
85
+
86
+ Generate a per-donor annual report in any format. Defaults: excludes refunded payments, uses your system timezone for year boundaries.
87
+
88
+ ```bash
89
+ # JSON to stdout (default — best for piping to agents)
90
+ zfy report eoy --year 2025
91
+
92
+ # Spreadsheet-friendly CSV
93
+ zfy report eoy --year 2025 --format csv --out eoy-2025.csv
94
+
95
+ # Top-50 donor markdown summary (fits in an LLM context)
96
+ zfy report eoy --year 2025 --format md --out eoy-2025.md --top 50
97
+
98
+ # One PDF receipt per donor
99
+ zfy report eoy --year 2025 --format pdf --out ./receipts/ \
100
+ --org "Friends of the Library" \
101
+ --logo ./logo.png --logo-size 64 \
102
+ --timezone America/Los_Angeles
103
+ ```
104
+
105
+ Useful flags (`zfy report eoy --help` for the full list):
106
+
107
+ | Flag | Notes |
108
+ | --- | --- |
109
+ | `--year <year>` | Required. Calendar year. |
110
+ | `--format <fmt>` | `json` \| `csv` \| `md` \| `pdf`. Default `json`. |
111
+ | `--out <path>` | Output file (or directory for PDF). Defaults to stdout. |
112
+ | `--timezone <tz>` | IANA timezone (e.g. `America/Los_Angeles`). Boundaries respect DST. |
113
+ | `--currency <code>` | Filter to a single currency. |
114
+ | `--include-refunded` | Include refunded payments (excluded by default). |
115
+ | `--top <n>` | Markdown: limit donor table. |
116
+ | `--org <name>` | PDF: organization name in the header. |
117
+ | `--logo <path>` | PDF: square PNG/JPEG mark — see spec below. |
118
+ | `--logo-size <pt>` | PDF: edge length of the logo slot (default 64 pt). |
119
+ | `--receipt-text <txt>` | PDF: override the default tax-receipt boilerplate. |
120
+
121
+ ### Logo spec for `--logo`
122
+
123
+ 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:
124
+
125
+ | Constraint | Limit |
126
+ | --- | --- |
127
+ | Format | PNG or JPEG (sniffed from file bytes — extension is ignored) |
128
+ | File size | ≤ 2 MB |
129
+ | Minimum dimensions | 64 × 64 px |
130
+ | Shape | Square within ±10% (e.g. 512×512, or 500×510 — but not 800×200) |
131
+
132
+ 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.
133
+
134
+ ## MCP server (use from Claude / agents)
135
+
136
+ `zfy-mcp` exposes the same operations as MCP tools over stdio. Add to `~/.claude.json` (or Claude Desktop's `claude_desktop_config.json`):
137
+
138
+ ```json
139
+ {
140
+ "mcpServers": {
141
+ "zeffy": {
142
+ "command": "zfy-mcp",
143
+ "env": { "ZEFFY_API_KEY": "sk_xxx" }
144
+ }
145
+ }
146
+ }
147
+ ```
148
+
149
+ Tools exposed:
150
+
151
+ | Tool | Description |
152
+ | --- | --- |
153
+ | `zeffy_list_payments` | List donations with date / status / campaign / contact filters |
154
+ | `zeffy_list_contacts` | List donors (lookup by email or date range) |
155
+ | `zeffy_list_campaigns` | List campaigns |
156
+ | `zeffy_eoy_report` | Per-donor annual summary (JSON or Markdown) |
157
+
158
+ After installing and configuring, ask your agent things like:
159
+
160
+ - "How much did we raise in Q4 2025?"
161
+ - "Who were our top 10 donors last year, and what did each give?"
162
+ - "Generate an EOY summary I can paste into our board report."
163
+
164
+ PDF and CSV output aren't exposed via MCP (binary data is awkward over stdio) — use the CLI for those.
165
+
166
+ ## SDK usage
167
+
168
+ Everything the CLI does is available as a typed library, including the EOY aggregation and the format renderers.
169
+
170
+ ```ts
171
+ import { Zeffy } from "@devessentials/zfy-cli";
172
+
173
+ const zeffy = new Zeffy(process.env.ZEFFY_API_KEY!);
174
+
175
+ // Single page (cursor-paginated under the hood)
176
+ const page = await zeffy.payments.list({ created_gte: 1735689600 });
177
+
178
+ // Auto-paginate across the whole range
179
+ for await (const p of zeffy.payments.iterate({ created_gte: 1735689600 })) {
180
+ console.log(p.id, p.amount, p.contact?.email);
181
+ }
182
+
183
+ // Build and render an EOY report yourself
184
+ import { buildEoyReport, formatMarkdown, writePdfReceipts } from "@devessentials/zfy-cli";
185
+
186
+ const report = await buildEoyReport(zeffy, {
187
+ year: 2025,
188
+ timezone: "America/Los_Angeles",
189
+ });
190
+
191
+ console.log(formatMarkdown(report, 25));
192
+ await writePdfReceipts(report, "./receipts", { orgName: "Friends of the Library" });
193
+ ```
194
+
195
+ 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](https://zod.dev) schemas — bad shapes throw with the raw response attached for debugging.
196
+
197
+ ## Development
198
+
199
+ ```bash
200
+ pnpm install
201
+ pnpm build # tsup → dist/
202
+ pnpm test # vitest
203
+ pnpm typecheck # tsc --noEmit
204
+ ```
205
+
206
+ CI runs `typecheck`, `test`, and `build` on every push and PR against Node 20 and 22.
207
+
208
+ ## License
209
+
210
+ MIT — see [LICENSE](./LICENSE). Not affiliated with Zeffy or Simplyk.
211
+
212
+ Found a bug or want to contribute? [Open an issue or PR](https://github.com/EssentialsDev/zfy-cli/issues).