moneybags
Moneybags
Самостоятельно размещаемый реестр личных финансов, с которым можно разговаривать.
Импортируйте выписки или синхронизируйте банки. Транзакции сначала категоризируются по правилам, а затем моделью, и каждое ваше исправление обучает правило, чтобы один и тот же мерчант никогда не был ошибочно категоризирован дважды. Затем спрашивайте о своих деньгах на простом языке — Moneybags запускает MCP-сервер, поэтому Claude читает ваш реестр напрямую.
"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"Одно развёртывание, один владелец. Ваши транзакции хранятся в вашей базе данных, ваши API-ключи принадлежат вам, и никакого посредника в виде сервиса нет.
Что это такое, а что нет
Это реестр для того, кто хочет хранить свои финансовые данные в базе данных, которой управляет сам, с категоризатором, который можно исправлять, и разговорным интерфейсом, который не является чат-ботом, прикрученным к панели управления.
Это не приложение для бюджетирования с мобильным клиентом и службой поддержки. Здесь нет регистрации, нет мультитенантности, нет хостинговой версии. Если вам нужно приложение, в которое ваша семья может войти со своих телефонов, используйте Monarch или YNAB — честно, они в этом хороши, и это не пытается им подражать.
Запуск стоит столько, сколько стоят ваша база данных и API-ключи. Для личного реестра на бесплатном тарифе Neon с загрузкой только выписок это ничего не стоит.
Related MCP server: OpenCoffer
Почему дизайн именно такой
Почти каждое сложное решение в этой кодовой базе касается не тихой потери денег. Не падения — потери. Реестр, который теряет категорию, раздражает; реестр, который теряет 6000 долларов и при этом сходится, опасен, потому что выглядит правильным.
Вот правила, которые из этого следуют:
Деньги — это целые центы. bigint в схеме, number в TypeScript. Числа с плавающей запятой появляются только на границе форматирования. Ничто никогда не суммирует float.
Отрицательное означает, что деньги ушли. Это применяется при парсинге, хранении, в математике реестра и в интерфейсе, поэтому чистый денежный поток за период — это просто SUM(amount_cents) без ветвления по каждой строке. Адаптер импорта, который перепутает это, создаст реестр, который внутренне согласован и полностью неверен, поэтому это единственное, о чём адаптерам говорят дважды.
is_transfer — это не категория. Это означает этот самый доллар уже учтён где-то ещё в этом реестре — внутренний перевод, который называет другой счёт, или оплата кредитной карты, покупки по которой также импортированы. Это категорически не для Venmo, Zelle, Cash App, снятия наличных в банкомате или пополнения сбережений. Деньги, которые ушли, — это расходы, независимо от того, по какому каналу они прошли.
Платёжный канал — это не мерчант. «Venmo» говорит вам, как двигались деньги, и ничего о том, что на них куплено. Эти строки сразу списываются как расходы — чтобы неотвеченный вопрос никогда тихо не уменьшал итог месяца — и ставятся в очередь для вашей пометки. Один ответ обучает правило, привязанное к контрагенту.
Ручные классификации никогда не перезаписываются. Каждый автоматический проход фильтрует по classification_source <> 'manual'. Ваш ответ имеет приоритет над любым правилом и любой моделью.
Дедупликация по отпечатку, а не по выписке. sha256(account, date, amount, normalized description) с уникальным индексом. Загружайте перекрывающиеся выписки в любом порядке; строки, которые уже есть, пропускаются. Счёт является частью этого отпечатка, поэтому незарегистрированный импорт отклоняется, как только у вас появляется более одного счёта.
Доход может быть потерян только одним способом. Итоги разделяются по знаку, поэтому положительная сумма считается доходом, в какую бы категорию она ни попала — несовершенная категория всё равно учитывается, а сбой классификации ничего не стоит. is_transfer — единственная точка отказа, поэтому правило может установить его на входящий платёж только в том случае, если шаблон прямо называет платёж или называет другой счёт. pnpm db:audit-income выводит список всех входящих платежей и всех правил, которые в настоящее время могут исключить один из них.
Классификатор отказывается угадывать. Сначала выполняются правила. Всё, что осталось, передаётся модели. Всё, что всё ещё не разрешено, попадает в очередь на проверку, а не в уверенный неверный ответ — и описания, которые структурно не могут нести цель, вообще пропускают модель, потому что она каждый раз отвечала бы «неизвестно» за деньги.
Установка
Node 20+, pnpm и база данных Postgres.
git clone https://github.com/YOUR-USERNAME/moneybags && cd moneybags
pnpm install
cp .env.example .env.localЗаполните три пункта:
# 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=...Затем:
pnpm db:migrate
pnpm db:seed # idempotent; seeds the category taxonomy
pnpm devЭто рабочий реестр с импортом выписок CSV. Всё ниже — опционально, и приложение честно говорит, что добавляет каждый пункт.
Опционально: модель
Установите AI_API_KEY. Вы получите категоризацию с помощью модели для мерчантов, которых не распознаёт ни одно правило, письменные аналитические сводки и чтение выписок из PDF/изображений.
Без неё правила по-прежнему категоризируют, нераспознанные строки попадают в очередь на проверку, а импорт CSV не затрагивается. Это поддерживаемый способ запуска, а не сломанный.
Подойдёт любой провайдер — Anthropic, OpenAI, OpenRouter, Groq или локальный Ollama или LM Studio. См. docs/ai.md. Чтение PDF требует Anthropic; все остальные функции работают где угодно.
Опционально: синхронизация банков
Подключайте счета через Plaid вместо загрузки выписок. Бесплатный тариф Plaid покрывает 10 подключений и включает транзакции.
Вам это не нужно. Загрузка выписок — это полноценный способ использования приложения, а отказ от Plaid означает на одного третьего участника меньше, у которого есть доступ к вашим банковским учётным данным. См. docs/plaid.md, где также объясняется ловушка бесплатного тарифа, о которой стоит знать перед началом.
Опционально: разговор с ним
Настройки → выпустите MCP-токен, затем укажите любому MCP-клиенту на https://your-host/api/mcp с этим bearer-токеном. Четырнадцать инструментов для чтения, записи и исправления. Намеренно нет инструмента удаления — неправильно понятая инструкция не должна иметь возможности уничтожить запись.
Развёртывание
Два документированных пути, ни один не имеет преимущества перед другим:
Docker Compose — приложение плюс Postgres, больше ничего не нужно:
cp .env.example .env # set APP_PASSWORD_HASH and SESSION_SECRET
docker compose up -dVercel + Neon — бесплатный тариф, не нужно запускать сервер.
Оба описаны в docs/deploy.md, включая настройку обратного прокси, если вы хотите разместить его за Authelia или Tailscale.
Аутентификация
Три метода; настройте хотя бы один, иначе приложение откажется запускаться, а не будет обслуживать ваши финансы для любого, кто найдёт URL.
Метод | Для чего |
Пароль | По умолчанию. Храните scrypt-хэш через |
OIDC | Любой провайдер, соответствующий стандартам — Google, Authentik, Keycloak, Zitadel, Okta. Требуется список разрешённых; пустой список запрещает доступ всем. |
Доверенный заголовок | Уже за Authelia, oauth2-proxy, Cloudflare Access или Tailscale. Безопасно только тогда, когда приложение недоступно иначе, кроме как через прокси. |
Вход ограничен по частоте, пароли сравниваются за постоянное время, сеансы — это подписанные JWT, отзываемые массово через SESSION_VERSION, а токены доступа Plaid зашифрованы AES-256-GCM в состоянии покоя. См. docs/security.md для модели угроз и того, от чего она не защищает.
Компонуемость
Транзакции поступают через одну границу: src/lib/sources. Всё ниже по потоку — дедупликация, сверка, классификация, реестр — видит только ParsedTransaction[] и не может определить, пришла ли строка через загрузку или синхронизацию.
Добавление банка, агрегатора или неудобного диалекта CSV — это адаптер и ничего больше:
registerFileSource({
id: "my-bank",
label: "My Bank CSV",
accepts: ({ filename }) => filename.startsWith("mybank-"),
parse: ({ bytes }) => ({ transactions: parseMyBank(bytes), warnings: [] }),
});Провайдер модели находится за таким же швом — ни один SDK вендора не импортируется за пределами src/lib/ai. docs/extending.md описывает таксономию, правила, источники, провайдеров синхронизации и MCP-инструменты.
Команды
| обычные |
| сгенерировать |
| схема, затем таксономия |
| повторно запустить конвейер по реестру, пропуская ручные строки |
| проверить, что ни один входящий платёж не исключён из дохода |
| что связано и граница синхронизации каждого счёта |
Стек
Next.js 15 (App Router), Postgres через Drizzle, Tailwind. Anthropic SDK и Plaid SDK оба опциональны во время выполнения и изолированы за интерфейсами.
Вклад в проект
CLAUDE.md документирует, почему всё устроено так, как устроено, обычно называя ошибку, которая к этому привела. Прочитайте его перед тем, как трогать src/lib/classify или src/lib/reconcile — несколько регрессий закреплены тестами, и комментарии говорят, что сломается, если их отменить.
Общее правило при изменении классификатора: предпочитайте недомэтчинг переизбытку. Правило, которое больше никогда не сработает, стоит одного повторного исправления. Правило, которое переизбыточно, тихо переписывает историю, которую вы уже проверили.
Лицензия
MIT — см. LICENSE.
Это работает с реальными финансовыми данными. Он поставляется без каких-либо гарантий, и ваше развёртывание, ключи и резервные копии — ваша ответственность.
This server cannot be installed
Maintenance
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
- FlicenseNot gradedqualityDmaintenanceEnables 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.
- AlicenseNot gradedqualityCmaintenanceEnables 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.14MIT
- AlicenseAqualityDmaintenancePersonal expense tracker MCP server that enables tracking expenses, income, budgets, and savings goals through natural language.10MIT
- FlicenseNot gradedqualityCmaintenanceExposes personal-finance tools like accounts, transactions, spending analysis, budgets, bills, reminders, portfolio, and goals via MCP, enabling any MCP client to query financial data.
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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