Skip to main content
Glama
raphaelcarreiro

financas-mcp

financas-mcp

Servidor MCP (Streamable HTTP) que responde "posso comprar X em N parcelas?" com base na fatura real do cartão Nubank (Pluggy / Open Finance ou CSV) e nos tetos de gastos guardados em SQLite. Feito para ser conectado ao claude.ai como connector remoto via Cloudflare Tunnel.

Rodar local

Requisitos: Node 22, pnpm 10 (via corepack enable pnpm).

cp .env.example .env

Edite .env e preencha MCP_AUTH_TOKEN. Sem PLUGGY_* o servidor usa o gateway CSV lendo CSV_STATEMENTS_DIR (padrão ./statements).

pnpm install
pnpm dev

Confira:

curl http://localhost:3000/health

Outros comandos: pnpm test, pnpm typecheck, pnpm lint, pnpm build, pnpm db:generate (nova migration após mudar src/infrastructure/persistence/schema.ts).

As migrations em drizzle/ rodam no boot. Na primeira execução o seed insere tetos, gastos fixos, reserva anual e recorrentes esperados. Depois disso tudo é alterado pelas tools.

CSV do Nubank

Exporte a fatura pelo app (colunas date,title,amount) e salve em statements/YYYY-MM.csv, onde YYYY-MM é o mês da fatura (a que vence em YYYY-MM-10). Sem mês no nome, o gateway deduz pelo dia de fechamento. Exemplo em test/fixtures/.

Related MCP server: Expense Tracker MCP Server

Criar o token

openssl rand -hex 32

Coloque o valor em MCP_AUTH_TOKEN. Toda requisição a /mcp precisa de Authorization: Bearer <token>; GET /health é aberto.

Docker (local, sem túnel)

docker compose -f docker-compose.yml -f docker/compose.local.yml up --build mcp

Publica 127.0.0.1:3000. O SQLite fica no volume mcp-data (/data/financas.db) e ./statements é montado somente leitura em /statements.

Cloudflare Tunnel

  1. No Cloudflare Zero Trust: Networks → Tunnels → Create a tunnel (tipo Cloudflared). Copie o token.

  2. Em Public Hostname, aponte um subdomínio (ex.: financas.seudominio.com) para http://mcp:3000.

  3. Coloque o token em CLOUDFLARE_TUNNEL_TOKEN no .env.

  4. Suba os dois serviços:

docker compose up -d --build

O serviço mcp não publica porta no host; só o cloudflared fala com ele pela rede do compose. Teste com curl https://financas.seudominio.com/health.

Opcional: adicione uma Access Policy no Cloudflare para restringir ainda mais o hostname.

Conectar no claude.ai

Settings → Connectors → Add custom connector:

  • URL: https://<seu-dominio>/mcp

  • Autenticação: Bearer token, valor de MCP_AUTH_TOKEN

Depois, em uma conversa, ative o connector e pergunte, por exemplo: "posso comprar um notebook de 4500 em 6x?".

Tools

Tool

Uso

get_open_invoice

Status da fatura aberta: à vista, parcelas, recorrentes pendentes, folgas, dias até fechar

get_installment_schedule(months=12)

Comprometimento com parcelas mês a mês

can_i_buy(amount, installments=1, startMonth?)

Avalia a compra e sugere bestMonth

get_closed_invoices(n=6)

Resumo das últimas faturas fechadas

list/upsert/remove_recurring_expected

Assinaturas esperadas no cartão

list/upsert/remove_planned_purchase

Compras planejadas

get/update_budget_params

Tetos, dia de fechamento e vencimento

Regras

  • Fatura fecha no closingDay (padrão 2) e vence no dueDay (padrão 10). Compra entre closingDay+1 de M-1 e closingDay de M entra na fatura M. Ambos configuráveis via update_budget_params.

  • À vista: sem parcela (IOF de ida conta). Parcela nova: 1/N. Parcela antiga: k/N com k > 1. Pagamentos, estornos e IOF de volta não contam.

  • Cronograma: parcela k/N na fatura aberta segue ativa por mais N-k meses; compras planejadas com mês definido entram como amount/installments.

  • can_i_buy à vista compara com a folga de à vista da fatura aberta (teto - gasto - recorrentes pendentes). Parcelado compara amount/installments com a menor folga entre o mês inicial e o último mês.

  • Total previsto do mês = cartão previsto + gastos fixos + aporte da reserva anual (amount / meses da janela dentro da janela).

Pendências de validação com o payload real da Pluggy

Tudo isso está isolado em src/infrastructure/pluggy/pluggy-mapper.ts e pluggy-card-statement-gateway.ts:

  1. Sinal e type das transações de cartão: assumido DEBIT = compra e CREDIT = pagamento ("pagamento" na descrição) ou estorno. Valor usa Math.abs(amount).

  2. creditCardMetadata.totalAmount: assumido como valor total da compra parcelada. O tipo do SDK descreve como "amount of the installment"; se for o valor da parcela, trocar purchaseTotal para totalAmount * totalInstallments.

  3. IOF: detectado por prefixo "IOF" na descrição (e "IOF de volta" para devolução). Conferir como o Nubank via Open Finance nomeia esses lançamentos e se feeType ajuda.

  4. Agrupamento por fatura: usa creditCardMetadata.billForecastDate (YYYY-MM) quando presente; senão cai na regra de calendário por data. Validar se o Nubank preenche esse campo e se o mês bate com o vencimento.

  5. Datas: transaction.date convertida com toISOString().slice(0, 10) (UTC). Se a Pluggy devolver meia-noite local, pode deslocar um dia; ajustar para o fuso em toIsoDate.

  6. Bills (fetchCreditCardBills): o mês da fatura é derivado de dueDate; billClosingDate pode vir null, então o fechamento cai no cálculo por closingDay. Conferir se as datas batem com a fatura do app.

  7. Fatura aberta: creditData.balanceCloseDate e balanceDueDate da conta são usados como fechamento e vencimento. Confirmar se referem-se à fatura aberta.

  8. Conta: usa a primeira conta type === "CREDIT" do item; se houver mais de um cartão, definir PLUGGY_ACCOUNT_ID.

  9. Transações PENDING são incluídas. Decidir se devem entrar no cálculo.

  10. Janela de busca: fatura aberta busca desde 5 dias antes do início do período; faturas fechadas buscam limit meses para trás numa só chamada (fetchAllTransactions). Avaliar volume e rate limit.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    Enables tracking and managing personal expenses through a local SQLite database. Supports adding, editing, deleting, listing, and summarizing expenses by category, as well as managing credit accounts.
    6
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables natural language management of personal expenses, including adding, listing, and summarizing expenses with local SQLite storage.
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables querying personal finance reports (merchant spending, largest expenses) and performing currency conversion via a local SQLite database.
    24
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Connects Nubank accounts to Claude, ChatGPT, and AI agents via Open Finance Brasil, enabling natural language queries about balances, statements, credit card bills, and investments in read-only mode.
    MIT