Skip to main content
Glama
aroesec

moneybags

by aroesec

Moneybags

Un libro de contabilidad personal autoalojado con el que puedes hablar.

Importa extractos o sincroniza tus bancos. Las transacciones se clasifican primero por reglas y después por un modelo, y cada corrección que haces enseña una regla para que el mismo comercio nunca se clasifique mal dos veces. Luego pregunta sobre tu dinero en lenguaje natural: Moneybags ejecuta un servidor MCP, así que Claude lee tu libro de contabilidad directamente.

"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"

Un despliegue, un propietario. Tus transacciones viven en tu base de datos, tus claves API son tuyas y no hay ningún servicio en el medio.


Qué es y qué no es

Es un libro de contabilidad para alguien que quiere sus datos financieros en una base de datos que controla, con un clasificador que se puede corregir y una interfaz conversacional que no es un chatbot pegado a un panel.

No es una aplicación de presupuestos con cliente móvil y equipo de soporte. No hay registro, ni multiinquilino, ni versión alojada. Si quieres una aplicación a la que tu familia pueda entrar desde sus teléfonos, usa Monarch o YNAB; de verdad, son buenos en eso y esto no intenta serlo.

Ejecutarlo cuesta lo que cuesten tu base de datos y tus claves API. Para un libro de contabilidad personal en el plan gratuito de Neon con solo carga de extractos, eso es nada.

Related MCP server: OpenCoffer

Por qué el diseño es así

Casi cada decisión difícil en este código se trata de no perder dinero silenciosamente. No de fallar, sino de perder. Un libro que pierde una categoría es molesto; un libro que pierde 6.000 $ y sigue cuadrando es peligroso, porque parece correcto.

Estas son las reglas que se derivan de eso:

El dinero son céntimos enteros. bigint en el esquema, number en TypeScript. Los flotantes aparecen solo en el límite del formato. Nada suma un flotante, nunca.

Negativo significa que el dinero salió. Se aplica en el análisis, el almacenamiento, las matemáticas del libro y la interfaz, así que el flujo de caja neto de un período es un simple SUM(amount_cents) sin ramificaciones por fila. Un adaptador de importación que lo haga al revés produce un libro internamente coherente y completamente equivocado, por eso es lo único que se les dice dos veces a los adaptadores.

is_transfer no es una categoría. Significa este dólar exacto ya está contado en otro lugar de este libro: una transferencia interna que nombra la otra cuenta, o un pago de tarjeta de crédito cuyas compras también se importan. No es en absoluto para Venmo, Zelle, Cash App, retiros de cajero o aportaciones de ahorro. El dinero que salió es gasto, sea cual sea el medio por el que se movió.

Un medio de pago no es un comercio. «Venmo» te dice cómo se movió el dinero y nada sobre lo que se compró. Esas filas se cargan como gasto de inmediato, para que una pregunta sin respuesta nunca reduzca silenciosamente el total del mes, y se ponen en cola para que las etiquetes. Una respuesta enseña una regla clave para la contraparte.

Las clasificaciones manuales nunca se sobrescriben. Cada pasada automática filtra por classification_source <> 'manual'. Tu respuesta supera a cualquier regla y a cualquier modelo.

La deduplicación es por huella, no por extracto. sha256(account, date, amount, normalized description) con un índice único. Sube extractos superpuestos en cualquier orden; las filas ya presentes se omiten. La cuenta es parte de esa huella, por eso se rechaza una importación sin archivar cuando tienes más de una cuenta.

Los ingresos solo se pueden perder de una manera. Los totales se dividen por signo, así que una cantidad positiva cuenta como ingreso sea cual sea la categoría en la que caiga: una categoría imperfecta sigue contando, y un fallo de clasificación no cuesta nada. is_transfer es el único punto de fallo, así que una regla solo puede activarlo en una entrada cuando el patrón nombra un pago directamente o nombra la otra cuenta. pnpm db:audit-income lista cada entrada y cada regla que actualmente puede excluir una.

El clasificador se niega a adivinar. Las reglas se ejecutan primero. Lo que quede va a un modelo. Lo que aún no se resuelva cae en una cola de revisión, no en una respuesta equivocada con confianza; y las descripciones que estructuralmente no pueden llevar un propósito se saltan el modelo por completo, porque respondería «desconocido» cada vez a un costo.

Configuración

Node 20+, pnpm y una base de datos Postgres.

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

Rellena tres cosas:

# 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=...

Luego:

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

Eso es un libro de contabilidad funcional con importación de extractos CSV. Todo lo siguiente es opcional y la aplicación es honesta sobre lo que aporta cada cosa.

Opcional: un modelo

Configura AI_API_KEY. Obtienes clasificación asistida por modelo para comercios que ninguna regla reconoce, información redactada y lectura de extractos en PDF/imagen.

Sin ella, las reglas siguen clasificando, las filas no coincidentes van a la cola de revisión y la importación CSV no se ve afectada. Esa es una forma compatible de ejecutar esto, no una rota.

Cualquier proveedor funciona: Anthropic, OpenAI, OpenRouter, Groq, o un Ollama o LM Studio local. Consulta docs/ai.md. La lectura de PDF necesita Anthropic; cualquier otra función funciona en cualquier lugar.

Opcional: sincronización bancaria

Conecta cuentas a través de Plaid en lugar de subir extractos. El plan gratuito de Plaid cubre 10 conexiones e incluye transacciones.

No necesitas esto. La carga de extractos es una forma completa de usar la aplicación, y omitir Plaid significa un tercero menos con credenciales de tu banco. Consulta docs/plaid.md, que también explica la trampa del plan gratuito que conviene conocer antes de empezar.

Opcional: hablar con él

Configuración → emite un token MCP y luego apunta cualquier cliente MCP a https://your-host/api/mcp con ese token de portador. Catorce herramientas para leer, registrar y corregir. Deliberadamente no hay herramienta de borrado: una instrucción mal oída no debe poder destruir un registro.

Despliegue

Dos rutas documentadas, ninguna con privilegios sobre la otra:

Docker Compose — aplicación más Postgres, nada más necesario:

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

Vercel + Neon — plan gratuito, sin servidor que ejecutar.

Ambas están en docs/deploy.md, incluida la configuración de proxy inverso si quieres ponerlo detrás de Authelia o Tailscale.

Autenticación

Tres métodos; configura al menos uno o la aplicación se niega a iniciar en lugar de servir tus finanzas a cualquiera que encuentre la URL.

Método

Para

Contraseña

El predeterminado. Almacena un hash scrypt mediante pnpm auth:hash, no texto plano.

OIDC

Cualquier proveedor compatible con estándares: Google, Authentik, Keycloak, Zitadel, Okta. Se requiere una lista de permitidos; una vacía deniega a todos.

Encabezado de confianza

Ya detrás de Authelia, oauth2-proxy, Cloudflare Access o Tailscale. Solo es seguro cuando la aplicación es inalcanzable excepto a través del proxy.

El inicio de sesión tiene límite de velocidad, las contraseñas se comparan en tiempo constante, las sesiones son JWT firmados revocables en masa mediante SESSION_VERSION, y los tokens de acceso de Plaid están cifrados en reposo con AES-256-GCM. Consulta docs/security.md para el modelo de amenazas y lo que no protege.

Componibilidad

Las transacciones entran por un único límite: src/lib/sources. Todo lo posterior (deduplicación, conciliación, clasificación, el libro) solo ve ParsedTransaction[] y no puede saber si una fila llegó por carga o por sincronización.

Añadir un banco, un agregador o un dialecto CSV incómodo es un adaptador y nada más:

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

El proveedor de modelos está detrás del mismo tipo de costura: no se importa ningún SDK de proveedor fuera de src/lib/ai. docs/extending.md cubre la taxonomía, las reglas, las fuentes, los proveedores de sincronización y las herramientas MCP.

Comandos

pnpm dev · build · test · typecheck

lo habitual

pnpm auth:hash '<password>'

genera APP_PASSWORD_HASH

pnpm db:migratedb:seed

esquema, luego taxonomía

pnpm db:reclassify

vuelve a ejecutar el pipeline sobre el libro, omitiendo filas manuales

pnpm db:audit-income

verifica que ninguna entrada esté excluida de los ingresos

pnpm db:plaid-status

qué está vinculado y el límite de sincronización de cada cuenta

Pila

Next.js 15 (App Router), Postgres mediante Drizzle, Tailwind. El SDK de Anthropic y el SDK de Plaid son ambos opcionales en tiempo de ejecución y están aislados detrás de interfaces.

Contribuciones

CLAUDE.md documenta por qué las cosas son como son, normalmente nombrando el error que las causó. Léelo antes de tocar src/lib/classify o src/lib/reconcile: varias regresiones están fijadas por pruebas, y los comentarios dicen qué se rompe si las deshaces.

La regla general al cambiar el clasificador: prefiere sub-coincidir a sobre-coincidir. Una regla que nunca vuelve a activarse cuesta una re-corrección. Una regla que sobre-coincide reescribe silenciosamente historia que ya revisaste.

Licencia

MIT — consulta LICENSE.

Esto maneja datos financieros reales. No tiene garantía, y tu despliegue, claves y copias de seguridad son tu responsabilidad.

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