Skip to main content
Glama
aroesec

moneybags

by aroesec

Moneybags

Ein selbst gehostetes persönliches Finanz-Hauptbuch, mit dem du sprechen kannst.

Importiere Kontoauszüge oder synchronisiere deine Banken. Transaktionen werden zuerst durch Regeln und dann durch ein Modell kategorisiert, und jede Korrektur, die du vornimmst, lehrt eine Regel, sodass derselbe Händler nie zweimal falsch kategorisiert wird. Dann frag nach deinem Geld in einfacher Sprache – Moneybags betreibt einen MCP-Server, sodass Claude dein Hauptbuch direkt liest.

"How much did I spend on groceries in August?"
"I just bought coffee, about six dollars"
"That Venmo payment was for tree work, not uncategorized"

Eine Bereitstellung, ein Besitzer. Deine Transaktionen leben in deiner Datenbank, deine API-Schlüssel gehören dir, und es gibt keinen Dienst in der Mitte.


Was das ist und was nicht

Es ist ein Hauptbuch für jemanden, der seine Finanzdaten in einer Datenbank haben möchte, die er kontrolliert, mit einem Kategorisierer, der korrigiert werden kann, und einer Konversationsschnittstelle, die kein an ein Dashboard angeklebter Chatbot ist.

Es ist keine Budgetierungs-App mit einem mobilen Client und einem Support-Team. Es gibt keine Anmeldung, kein Multi-Tenancy, keine gehostete Version. Wenn du eine App möchtest, in der sich deine Familie auf ihren Telefonen anmelden kann, nutze Monarch oder YNAB – wirklich, die sind darin gut, und das versucht das hier nicht zu sein.

Der Betrieb kostet, was deine Datenbank und API-Schlüssel kosten. Für ein persönliches Hauptbuch auf Neons kostenlosem Tarif mit nur Kontoauszugs-Upload ist das nichts.

Related MCP server: OpenCoffer

Warum das Design so ist, wie es ist

Fast jede schwierige Entscheidung in dieser Codebasis dreht sich darum, kein Geld stillschweigend zu verlieren. Nicht abstürzen – verlieren. Ein Hauptbuch, das eine Kategorie fallen lässt, ist ärgerlich; ein Hauptbuch, das 6.000 $ fallen lässt und trotzdem ausgeglichen ist, ist gefährlich, weil es korrekt aussieht.

Das sind die Regeln, die daraus folgen:

Geld ist ganzzahlige Cent. bigint im Schema, number in TypeScript. Floats erscheinen nur an der Formatierungsgrenze. Nichts summiert jemals einen Float.

Negativ bedeutet Geld ausgegeben. Angewendet beim Parsen, Speichern, in der Hauptbuch-Mathematik und in der UI, sodass der Netto-Cashflow einer Periode ein einfaches SUM(amount_cents) ist, ohne Verzweigung pro Zeile. Ein Import-Adapter, der das umgekehrt macht, erzeugt ein Hauptbuch, das intern konsistent und völlig falsch ist – deshalb ist es das Einzige, was Adaptern zweimal gesagt wird.

is_transfer ist keine Kategorie. Es bedeutet dieser exakte Dollar wird bereits an anderer Stelle in diesem Hauptbuch gezählt – eine interne Überweisung, die das andere Konto nennt, oder eine Kreditkartenzahlung, deren Käufe ebenfalls importiert werden. Es ist ausdrücklich nicht für Venmo, Zelle, Cash App, Geldautomaten-Abhebungen oder Sparbeiträge gedacht. Geld, das ausgegangen ist, ist Ausgabe, egal auf welchem Weg.

Ein Zahlungsweg ist kein Händler. „Venmo“ sagt dir, wie Geld bewegt wurde, und nichts darüber, was gekauft wurde. Diese Zeilen werden sofort als Ausgabe verbucht – damit eine unbeantwortete Frage nie stillschweigend die Monatssumme reduziert – und zur Beschriftung für dich in die Warteschlange gestellt. Eine Antwort lehrt eine Regel, die auf den Gegenpartei-Schlüssel ausgerichtet ist.

Manuelle Klassifizierungen werden nie überschrieben. Jeder automatisierte Durchlauf filtert nach classification_source <> 'manual'. Deine Antwort hat Vorrang vor jeder Regel und jedem Modell.

Deduplizierung erfolgt per Fingerabdruck, nicht per Kontoauszug. sha256(account, date, amount, normalized description) mit einem eindeutigen Index. Lade überlappende Kontoauszüge in beliebiger Reihenfolge hoch; bereits vorhandene Zeilen werden übersprungen. Das Konto ist Teil dieses Fingerabdrucks, weshalb ein nicht zugeordneter Import abgelehnt wird, sobald du mehr als ein Konto hast.

Einkommen kann nur auf eine Weise verloren gehen. Summen werden nach Vorzeichen getrennt, sodass ein positiver Betrag als Einkommen zählt, egal in welche Kategorie er fällt – eine unvollkommene Kategorie zählt trotzdem, und ein Klassifizierungsfehler kostet nichts. is_transfer ist der einzige Fehlerpunkt, daher darf eine Regel es nur bei einem Zufluss setzen, wenn das Muster eine Zahlung eindeutig benennt oder das andere Konto nennt. pnpm db:audit-income listet jeden Zufluss und jede Regel auf, die derzeit einen ausschließen kann.

Der Klassifizierer weigert sich zu raten. Regeln laufen zuerst. Was übrig bleibt, geht an ein Modell. Alles, was immer noch ungelöst ist, landet in einer Überprüfungswarteschlange, nicht in einer selbstbewussten falschen Antwort – und Beschreibungen, die strukturell keinen Zweck tragen können, überspringen das Modell vollständig, weil es jedes Mal „unbekannt“ antworten würde, und das kostet.

Einrichtung

Node 20+, pnpm und eine Postgres-Datenbank.

git clone https://github.com/YOUR-USERNAME/moneybags && cd moneybags
pnpm install
cp .env.example .env.local

Fülle drei Dinge aus:

# 1. Your database
DATABASE_URL="postgresql://..."

# 2. A session secret
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"

# 3. A password
pnpm auth:hash 'the password you want'      # prints APP_PASSWORD_HASH=...

Dann:

pnpm db:migrate
pnpm db:seed        # idempotent; seeds the category taxonomy
pnpm dev

Das ist ein funktionierendes Hauptbuch mit CSV-Kontoauszugs-Import. Alles unten ist optional, und die App ist ehrlich darüber, was jede Option hinzufügt.

Optional: ein Modell

Setze AI_API_KEY. Du erhältst modellgestützte Kategorisierung für Händler, die keine Regel erkennt, aufbereitete Einblicke und das Lesen von PDF-/Bild-Kontoauszügen.

Ohne sie kategorisieren weiterhin Regeln, nicht zugeordnete Zeilen gehen in die Überprüfungswarteschlange, und der CSV-Import bleibt unberührt. Das ist eine unterstützte Art, das zu betreiben, keine kaputte.

Jeder Anbieter funktioniert – Anthropic, OpenAI, OpenRouter, Groq oder ein lokales Ollama oder LM Studio. Siehe docs/ai.md. PDF-Lesen benötigt Anthropic; jede andere Funktion funktioniert überall.

Optional: Bank-Synchronisierung

Verbinde Konten über Plaid, anstatt Kontoauszüge hochzuladen. Plaids kostenloser Tarif umfasst 10 Verbindungen und beinhaltet Transaktionen.

Das brauchst du nicht. Kontoauszugs-Upload ist eine vollständige Möglichkeit, die App zu nutzen, und Plaid zu überspringen bedeutet, dass eine dritte Partei weniger Zugangsdaten zu deiner Bank hat. Siehe docs/plaid.md, das auch die Kostenfalle des kostenlosen Tarifs erklärt, die du kennen solltest, bevor du beginnst.

Optional: mit ihm sprechen

Einstellungen → ein MCP-Token ausstellen, dann jeden MCP-Client auf https://your-host/api/mcp mit diesem Bearer-Token richten. Vierzehn Werkzeuge zum Lesen, Protokollieren und Korrigieren. Es gibt bewusst kein Löschwerkzeug – eine falsch verstandene Anweisung darf keinen Datensatz zerstören.

Bereitstellung

Zwei dokumentierte Wege, keiner hat Vorrang vor dem anderen:

Docker Compose – App plus Postgres, sonst nichts nötig:

cp .env.example .env    # set APP_PASSWORD_HASH and SESSION_SECRET
docker compose up -d

Vercel + Neon – kostenloser Tarif, kein Server zu betreiben.

Beide sind in docs/deploy.md, einschließlich des Reverse-Proxy-Setups, falls du es hinter Authelia oder Tailscale haben möchtest.

Authentifizierung

Drei Methoden; konfiguriere mindestens eine, sonst weigert sich die App zu starten, anstatt deine Finanzen jedem zu servieren, der die URL findet.

Methode

Zweck

Passwort

Die Standardmethode. Speichere einen scrypt-Hash über pnpm auth:hash, nicht im Klartext.

OIDC

Jeder standardkonforme Anbieter – Google, Authentik, Keycloak, Zitadel, Okta. Eine Zulassungsliste ist erforderlich; eine leere verweigert allen den Zugriff.

Vertrauter Header

Bereits hinter Authelia, oauth2-proxy, Cloudflare Access oder Tailscale. Nur sicher, wenn die App außer über den Proxy nicht erreichbar ist.

Die Anmeldung ist ratenbegrenzt, Passwörter werden in konstanter Zeit verglichen, Sitzungen sind signierte JWTs, die über SESSION_VERSION in großen Mengen widerrufen werden können, und Plaid-Zugriffstokens sind im Ruhezustand mit AES-256-GCM verschlüsselt. Siehe docs/security.md für das Bedrohungsmodell und wogegen es nicht schützt.

Komponierbarkeit

Transaktionen gelangen über eine Grenze: src/lib/sources. Alles nachgelagerte – Deduplizierung, Abgleich, Klassifizierung, das Hauptbuch – sieht nur ParsedTransaction[] und kann nicht erkennen, ob eine Zeile per Upload oder Synchronisierung angekommen ist.

Eine Bank, einen Aggregator oder einen sperrigen CSV-Dialekt hinzuzufügen ist ein Adapter und sonst nichts:

registerFileSource({
  id: "my-bank",
  label: "My Bank CSV",
  accepts: ({ filename }) => filename.startsWith("mybank-"),
  parse: ({ bytes }) => ({ transactions: parseMyBank(bytes), warnings: [] }),
});

Der Modellanbieter steckt hinter derselben Art von Naht – kein Vendor-SDK wird außerhalb von src/lib/ai importiert. docs/extending.md behandelt die Taxonomie, Regeln, Quellen, Synchronisierungsanbieter und MCP-Werkzeuge.

Befehle

pnpm dev · build · test · typecheck

das Übliche

pnpm auth:hash '<password>'

APP_PASSWORD_HASH generieren

pnpm db:migratedb:seed

Schema, dann Taxonomie

pnpm db:reclassify

Pipeline über das Hauptbuch erneut ausführen, manuelle Zeilen überspringen

pnpm db:audit-income

prüfen, dass kein Zufluss vom Einkommen ausgeschlossen wird

pnpm db:plaid-status

was verknüpft ist und die Synchronisierungsgrenze jedes Kontos

Technologie-Stack

Next.js 15 (App Router), Postgres über Drizzle, Tailwind. Das Anthropic SDK und das Plaid SDK sind beide zur Laufzeit optional und hinter Schnittstellen isoliert.

Mitwirken

CLAUDE.md dokumentiert, warum die Dinge so sind, wie sie sind, und nennt normalerweise den Fehler, der sie verursacht hat. Lies es, bevor du src/lib/classify oder src/lib/reconcile anfasst – mehrere Regressionen sind durch Tests fixiert, und die Kommentare sagen, was bricht, wenn du sie rückgängig machst.

Die allgemeine Regel beim Ändern des Klassifizierers: Unter-Übereinstimmung der Über-Übereinstimmung vorziehen. Eine Regel, die nie wieder greift, kostet eine erneute Korrektur. Eine Regel, die übermäßig übereinstimmt, schreibt stillschweigend Geschichte um, die du bereits geprüft hast.

Lizenz

MIT – siehe LICENSE.

Das verarbeitet echte Finanzdaten. Es kommt ohne Garantie, und deine Bereitstellung, Schlüssel und Backups liegen in deiner Verantwortung.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables users to track personal expenses through natural language interactions with comprehensive category support and financial summaries. Provides both local and remote MCP server options with SQLite storage for fast expense management operations.
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables querying personal finance data including accounts, transactions, spending, holdings, net worth, and budgets from your self-hosted OpenCoffer instance. Supports natural language queries through any MCP-compatible client.
    14
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Personal expense tracker MCP server that enables tracking expenses, income, budgets, and savings goals through natural language.
    10
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Exposes personal-finance tools like accounts, transactions, spending analysis, budgets, bills, reminders, portfolio, and goals via MCP, enabling any MCP client to query financial data.

View all related MCP servers

Related MCP Connectors

  • Personal finance by conversation: expenses, receipts, statement import, budgets, net worth.

  • Log, query, and edit expenses, budgets, and accounts in Ledgy from any MCP-compatible AI assistant.

  • Ask your AI about bank accounts, spending, debts, holdings, and investment activity.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aroesec/moneybags'

If you have feedback or need assistance with the MCP directory API, please join our Discord server