I Needed an AI Bookkeeper, So I Gave QuickBooks 143 New Tools

>2026-01-14|5 min read

Get the tool:

Quick Start: Add to your Claude config
json{ "mcpServers": { "quickbooks": { "command": "npx", "args": ["quickbooks-online-mcp-server"], "env": { "QUICKBOOKS_CLIENT_ID": "your-client-id", "QUICKBOOKS_CLIENT_SECRET": "your-client-secret", "QUICKBOOKS_ENVIRONMENT": "sandbox" } } } }

Get credentials from the Intuit Developer Portal.

The idea was simple: let Claude handle my bookkeeping. Pull reports, reconcile transactions, generate invoices. QuickBooks Online has an API. Someone must have wrapped it for MCP already.

Intuit had. Their official

quickbooks-online-mcp-server
existed. I cloned it, configured OAuth, and asked Claude to pull a Balance Sheet.

Nothing. The report tools didn't exist. Neither did payments, deposits, transfers, or half the entities a real bookkeeper needs. Worse, the server wouldn't even start. A missing file broke the OAuth flow entirely.

This is exactly what open source is for.

What Was Broken

Three issues were sitting in the repo, unanswered:

Issue #4: No Balance Sheet or P&L reports. The most fundamental financial statements, and the MCP server couldn't generate them.

Issue #5: Environment variable naming was wrong.

QUICKBOOKS_REDIRECT_URI
wasn't being read correctly.

Issue #6: The

auth-server.ts
file referenced in the OAuth flow didn't exist. The server literally couldn't authenticate.

Beyond the bugs, the coverage was sparse. Maybe 20 tools total. Customers, invoices, bills. The basics. But bookkeeping is more than basics.

What I Built

I spent a few days expanding the server from ~20 tools to 143. Full CRUD operations across 29 entity types. 11 financial reports. And 335 unit tests with 100% code coverage.

| Category | What's New | |----------|------------| | Payments | Payment, SalesReceipt, CreditMemo, RefundReceipt | | Banking | Deposit, Transfer | | Procurement | PurchaseOrder, VendorCredit | | Time Tracking | TimeActivity | | Organization | Class, Department, Term, PaymentMethod | | Tax | TaxCode, TaxRate, TaxAgency | | Reports | Balance Sheet, P&L, Cash Flow, Trial Balance, General Ledger, Aging Reports |

Every handler follows the same pattern: authenticate, build payload, execute, handle errors. Consistency across 87 handler files means the codebase stays predictable.

The Reports That Matter

Financial reports are where this gets useful. You can now ask Claude for real accounting outputs:

javascript// Get a Balance Sheet get_balance_sheet({ start_date: "2026-01-01", end_date: "2026-01-14", accounting_method: "Accrual" }) // Profit & Loss statement get_profit_and_loss({ start_date: "2026-01-01", end_date: "2026-01-14" }) // Aged Receivables (who owes you money) get_aged_receivables_detail({ aging_period: 30 })

These aren't toy outputs. They're the same reports your accountant pulls at year-end. Now Claude can pull them on demand.

100% Test Coverage

I'm a believer in testing. Not for the badge, but because accounting software handles money. You don't want edge cases lurking in your payment handlers.

Test Suites: 12 passed, 12 total Tests: 335 passed, 335 total Coverage: - Statements: 100% - Branches: 100% - Functions: 100% - Lines: 100%

Every conditional path is tested. Every optional field has both "with" and "without" test cases. Every search handler tests empty responses. The ESM module system made this tricky (Jest's

unstable_mockModule
was essential), but the result is a codebase you can trust.

Using Claude as Your Bookkeeper

Here's what this actually looks like in practice. You can have conversations like:

"Show me all unpaid invoices over 30 days old"

Claude searches invoices, filters by date and status, and presents the results.

"Create an invoice for Acme Corp, $2,500 for consulting services"

Claude creates the invoice with proper line items and customer references.

"What's my cash position? Show me the cash flow statement for this month"

Claude pulls the Cash Flow report with the right date parameters.

"Record a $500 payment from Customer #42 against Invoice #1001"

Claude creates the payment record with the correct references.

This isn't a chatbot pretending to do bookkeeping. It's direct API access to your actual QuickBooks data through a properly tested MCP interface.

Try it yourself: This demo shows the kinds of queries you can make with the 143 tools.

quickbooks-mcp-server
[CLEAR]
Try: Loading queries...
Connecting to QuickBooks...
claude>Loading...

Demo mode. Try typing "create invoice", "record payment", or "cash flow"

The Architecture

For those interested in how it's built:

src/ ├── clients/ │ └── quickbooks-client.ts # OAuth + token management ├── handlers/ # 87 handler files │ ├── create-quickbooks-*.ts # Create operations │ ├── get-quickbooks-*.ts # Read operations │ ├── update-quickbooks-*.ts # Update operations │ ├── delete-quickbooks-*.ts # Delete operations │ └── search-quickbooks-*.ts # Search operations └── tools/ # MCP tool definitions

The

node-quickbooks
library uses callbacks, so every handler wraps the API call in a Promise. Input fields use snake_case, QuickBooks wants PascalCase, so there's mapping at the boundary. Three layers of error handling catch auth failures, API errors, and unexpected exceptions.

Open Source Wins

I submitted this as PR #10 to Intuit's repo. Whether they merge it or not, the fork is available and fully functional.

This is the open source story I love. I needed something. It didn't exist in usable form. I built it. Now anyone who wants an AI bookkeeper has a foundation to start from.

The QuickBooks API is comprehensive. The MCP protocol makes it accessible. All that was missing was someone willing to write the glue code. 143 tools, 335 tests, and a weekend later, the glue exists.

Getting Started

  1. Clone the repo
  2. Get API credentials from Intuit Developer Portal
  3. Add to your Claude config (see Quick Start above)
  4. Start with sandbox mode until you're comfortable
  5. Ask Claude to pull a Balance Sheet

Your AI bookkeeper is ready.

>_Eric Engine

Ask me anything

Type your question below

>