Skip to main content
Glama
mhopareprathmesh5-creator

expense-tracker-mcp

expense-tracker-mcp

Un servidor MCP remoto para llevar un seguimiento de gastos personales, respaldado por Postgres, diseñado para ser manejado por dos clientes diferentes: Claude como conector y un agente LangGraph personalizado.

Registra un gasto diciendo "gasté 450 en comestibles hoy", y luego pregunta "¿cuánto gasté en comida este mes?" — y obtén la misma respuesta de cualquiera de los dos clientes, porque el estado vive en una base de datos en lugar de en una sesión de chat.

Claude (connector) ─┐
                    ├─► expense-tracker-mcp ─► Neon Postgres
LangGraph agent ────┘        (FastMCP)

Estado

Fase

1

Base del servidor — herramientas tipadas, Postgres, validación de categorías

funciona localmente

2

Cliente LangGraph — terminal, create_react_agent, memoria con checkpoint

no iniciada

3

Interfaz Streamlit sobre el agente funcional

no iniciada

4

OAuth 2.1, consultas limitadas al usuario autenticado

no iniciada

La fase 1 está verificada de extremo a extremo contra una base de datos Neon real. El despliegue es el siguiente paso.

Related MCP server: expense-tracker-mcp-server

Herramientas

Herramienta

Propósito

list_categories

La taxonomía válida, para que el modelo pueda consultarla en lugar de adivinar.

add_expense

Registra un gasto. Valida la categoría antes de escribir.

list_expenses

Filas individuales, las más recientes primero. Filtros opcionales por rango de fechas y categoría.

summarize

Totales en un rango de fechas, agrupados por categoría — o por subcategoría cuando filtras a una categoría.

La taxonomía también se publica como recurso, expenses://categories. Esa duplicación es deliberada, y probar con Claude es lo que la puso ahí: los recursos son la primitiva MCP correcta para datos de referencia de solo lectura, pero un cliente solo lee uno cuando un usuario lo adjunta — a los modelos se les dan herramientas, no recursos. Al preguntar "¿qué categorías puedo usar?", Claude informó que la taxonomía no estaba disponible y ofreció escribir una fila basura para poder leer los valores válidos del error de rechazo. La herramienta es lo que el modelo realmente puede alcanzar; el recurso permanece para clientes que navegan recursos directamente.

Las categorías son una taxonomía fija de dos niveles definida en categories.json — 20 categorías, cada una con subcategorías. Cualquier cosa fuera de ella se rechaza con los valores válidos incluidos en el error, para que el modelo pueda corregirse en un solo viaje de ida y vuelta.

Ejecutarlo localmente

Requisitos previos: Python 3.10+, uv y una cuenta de Neon (el nivel gratuito es suficiente).

git clone https://github.com/<your-username>/expense-tracker-mcp
cd expense-tracker-mcp
uv sync

Configura la base de datos. Copia el archivo de ejemplo y completa tu cadena de conexión de Neon:

cp .env.example .env      # PowerShell: Copy-Item .env.example .env

Dos cosas importantes sobre esa cadena:

  • Usa la conexión agrupada — el host contiene -pooler.

  • Elimina la cadena de consulta ?sslmode=require&channel_binding=require. asyncpg no acepta los parámetros de consulta de libpq y lanzará invalid dsn: invalid connection option "sslmode". TLS se solicita explícitamente en el código en su lugar. (El servidor también elimina estos de forma defensiva, por lo que una cadena pegada sin procesar aún funciona).

Crea la tabla. Ejecuta schema.sql una vez, en el Editor SQL de Neon o en cualquier cliente de Postgres. Cada declaración es idempotente.

Inicia el servidor:

uv run python main.py            # http://127.0.0.1:8000/mcp

O explóralo interactivamente con el Inspector MCP (necesita Node):

uv run fastmcp dev inspector main.py

Una solicitud GET del navegador a /mcp devuelve 406 Not Acceptable. Eso es correcto, no un fallo — MCP requiere POST con Accept: application/json, text/event-stream.

Despliegue

Construido para Prefect Horizon (anteriormente FastMCP Cloud). Apúntalo a este repositorio con el punto de entrada main.py:mcp y establece DATABASE_URL en las variables de entorno. Los servidores desplegados obtienen una URL *.fastmcp.app, que se puede añadir directamente a Claude como conector.

Ten en cuenta que deliberadamente no hay archivo .python-version. Horizon compila con UV_PROJECT_ENVIRONMENT=/usr/local, un prefijo de Python del sistema en lugar de un virtualenv; una fijación de versión hace que uv lo rechace, descargue un CPython gestionado y falle al intentar recrear un directorio que no es venv. El requisito requires-python = ">=3.10" en pyproject.toml es suficiente.

Decisiones de diseño

El dinero es NUMERIC(12,2), nunca un flotante. El punto flotante binario no puede representar 0.1 exactamente, por lo que sumar cantidades flotantes acumula error y los totales se desvían por céntimos. Las cantidades son Decimal en Python, NUMERIC en Postgres y cruzan el cable como cadenas — los números JSON son dobles IEEE-754, por lo que serializar como flotante reintroduciría la desviación en el último paso. 450.55 + 120.45 devuelve exactamente 571.00.

El grupo de conexiones se crea de forma diferida, nunca en la importación. Conectar en el momento de la importación convierte un problema transitorio de base de datos en un despliegue fallido; un grupo diferido lo convierte en una llamada de herramienta fallida que el llamador puede reintentar. La creación del esquema es igualmente un script separado de una sola vez, no algo que el servidor haga al arrancar.

Cada parámetro está anotado. FastMCP construye el esquema JSON que el modelo ve a partir de las sugerencias de tipo, por lo que date: date llega al modelo como {"type": "string", "format": "date"} y amount lleva exclusiveMinimum: 0. Los parámetros sin tipo degradan notablemente la precisión de la llamada a herramientas — y la entrada inválida se rechaza mediante la validación del esquema antes de que el cuerpo de la herramienta se ejecute.

Cada herramienta devuelve un dict, tanto en éxito como en fallo, con una clave ok. Una herramienta que devuelve una lista en éxito y un dict en error obliga a cada llamador a verificar el tipo antes de usar el resultado.

user_id existe desde el primer día, con un valor predeterminado y actualmente sin uso; la fase 4 limita cada consulta por él. Añadir una columna NOT NULL a una tabla poblada más tarde es una migración — añadirla ahora es gratis. Deliberadamente no es un parámetro de herramienta: si el modelo pudiera elegir el user_id, cualquier cliente podría leer los gastos de cualquiera solo con preguntar.

El registro va a stderr. Sobre el transporte stdio, stdout es el canal JSON-RPC, y un print() suelto corrompe el flujo del protocolo.

Aún no implementado

Limitaciones honestas en lugar de descuidos:

  • Sin herramientas de edición o eliminación. Corregir un gasto mal registrado significa ir directamente a la base de datos. Diferido hasta que demuestre ser molesto en la práctica.

  • Sin columna de moneda. Se asume que cada cantidad está en una sola moneda.

  • Sin autenticación. Cada gasto se escribe como user_id = 'default', por lo que el servidor desplegado es de un solo inquilino hasta la fase 4.

Estructura

main.py           the server: three tools, one resource
schema.sql        one-time table + index creation
categories.json   the category taxonomy, single source of truth
.env.example      documents DATABASE_URL

Construido con

FastMCP 3 · asyncpg · Neon Postgres

F
license - not found
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

  • 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
    B
    quality
    D
    maintenance
    MCP server for tracking personal expenses using FastMCP and SQLite, enabling adding, listing, updating, deleting expenses and summarizing by category via natural language tools.
    5
    1
  • F
    license
    Not graded
    quality
    D
    maintenance
    A local MCP server for tracking personal expenses using SQLite, enabling users to add, list, and summarize expenses via natural language.
  • F
    license
    Not graded
    quality
    C
    maintenance
    MCP server for tracking expenses with local SQLite storage. Provides tools to add, list, and summarize expenses by category.

View all related MCP servers

Related MCP Connectors

  • Hosted MCP server for Mini Accountant: invoices, expenses, customers, analytics, tax estimates.

  • MCP server for managing Prisma Postgres.

  • GibsonAI MCP server: manage your databases with natural language

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/mhopareprathmesh5-creator/expense-tracker-mcp'

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