QuickBooks Online MCP Server

Servidor MCP do QuickBooks Online para faturas, clientes e pagamentos. OAuth 2.1 + PKCE, stdio/HTTP.

Documentação

Servidor MCP do QuickBooks Online

CI Python 3.11+ License: MIT

Servidor MCP do QuickBooks Online para Claude Desktop e qualquer cliente MCP, escrito em Python sobre o SDK oficial do MCP (FastMCP). Ele expõe 18 ferramentas para faturas, clientes e pagamentos (criar, ler, atualizar, excluir, listar, pesquisar), além de recursos somente leitura de empresa e contas a receber, por trás de um fluxo real de OAuth 2.1 com código de autorização + PKCE, renovação automática de tokens, limitação de taxa no lado do cliente que respeita os limites do QuickBooks e erros estruturados que informam ao agente o que fazer em seguida. Ele opera via stdio e HTTP Streamable.

Relacionados: Servidor MCP do HubSpot CRM · Gateway de Auditoria MCP · O que o MCP de produção realmente exige

Arquitetura

flowchart LR
    Agent["MCP client<br/>(Claude Desktop / HTTP)"]
    subgraph Server["mcp-quickbooks (FastMCP)"]
        Tools["18 tools<br/>invoices · customers · payments"]
        Resources["resources<br/>company · receivables · customers"]
        Client["QBOClient<br/>retry · backoff · error mapping"]
        RL["RateLimiter<br/>per-second + per-minute buckets"]
        Auth["AuthManager<br/>OAuth 2.1 + PKCE · token refresh"]
        Store[("token store<br/>.qbo_tokens.json")]
    end
    QBO["Intuit QuickBooks Online API<br/>/v3/company/{realmId}"]

    Agent <-->|stdio / streamable-http| Tools
    Agent <-->|resources/read| Resources
    Tools --> Client
    Resources --> Client
    Client --> RL
    Client --> Auth
    Auth <--> Store
    Auth <-->|token + refresh| QBO
    Client -->|REST + query| QBO

O servidor não mantém estado e não armazena dados de clientes: é um proxy sem estado sobre a API REST do QuickBooks. Os tokens ficam em um arquivo local que você controla; o cliente é implantado com suas próprias credenciais da Intuit.

Ferramentas

Cada ferramenta retorna um resultado estruturado { "ok": true, ... }, ou { "ok": false, "error": {...} } com um suggestion. Cada uma carrega anotações MCP (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) e um esquema de saída declarado.

  • create_customer: Criar um cliente. O nome de exibição deve ser único; o QuickBooks rejeita duplicatas com o erro 6240.
  • get_customer: Ler um cliente pelo Id, incluindo saldo, dados de contato e o SyncToken atual.
  • update_customer: Atualização esparsa de um cliente existente. Exige o Id e um SyncToken recente.
  • delete_customer: Desativar um cliente (o QuickBooks não permite exclusão definitiva de clientes), preservando o histórico.
  • list_customers: Listar clientes, dos mais recentemente atualizados para os mais antigos, com paginação controlada pelo chamador.
  • search_customers: Localizar clientes por prefixo do nome de exibição, e-mail exato ou flag de ativo.
  • create_invoice: Criar uma fatura para um cliente existente com um ou mais itens de linha.
  • get_invoice: Ler uma fatura pelo Id, incluindo linhas, totais, saldo e o SyncToken atual.
  • update_invoice: Substituir uma fatura. As linhas são substituídas por completo, então envie todas as linhas que ela deve ter ao final.
  • delete_invoice: Excluir uma fatura permanentemente. Exige o Id e um SyncToken recente.
  • list_invoices: Listar faturas, da data de transação mais recente para a mais antiga, com paginação controlada pelo chamador.
  • search_invoices: Localizar faturas por Id do cliente, intervalo de datas de transação ou número do documento.
  • create_payment: Registrar um pagamento recebido, opcionalmente aplicado a uma fatura específica.
  • get_payment: Ler um pagamento pelo Id, incluindo transações vinculadas e o SyncToken atual.
  • update_payment: Substituir um pagamento. Remover o vínculo com a fatura reabre o saldo daquela fatura.
  • delete_payment: Excluir um pagamento permanentemente. Qualquer fatura que ele quitou volta a ficar não paga.
  • list_payments: Listar pagamentos, da data de transação mais recente para a mais antiga, com paginação controlada pelo chamador.
  • search_payments: Localizar pagamentos por Id do cliente ou intervalo de datas de transação.

Recursos

JSON somente leitura:

  • qbo://company: perfil da empresa e endereço legal
  • qbo://summary/receivables: contagens de faturas abertas/vencidas e saldo pendente
  • qbo://summary/customers: clientes ativos classificados por saldo pendente

Escopos de privilégio mínimo

O escopo padrão é apenas com.intuit.quickbooks.accounting. Adicione com.intuit.quickbooks.payment (via QBO_SCOPES) somente se você conectar o processamento de pagamentos. A string de escopo é validada na inicialização contra o conjunto de escopos conhecidos da Intuit, então um erro de digitação falha rapidamente em vez de subautorizar silenciosamente. Escopos de identidade (openid, profile, email) nunca são solicitados, a menos que você opte por incluí-los.

Limitação de taxa e novas tentativas

Um limitador duplo de token bucket limita o tráfego de saída abaixo dos tetos por segundo e por minuto do QuickBooks (configurável via QBO_REQUESTS_PER_SECOND / QBO_REQUESTS_PER_MINUTE). Em 429, o cliente respeita o cabeçalho Retry-After; em 429/5xx sem esse cabeçalho, ele usa backoff exponencial com jitter, até QBO_MAX_RETRIES. Um único 401 dispara a renovação do token e uma nova tentativa transparente.

Início rápido

uv venv --python 3.12 .venv
uv pip install -e ".[dev]"

cp .env.example .env       # fill in QBO_CLIENT_ID / QBO_CLIENT_SECRET
mcp-quickbooks auth        # opens Intuit, captures the redirect, stores tokens
mcp-quickbooks status      # verify the token refreshes

mcp-quickbooks stdio       # run over stdio (Claude Desktop)
mcp-quickbooks http --port 8000   # run over Streamable HTTP

As credenciais são lidas de forma preguiçosa. O servidor inicia, responde a initialize e atende a tools/list sem nenhuma variável QBO_* definida; uma chamada de ferramenta sem credenciais retorna um 401 estruturado informando ao chamador o que configurar. Isso mantém a introspecção de registro e os testes de fumaça em contêineres funcionando sem segredos.

Claude Desktop

{
  "mcpServers": {
    "quickbooks": {
      "command": "mcp-quickbooks",
      "args": ["stdio"],
      "env": { "QBO_ENVIRONMENT": "sandbox" }
    }
  }
}

Docker

docker build -t mcp-quickbooks .
docker run --rm -i --env-file .env mcp-quickbooks

Executando contra um sandbox real da Intuit

  1. Crie um aplicativo no portal de desenvolvedores da Intuit e abra a seção Keys & OAuth. Copie o id e o segredo do cliente de Development.
  2. Adicione um URI de redirecionamento que corresponda a QBO_REDIRECT_URI no seu .env (padrão http://localhost:8765/callback).
  3. Crie uma empresa sandbox no painel do desenvolvedor; o id da empresa é o seu QBO_REALM_ID.
  4. Defina QBO_ENVIRONMENT=sandbox, preencha QBO_CLIENT_ID / QBO_CLIENT_SECRET e execute mcp-quickbooks auth. O fluxo do navegador retorna um realmId automaticamente; ele é armazenado junto com os tokens.
  5. mcp-quickbooks status confirma que os tokens são renovados. Agora você está operando o sandbox real.

Alterne QBO_ENVIRONMENT=production (com chaves de produção e uma empresa conectada) para apontar para os livros reais. Credenciais e tokens são seus; nada é commitado: .env e .qbo_tokens.json estão no gitignore.

Testes

A suíte roda totalmente offline. Cada chamada ao QuickBooks e ao OAuth é atendida por um fake em memória (tests/fake_qbo.py) alimentado por fixtures no estilo de gravações em tests/fixtures/, conectado por meio de um transporte mock httpx: sem rede, sem credenciais reais.

uv run pytest

Metadados de registro

server.json descreve o servidor para o registro MCP, e .mcp.json é o trecho de configuração do cliente que os rastreadores de diretórios procuram. A publicação é intencionalmente deixada como uma etapa manual. Veja PUBLISHING.md. Nada aqui é enviado a nenhum registro.

Contrate-me

Eu torno integrações críticas para a era da IA e para o dinheiro seguras em produção: autenticação real, limites de taxa reais, tratamento de erros real, testes reais. Disponível para construção de servidores MCP e endurecimento de integrações de API. Portfólio e contato: https://amin-ale.github.io/portfolio-site · amin.ale.business@gmail.com

Licença

MIT: veja LICENSE.