budget-mcp
MCP que permite a tu agente gestionar una base de datos de presupuesto personal
Documentación
💰 Servidor MCP de Presupuesto Personal
Gestiona tus finanzas personales conversando con un LLM. Un servidor MCP que ofrece a cualquier cliente compatible con MCP herramientas tipadas para registrar transacciones, gestionar una biblioteca de categorías y analizar gastos, además de paneles interactivos renderizados directamente en el cliente de chat.
Construido con Python, FastMCP, SQLAlchemy, SQLite y PostgreSQL.
Por qué existe esto
El chat es una buena interfaz para registrar gastos. "Gasté 42 £ en Tesco y 8 £ en café" es más rápido que abrir una aplicación y rellenar dos formularios, y un LLM puede categorizarlo por ti.
El problema es que un LLM sin herramientas te dirá felizmente que ha registrado tu transacción. Para que esto funcione, el modelo debe ser incapaz de confundir "he registrado esto" con "he descrito que registro esto" — por lo que las herramientas deben devolver un éxito o fracaso inequívoco, rechazar entradas incorrectas en lugar de adaptarlas, y exponer suficiente superficie de consulta para que el agente lea el estado real en lugar de reconstruirlo a partir del historial de la conversación.
Ese problema de diseño es el verdadero propósito de este repositorio. El presupuesto es la excusa.
📸 Capturas de pantalla
| Panel de presupuesto | Tendencias de gasto |
|---|---|
![]() | ![]() |
🧠 Notas de diseño: hacer que las llamadas del agente sean fiables
Fallo explícito en lugar de coerción silenciosa. Las herramientas validan la entrada y devuelven un error estructurado que indica qué falló, en lugar de adivinar la intención. Un type inválido, una fecha mal formada o un category_id que no existe fallan de forma visible, para que el agente pueda corregirse e informar con precisión al usuario en lugar de inventar una confirmación.
Herramientas de escritura orientadas a lotes. add_transaction, update_transaction, delete_transaction y add_category aceptan tanto un solo elemento como una lista de items. Los agentes manejan naturalmente varias cosas a la vez ("registra estos cinco gastos"), y obligarlos a una llamada por registro multiplica la latencia y el número de lugares donde puede ocultarse un fallo parcial.
Integridad referencial en el límite de la herramienta. delete_category acepta un reassign_to_category_id opcional, por lo que eliminar una categoría no puede dejar transacciones huérfanas silenciosamente. La decisión de integridad se expone como un parámetro sobre el que el agente debe razonar, en lugar de un efecto secundario que descubre más tarde.
Superficie de lectura dimensionada para uso multiturno. get_summary, get_transactions y get_uncategorized_transactions cubren lecturas agregadas, detalladas y de triaje con argumentos de filtro consistentes en las tres. get_uncategorized_transactions devuelve resultados ordenados por descripción específicamente para que un agente pueda categorizar importaciones masivas en grupos coherentes en lugar de fila por fila.
Arranque de esquema idempotente. Las tablas y 15 categorías predeterminadas se crean en el primer arranque, por lo que un clon nuevo o un despliegue en la nube es inmediatamente utilizable y no hay estado parcialmente inicializado en el que pueda aterrizar una llamada de herramienta.
✨ Características
- Almacenamiento local o en la nube — SQLite sin configuración (en memoria o
data/budget.db), o PostgreSQL a través de cualquier proveedor como Neon. - Paneles interactivos en el cliente — gráficos circulares de categorías y tablas de transacciones buscables renderizados mediante
prefab-ui, devueltos como aplicaciones de interfaz MCP en lugar de texto plano. - Tendencias de gasto — gráfico de líneas continuo por categoría con alternancia de granularidad mes/semana/día, control deslizante de rango de fechas y tabla buscable.
- Operaciones por lotes — escritura de un solo elemento o masiva en transacciones y categorías.
- Entorno reproducible —
uvpara una resolución de dependencias rápida y bloqueada. - Amplio soporte de clientes — Claude Desktop, Claude Code, Cursor, Goose, Open WebUI y cualquier otro host MCP.
🚀 Inicio rápido
git clone https://github.com/PedroLiu1999/budget-mcp.git
cd budget-mcp
uv sync
uv run pytest # confirm the install works
uv run server.py # start the server (in-memory SQLite by default)
Luego regístralo con tu cliente — Claude Code es el comando de una línea:
claude mcp add budget -- uv run --directory "/absolute/path/to/budget-mcp" server.py
Para persistir datos, establece DATABASE_URL en un archivo .env primero (consulta Configuración de base de datos).
🛠 Herramientas disponibles
12 herramientas — haz clic para expandir la referencia completa
| Herramienta | Descripción | Argumentos |
|---|---|---|
budget_dashboard | Aplicación de interfaz interactiva: gráfico de desglose por categorías y tabla de transacciones buscable. | search (str, opt)month (str YYYY-MM, opt)type (income|expense, opt)limit (int, predeterminado 100) |
spending_trends | Aplicación de interfaz interactiva: gasto a lo largo del tiempo con gráfico de líneas por categoría, alternancia de granularidad, control deslizante de rango de fechas y tabla buscable. | granularity (month|week|day, predeterminado month)days_range (lista de rango [start, end], opt)category_id (int, opt)type (expense|income, opt)start_date (str, opt)end_date (str, opt)limit (int, predeterminado 1000) |
add_transaction | Registra una o muchas transacciones de ingreso/gasto. | items (lista de dicts, opt — lote)amount (float, opt)category_id (int, opt)description (str, opt)type (expense|income, opt)date (str YYYY-MM-DD, opt) |
get_summary | Resumen agregado: ingresos, gastos, saldo neto, desglose opcional por categoría. | month (str YYYY-MM, opt)start_date / end_date (str YYYY-MM-DD, opt)category_id (int, opt)type (income|expense, opt)by_category (bool, predeterminado False) |
get_transactions | Registros detallados de transacciones por filtro. | category_id (int, opt)type (income|expense, opt)month (str, opt)start_date / end_date (str, opt)min_amount / max_amount (float, opt)search (str, opt)limit (int, predeterminado 50) |
get_uncategorized_transactions | Transacciones sin categorizar ordenadas por descripción, para categorización masiva. | type (income|expense, opt)search (str, opt)limit (int, predeterminado 100) |
update_transaction | Actualiza una o muchas transacciones. | items (lista de dicts de actualización, opt)transaction_id (int, opt)amount (float, opt)category_id (int, opt)description (str, opt)type (str, opt)date (str YYYY-MM-DD, opt) |
delete_transaction | Elimina una o muchas transacciones por ID. | transaction_ids (int o lista de int) |
list_categories | Lista las categorías activas. | type (expense|income, opt) |
add_category | Añade una o muchas categorías. | items (lista de dicts, opt)name (str, opt)type (expense|income, opt)description (str, opt) |
update_category | Actualiza las propiedades de una categoría. | category_id_or_name (str)new_name (str, opt)type (str, opt)description (str, opt) |
delete_category | Elimina una o muchas categorías, reasignando opcionalmente sus transacciones. | category_ids_or_names (str, int o lista)reassign_to_category_id (int, opt) |
⚙️ Configuración de base de datos
Se establece mediante la variable de entorno DATABASE_URL en un archivo .env. Mantén .env fuera del control de versiones.
SQLite local — en memoria (predeterminado si DATABASE_URL no está establecido):
DATABASE_URL=sqlite:///:memory:
Archivo SQLite local — persiste entre reinicios:
DATABASE_URL=sqlite:///data/budget.db
PostgreSQL / Neon:
DATABASE_URL=postgresql://<user>:<password>@<hostname>/<dbname>?sslmode=require
Las tablas y 15 categorías semilla predeterminadas se crean automáticamente en el primer arranque.
🔌 Configuración del cliente
Claude Code, Claude Desktop, Cursor, Open WebUI
Claude Code (CLI)
claude mcp add budget -- uv run --directory "/absolute/path/to/budget-mcp" server.py
Claude Desktop
Añade a claude_desktop_config.json:
{
"mcpServers": {
"personal-budget": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/budget-mcp", "server.py"]
}
}
}
IDE Cursor
Configuración → Funciones → MCP → Añadir nuevo servidor MCP
- Tipo:
command - Nombre:
budget-mcp - Comando:
uv run --directory "/absolute/path/to/budget-mcp" server.py
Open WebUI
Puentea el servidor stdio sobre HTTP con mcpo:
uvx mcpo --port 8000 -- uv run server.py
Luego, en Panel de administración → Configuración → Herramientas externas, añade la URL de conexión OpenAPI http://localhost:8000 (o http://host.docker.internal:8000 desde Docker).
☁️ Despliegue en la nube
Para hosts remotos, Docker o plataformas como Horizon:
- Establece
DATABASE_URLa una cadena de conexión PostgreSQL en la nube en el entorno de despliegue — SQLite en memoria no persistirá entre reinicios. - Apunta el ejecutor a la aplicación ASGI:
fastmcp run server.py:mcp
Las tablas del esquema y las categorías predeterminadas se inicializan al importar, por lo que no se necesita ningún paso de migración en el primer arranque.
🧪 Pruebas
uv run pytest
Inspecciona las herramientas interactivamente con el Inspector FastMCP:
uv run fastmcp dev inspector server.py:mcp
O previsualiza aplicaciones de interfaz interactivas directamente en el navegador:
uv run fastmcp dev apps server.py:mcp
📝 Licencia
MIT — consulta LICENCIA.

