QuickBooks Desktop MCP
Provides read and write access to QuickBooks Desktop on the same machine, including searching customers, items, invoices, accounts and transactions, and (with two-step confirmation codes) creating invoices, customers, items, receive payments, deposits, checks, journal entries, and reverting its own runs.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@QuickBooks Desktop MCP show my open invoices for Acme Corp"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 |
| Geopend bedrijfsbestand, product/versie/land, ondersteunde qbXML-versies en de gebruikte, multicurrency aan/uit, home currency |
| Pad van het geopende bedrijfsbestand |
| Klanten zoeken op (deel van) naam, bedrijfsnaam, contact, e-mail; met valuta en saldo |
| Items zoeken op naam, art.code (ManufacturerPartNumber) of omschrijving |
| Openstaande facturen, per klant of alles |
| Factuur op nummer, bedrag en/of datum(bereik) en klant, optioneel met regels |
| Rekeningschema met valuta en saldo; saldo van één rekening |
| Alle transacties in een periode (optioneel per rekening, relatie, type) |
| Valutalijst met ISO-code en opgeslagen koers |
| Upstream-leestools |
| Eigen runs met wat ze geboekt hebben |
Schrijven (altijd twee stappen):
Tool | qbXML |
| InvoiceAdd: itemregels en tekst-kopregels, memo, RefNumber, TxnDate, SalesTaxCodeRef, optioneel ExchangeRate, valutacontrole, verwacht totaal |
| CustomerAdd, ook met valuta |
| ItemNonInventoryAdd |
| ReceivePaymentAdd, gekoppeld aan facturen, met koers |
| DepositAdd (ook in vreemde valuta, met koers) |
| CheckAdd: bankkosten, vaste posten, vraagpost-afschrijvingen |
| JournalEntryAdd, ook met één vreemde valuta |
| Upstream-schrijftools, nu ook tweestaps |
| Eigen run terugdraaien (ook tweestaps) |
Twee stappen, afgedwongen in de server
Aanroep zonder
confirm_code: de server bouwt het exacte qbXML-request, doet de controles en geeft een voorbeeld plus controlecode. Er wordt niets geboekt.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_rateis 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;
currencybijqb_create_invoiceis 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_paymentop een tussenrekening in valuta A, daarnaqb_depositnaar de bank in valuta B met de koers; een eventuele afrondingsrest van een cent metqb_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.
QuickBooks openen als Admin, single-user, met het (kopie-)bedrijfsbestand.
QBBridgeSetup.exedraaien. De installer zetqbbridge-mcp.exe(32-bit) inC:\Program Files (x86)\QBBridgeen registreert de server alsqbbridgein%APPDATA%\Claude\claude_desktop_config.json(bestaande servers blijven staan). Windows SmartScreen kan waarschuwen ("onbekende uitgever"): de installer is niet gesigneerd.Claude Desktop herstarten. Laat bij de tools van
qbbridgede 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.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.
Controleer in
qb_status:qbxml_version_in_use(13.0 of lager),country,multicurrency_onenhome_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 |
|
|
|
|
|
|
|
|
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.exeHet 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 pakketmcp):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 toolsqb_account_balanceBRead-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_duplicateARead-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_infoARead-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_invoiceARead-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_transactionsARead-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_accountsARead-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_currenciesBRead-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_invoicesARead-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_runsARead-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_vendorsARead-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_transactionsBRead-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_runADestructive
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_customersARead-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_itemsARead-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_statusARead-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_historyARead-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
Scored across 25 tools
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.
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'.
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.
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
Related MCP Connectors
Connect Claude or Cursor to books, invoices, bills, payroll, and sealed closes.
Hosted remote MCP for protected account access, permissions, activity history and supported undo.
Headless API-first double-entry accounting & bookkeeping engine. 84 MCP tools over HTTP.
QuickBooks Online in Claude and ChatGPT: 221 tools, full ledger, multi-company, Canada + US, FR/EN.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceThis 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.7MIT
- FlicenseAqualityDmaintenanceProvides double-entry accounting ledger creation, transaction recording, and financial reporting capabilities via MCP.7-
- AlicenseAqualityBmaintenanceConnects 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.2238 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables 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