ohneben's Buchhaltungsbutler MCP
Gerencie sua contabilidade do BuchhaltungsButler em linguagem natural a partir de assistentes de IA como Claude, Cursor e qualquer outro cliente MCP.
Documentação
MCP do Buchhaltungsbutler da ohneben
Licença e verificações
Registro MCP
Identificadores de pacote
Este servidor tem identificadores próprios. O que tem nome diferente não faz parte dele:
| Onde | Identificador |
|---|---|
| Registro MCP | io.github.ohneben/buchhaltungsbutler-mcp |
| Container (GHCR) | ghcr.io/ohneben/buchhaltungsbutler-mcp |
| npm | @ohneben/buchhaltungsbutler-mcp (ainda não publicado) |
O pacote npm buchhaltungsbutler-mcp sem escopo é um projeto diferente, de outro autor
(mrvnklm/buchhaltungsbutler-mcp),
e não tem relação com este aqui. Diretórios que linkam desta página
para lá estão linkando para o pacote errado.
Gerencie sua contabilidade do BuchhaltungsButler em linguagem natural a partir de assistentes de IA como Claude, Cursor e qualquer outro cliente MCP.
Este servidor Model-Context-Protocol disponibiliza a API v1 do BuchhaltungsButler — todos os 54 endpoints como 46 ferramentas MCP, gerados a partir da especificação oficial OpenAPI (versão da spec 1.9.1). Cada ferramenta é categorizada por segurança (somente leitura / escrita / destrutiva), para que seu assistente saiba o que uma ação faz antes de executá-la. Funciona via stdio (Claude Desktop e outros lançadores locais) ou Streamable HTTP (hospedado em Docker).
Por que este servidor
Alguns servidores MCP apenas repassam uma API. Este aqui foi projetado para ser entregue com segurança a um modelo de linguagem e operado no dia a dia:
| O que você recebe | Por que isso importa |
|---|---|
| Todos os 54 endpoints, gerados automaticamente a partir da spec oficial | Cobertura completa de comprovantes, transações, lançamentos, faturas, avaliações e dados mestres. Nada selecionado manualmente, nada esquecido. |
| Cada ferramenta é categorizada por segurança 🟢 / 🟡 / 🔴 | Um banner no início de cada descrição de ferramenta diz exatamente ao modelo o que acontece — ler, criar, alterar, reverter ou excluir — antes de agir. |
Anotações MCP legíveis por máquina (readOnlyHint, destructiveHint) | Hosts que avaliam anotações (Claude é um deles) podem permitir automaticamente acessos de leitura e exigir confirmação antes de ações destrutivas. |
| Dois transportes: stdio e Streamable HTTP | Use localmente no Claude Desktop — ou opere um servidor de execução contínua que qualquer número de clientes MCP pode acessar via HTTP. |
| Docker + docker-compose, health-check, reinício automático | Implantação pronta para produção desde o início: docker compose up, e ele permanece ativo. |
| Autenticação por Bearer Token no endpoint HTTP | Obrigatória assim que o servidor for vinculado além do loopback: sem MCP_AUTH_TOKEN ele se recusa a iniciar, em vez de expor a API sem proteção. |
| Rate limiting integrado | Reduz-se automaticamente abaixo do limite do BuchhaltungsButler de 100 requisições/cliente/minuto, para você nunca esbarrar nele. |
| Suas credenciais nunca chegam ao modelo | As credenciais ficam no ambiente do servidor e são injetadas a cada requisição — o assistente vê apenas entradas de ferramentas e respostas da API. |
Em comparação
No estado atual, este é o único servidor MCP dedicado ao BuchhaltungsButler. Alternativamente, você poderia apontar um wrapper genérico OpenAPI→MCP para a spec — mas isso deixa bastante coisa de lado:
| Capacidade | Este projeto | Wrapper genérico OpenAPI→MCP* |
|---|---|---|
| Todos os 54 endpoints do BuchhaltungsButler cobertos | ✅ | ✅ |
| 🟢 / 🟡 / 🔴 Categoria de segurança + banner por ferramenta | ✅ | ❌ |
Anotações MCP readOnlyHint / destructiveHint | ✅ | ➖ |
Resolução de $ref para payloads em lote + descrições limpas de HTML | ✅ | ➖ |
| Rate limiting integrado (permanece abaixo dos 100/cliente/min. do BB) | ✅ | ❌ |
Transporte stdio | ✅ | ✅ |
| Transporte Streamable HTTP | ✅ | ➖ |
| Docker + docker-compose, health-check, reinício automático | ✅ | ❌ |
| Autenticação Bearer Token forçada no endpoint | ✅ | ❌ |
| Credenciais injetadas no servidor, nunca enviadas ao modelo | ✅ | ➖ |
| Licença | MIT | variada |
*Wrappers genéricos OpenAPI→MCP transformam qualquer spec Swagger/OpenAPI em ferramentas MCP. Eles alcançam os mesmos endpoints, mas tratam toda operação da mesma forma — sem categorias de segurança, sem histórico operacional, sem proteções adaptadas a dados contábeis reais. "➖" = varia conforme a ferramenta / não garantido.
O que você pode fazer com isso
Assim que o servidor estiver conectado, você pode pedir ao seu assistente, por exemplo:
- "Liste todos os comprovantes de entrada do último mês que ainda estão em aberto."
- "Crie um rascunho de fatura para a ACME GmbH: 10 horas de consultoria a 120 €."
- "Lance esta transação bancária na conta contábil 4400."
- "Carregue este comprovante em PDF e associe-o à transação correspondente."
- "Mostre meus fornecedores e crie um novo para nosso provedor de hospedagem."
- "Gere a BWA do último trimestre e mostre o extrato da conta 4400."
As ferramentas são geradas automaticamente a partir da API oficial e agrupadas em 🟢 somente leitura, 🟡 escrita e 🔴 destrutivas — um host bem implementado pode tratar cada grupo de forma diferente.
Como funciona
Claude / Cursor / beliebiger MCP-Client ──MCP──► dieser Server ──HTTPS──► BuchhaltungsButler API (Cloud)
O servidor lê a spec OpenAPI fornecida e a transforma em ferramentas MCP (incluindo
resolução de payloads em lote $ref e remoção de HTML das descrições),
atribui a cada ferramenta sua categoria de segurança e anexa suas credenciais de autenticação básica
bem como o api_key a cada requisição de saída. Suas credenciais permanecem no
ambiente do servidor — o modelo nunca as vê e nunca as toca.
Pré-requisitos
- Uma conta BuchhaltungsButler com acesso à API — um API Client + API Secret
(Configurações → API), bem como um
api_keyde cliente (veja Obter credenciais de API). - Docker (Docker Desktop no macOS/Windows) para o início rápido abaixo — ou Node.js ≥ 18, para iniciar a partir do código-fonte.
Início rápido (Docker)
1. Armazene as credenciais. Copie a configuração de exemplo e preencha:
cp .env.example .env
# .env bearbeiten → BB_API_CLIENT, BB_API_SECRET, BB_API_KEY setzen
# → MCP_AUTH_TOKEN setzen. PFLICHT, sonst startet der Server
# nicht, denn .env.example bindet auf 0.0.0.0:
# openssl rand -hex 32
2. Inicie o servidor:
docker compose up -d --build
3. Verifique se ele está rodando:
curl -s http://localhost:3000/health # → {"status":"ok","server":"buchhaltungsbutler-mcp"}
4. Conecte o cliente MCP. Endpoints remotos são adicionados no Claude como Custom Connector
(Configurações → Connectors) ou, localmente, com bridge via
mcp-remote. Insira o seguinte em
mcpServers na configuração do seu cliente e reinicie o aplicativo completamente em seguida:
{
"mcpServers": {
"buchhaltungsbutler": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:3000/mcp",
"--header", "Authorization: Bearer DEIN_MCP_AUTH_TOKEN"
]
}
}
}
(A linha --header só é omitida se você vincular sem token no loopback.
No início rápido com Docker acima, o token é obrigatório.)
Prefere uma imagem pronta?
Cada push para main publica uma imagem pronta para uso na GitHub Container
Registry — assim você pode pular completamente o build local:
docker run -d --name buchhaltungsbutler-mcp -p 3000:3000 --env-file .env \
ghcr.io/ohneben/buchhaltungsbutler-mcp:latest
Obter credenciais de API
O BuchhaltungsButler usa dois níveis de autenticação (veja a documentação oficial):
- Autenticação básica HTTP — um API Client + API Secret, suas credenciais globais de API. Encontradas ou criadas no BuchhaltungsButler em Configurações → API.
api_key— define a qual conta de cliente uma requisição se refere. Ele fica nas configurações de dados da empresa do respectivo cliente.
Insira todos os três valores em .env. O servidor os anexa a cada requisição; seu
assistente nunca os vê. Uma chamada de ferramenta individual pode opcionalmente
enviar um api_key próprio para acessar uma conta de cliente diferente.
Configuração
Tudo é definido em .env (copiado de .env.example):
| Variável | Obrigatória | Padrão | Descrição |
|---|---|---|---|
BB_API_CLIENT | ✅ | — | API Client (usuário da autenticação básica) |
BB_API_SECRET | ✅ | — | API Secret (senha da autenticação básica) |
BB_API_KEY | ✅ | — | api_key padrão do cliente |
MCP_TRANSPORT | — | stdio | stdio ou http (a imagem Docker usa http por padrão) |
PORT | — | 3000 | Porta HTTP em que escuta |
HOST | — | 0.0.0.0 | Endereço de bind HTTP |
MCP_HTTP_PATH | — | /mcp | Rota HTTP para MCP |
MCP_AUTH_TOKEN | ⚠️ | (desativado) | Exige Authorization: Bearer <Token> em /mcp. Obrigatório se HOST não for um endereço de loopback — caso contrário, o servidor não inicia |
MCP_ALLOWED_HOSTS | — | (automático) | Cabeçalhos Host permitidos, separados por vírgula (proteção contra DNS rebinding). Necessário atrás de um proxy reverso |
MCP_ALLOW_INSECURE | — | (desativado) | Remove a recusa de iniciar sem token. Apenas para endpoints comprovadamente inacessíveis |
MCP_SESSION_TTL | — | 1800 | Segundos de inatividade antes de uma sessão ser descartada |
MCP_MAX_SESSIONS | — | 256 | Limite máximo de sessões simultâneas |
BB_ALLOW_API_KEY_OVERRIDE | — | (desativado) | Permite que uma chamada de ferramenta sobrescreva o api_key |
BB_RATE_LIMIT | — | 90 | Limite do lado do cliente de requisições por minuto |
BB_BASE_URL | — | (da spec) | Sobrescreve a URL base da API |
Após alterações em .env, recarregue com docker compose up -d --force-recreate.
Nomes das ferramentas
Cada ferramenta se chama <ressource>_<verb>. Os verbos são fixos: list, get,
create, update, delete, upload, assign, unassign, unconfirm,
restore, cancel. Assim, a mesma coisa tem o mesmo nome em todos os lugares, independentemente
de como o respectivo caminho do BB está escrito (a API mistura add e
create, e dois caminhos em lote estão em camelCase).
A criação sempre ocorre por meio de uma ferramenta que recebe uma lista. receipts_create
cria um comprovante ou cem; um único registro é uma lista com
uma entrada. Por isso existem 46 ferramentas para 54 endpoints: oito
endpoints individuais foram absorvidos por seus equivalentes em lote.
Nomes antigos continuam funcionando
Os nomes até 1.1.1 continuam funcionando. Eles não estão mais no catálogo,
mas são resolvidos na chamada, para que chamadas fixadas de
versões mais antigas não caiam no vazio. Uma chamada de receipts_add com
campos individuais continua caindo em /receipts/add.
BB_READ_ONLY e BB_TOOL_ALLOWLIST têm precedência: por um nome antigo
não é possível alcançar uma ferramenta que a política exclui.
| Antigo (até 1.1.1) | Novo |
|---|---|
accounts_get | accounts_list |
receipts_get | receipts_list |
receipts_get_id_by_customer | receipts_get_by_id |
receipts_add, receipts_addBatch | receipts_create |
transactions_add, transactions_addBatch | transactions_create |
settings_get_creditors | creditors_list |
settings_add_creditor, settings_add_batch_creditors | creditors_create |
settings_get_postingaccounts | postingaccounts_list |
postings_add_free, postings_add_batch_free | postings_create_free |
transactions_assign_receipt, transactions_assign_batch_receipt | transactions_assign_receipts |
O mapeamento completo está em src/naming.ts.
Categorias de segurança das ferramentas
Cada descrição de ferramenta começa com um destes banners e carrega as anotações MCP correspondentes:
| Banner | Quantidade | readOnlyHint | destructiveHint | Significado |
|---|---|---|---|---|
| 🟢 SOMENTE LEITURA | 15 | true | false | Apenas recupera dados. Inofensivo. |
| 🟡 ESCRITA · cria dados | 17 | false | false | Cria registros (não idempotente; chamadas repetidas geram duplicatas). |
| 🟡 ESCRITA · altera dados | 4 | false | false | Altera diretamente dados mestre existentes. |
| 🟡 ESCRITA · vincula/desvincula | 3 | false | false | Atribui ou remove a atribuição entre documento e transação. Reversível. |
| 🟡 ESCRITA · reverte estado | 4 | false | false | Define lançamentos como não confirmados / restaura documentos. Reversível. |
| 🔴 DESTRUTIVO · exclui | 3 | false | true | Exclui ou estorna um registro. Exige confirmação prévia. |
Hosts que respeitam anotações (incluindo o Claude) podem exigir confirmação para
ferramentas destructiveHint e confiar automaticamente em ferramentas readOnlyHint.
Cada ferramenta também traz um outputSchema, ou seja, a forma da
resposta de sucesso. Chamadas bem-sucedidas entregam a resposta não apenas como
texto, mas também como structuredContent.
Com
npm run list-tools(sem credenciais), é possível exibir o catálogo completo a qualquer momento.
🟢 SOMENTE LEITURA (15)
| Ferramenta | Endpoint |
|---|---|
accounts_list | POST /accounts/get |
cost_locations_list | POST /cost-locations/get |
creditors_list | POST /settings/get/creditors |
debtors_list | POST /settings/get/debtors |
postingaccounts_list | POST /settings/get/postingaccounts |
postings_list | POST /postings/get |
receipts_get_by_id | POST /receipts/get/id_by_customer |
receipts_list | POST /receipts/get |
receipts_list_assigned_transactions | POST /receipts/assigned-transactions/get |
reports_get_bwa | POST /reports/get/bwa |
reports_get_sums | POST /reports/get/sums |
reports_get_sums_ledger | POST /reports/get/sums/ledger |
transactions_get_by_id | POST /transactions/get/id_by_customer |
transactions_list | POST /transactions/get |
transactions_list_assigned_receipts | POST /transactions/assigned-receipts/get |
🟡 ESCRITA · cria dados (17)
Ferramentas com dois endpoints aceitam uma lista. Se a chamada vier com campos individuais, ela vai para o endpoint individual.
| Ferramenta | Endpoint | Endpoint individual |
|---|---|---|
accounts_create | POST /accounts/add | |
comments_create | POST /comments/add | |
cost_locations_create | POST /cost-locations/add | |
creditors_create | POST /settings/add-batch/creditors | POST /settings/add/creditor |
debtors_create | POST /settings/add-batch/debtors | POST /settings/add/debtor |
invoices_create | POST /invoices/create | |
invoices_create_draft | POST /invoices/create/draft | |
invoices_create_e_invoice | POST /invoices/create/e-invoice | |
postingaccounts_create | POST /settings/add/postingaccount | |
postings_create_for_receipt | POST /postings/add-batch/receipts | POST /postings/add/receipt |
postings_create_for_transaction | POST /postings/add-batch/transactions | POST /postings/add/transaction |
postings_create_free | POST /postings/add-batch/free | POST /postings/add/free |
receipts_create | POST /receipts/addBatch | POST /receipts/add |
receipts_upload | POST /receipts/upload | |
reports_create_bwa | POST /reports/create/bwa | |
reports_create_sums | POST /reports/create/sums | |
transactions_create | POST /transactions/addBatch | POST /transactions/add |
🟡 ESCRITA · altera (4) · vincula (3) · reverte (4)
| Ferramenta | Endpoint | Subcategoria |
|---|---|---|
cost_locations_update | POST /cost-locations/update | altera |
creditors_update | POST /settings/update/creditor | altera |
debtors_update | POST /settings/update/debtor | altera |
postingaccounts_update | POST /settings/update/postingaccount | altera |
postings_assign_receipt_to_free | POST /postings/assign/receipt-to-free-posting | vincula |
transactions_assign_receipts | POST /transactions/assign-batch/receipt | vincula |
transactions_unassign_receipt | POST /transactions/unassign/receipt | vincula |
postings_unconfirm_free | POST /postings/unconfirm/free | reverte |
postings_unconfirm_for_receipt | POST /postings/unconfirm/receipt | reverte |
postings_unconfirm_for_transaction | POST /postings/unconfirm/transaction | reverte |
receipts_restore | POST /receipts/restore/id_by_customer | reverte |
🔴 DESTRUTIVO · exclui (3)
| Ferramenta | Endpoint | Observação |
|---|---|---|
receipts_delete | POST /receipts/delete/id_by_customer | Recuperável via receipts_restore |
cost_locations_delete | POST /cost-locations/delete | Não recuperável |
postings_cancel | POST /postings/cancel | Lançamentos ainda não confirmados são excluídos; confirmados são compensados por um estorno |
O que a API v1 não consegue fazer
Essas lacunas também estão propositalmente nas descrições das ferramentas, para que o modelo não procure um endpoint que não existe:
| Recurso | Ausente |
|---|---|
| Credores, devedores, contas contábeis | sem exclusão |
Contas (accounts) | sem alteração, sem exclusão |
| Comentários | sem leitura, sem alteração, sem exclusão |
| Faturas | sem leitura, sem alteração, sem estorno |
| Transações | sem alteração, sem exclusão |
Executar a partir do código-fonte (stdio, sem Docker)
Prefere o modo stdio clássico para o Claude Desktop? Então compile localmente:
npm install
npm run build
Depois, aponte o Claude Desktop em claude_desktop_config.json para o ponto de entrada
compilado:
{
"mcpServers": {
"buchhaltungsbutler": {
"command": "node",
"args": ["/ABSOLUTER/PFAD/Buchhaltungsbutler MCP/dist/index.js"],
"env": {
"MCP_TRANSPORT": "stdio",
"BB_API_CLIENT": "dein-api-client",
"BB_API_SECRET": "dein-api-secret",
"BB_API_KEY": "dein-kunden-api-key"
}
}
}
}
Ou execute o contêiner via stdio:
{
"mcpServers": {
"buchhaltungsbutler": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT=stdio",
"-e", "BB_API_CLIENT", "-e", "BB_API_SECRET", "-e", "BB_API_KEY",
"buchhaltungsbutler-mcp:latest"
],
"env": {
"BB_API_CLIENT": "dein-api-client",
"BB_API_SECRET": "dein-api-secret",
"BB_API_KEY": "dein-kunden-api-key"
}
}
}
}
(Compile a imagem antes: docker build -t buchhaltungsbutler-mcp:latest .)
Manter a spec atualizada
O spec.json incluído é a spec oficial da OpenAPI do BuchhaltungsButler v1 — a
fonte definitiva para as ferramentas. Para atualizá-la para um padrão de API mais recente:
curl -s https://app.buchhaltungsbutler.de/docs/api/v1.de.json -o spec.json
npm run build
Novos caminhos são adotados automaticamente; registre-os em PATH_CATEGORY em
src/categories.ts para que recebam a categoria de segurança correta (caminhos
não mapeados caem conservadoramente na categoria create).
Observação sobre o número de versão: o BuchhaltungsButler não mantém o campo
info.versionde forma confiável na spec — o conteúdo pode mudar sem que o número aumente. Portanto, não confie na versão ao comparar; em vez disso, compare a lista de caminhos (paths) e os parâmetros dos endpoints.
Desenvolvimento
npm install
npm run build # TypeScript → dist/ kompilieren
npm test # Vitest-Suite ausführen
npm run list-tools # kategorisierten Tool-Katalog ausgeben (ohne Zugangsdaten)
A CI compila e testa cada push no Node 20 e 22; pushes em main publicam
adicionalmente uma imagem Docker na GitHub Container Registry.
Observações e convenções
- Datas:
YYYY-MM-DD. Valores: ponto como separador decimal (ex.:-12.30). - Uploads de arquivos (
receipts_upload): o arquivo é enviado como string Base64 no campofile.receipts_createcria documentos sem arquivo. - Paginação: a maioria das ferramentas
listaceitalimiteoffsete informa o total emrows. - Criação sempre ocorre por uma ferramenta que aceita um array; os esquemas dos itens são resolvidos a partir das definições da spec e fornecidos ao modelo. Um único registro é um array com uma entrada.
- Avaliações (BWA, balancete de soma e saldos) são geradas de forma assíncrona em segundo
plano: primeiro chame
reports_create_*, depoisreports_get_*com oid_by_customerretornado. Uma nova avaliação do mesmo tipo substitui a anterior. - Limite de taxa: o BuchhaltungsButler permite 100 solicitações/cliente/minuto; o servidor
se autorregula em
BB_RATE_LIMIT(padrão 90) para permanecer seguramente abaixo disso.
Segurança
- Suas credenciais de API ficam exclusivamente em
.env, e esse arquivo é excluído do Git. Nunca faça commit de segredos reais. Se algo vazar, rotacione as credenciais em BuchhaltungsButler → Configurações → API. - O endpoint HTTP exige um token assim que for vinculado além do loopback.
Sem
MCP_AUTH_TOKEN, o servidor se recusa a iniciar e explica no texto de erro o que fazer. Envie o token como cabeçalhoAuthorization: Bearer <Token>, idealmente atrás de TLS. - Mesmo no localhost: sem token, o cabeçalho
Hosté limitado a nomes de localhost, para que nenhuma página web arbitrária acesse o endpoint via DNS rebinding. Atrás de um proxy reverso, definaMCP_ALLOWED_HOSTSpara isso. - Atrás de um proxy reverso, defina o cabeçalho
Hostno proxy como fixo para o nome do upstream interno e registre exatamente esse nome emMCP_ALLOWED_HOSTS. Assim, a verificação não depende do domínio público e sobrevive a uma troca de domínio. (Dica de @WinFuture23.) - Se você definir
MCP_ALLOWED_HOSTSe sua plataforma tiver um health check HTTP, o hostname dele precisa estar na lista. O Railway enviaHost: healthcheck.railway.app; as sondas do Kubernetes consultam conforme a configuração via IP do contêiner. Se o nome faltar, o health check recebe um 403 e a plataforma considera o deployment como quebrado. /healthfica atrás da verificação de host, mas antes da verificação de token: um health check da plataforma não precisa de token. Além disso,/healthsempre aceitalocalhost,127.0.0.1e[::1], para que oHEALTHCHECKdo Dockerfile incluído continue funcionando se você definirMCP_ALLOWED_HOSTSpara seu domínio público. Se o seu health check consultar via IP do contêiner ou nome de serviço, você precisa incluir esse nome emMCP_ALLOWED_HOSTS.- O
api_keypor chamada de ferramenta está desativado por padrão (BB_ALLOW_API_KEY_OVERRIDE=1o libera), para que o modelo não possa decidir sozinho em qual locatário escrever.
A política completa e o canal para reportar vulnerabilidades estão em SECURITY.md.
Créditos e licença
Uma integração comunitária não oficial para BuchhaltungsButler; não afiliada nem endossada pelo BuchhaltungsButler. Baseada no Model Context Protocol. Publicada sob a licença MIT.