π TaxFormatter
Crypto CSVs and bank statement PDFs, parsed into tax-ready data.
REST API Β· MCP Server Β· Node SDK Β· Python SDK Β· Consumer Dashboard
π What It Does
TaxFormatter turns messy financial exports into structured, tax-ready data β for humans and for AI agents.
Drop a CSV from Coinbase, a ZIP from Kraken, a .tar.gz from Binance, or a PDF statement from Chase, and get back a clean, normalized transaction set you can pipe into Koinly, TurboTax, CoinLedger, ZenLedger β or straight into your own software.
Exchange CSV Clean, normalized
Bank PDF β transactions (JSON / CSV)
XLSX / ZIP / TAR.GZ + AI-generated insights
β¨ Features
π Developer REST API
Ship a crypto-tax or bank-ingestion feature into your product in an afternoon.
POST /v1/parseβ upload a CSV or PDF, get structured JSON backGET /v1/sourcesβ list every supported exchange, bank, and output format, each with averified/betastatusGET /v1/usageβ monthly quota, RPM limit, current consumptionGET /v1/healthβ liveness probe- Auth:
X-API-Keyheader withtf_live_*keys (SHA-256 hashed at rest) - Host:
https://api.taxformatter.com
π€ MCP Server for AI Agents
Give Claude, Cursor, Windsurf, or any MCP-compatible agent the ability to parse crypto and bank data directly.
npx @taxformatter/mcp-server
| Tool | What it does |
|---|---|
parse_crypto_csv | Auto-detects the exchange, returns normalized transactions |
parse_bank_statement | Extracts transactions from bank statement PDFs |
list_supported_sources | Queries every supported source + output format |
π¦ Official SDKs
- Node.js β
@taxformatter/sdkβ promise-based, fully typed - Python β
taxformatterβ idiomatic, type-hinted
π¦ 14 Exchanges Β· 6 Banks Β· 4 Export Formats
Every public supported-source claim is generated from two registries, and drift tests fail CI if any surface disagrees with them:
- Exchanges β
backend/configs/exchanges.yaml, mirrored bylib/exchange-registry.ts - Banks β
backend/configs/banks/*.yaml, mirrored bylib/bank-registry.ts
GET /v1/sources serves the same lists. Every entry carries a status: verified means a fixture-backed parse test runs on every change; beta means the parser exists but has no fixture yet. A new status is earned by a test, never by editing a registry.
Exchanges (verified): Binance Β· Coinbase Β· Kraken Β· KuCoin Β· Bybit Β· Cash App Β· Robinhood Β· Crypto.com Β· Gemini Β· FTX Β· Bitfinex Β· OKX
Exchanges (beta): Venmo
Banks (verified): Chase Β· Mercury Β· Navy Federal
Banks (beta): Bank of America Β· Wells Fargo Β· Citi
Export formats: Koinly Β· TurboTax (Form 8949) Β· CoinLedger Β· ZenLedger
Per-exchange detail: content/docs/getting-started/supported-exchanges.md.
π§ Tiered AI Insights
Every parsed file comes back with analysis scaled to your plan. Plans expose an insights level; the level β model mapping lives in lib/insights-engine.ts and is published only in the API docs and blog Updates posts.
| Level | Plans | Output |
|---|---|---|
| Standard | Free / Starter | Quick stats + basic flagging |
| Advanced | Growth | Balanced analysis, breakdowns |
| Premium | Business | Deep analysis + tax suggestions |
The insights contract is strict. Model output is validated against a fixed schema, and a refusal, truncation, or unparseable response falls back to the deterministic quick stats with an insights unavailable warning rather than partial flags. Every result is stamped with the model, prompt version, and effort that produced it, and every model call logs tokens, cache-hit rate, latency, and cost.
π₯οΈ Consumer Dashboard
Not a developer? The web app at taxformatter.com is a full drag-and-drop experience with real-time job status, exchange auto-detection, transformation previews, and one-click downloads.
ποΈ Tech Stack
| Layer | Technology |
|---|---|
| Frontend | Next.js 16 Β· React 19 Β· TypeScript Β· Tailwind v4 |
| Auth | NextAuth (Google OAuth + email/password + 2FA) |
| Database | Neon (serverless PostgreSQL) |
| Storage | AWS S3 (presigned URLs) |
| Queue | AWS SQS + DLQ |
| Compute | AWS Lambda Γ 4 (scanner, processor, webhook, api) |
| Edge | AWS API Gateway + WAF + CloudFront |
| Payments | Stripe (consumer + developer tiers) |
| AWS SES / Nodemailer | |
| Monitoring | Sentry + CloudWatch |
| Cron | Vercel Cron (daily 30-day retention prune) |
| IaC | Terraform |
π Repo Layout
trw/
βββ app/ # Next.js App Router (marketing, dashboard, docs, blog)
β βββ api/ # Internal API routes (NextAuth, uploads, jobs, dev keys, cron/prune)
β βββ dashboard/ # Authenticated user area + /dashboard/developer
β βββ docs/ Β· blog/ # MDX-powered docs site and blog (content in content/)
β βββ playground/ # API playground
β βββ samples/ # Sample outputs
β βββ upload/ # Anonymous bank statement β CSV landing page
β
βββ backend/ # Python processing layer (AWS Lambda)
β βββ handlers/ # scanner Β· processor Β· webhook Β· api
β βββ services/
β β βββ engine.py # CSV parsing (14 exchange parsers)
β β βββ format_converter.py # Koinly β TurboTax/CoinLedger/ZenLedger
β β βββ fingerprinting.py # Exchange auto-detection
β β βββ ai_insights.py # Tiered AI analysis (schema-validated, refusal-safe)
β β βββ api_auth.py # API key validation + rate limiting
β β βββ bank_statement/ # PDF extraction pipeline
β βββ configs/
β β βββ exchanges.yaml # Exchange source registry (serves /v1/sources)
β β βββ banks/*.yaml # Bank source registry + parser configs
β βββ tests/ # pytest suite + parse fixtures
β βββ terraform/ # Infra as code
β
βββ packages/
β βββ mcp-server/ # @taxformatter/mcp-server (npm)
β βββ sdk-node/ # @taxformatter/sdk (npm)
β βββ sdk-python/ # taxformatter (PyPI)
β
βββ components/ # React components (marketing, dashboard, ui)
βββ content/ # Docs (.md) and blog (.mdx) sources
βββ lib/ # Business logic (auth, api-keys, stripe, email)
β βββ exchange-registry.ts # Mirrors backend/configs/exchanges.yaml
β βββ bank-registry.ts # Mirrors backend/configs/banks/*.yaml
β βββ tier-registry.ts # The one price list (plan, price, quota, RPM, insights level)
β βββ insights-engine.ts # The one model list (insights level β model)
β βββ retention.ts # RETENTION_DAYS = 30
βββ db/ # PostgreSQL schema + migrations
βββ __tests__/ # Jest suite, incl. copy and registry drift guards
βββ docs/ # Setup guides, plans, build reports
Full architectural reference: ARCHITECTURE.md
β‘ Quick Start
Run the web app
npm install
npm run dev
Open http://localhost:3000.
Try the API
curl -X POST https://api.taxformatter.com/v1/parse \
-H "X-API-Key: tf_live_..." \
-F "[email protected]"
Use the MCP server with Claude Code
{
"mcpServers": {
"taxformatter": {
"command": "npx",
"args": ["@taxformatter/mcp-server"],
"env": { "TAXFORMATTER_API_KEY": "tf_live_..." }
}
}
}
Install the Node SDK
npm install @taxformatter/sdk
import { TaxFormatter } from "@taxformatter/sdk";
const tf = new TaxFormatter(process.env.TF_API_KEY!);
// Parse a file by path, or pass a Buffer with a filename
const result = await tf.parse("./coinbase.csv");
const turbotax = await tf.parse(buffer, "coinbase.csv", { outputFormat: "turbotax" });
Install the Python SDK
pip install taxformatter
from taxformatter import TaxFormatter
tf = TaxFormatter("tf_live_...")
result = tf.parse("./coinbase.csv")
π§ͺ Testing
npm test # Jest (700+ tests: API routes, MCP, keys, registries, UI)
npm run test:e2e # Playwright end-to-end tests
npm run typecheck # TypeScript strict mode
npm run lint # ESLint
cd backend && pytest # Python engine, parsers, insights, API Lambda (370+ tests)
Public copy is tested too. Drift guards under __tests__/ fail if any surface hard-codes a price, quota, or model name outside the registries, names an exchange or bank the registries don't list, or carries a superseded retention or marketing claim.
π³ Pricing
One plan, two ways to use it β drop a file in the dashboard or call our API. Same quota, same AI insights.
| Tier | Price | Quota | RPM | AI Insights | Highlights |
|---|---|---|---|---|---|
| Free | $0 | 25 files | 10 | Standard | All exchanges Β· No credit card |
| Starter | $29/mo | 100 files | 30 | Standard | All exchanges |
| Growth | $99/mo | 500 files | 60 | Advanced | + Bank PDF parsing |
| Business | $249/mo | 2,000 files | 120 | Premium | + Custom integrations |
Source of truth: lib/tier-registry.ts (prices, quotas, limits) and lib/insights-engine.ts (which model serves each insights level). Model names are published in the API docs and blog Updates posts only.
π Security Highlights
- API payloads never stored β request bodies are parsed in memory and never written to S3 or the database
- Metadata-only request log β
api_requestsstores key id, endpoint, status, bytes, timing, detected source, error code, and caller IP; never file contents - API keys SHA-256 hashed at rest, prefixed
tf_live_for easy identification - Uploads only β TaxFormatter never asks for exchange API keys or bank logins
- TLS 1.3 enforced everywhere
- AES-256 encryption on all stored uploads
- AWS WAF in front of the API
- 30-day retention β uploads, outputs, and parsed rows are deleted within 30 days (sooner from the dashboard); enforced by an S3 lifecycle rule and a daily prune cron
Full disclosure at taxformatter.com/security.
π Documentation
- ARCHITECTURE.md β Full system design
- content/docs/api/index.md β API reference
- content/docs/getting-started/supported-exchanges.md β per-exchange status, generated from the registry
- packages/mcp-server/README.md β MCP setup guide
- RELIABILITY.md β SLOs, incident playbooks
- docs/PARKED_UNTIL_REVIEW.md β post-launch initiatives frozen until the Oct 28 review
- docs/ β Stripe, Sentry, deployment guides, and build reports
License
Source-available, not open source. Copyright (c) 2026 Quantum Transfer Group, all rights reserved β you may read and audit this code, but not run, copy, or build on it. Full terms in LICENSE; the published npm and PyPI client packages are licensed separately.
Security
Found a vulnerability? Report it privately β see SECURITY.md. Please don't open a public issue.
Contributing
Bug reports are welcome, especially parsing failures against real exchange or bank exports. We don't accept outside pull requests β see CONTRIBUTING.md.