Skip to main content
Glama
QuickBooks Desktop MCP

QuickBooks Desktop MCP

by Compolaga

QuickBooks Desktop MCP — fork van qbbridge

Lokale MCP-server waarmee een MCP-client (Claude Desktop) QuickBooks Desktop op dezelfde pc leest en, na akkoord per boeking, boekt: facturen, klanten, items, ontvangsten, stortingen, cheques/bankkosten en journaalposten. Alleen generieke QuickBooks-handelingen; bedrijfskennis (welke klant, welk item, welke rekening, welke koers) hoort in de skill van de gebruiker, niet hier.

Herkomst

Fork van lilfroog/qbbridge (MIT), geïmporteerd op upstream-commit 65f409e4281683682436dbc34d370c7e00c39bcb. De MIT-licentie van het origineel staat ongewijzigd in LICENSE. Wat deze fork toevoegt of verandert:

  • qbXML-versie wordt per sessie bepaald (hoogste versie die QuickBooks ondersteunt en ≤ QBBRIDGE_QBXML_MAX, standaard 13.0 voor QuickBooks 2016) in plaats van hard 16.0.

  • 32-bit build (PyInstaller x86 + Inno Setup), nodig voor 32-bit QuickBooks.

  • Nieuwe tools voor facturen, klanten, items, betalingen, stortingen, journaalposten, cheques, valuta en status (zie hieronder).

  • Elke schrijf-tool werkt in twee stappen met een controlecode die de server zelf afdwingt.

  • Terugdraaien alleen van eigen runs; de upstream-tools die bestaande transacties wijzigen of verwijderen zijn niet meer als tool beschikbaar.

  • Logboek van elk qbXML-request en -antwoord.

Related MCP server: Accounting Ledger MCP Server

Tools

Lezen (altijd toegestaan):

Tool

Wat

qb_status

Geopend bedrijfsbestand, product/versie/land, ondersteunde qbXML-versies en de gebruikte, multicurrency aan/uit, home currency

qb_company_info

Pad van het geopende bedrijfsbestand

qb_search_customers

Klanten zoeken op (deel van) naam, bedrijfsnaam, contact, e-mail; met valuta en saldo

qb_search_items

Items zoeken op naam, art.code (ManufacturerPartNumber) of omschrijving

qb_list_open_invoices

Openstaande facturen, per klant of alles

qb_find_invoice

Factuur op nummer, bedrag en/of datum(bereik) en klant, optioneel met regels

qb_list_accounts / qb_account_balance

Rekeningschema met valuta en saldo; saldo van één rekening

qb_find_transactions

Alle transacties in een periode (optioneel per rekening, relatie, type)

qb_list_currencies

Valutalijst met ISO-code en opgeslagen koers

qb_list_vendors, qb_vendor_history, qb_query_transactions, qb_check_duplicate

Upstream-leestools

qb_list_runs

Eigen runs met wat ze geboekt hebben

Schrijven (altijd twee stappen):

Tool

qbXML

qb_create_invoice

InvoiceAdd: itemregels en tekst-kopregels, memo, RefNumber, TxnDate, SalesTaxCodeRef, optioneel ExchangeRate, valutacontrole, verwacht totaal

qb_create_customer

CustomerAdd, ook met valuta

qb_create_item

ItemNonInventoryAdd

qb_receive_payment

ReceivePaymentAdd, gekoppeld aan facturen, met koers

qb_deposit

DepositAdd (ook in vreemde valuta, met koers)

qb_write_check

CheckAdd: bankkosten, vaste posten, vraagpost-afschrijvingen

qb_journal_entry

JournalEntryAdd, ook met één vreemde valuta

qb_add_transaction, qb_add_vendor

Upstream-schrijftools, nu ook tweestaps

qb_revert_run

Eigen run terugdraaien (ook tweestaps)

Twee stappen, afgedwongen in de server

  1. Aanroep zonder confirm_code: de server bouwt het exacte qbXML-request, doet de controles en geeft een voorbeeld plus controlecode. Er wordt niets geboekt.

  2. Na akkoord van de gebruiker: dezelfde aanroep met dezelfde argumenten plus confirm_code. De code is een HMAC over (tool, geopend bedrijfsbestand, exact request) met een geheime sleutel van de server, plus een nonce. Elk ander argument, een ander bestand of een verzonnen code wordt geweigerd; een code werkt één keer.

Wat de code garandeert: wat geboekt wordt is exact het request uit het getoonde voorbeeld, en er ging altijd een voorbeeld aan vooraf. Wat de code niet garandeert: dat een mens akkoord gaf. De agent krijgt de code zelf terug en kan hem doorgeven zonder te vragen. Het menselijke akkoord loopt via de toestemmingsvraag van de MCP-client: laat in Claude Desktop de schrijf-tools op "vragen" staan (zie Installatie).

Verder weigert de server: een factuurnummer dat al bestaat; een expected_total dat niet klopt (bij een factuur is dat het subtotaal, de som van de regels zonder btw; na het boeken nogmaals vergeleken met het subtotaal van QuickBooks zelf, en een afwijkende factuur wordt dan direct weer verwijderd, met de bijbehorende regel uit het run-log); onbekende klanten, items of rekeningen; betalingen boven het openstaande saldo (ook als dezelfde factuur meerdere keren in apply_to staat) of op facturen van een andere klant. Bedragen als tekst worden alleen geaccepteerd als ze eenduidig zijn: 1250.50, 1,250.50, 1.250,50 en 12,50 mogen; 1,250 of 1.250 (duizend of decimaal?) wordt geweigerd.

Terugdraaien

Elke boeking komt in een run (run_id in het resultaat; met run_id als argument voeg je een boeking toe aan een bestaande run, bijvoorbeeld alle regels van één bankafschrift). qb_revert_run(run_id) draait een run in omgekeerde volgorde terug. De run wordt alleen in de eigen run-map gezocht. Het run-log bevat per boeking alleen wat er is aangemaakt (type en TxnID/ListID) en in welk bedrijfsbestand; de revert bouwt zelf het TxnDelRq/ListDelRq voor precies die objecten. Een revert wordt geweigerd als QuickBooks een ander bedrijfsbestand open heeft dan dat van de run, of als een regel van het run-log onleesbaar is (bijvoorbeeld een halve regel na een crash): dan wordt niets teruggedraaid en ook niets meer aan die run toegevoegd. Antwoordt QuickBooks op een boeking met een waarschuwing (statusCode ≠ 0) maar wel met een TxnID/ListID, dan staat de boeking toch in het run-log en krijgt de aanroeper de waarschuwing terug. Mislukt een deel van een revert, dan slaat een herhaalde revert de al teruggedraaide stappen over; aan een (deels) teruggedraaide run kun je niets meer toevoegen. Bestaande boekingen van de gebruiker kan de server niet verwijderen of wijzigen.

Valuta (multicurrency)

  • exchange_rate is altijd: home-valuta per 1 eenheid vreemde valuta (bijvoorbeeld home USD, bank in EUR: 1 EUR = 1,08 USD). QuickBooks bewaart koersen op 6 decimalen.

  • De factuurvaluta is altijd de valuta van de klant; currency bij qb_create_invoice is alleen een controle.

  • QuickBooks staat een ontvangst van een klant in valuta A niet toe op een bankrekening in een andere vreemde valuta B ("The currency of the account must be either in home currency or the transaction currency"). Werkende route: qb_receive_payment op een tussenrekening in valuta A, daarna qb_deposit naar de bank in valuta B met de koers; een eventuele afrondingsrest van een cent met qb_journal_entry. Hoe er in een echte administratie geboekt wordt, bepaalt de skill.

  • Ontbreekt een valuta in de lijst van QuickBooks, dan kan die als eigen valuta worden toegevoegd (in QuickBooks zelf, niet via deze server).

Installatie (QuickBooks Desktop, 32-bit)

Altijd eerst op een kopie van het bedrijfsbestand. Maak in QuickBooks een backup (.QBB) of kopie van het bestand, open de kopie, en test daar qb_status en één factuur. Pas daarna het echte bestand.

  1. QuickBooks openen als Admin, single-user, met het (kopie-)bedrijfsbestand.

  2. QBBridgeSetup.exe draaien. De installer zet qbbridge-mcp.exe (32-bit) in C:\Program Files (x86)\QBBridge en registreert de server als qbbridge in %APPDATA%\Claude\claude_desktop_config.json (bestaande servers blijven staan). Windows SmartScreen kan waarschuwen ("onbekende uitgever"): de installer is niet gesigneerd.

  3. Claude Desktop herstarten. Laat bij de tools van qbbridge de schrijf-tools (qb_create_*, qb_receive_payment, qb_deposit, qb_write_check, qb_journal_entry, qb_add_*, qb_revert_run) op "vragen" (toestemming per aanroep) staan, niet op "altijd toestaan". Die toestemmingsvraag is het menselijke akkoord; de controlecode bewaakt alleen dat het geboekte request gelijk is aan het voorbeeld.

  4. In Claude: "roep qb_status aan". QuickBooks toont dan eenmalig de toegangsvraag "QBBridge without a certificate is requesting permission":

    • kies "Yes, always allow access; even when my QuickBooks isn't running" (bevestigen met Yes);

    • het vak "type 'yes'" is grijs en neemt geen invoer (bekende QuickBooks-bug; de letters y/e springen naar de keuzerondjes). Truc: klik eerst op de link "Learn more about permissions of applications that integrates with QuickBooks". Er opent een browser; sluit die. Klik dan in het vak, typ yes, kies Continue en daarna Confirm.

    • Toestemming geldt per bedrijfsbestand en per programma: na een nieuwe versie van de exe of op het echte bestand komt de vraag opnieuw. Terugvinden/intrekken: Edit > Preferences > Integrated Applications.

  5. Controleer in qb_status: qbxml_version_in_use (13.0 of lager), country, multicurrency_on en home_currency. Is het land niet US, CA of UK, dan ondersteunt de SDK de editie officieel niet; stop dan en overleg.

Bestanden van de server: %LOCALAPPDATA%\QBBridge\ (runs\ undo-logs, log\ alle qbXML-requests en -antwoorden, confirm.key en used_codes\ met één bestand per gebruikte controlecode). Instelbaar met omgevingsvariabelen:

Variabele

Standaard

QBBRIDGE_QBXML_MAX

13.0

QBBRIDGE_APP_NAME

QBBridge (naam in de toegangsvraag van QuickBooks)

QBBRIDGE_DATA_DIR

%LOCALAPPDATA%\QBBridge

QBBRIDGE_RUNS_DIR / QBBRIDGE_LOG_DIR

<data>\runs / <data>\log

Waarom 32-bit

QuickBooks Desktop t/m 2021 is 32-bit. De COM-component QBXMLRP2.RequestProcessor werkt dan alleen vanuit een 32-bit proces; een 64-bit Python geeft 0x800700C1. De server draait daarom als 32-bit exe (PyInstaller met 32-bit Python). Die werkt ook met 64-bit QuickBooks 2022+ (getest met QuickBooks Enterprise 24 op Windows 11 ARM).

Bouwen

In Windows, met de 32-bit Python van python.org en Inno Setup 6:

powershell -ExecutionPolicy Bypass -File installer\build_win32.ps1 -Python C:\py32\python.exe -Iscc C:\inno\ISCC.exe

Het script weigert een 64-bit Python, installeert installer/requirements-win32.txt (mcp<2; cryptography<45, want nieuwere versies hebben geen 32-bit wheel), bouwt installer\dist\qbbridge-mcp.exe en configure_claude_desktop.exe en daarna installer\Output\QBBridgeSetup.exe. Zie ook installer/README.md.

Testen

  • tests/test_offline.py: controlecode, versiekeuze, bedragen, en de schrijf-tools tegen een nep-QuickBooks (zonder QuickBooks; vereist het pakket mcp): python -m pytest tests/test_offline.py.

  • tests/vm/mcp_harness.py: MCP-client die de server via stdio start zoals Claude Desktop en elke aanroep vastlegt, voor tests tegen een echte QuickBooks Desktop met een testbedrijfsbestand. Scenario's en resultaten met bedrijfsdata horen niet in deze repo.

Licentie

MIT, zie LICENSE (copyright van de oorspronkelijke auteur van qbbridge).

Available Tools

25 tools
qb_account_balanceB
Read-only

Balance of one account (e.g. a bank account or the suspense account), in that account's currency.

Inputs: account (required).

qb_add_transactionA

Adds a transaction (Check, Deposit, CreditCardCharge, or CreditCardCredit) in the home currency. lines: [{"account": str, "amount": number or string, "memo": str|None}, ...]. For foreign-currency accounts or exchange rates use qb_write_check / qb_deposit instead. A Deposit has no header payee or refnum in qbXML: payee is put on every line (as EntityRef) and a refnum is refused.

Two steps: without confirm_code this only returns a preview and a confirm code; with the code it books and logs an undo entry (qb_revert_run).

Inputs: lines (required), account (required), txn_date (required), txn_type (required), +6 more.

qb_add_vendorA

Creates a vendor. Two steps (preview + confirm_code). Refuses if a vendor with this exact name exists; check qb_list_vendors first for near-duplicates in spelling/casing.

Inputs: name (required), run_id, confirm_code, expected_company_file.

qb_check_duplicateA
Read-only

Checks whether a transaction with this date+amount already exists somewhere in the company file, within a tolerance window (banks don't always post the two sides of a transfer/payment on the exact same date). Use this before posting anything, to avoid double-entry -- especially for payments/transfers, where the same real-world event can get recorded from either side of a linked account. By default it looks at Check, Deposit, CreditCardCharge, CreditCardCredit, Transfer, Invoice, ReceivePayment and JournalEntry.

Inputs: date (required), amount (required), account, txn_types, +1 more. Returns: result

qb_company_infoA
Read-only

Returns the company file path QuickBooks Desktop currently has open. Call this first, and before any write, to confirm you're pointed at the right client's file.

Inputs: no named parameters.

qb_create_customerB

Creates a customer. bill_address: {"lines": [..max 5], "city", "state", "postal_code", "country"}, or the form qb_search_customers returns ({"Addr1".."Addr5", "City", "State", "PostalCode", "Country"}); unknown keys are refused. currency: ISO code or QuickBooks name (multicurrency only; cannot be changed later once used). Refuses if a customer with this exact name exists. Two steps (preview + confirm_code).

Inputs: name (required), email, phone, run_id, +8 more.

qb_create_invoiceA

Creates an invoice.

lines, in invoice order: item line {"item": exact item full name, "description", "quantity", "rate"} (or "amount" instead of quantity x rate), optional "sales_tax_code" per line; text-only line (e.g. a product-group heading) {"description": "..."} without item. sales_tax_code: default SalesTaxCodeRef for item lines (e.g. "Non"). currency: optional check -- refused if the customer's currency differs (the invoice currency is always the customer's currency). exchange_rate: home-currency units per 1 unit of invoice currency. expected_total: the invoice SUBTOTAL, i.e. the sum of the lines excluding sales tax. Refused before booking if the lines add up to something else; checked again after booking against QuickBooks' own Subtotal, and an invoice that differs is removed again immediately. Without expected_total the same check is made against the subtotal of the preview. Sales tax is computed by QuickBooks on top and returned as sales_tax_total / total. Refuses a ref_number that already exists, unknown customer or items. Two steps (preview + confirm_code).

Inputs: lines (required), customer (required), txn_date (required), ref_number (required), +13 more.

qb_create_itemA

Creates a non-inventory item (max 31 characters, no ':'). Use only after the user explicitly asked for a NEW item; search first with qb_search_items. manufacturer_part_number can hold an article code so qb_search_items finds it. Two steps (preview + confirm_code).

Inputs: name (required), income_account (required), price, run_id, +5 more.

qb_depositA

Money into a bank account (Make Deposits). lines: [{"account": source account (e.g. a suspense account), "amount", "memo", "entity"}] or [{"payment_txn_id": a received payment sitting in Undeposited Funds}] (no "amount": it is the payment's own amount, looked up in QuickBooks and counted in the total and expected_total). Amounts are in the bank account's currency; exchange_rate = home-currency units per 1 unit of that currency. Two steps (preview + confirm_code).

Inputs: lines (required), txn_date (required), deposit_to_account (required), memo, +6 more.

qb_find_invoiceA
Read-only

Finds invoices by ref number (exact), and/or amount (matches total = subtotal + tax, or balance remaining), date range (YYYY-MM-DD) and customer. Give at least one criterion.

Inputs: amount, date_to, customer, date_from, +2 more. Returns: result

qb_find_transactionsA
Read-only

All transactions in a date range (YYYY-MM-DD), optionally for one account or entity and of given types (e.g. ["Invoice", "ReceivePayment", "Deposit", "Check", "JournalEntry"]). One row per transaction: type, date, ref, entity, account, amount, currency. Use before booking a bank line to avoid booking it twice.

Inputs: date_to (required), date_from (required), entity, account, +2 more. Returns: result

qb_journal_entryA

General journal entry. lines: [{"kind": "debit"|"credit", "account", "amount", "memo", "entity"}]; debits must equal credits. With multicurrency, an entry may use one foreign currency (currency + exchange_rate = home-currency units per 1 unit) next to home-currency accounts; amounts are then in that foreign currency. ref_number max 11 characters. Two steps (preview + confirm_code).

Inputs: lines (required), txn_date (required), run_id, currency, +4 more.

qb_list_accountsA
Read-only

Lists the chart of accounts: name, type, number, active, currency, balance, total_balance. account_type optionally filters (e.g. "Bank", "Income", "Expense", "OtherCurrentAsset"). Use this to confirm an account name exists exactly before posting to it.

balance vs total_balance: for a parent account with subaccounts, "balance" is that account's OWN activity only; "total_balance" includes every subaccount. Balances are in the account's own currency.

Inputs: active_only, account_type. Returns: result

qb_list_currenciesB
Read-only

QuickBooks' currency list (name, ISO code, active, stored exchange rate in home currency per unit). Only meaningful with multicurrency on.

Inputs: active_only. Returns: result

qb_list_open_invoicesA
Read-only

Unpaid invoices (balance > 0), for one customer (exact full name) or all. Returns ref number, date, customer, currency, total and balance.

Inputs: customer, max_results. Returns: result

qb_list_runsA
Read-only

Lists this server's recent runs (newest first) with what each booked and in which company file, so you can find a run to inspect or revert. Fully reverted runs are not listed; partly reverted ones are marked, and a damaged run log is reported instead of its bookings.

Inputs: limit. Returns: result

qb_list_vendorsA
Read-only

Lists vendors (name, ListID). Use this to confirm a payee exists exactly before posting a transaction against it.

Inputs: active_only. Returns: result

qb_query_transactionsB
Read-only

Queries transactions of one type (Check, Deposit, CreditCardCharge, CreditCardCredit, Transfer, JournalEntry). date_from/date_to as YYYY-MM-DD. Returns normalized records: date, amount, payee, account (first line), memo, txn_id, edit_sequence.

Inputs: txn_type (required), entity, account, date_to, +1 more. Returns: result

qb_receive_paymentA

Records a customer payment and applies it to open invoices (Customers > Receive Payments). amount is in the customer's currency. apply_to: [{"invoice_ref": "INV-001", "amount": ...} or {"txn_id": ..., "amount"}]; the same invoice listed twice is applied once with the summed amount. deposit_to_account: bank account or Undeposited Funds (QuickBooks requires an account in the customer's currency or the home currency). exchange_rate: home-currency units per 1 unit of the customer's currency. Refuses invoices of another customer, already paid, or over-applied. Two steps (preview + confirm_code).

Inputs: amount (required), apply_to (required), customer (required), txn_date (required), +10 more.

qb_revert_runA
Destructive

Undoes every booking of one of THIS server's own runs (run_id from a write tool's result or qb_list_runs), newest first. Only own bookings can be undone: the run log is looked up by id in this server's own run directory, records only what the run created, and revert deletes exactly those objects. Refused if QuickBooks has another company file open than the one the run was booked in, or if the run log is damaged. Two steps: without confirm_code it shows what would be undone. After a partial failure, calling it again skips the steps already undone; a booking that no longer exists in QuickBooks (removed by hand) counts as undone. A (partly) reverted run takes no new bookings.

Inputs: run_id (required), confirm_code.

qb_search_customersA
Read-only

Finds customers whose name, company name, contact or e-mail contains query (case-insensitive; empty = all). Returns currency and balance.

Inputs: query, max_results, include_inactive. Returns: result

qb_search_itemsA
Read-only

Searches the item list: matches query (case-insensitive) against item name, full name, manufacturer part number (art. code) and description. Returns type, price, income account, tax code.

Inputs: query, max_results, include_inactive. Returns: result

qb_statusA
Read-only

Call this first. Reports whether QuickBooks answers, which company file is open, product/edition/country, the qbXML versions QuickBooks supports and the one this server uses (highest <= QBBRIDGE_QBXML_MAX, default 13.0 for QuickBooks 2016), and whether multicurrency is on plus the home currency.

Inputs: no named parameters.

qb_vendor_historyA
Read-only

Returns which account(s) this vendor's past transactions were booked to, with counts -- e.g. {"Food Purchases": 175}. Use this before guessing an account for a new transaction from a known vendor: prefer whatever this vendor has actually been booked to before, not a plausible-sounding guess.

Inputs: vendor_name (required), txn_types.

qb_write_checkA

Money out of a bank account (Write Checks), e.g. bank charges, fixed monthly payments or an unknown debit to a suspense account. lines: [{"account": expense/other account, "amount", "memo", "customer"}]. Amounts in the bank account's currency; exchange_rate = home-currency units per 1 unit of that currency. Two steps (preview + confirm_code).

Inputs: lines (required), txn_date (required), bank_account (required), memo, +7 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 25 tools

    Disambiguation3/5

    Several tools overlap in purpose: qb_status and qb_company_info both report the open company file; qb_query_transactions, qb_find_transactions, qb_find_invoice and qb_list_open_invoices are four different ways to retrieve transactions; and qb_add_transaction partially duplicates qb_write_check/qb_deposit/qb_journal_entry. Descriptions do clarify the boundaries (home-currency-only add_transaction, single-type query vs. cross-type date-range find, check_duplicate vs. find_transactions), but an agent still has real choices to make between similarly purposed tools.

    Naming Consistency4/5

    The qb_ prefix and snake_case are used uniformly across all 25 tools, giving a predictable surface. The only inconsistency is verb choice: creation uses both 'add' (qb_add_transaction, qb_add_vendor) and 'create' (qb_create_customer, qb_create_invoice, qb_create_item), and retrieval mixes 'list', 'search', 'find', and 'query'.

    Tool Count3/5

    25 tools is at the heavy end, though QuickBooks Desktop is a genuinely broad domain (accounts, customers, vendors, items, currencies, multiple transaction types, invoices, payments, run revert). A handful do not clearly earn their place given redundancy: qb_company_info vs qb_status, and qb_add_transaction vs the four specialized write tools.

    Completeness3/5

    The write side covers invoices, payments, deposits, checks, journal entries and a strong revert/run-log safety net, and the read side covers accounts, vendors, customers, items, currencies and transactions. However, there is no update or delete for customers, vendors, items or booked transactions, and the entire Accounts Payable side (bills, bill payments, vendor credits) is absent despite vendor tools existing.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      This MCP server enables AI assistants like Claude to perform Wave Accounting bookkeeping tasks—such as drafting invoices, managing customers, recording payments, and looking up financial data—through natural language commands.
      7
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Connects Claude Desktop, Claude Code, and other MCP-compatible clients to cloud accounting and GST billing records, enabling GST-compliant invoice creation, ledger and voucher management, balance queries, and real-time financial reporting through natural language with role-based tenant isolation.
      22
      38 npm
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables an MCP client such as Claude Code to run financial reports, query records, and create, update, void, delete, deactivate, email, or attach records in a company's QuickBooks Online books through the Accounting API. It runs locally over stdio with read and write tools separated, dry-run previews, an optional read-only mode, and a local audit log so the owner stays in control of every change.
      Apache 2.0