AI-powered personal finance tracker. Track spending, scan receipts, manage budgets, monitor your portfolio — with an MCP interface so your AI assistant can do the heavy lifting.
Transactions — Full CRUD with filtering, search, bulk operations, tags, and inline editing. Description, merchant, and tag fields autocomplete from your previously-used values. Link transactions to receipts for audit trails.
Categories — Hierarchical tree with icons and colors. Merge, reparent, and drill down into spending per category.
Budgets — Monthly spending limits per category. Visual progress bars (green/yellow/red), copy from previous month, historical adherence tracking.
Recurring — Templates for subscriptions, salaries, and other repeating transactions. Automatic daily generation with independent editing of each occurrence.
Assets & Portfolio — Track bank accounts, savings, stocks, ETFs, crypto. Lot-based cost tracking, automatic market price fetching, net worth over time.
Reports — Two report suites:
- Cash Flow — spending by category, trends, merchant breakdowns, budget vs actual, income vs expenses
- Portfolio — net worth history, allocation breakdown, asset performance, realized vs unrealized P&L
Dashboard — KPI cards, spending trend, category breakdown donut, budget alerts, upcoming recurring, net worth sparkline, top movers, allocation overview.
Receipt Scanning — Upload receipt images via REST; your AI extracts line items, categorizes them, and links everything automatically.
MCP Server — 67 tools across transactions, categories, budgets, recurring, assets, portfolio reports, financial data, and more. Your AI assistant connects over Streamable HTTP and can do everything the web UI can — plus ad-hoc SQL queries.
What can the AI do? (example report)
Prompt: Using Kinti, what interesting things can you tell me about my spending habits?
You travel... a lot
The single most striking pattern: 19 intercity trips in 2.5 months — 10 FlixBus rides (avg €19.47 each) and 9 Deutsche Bahn trips (avg €52.87 each). That's nearly two trips a week. Deutsche Bahn alone cost €475 — more than entertainment, health, and subscriptions combined.
You eat out more than you cook
| Month | Dining | Groceries | Ratio |
|---|---|---|---|
| January | €377 | €261 | 1.44x |
| February | €294 | €353 | 0.83x |
| March (17d) | €228 | €207 | 1.10x |
January was notably bad — 32 dining transactions, basically one per day. Clear regulars: Nando's (5 visits), La Piazza (3 visits, avg €38/dinner), Wagamama (5 visits).
February was the most expensive month — by far
€2,173 vs €1,906 in January (+14%), driven by a shopping spike: €294 in Feb vs €108 in Jan. Two MediaMarkt visits averaged €83.51 each. One Primark run: €111.57.
The predictable stuff is fine
Subscriptions are a rock-solid €35.96/month (Netflix + Prime + Spotify + iCloud). Utilities average ~€85/month. Nothing surprising there.
Bottom line
Your biggest controllable levers are dining out (€899 over 3 months, 73 transactions) and transport (you could save ~€150+/month by taking fewer DB trips). Groceries are actually quite reasonable — the issue is supplementing them heavily with restaurants.
Generated by Claude via the Kinti MCP tools — no custom prompting, just "tell me something interesting."
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript (strict) |
| Styling | Tailwind CSS 4 + shadcn/ui |
| Charts | Recharts (via shadcn/ui) |
| Database | SQLite via better-sqlite3 |
| ORM | Drizzle ORM + Drizzle Kit |
| Validation | Zod |
| MCP | @modelcontextprotocol/sdk |
- Node.js 20+
- npm
npm install -g kinti
kinti startStarts on port 4000. Data (database, logs, backups, receipts) is stored in ~/.kinti/ and persists across updates.
# Custom port or data directory
kinti start --port 3000 --data /path/to/data
# Update to the latest version
kinti updateOpen http://localhost:4000. You'll be prompted to configure your timezone and base currency to get started.
git clone https://github.com/psionski/kinti.git
cd kinti
npm install
# (Optional) Seed with 12 months of realistic sample data
npm run db:seed
# Start the dev server
npm run devIf you seeded sample data, you'll get an interactive tutorial that walks you through the UI — after which you can clear the sample data and start fresh.
Just tell your AI assistant:
Connect to the Kinti MCP server at
http://localhost:4000/api/mcp
Most modern AI clients (Claude, ChatGPT, etc.) handle the setup themselves. If yours needs manual configuration, the transport is Streamable HTTP and the endpoint is http://<host>:4000/api/mcp.
On first interaction, the AI will call get_started to learn about Kinti's conventions, then walk you through the full onboarding flow: setting your timezone, entering your current cash balance, adding savings accounts, and setting up investment tracking with automatic market prices.
| Command | Description |
|---|---|
npm run dev |
Start development server (port 4000) |
npm run build |
Build for production |
npm run start |
Start production server (port 4000) |
npm run db:generate |
Generate Drizzle migrations from schema changes |
npm run db:migrate |
Apply pending migrations |
npm run db:seed |
Seed database with 12 months of sample data |
npm run db:studio |
Open Drizzle Studio (DB browser) |
npm run check |
Typecheck + lint + format check |
npm run lint:fix |
Auto-fix lint issues |
npm run format:fix |
Auto-format all files |
npm test |
Run unit/integration tests (Vitest) |
npm run test:e2e |
Run E2E tests (Playwright) |
REST — Full OpenAPI-documented REST API. Swagger UI is available at /api-docs when the server is running, and the raw OpenAPI spec at /api/openapi.
MCP — 67 tools organized by domain: transactions, categories, budgets, recurring, receipts, reporting, portfolio reports, assets, financial data, backups, settings, and escape-hatch SQL. Connect any MCP client to /api/mcp. The get_started tool returns full usage instructions, conventions, and the onboarding flow.
Three entry points, one service layer:
Browser (React UI) ──▶ API Routes (/api/*) ──▶ Service Layer ──▶ SQLite
▲
AI Assistant ──▶ MCP Endpoint (/api/mcp) ──────┘
Server Components can also call services directly during SSR. All paths converge on the same services and the same database — no logic duplication.
Kinti is designed for self-hosted, single-user use. The recommended setup is to run it behind Tailscale — no auth layer needed, Tailscale provides mutual WireGuard authentication at the network level. Works on desktop, iOS, and Android.
See CONTRIBUTING.md.
AGPL-3.0 — free to use, modify, and self-host. If you run a modified version as a network service, you must share your source code.