Ledgr connects to your bank accounts through Plaid, automatically syncs and categorizes transactions, and gives you budgets, investment tracking, bill detection, and financial reports — all running on your own server with your own data.
It also exposes an MCP server, so AI assistants like Claude can query your finances through natural conversation.
You: "How much did I spend on dining out last month?"
Claude: Based on your transactions, you spent $342.18 on dining out in April...
- Automatic bank sync — connect 12,000+ banks via Plaid, transactions sync automatically
- Smart categorization — four-tier pipeline: your rules > merchant defaults > Plaid categories > AI fallback
- Budgets — set monthly budgets by category, track progress in real time
- Investment tracking — portfolio holdings, performance history, and allocation breakdowns
- Recurring bill detection — automatically identifies subscriptions and recurring charges
- Financial reports — spending, income, net worth, and category trends over time
- AI agent interface (MCP) — query your finances from Claude Code, Claude Desktop, Cursor, or any MCP client
- BYOK AI categorization — bring your own API key (OpenAI, Anthropic, Google, or local models)
- CSV/OFX import — for accounts not supported by Plaid
- Self-hosted — Docker Compose with PostgreSQL, your data never leaves your server
Requires Docker and Docker Compose.
mkdir ledgr && cd ledgr
curl -O https://raw.githubusercontent.com/KenTaniguchi-R/ledgr/main/docker-compose.yml
curl -o .env https://raw.githubusercontent.com/KenTaniguchi-R/ledgr/main/.env.exampleGenerate your encryption key and add it to .env:
openssl rand -hex 32
# Paste the output as ENCRYPTION_KEY= in .envStart the app:
docker compose up -dVisit http://localhost:4200, create an account, and start exploring.
Add your Plaid keys to
.envto enable bank sync — see Connect Your Bank below. The app works without Plaid via CSV import.
- Sign up at dashboard.plaid.com and get your
client_idand secret from Developers > Keys - Add them to your
.env:PLAID_CLIENT_ID=your_client_id PLAID_SECRET=your_secret PLAID_ENV=production # or sandbox for fake data
- Restart:
docker compose restart - In the app, go to Accounts > Link Bank to connect via Plaid
Don't have Plaid keys yet? The app still works — import transactions via CSV and add Plaid later.
Ledgr ships with a built-in MCP server and plugin support. Pick your tool:
Claude Code
/plugin marketplace add KenTaniguchi-R/ledgr
/plugin install ledgr@ledgrCodex CLI
codex plugin marketplace add KenTaniguchi-R/ledgrOpenCode — add to opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["ledgr"]
}OpenClaw
openclaw plugins install ledgr --marketplace KenTaniguchi-R/ledgrHermes
hermes plugins install KenTaniguchi-R/ledgrOther MCP clients (Cursor, Windsurf, Cline, etc.)
Point any MCP-compatible client to your Ledgr instance:
http://localhost:4200/api/mcp
On first connection, Ledgr redirects you through an OAuth flow to authorize access.
| Tool | Description |
|---|---|
list_accounts |
View linked bank accounts and balances |
list_transactions |
Search and filter transactions |
list_budgets |
Check budget progress |
list_categories |
View spending categories |
list_investments |
Portfolio holdings and performance |
generate_report |
Spending, income, and net worth reports |
list_recurring |
Recurring transactions and bills |
sync_accounts |
Trigger a bank sync |
show_dashboard |
Interactive financial dashboard |
manage_categories |
Create and update categories |
Example prompts:
- "How much did I spend on groceries this month?"
- "Show me my budget status"
- "What recurring bills do I have?"
- "Generate a spending report for Q1"
- "Sync my accounts and show my balances"
| Ledgr | Actual Budget | Firefly III | Maybe Finance | |
|---|---|---|---|---|
| Automatic bank sync | Plaid (12,000+ banks) | GoCardless (EU) | Spectre/GoCardless | -- |
| AI agent (MCP) | Yes | -- | -- | -- |
| AI categorization | Yes (BYOK) | -- | -- | -- |
| Investment tracking | Yes | -- | -- | Yes |
| Self-hostable | Yes | Yes | Yes | Yes |
| Database | PostgreSQL | SQLite | MySQL/Postgres | Postgres |
| License | AGPL-3.0 | MIT | AGPL-3.0 | AGPL-3.0 |
docker compose pull
docker compose up -dMigrations run automatically on container startup.
| Variable | Required | Default | Description |
|---|---|---|---|
ENCRYPTION_KEY |
Yes | -- | Encrypts Plaid tokens & API keys. openssl rand -hex 32 |
BETTER_AUTH_SECRET |
Recommended | auto-generated | Session secret. openssl rand -base64 32 |
PORT |
No | 4200 |
Host port for the app |
POSTGRES_PASSWORD |
No | ledgr |
Database password (change in production) |
PLAID_CLIENT_ID |
No | -- | Plaid client ID |
PLAID_SECRET |
No | -- | Plaid secret key |
PLAID_ENV |
No | production |
production or sandbox |
AI_PROVIDER |
No | -- | openai, anthropic, google, or custom |
AI_API_KEY |
No | -- | Provider API key for AI categorization |
See .env.example for all options.
If you're self-hosting Ledgr, use the Quick Start above. The instructions below are for contributors.
git clone https://github.com/KenTaniguchi-R/ledgr.git
cd ledgr
pnpm install
cp .env.example .env # Fill in ENCRYPTION_KEY
pnpm dev:setup # Start DB + migrate + dev serverTo run the full app in Docker from source (instead of pulling the pre-built image):
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -dpnpm dev # Dev server (Turbopack)
pnpm test # Unit + integration tests
pnpm test:e2e # Playwright E2E tests
pnpm lint # ESLint
pnpm typecheck # Type checking
pnpm db:studio # Drizzle Studio (DB browser)| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript |
| UI | shadcn/ui + Tailwind CSS 4 |
| Charts | Recharts 3 |
| Database | PostgreSQL 18 via Drizzle ORM |
| Auth | Better Auth |
| Bank Sync | Plaid Node SDK |
| AI | Vercel AI SDK (BYOK) |
| MCP | Model Context Protocol SDK |
| Testing | Vitest + Playwright + Stryker |
- Mobile-responsive UI
- Plaid webhook support (real-time sync)
- Multi-currency support
- Custom report builder
- Transfer detection between accounts
- Goal tracking (savings goals, debt payoff)
- AI chat assistant (in-app)
- OFX/QFX import
- Recurring budget templates
See Issues for what's being worked on.
Security is critical for a finance app. If you discover a vulnerability, please do not open a public issue. Instead, see SECURITY.md for responsible disclosure instructions.
Contributions are welcome! Please open an issue first to discuss what you'd like to change.
- Fork the repo
- Create your branch (
git checkout -b feat/my-feature) - Commit your changes
- Push and open a Pull Request
AGPL-3.0 — you can self-host freely. If you modify and distribute the server, you must open-source your changes.



