Model Context Protocol (MCP) server for the QuickBooks Online Accounting API. Exposes 130+ tools across 22 QBO entities plus 10 financial reports for Claude and other MCP-compatible clients.
- Node.js >= 20
- QuickBooks Online OAuth2 app credentials (requires an Intuit developer account)
npm install
npm run buildQBO_ACCESS_TOKEN=your-access-token QBO_REALM_ID=your-realm-id npm startMCP_TRANSPORT=http QBO_ACCESS_TOKEN=your-access-token QBO_REALM_ID=your-realm-id npm startThe server listens on http://0.0.0.0:8080/mcp by default.
docker build -t qbo-mcp .
docker run -p 8080:8080 \
-e MCP_TRANSPORT=http \
-e QBO_ACCESS_TOKEN=your-access-token \
-e QBO_REALM_ID=your-realm-id \
qbo-mcp| Variable | Required | Default | Description |
|---|---|---|---|
QBO_ACCESS_TOKEN |
Yes (env mode) | — | QuickBooks Online OAuth2 access token |
QBO_REALM_ID |
Yes (env mode) | — | QuickBooks Online company (realm) ID |
QBO_ENV |
No | production |
API environment: production or sandbox |
MCP_TRANSPORT |
No | stdio |
Transport type: stdio or http |
MCP_HTTP_PORT |
No | 8080 |
HTTP server port |
MCP_HTTP_HOST |
No | 0.0.0.0 |
HTTP server bind address |
AUTH_MODE |
No | env |
Auth mode: env or gateway |
The server does not handle the OAuth flow — it consumes a pre-obtained access token. Two modes:
env mode (default). Token comes from QBO_ACCESS_TOKEN. Single tenant.
gateway mode. Token comes from per-request HTTP headers, isolated through AsyncLocalStorage so concurrent requests never share credentials. Set AUTH_MODE=gateway and send:
| Header | Required | Description |
|---|---|---|
X-Qbo-Access-Token |
Yes | OAuth2 access token |
X-Qbo-Realm-Id |
Yes | Company (realm) ID |
X-Qbo-Environment |
No | production or sandbox (defaults to production) |
When QBO rejects the access token, the server returns an MCP error whose text begins with the literal prefix QBO_UNAUTHORIZED:. The intended contract is that the gateway detects this prefix, refreshes the OAuth token, and retries the request.
Set QBO_ENV=sandbox (env mode) or X-Qbo-Environment: sandbox (gateway mode) to target Intuit's sandbox API at https://sandbox-quickbooks.api.intuit.com instead of production. Unrecognized values fail loudly (no silent fallback to production).
Tools are organized by domain. Call qbo_navigate with a domain name (e.g. customers, vendors, bills) to discover the tools in that domain. All tools are always callable — navigation is a discovery aid, not a prerequisite.
Each entity exposes some subset of list, get, create, update, search. Transactional entities support startDate/endDate filtering on the list operation. Updates are sparse and require the current SyncToken from a prior get.
Sales workflow
qbo_customers_*— list, get, create, searchqbo_invoices_*— list (Paid/Unpaid/Overdue status filter), get, create, sendqbo_estimates_*— list, get, create, updateqbo_sales_receipts_*— list, get, create, updateqbo_credit_memos_*— list, get, create, updateqbo_refund_receipts_*— list, get, create, updateqbo_payments_*— list, get, create
Purchase workflow
qbo_vendors_*— list, get, create, update, searchqbo_bills_*— list, get, create, update, searchqbo_bill_payments_*— list, get, create, updateqbo_vendor_credits_*— list, get, create, updateqbo_purchases_*— list, get, create, update (point-of-sale expenses)qbo_purchase_orders_*— list, get, create, update
Bank & money movement
qbo_deposits_*— list, get, create, updateqbo_transfers_*— list, get, create, updateqbo_journal_entries_*— list, get, create, update (balanced debit/credit)
Products & accounts
qbo_items_*— list, get, create, update, search (products and services)qbo_accounts_*— list, get, create, update, search (chart of accounts)
Classification & terms
qbo_classes_*— list, get, create, update, searchqbo_departments_*— list, get, create, update, searchqbo_terms_*— list, get, create, update, search (Net 30, etc.)qbo_payment_methods_*— list, get, create, update, search
Tax & company
qbo_tax_codes_*— list, get, search (read-only)qbo_tax_rates_*— list, get, search (read-only)qbo_company_info_*— list, get (read-only singleton)
People & time
qbo_employees_*— list, get, create, update, searchqbo_time_activities_*— list, get, create, update (billable time)
Attachments
qbo_attachables_*— list, get, create, update (metadata only; file upload uses a separate QBO endpoint)
qbo_reports_profit_and_lossqbo_reports_balance_sheetqbo_reports_cash_flowqbo_reports_trial_balanceqbo_reports_general_ledgerqbo_reports_aged_receivablesqbo_reports_aged_payablesqbo_reports_customer_salesqbo_reports_customer_balanceqbo_reports_vendor_expenses
qbo_expenses_list_purchases, qbo_expenses_get_purchase, qbo_expenses_list_bills, qbo_expenses_get_bill remain available. New work should use the dedicated qbo_purchases_* and qbo_bills_* tool families, which add create/update/search.
npm test # unit suite — fast, no credentials needed
npm run test:integration # hits a real QBO sandbox; skipped without credsThe integration suite calls one read tool per entity tier (customers, vendors, accounts, items, journal entries, company info) against Intuit's sandbox API. It only runs when both QBO_SANDBOX_ACCESS_TOKEN and QBO_SANDBOX_REALM_ID are present in the environment. CI wires these from the matching repo secrets and skips the job (with a clear notice) when they're absent — so dependabot/fork PRs don't fail.
Apache-2.0