Finanpy
БесплатноНе проверенMCP server for personal finance management that connects a SQLite database to any MCP client, allowing users to register, query, and analyze financial transacti
Описание
MCP server for personal finance management that connects a SQLite database to any MCP client, allowing users to register, query, and analyze financial transactions through natural language.
README
Finanpy é um servidor MCP (Model Context Protocol) para análise e gestão de finanças pessoais. Ele conecta um banco de dados SQLite a qualquer cliente MCP compatível, permitindo registrar, consultar e analisar transações financeiras através de linguagem natural.
📁 Estrutura do Projeto
.
├── finance.db # Banco de dados SQLite com as transações
├── database.py # Camada de acesso ao banco de dados
├── mcp_server.py # Servidor MCP com as ferramentas expostas
├── import_csv.py # Script para importar extratos do Nubank (CSV)
└── sample_agent.py # Agente de exemplo com LangChain + LangGraph
🗄️ Banco de Dados
O projeto utiliza SQLite com uma única tabela principal:
Tabela transactions
| Coluna | Tipo | Descrição |
|---|---|---|
id |
INTEGER | Chave primária, autoincremento |
identifier |
TEXT | Identificador único da transação (evita duplicatas) |
type |
TEXT | Tipo da transação: receita ou despesa |
amount |
REAL | Valor da transação (negativo para despesas) |
category |
TEXT | Categoria da transação (padrão: sem categoria) |
description |
TEXT | Descrição ou histórico da transação |
date |
TEXT | Data da transação em ISO 8601: YYYY-MM-DD |
Timezone: todas as datas são armazenadas em horário local (America/Sao_Paulo). Não há offset UTC explícito no banco.
Arredondamento: valores monetários são armazenados comoREALcom 2 casas decimais, usando arredondamento half-up no momento da inserção.
⚙️ Instalação
Pré-requisitos
- Python 3.10+
- uv
Dependências
uv add fastmcp
Para utilizar o agente de exemplo (sample_agent.py), instale também:
uv add langchain-openai langchain-mcp-adapters langgraph python-dotenv
Configuração
- Clone o repositório.
- Inicialize o banco de dados:
python database.py
- (Opcional) Importe um extrato do Nubank:
# Coloque o arquivo CSV exportado do Nubank na raiz do projeto:
# extrato_nubank_05_2026.csv
python import_csv.py
🚀 Executando o Servidor MCP
python mcp_server.py
Transporte STDIO
O Finanpy utiliza transporte STDIO: o cliente MCP inicia o servidor como um processo filho e se comunica com ele via stdin/stdout usando o protocolo MCP. Não há porta de rede envolvida.
Fluxo de inicialização:
- O client executa
python mcp_server.pycomo subprocesso. - O servidor anuncia suas capacidades (
tools,resources) via protocolo MCP pelostdout. - O client recebe o manifesto e passa a chamar ferramentas ou consultar recursos conforme necessário.
- O processo do servidor vive enquanto o client estiver ativo e é encerrado junto com ele.
Quando o client decide chamar cada ferramenta/recurso:
- Consulta
resumo_financeiro_atual(recurso) para orientar o raciocínio antes de responder perguntas sobre saldo ou categorias. - Chama
registrar_transacaoquando o usuário pede para registrar, lançar ou salvar uma transação. - Chama
listar_transacoesquando o usuário pede consultas, históricos ou totais por período/categoria.
🔧 Ferramentas e Recursos MCP
Ferramenta 1 — registrar_transacao
Registra uma nova transação financeira no banco de dados de forma idempotente.
Entradas:
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
type |
string | ✅ | "receita" ou "despesa" |
amount |
float | ✅ | Valor absoluto da transação (sempre positivo; o sinal é inferido do type) |
category |
string | ✅ | Categoria (ex: "alimentacao", "transporte", "moradia") |
description |
string | ✅ | Texto livre descrevendo a transação |
date |
string | ❌ | Data em ISO 8601 YYYY-MM-DD (padrão: data atual) |
identifier |
string | ❌ | UUID ou chave externa para idempotência (ex: ID do extrato bancário) |
Saída (sucesso):
{
"sucesso": true,
"id": 42,
"normalizado": {
"amount": 73.90,
"date": "2026-06-23",
"type": "despesa"
},
"avisos": []
}
Saída (duplicata detectada):
{
"sucesso": false,
"code": "DUPLICATE",
"id_existente": 17,
"mensagem": "Transação com este identifier já existe."
}
Erros e limites:
| Código | Causa | O que o client deve fazer |
|---|---|---|
INVALID_DATE |
Data fora do formato ISO 8601 ou data futura | Corrigir o formato para YYYY-MM-DD antes de reenviar |
DUPLICATE |
identifier já existe no banco |
Informar o usuário; não reenviar |
BAD_TYPE |
type diferente de "receita" ou "despesa" |
Normalizar para um dos dois valores antes de reenviar |
INVALID_AMOUNT |
amount negativo, zero ou não numérico |
Solicitar o valor correto ao usuário; nunca inferir |
DB_BUSY |
SQLite travado por operação concorrente | Retry com backoff exponencial: 200ms, 400ms, 800ms (máx. 3x) |
MISSING_FIELD |
Campo obrigatório ausente | Solicitar o campo faltante ao usuário antes de reenviar |
Atenção — sinal vs. tipo: nunca envie
amountnegativo comtype="despesa". O servidor armazena despesas com sinal negativo internamente; a entrada esperada é sempre o valor absoluto. Se o client receberamountnegativo do usuário junto comtype="despesa", deve aplicarabs(amount)antes de chamar a ferramenta.
Ferramenta 2 — listar_transacoes
Lista e filtra transações financeiras armazenadas no banco.
Entradas:
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
period |
string | ❌ | Período no formato YYYY-MM (ex: "2026-05") |
category |
string | ❌ | Filtra pelo nome exato da categoria |
type |
string | ❌ | "receita" ou "despesa" |
Saída (sucesso):
[
{
"id": 1,
"identifier": "69fa0c39-ca20-4683-849a-85519872249a",
"type": "receita",
"amount": 50.0,
"category": "sem categoria",
"description": "Resgate RDB",
"date": "2026-05-05"
}
]
Retorna uma lista vazia [] quando nenhum registro corresponde aos filtros (não é um erro).
Erros e limites:
| Código | Causa | O que o client deve fazer |
|---|---|---|
INVALID_PERIOD |
Formato de período inválido (ex: "05-2026") |
Corrigir para YYYY-MM antes de reenviar |
BAD_TYPE |
type diferente de "receita" ou "despesa" |
Normalizar antes de reenviar |
DB_BUSY |
SQLite travado por operação concorrente | Retry com backoff exponencial: 200ms, 400ms, 800ms (máx. 3x) |
Janela recomendada: evite consultar períodos superiores a 12 meses sem filtro de categoria, pois o retorno pode ser extenso. Prefira decompor em múltiplas chamadas mensais se necessário.
Recurso MCP — resumo_financeiro_atual
URI: finance://resumo_financeiro_atual
Recurso somente-leitura que retorna um snapshot consolidado das finanças do mês corrente. Diferente das ferramentas (que executam ações), este recurso é consultado pelo agente para orientar seu raciocínio antes de responder perguntas sobre saldo, categorias e situação financeira geral — evitando chamadas desnecessárias a listar_transacoes.
Saída:
{
"period": "2026-06",
"total_income": 9947.94,
"total_expense": 9947.94,
"balance": 0.0,
"expenses_by_category": {
"sem categoria": 9947.94
}
}
Quando o client deve consultá-lo:
- Antes de responder qualquer pergunta sobre saldo atual, total gasto ou total recebido no mês.
- Para verificar se há dados suficientes antes de sugerir categorias ao usuário.
- Como ponto de partida para decidir se é necessário chamar
listar_transacoescom filtros mais específicos.
📥 Importação de Extrato do Nubank
O script import_csv.py importa automaticamente transações a partir do CSV exportado pelo aplicativo do Nubank.
Formato esperado do CSV:
| Data | Valor | Identificador | Descrição |
|---|---|---|---|
| 05/05/2026 | -50.00 | 69fa0c7e-... | Transferência Pix |
| 06/05/2026 | 188.03 | 69fbee60-... | Resgate RDB |
O tipo da transação é derivado automaticamente pelo sinal do valor:
- Valor negativo →
despesa - Valor positivo →
receita
Transações com identifier já existente são ignoradas automaticamente (idempotência via INSERT OR IGNORE).
Categorias: todas as transações importadas via CSV chegam como
"sem categoria". Use o agente para categorizá-las após a importação.
🔄 Cenário de Uso Ponta a Ponta
Mensagem do usuário:
"Quanto gastei em alimentação em maio de 2026? E registra aí um Uber de R$ 73,90 que peguei hoje."
Raciocínio do agente:
- A pergunta envolve o mês atual — consultar o recurso
resumo_financeiro_atualpara ter contexto geral antes de filtrar. - Para o total de alimentação em maio, chamar
listar_transacoescom filtros de período e categoria. - Para registrar o Uber, chamar
registrar_transacaocom os dados fornecidos.
Passo 1 — Consulta ao recurso resumo_financeiro_atual
GET finance://resumo_financeiro_atual
Resposta do servidor:
{
"period": "2026-06",
"total_income": 1835.29,
"total_expense": 462.75,
"balance": 1372.54,
"expenses_by_category": {
"sem categoria": 462.75
}
}
O agente identifica que o mês atual é junho — a pergunta é sobre maio, então precisa de uma chamada específica.
Passo 2 — Chamada à ferramenta listar_transacoes
{
"period": "2026-05",
"category": "alimentacao",
"type": "despesa"
}
Resposta do servidor:
[
{
"id": 8,
"identifier": "nubank-2026-05-12-ifood",
"type": "despesa",
"amount": -49.90,
"category": "alimentacao",
"description": "iFood - Pizza",
"date": "2026-05-12"
},
{
"id": 15,
"identifier": "nubank-2026-05-22-mercado",
"type": "despesa",
"amount": -312.40,
"category": "alimentacao",
"description": "Mercado Extra",
"date": "2026-05-22"
}
]
Total calculado pelo agente: R$ 362,30.
Passo 3 — Chamada à ferramenta registrar_transacao
{
"type": "despesa",
"amount": 73.90,
"category": "transporte",
"description": "Uber",
"date": "2026-06-23",
"identifier": "manual-2026-06-23-uber-001"
}
Resposta do servidor:
{
"sucesso": true,
"id": 27,
"normalizado": {
"amount": 73.90,
"date": "2026-06-23",
"type": "despesa"
},
"avisos": []
}
Resposta final ao usuário:
"Em maio de 2026 você gastou R$ 362,30 em alimentação (iFood R$ 49,90 + Mercado Extra R$ 312,40). Sua despesa de Uber de R$ 73,90 foi registrada em transporte para hoje, 23/06/2026. ✅"
🤖 Agente de Exemplo
O arquivo sample_agent.py demonstra como integrar o servidor MCP com um agente LangChain + LangGraph usando GPT-4o-mini como modelo de linguagem, via transporte STDIO.
Configuração
Crie um arquivo .env na raiz do projeto:
OPENAI_API_KEY=sua_chave_aqui
Executando o agente
python sample_agent.py
Exemplo de interação real:
Finanpy - Assistente Financeiro Pessoal
Digite 'sair' para encerrar.
Você: Poderia categorizar as minhas transações realizadas? E também fazer uma somatória transacionada para cada categoria?
Finanpy: processando...
Finanpy: Aqui está a categorização das suas transações e a somatória para cada categoria:
### Receitas
1. Resgate RDB: R$ 50,00
2. Resgate RDB: R$ 188,03
...
**Total de Receitas**: R$ 9.882,74
### Despesas
1. Transferência enviada pelo Pix: R$ -50,00
...
**Total de Despesas**: R$ -10.188,84
🧩 Integração com Claude Desktop
Para usar o Finanpy diretamente no Claude Desktop, adicione ao arquivo de configuração do MCP (claude_desktop_config.json):
{
"mcpServers": {
"finanpy": {
"command": "python",
"args": ["/caminho/absoluto/para/mcp_server.py"]
}
}
}
O campo
"transport"pode ser omitido — o Claude Desktop usa STDIO por padrão. Use o caminho absoluto para omcp_server.pypara evitar erros de working directory.
Após reiniciar o Claude Desktop, as ferramentas e recursos do Finanpy estarão disponíveis automaticamente.
🔒 Segurança e Privacidade
- Dados sensíveis (PII): o banco contém informações financeiras pessoais, incluindo descrições de transações que podem conter nomes de pessoas (ex: transferências Pix). Não compartilhe o arquivo
finance.dbpublicamente. - Logs: evite ativar logging detalhado em produção, pois descrições de transações podem aparecer nos logs. Em desenvolvimento, use nível
WARNINGou superior. - Acesso ao banco: o SQLite não tem autenticação nativa. Garanta que o arquivo
finance.dbtenha permissões restritas ao usuário do sistema que executa o servidor (chmod 600 finance.db). - Variáveis de ambiente: nunca comite o arquivo
.envcom chaves de API no repositório. Adicione-o ao.gitignore.
📌 Observações Técnicas
- Datas: o campo
dateé armazenado como texto em formatoYYYY-MM-DD(ISO 8601). Entradas no formatoDD/MM/YYYY(como as do CSV do Nubank) são convertidas internamente. O client deve sempre enviar datas em ISO 8601. - Categorias: não há validação de categoria no servidor — qualquer string é aceita. Para padronizar, consulte o recurso
resumo_financeiro_atualpara ver as categorias já existentes antes de registrar uma nova transação. - Idempotência: o campo
identifiergarante que a mesma transação não seja inserida duas vezes (INSERT OR IGNORE). Ao importar extratos, use sempre o ID original do banco comoidentifier. - Concorrência: SQLite não suporta múltiplos escritores simultâneos. Se múltiplos agentes estiverem ativos, implemente retry com backoff exponencial em caso de
DB_BUSY. - Banco de dados: o arquivo
finance.dbé criado automaticamente na raiz do projeto ao executardatabase.pyoumcp_server.py.
Установка Finanpy
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/Gahbrielms/exercicio_mcpFAQ
Finanpy MCP бесплатный?
Да, Finanpy MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Finanpy?
Нет, Finanpy работает без API-ключей и переменных окружения.
Finanpy — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Finanpy в Claude Desktop, Claude Code или Cursor?
Открой Finanpy на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
wenb1n-dev/SmartDB_MCP
A universal database MCP server supporting simultaneous connections to multiple databases. It provides tools for database operations, health analysis, SQL optim
автор: wenb1n-devPostgres Server
This server enables interaction with PostgreSQL databases through the Model Context Protocol, optimized for the AWS Bedrock AgentCore Runtime. It provides tools
автор: madhurprashPostgres
Query your database in natural language
автор: AnthropicPostgreSQL
Read-only database access with schema inspection.
автор: modelcontextprotocolCompare Finanpy with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории data
