Skip to main content
Glama
mhopareprathmesh5-creator

expense-tracker-mcp

expense-tracker-mcp

Удалённый MCP сервер для учёта личных расходов на базе Postgres, рассчитанный на работу с двумя разными клиентами: Claude в роли коннектора и кастомным агентом на LangGraph.

Запишите расход фразой «потратил 450 на продукты сегодня», затем спросите «сколько я потратил на еду в этом месяце?» — и получите одинаковый ответ от любого клиента, потому что состояние хранится в базе данных, а не в чат-сессии.

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

Статус

Фаза

1

Фундамент сервера — типизированные инструменты, Postgres, валидация категорий

работает локально

2

Клиент LangGraph — терминал, create_react_agent, память с чекпоинтами

не начато

3

Фронтенд на Streamlit поверх работающего агента

не начато

4

OAuth 2.1, запросы, ограниченные аутентифицированным пользователем

не начато

Фаза 1 проверена от начала до конца на реальной базе Neon. Развёртывание — следующий шаг.

Related MCP server: expense-tracker-mcp-server

Инструменты

Инструмент

Назначение

list_categories

Допустимая таксономия, чтобы модель могла её найти, а не угадывать.

add_expense

Записать один расход. Проверяет категорию перед записью.

list_expenses

Отдельные строки, сначала новые. Необязательные фильтры по диапазону дат и категории.

summarize

Итоги за диапазон дат, сгруппированные по категории — или по подкатегории, если отфильтровать по одной категории.

Таксономия также публикуется как ресурс, expenses://categories. Это дублирование намеренно, и именно тестирование с Claude привело к нему: ресурсы — правильный примитив MCP для справочных данных только для чтения, но клиент читает их только тогда, когда пользователь их прикрепляет — моделям выдаются инструменты, а не ресурсы. На вопрос «какие категории я могу использовать?» Claude сообщил, что таксономия недоступна, и предложил записать мусорную строку, чтобы прочитать допустимые значения из ошибки отклонения. Инструмент — это то, до чего модель реально может дотянуться; ресурс остаётся для клиентов, которые просматривают ресурсы напрямую.

Категории — это фиксированная двухуровневая таксономия, определённая в categories.json — 20 категорий, у каждой есть подкатегории. Всё, что вне её, отклоняется с включением допустимых значений в ошибку, так что модель может исправиться за один цикл.

Запуск локально

Предварительные требования: Python 3.10+, uv и аккаунт Neon (бесплатного тарифа достаточно).

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

Настройте базу данных. Скопируйте пример файла и заполните строку подключения к Neon:

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

В этой строке важны две вещи:

  • Используйте пулированное подключение — хост содержит -pooler.

  • Удалите строку запроса ?sslmode=require&channel_binding=require. asyncpg не принимает параметры запроса libpq и вызовет invalid dsn: invalid connection option "sslmode". TLS запрашивается явно в коде. (Сервер также удаляет их на всякий случай, так что даже сырая вставленная строка работает.)

Создайте таблицу. Выполните schema.sql один раз в SQL-редакторе Neon или любом клиенте Postgres. Каждый оператор идемпотентен.

Запустите сервер:

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

Или исследуйте его интерактивно с помощью MCP Inspector (требуется Node):

uv run fastmcp dev inspector main.py

Браузерный GET на /mcp возвращает 406 Not Acceptable. Это правильно, а не сбой — MCP требует POST с Accept: application/json, text/event-stream.

Развёртывание

Создан для Prefect Horizon (ранее FastMCP Cloud). Укажите этот репозиторий с точкой входа main.py:mcp и задайте DATABASE_URL в переменных окружения. Развёрнутые серверы получают URL вида *.fastmcp.app, который можно добавить напрямую в Claude как коннектор.

Обратите внимание: намеренно нет файла .python-version. Horizon собирает с UV_PROJECT_ENVIRONMENT=/usr/local, системным префиксом Python, а не виртуальным окружением; фиксация версии заставит uv отклонить его, скачать управляемый CPython и потерпеть неудачу при попытке воссоздать не-venv каталог. Нижней границы requires-python = ">=3.10" в pyproject.toml достаточно.

Архитектурные решения

Деньги — это NUMERIC(12,2), никогда не float. Двоичная плавающая точка не может точно представить 0.1, поэтому суммирование float-сумм накапливает ошибку, и итоги расходятся на центы. Суммы — это Decimal в Python, NUMERIC в Postgres и передаются по сети как строки — JSON-числа являются IEEE-754 double, так что сериализация как float вернула бы дрейф на самом последнем шаге. 450.55 + 120.45 возвращает ровно 571.00.

Пул подключений создаётся лениво, никогда при импорте. Подключение при импорте превращает временную проблему с базой данных в неудачное развёртывание; ленивый пул превращает её в один неудачный вызов инструмента, который вызывающий может повторить. Создание схемы также является отдельным одноразовым скриптом, а не тем, что сервер делает при запуске.

Каждый параметр аннотирован. FastMCP строит JSON-схему, которую видит модель, из подсказок типов, поэтому date: date доходит до модели как {"type": "string", "format": "date"}, а amount несёт exclusiveMinimum: 0. Нетипизированные параметры заметно ухудшают точность вызова инструментов — и недопустимый ввод отклоняется валидацией схемы до того, как тело инструмента вообще выполнится.

Каждый инструмент возвращает dict, как при успехе, так и при ошибке, с ключом ok. Инструмент, который возвращает список при успехе и dict при ошибке, заставляет каждого вызывающего проверять тип перед использованием результата.

user_id существует с первого дня, имеет значение по умолчанию и пока не используется; фаза 4 ограничивает каждый запрос по нему. Добавление столбца NOT NULL в заполненную таблицу позже — это миграция; добавить его сейчас — бесплатно. Он намеренно не является параметром инструмента: если бы модель могла выбирать user_id, любой клиент мог бы читать чужие расходы, просто спросив.

Логирование идёт в stderr. При stdio-транспорте stdout является каналом JSON-RPC, и случайный print() повреждает поток протокола.

Ещё не реализовано

Честные ограничения, а не упущения:

  • Нет инструментов редактирования или удаления. Исправление неправильно записанного расхода означает прямое обращение к базе данных. Отложено, пока это не станет раздражать на практике.

  • Нет столбца валюты. Предполагается, что все суммы в одной валюте.

  • Нет аутентификации. Каждый расход записывается как user_id = 'default', поэтому развёрнутый сервер является однопользовательским до фазы 4.

Структура

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

Создано с помощью

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