quickbooks-mcp
Provides comprehensive CRUD operations for 29 entity types (e.g., customers, invoices, bills, vendors) and 11 financial reports via the QuickBooks Online API, with safety features for mutation prompts and injection detection.
Click on "Install 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-mcpshow me the profit and loss for last quarter"
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 Online MCP Server
A comprehensive Model Context Protocol (MCP) server for QuickBooks Online
Quick Start | Available Tools | Authentication | Documentation
Safety model
This server is built for use against real books. It exposes 141 QuickBooks Online tools — or 70 in read-only mode — with two safeguards around them.
1. Mutations pause for a human. Every create_*, update_* and delete_*
call surfaces an approval prompt describing what is about to happen in plain
English, before it executes:
DELETE invoice on LIVE books.
Id: 1042
Irreversible. Recoverable only via the QuickBooks Audit Log.2. QuickBooks text is treated as untrusted input. Customer names, invoice
memos, private notes and attachment filenames are attacker-influenceable — a
counterparty can put text in them. Read responses wrap every string in
<untrusted-qbo-data field="KEY"> delimiters so an agent reads them as data
rather than instructions, and flags strings matching known injection patterns:
WARNING: INJECTION SUSPECTED in 1 field
Invoice[0].PrivateNote - matched: instruction-override - "<untrusted-qbo-data field="excerpt">Ignore all previous instructions...</untrusted-qbo-data>"
<untrusted-qbo-data field="PrivateNote">Ignore all previous instructions...</untrusted-qbo-data>IDs, dates and amounts pass through byte-exact so arithmetic and reconciliation are unaffected.
The two halves fail in deliberately opposite directions. The confirmation gate fails closed — any error produces a prompt, never silent execution. The sanitizer fails open — if it errors it returns the data with a warning, because silently blocking a P&L is worse than the risk it mitigates.
Related MCP server: qbo-mcp
Installing the safeguards — both steps are required
The confirmation gate lives in the Claude Code harness, not in the server. It
needs two entries in ~/.claude/settings.json, and the second one is the
part that actually matters.
{
"permissions": {
"ask": [
"mcp__qbo-write__create_*", "mcp__qbo-write__update_*", "mcp__qbo-write__delete_*",
"mcp__qbo-write__create-*", "mcp__qbo-write__update-*", "mcp__qbo-write__delete-*"
]
},
"hooks": {
"PreToolUse": [
{
"matcher": "mcp__qbo-write__(create|update|delete).*",
"hooks": [
{ "type": "command", "command": "<absolute path to your clone>/bin/qbo-confirm-hook" }
]
}
]
}
}Do not skip the
permissions.askrules. APreToolUsehook is advisory. Claude Code's docs are explicit that "deny and ask rules are evaluated regardless of what a PreToolUse hook returns", and inautomode a classifier resolves the hook'saskdecision without involving you. We found this by watching it happen: two near-identicalcreate_estimatecalls in one session, one prompted and one executed silently against production. Theaskrule is what guarantees the prompt, in every permission mode. The hook only supplies the human-readable summary shown inside it.
Both separators are needed because six tools use the legacy hyphen form
(create-bill, create-vendor, update-bill, update-vendor, delete-bill,
delete-vendor).
The matcher is keyed on the MCP server name, so it must match whatever name you register this server under. Registering the same server a second time under a different name silently bypasses the gate.
Read-only by default
Two launch wrappers are provided. Prefer the read-only one for anything that only reads:
Wrapper | Tools | Mutating |
| 70 | 0 — write tools are not registered at all |
| 141 | 71 |
Read-only mode is enforced at registration time via QUICKBOOKS_DISABLE_WRITE,
QUICKBOOKS_DISABLE_UPDATE and QUICKBOOKS_DISABLE_DELETE, so the write tools
are absent from the catalogue rather than merely discouraged.
Both wrappers read the OAuth client secret from the macOS Keychain rather than
.env, so anything that merely reads .env gets a refresh token it cannot use.
Honest limitations
The gate is a prompt, not a policy engine. It stops unattended writes. It does not stop an approved-but-wrong write.
Amounts shown in the prompt are informational. They are read from the tool payload before the handler transforms it and before QuickBooks computes tax, so they can overstate but should not be relied on as the posted total. Nothing is gated on them — every money document prompts regardless of amount.
Injection detection is pattern-based, so it will miss novel phrasings. The delimiting is the load-bearing half; the pattern flags are a convenience.
get_invoice_pdfreturns base64 inline by default and skips injection detection for genuine PDF payloads (verified by the%PDF-magic bytes). Hostile text inside a real PDF's content stream is not inspected.Only tested on macOS with Claude Code. The hook is a Claude Code integration; other MCP clients get the sanitizer but no confirmation gate.
Test suite: 36 suites, 818 tests, with a 100% coverage gate on src/.
Overview
This MCP server provides complete QuickBooks Online API integration for Claude Code and other MCP-compatible clients. It includes full CRUD operations for 29 entity types and 11 financial reports, giving you comprehensive access to QuickBooks Online functionality.
Key Features
144 Total Tools - Complete coverage of QuickBooks Online API
29 Entity Types - Full CRUD operations (Create, Read, Update, Delete, Search)
11 Financial Reports - Balance Sheet, P&L, Cash Flow, and more
OAuth 2.0 Authentication - Secure token-based authentication
TypeScript - Full type safety with Zod validation
Tested - Jest test suite with ESM support
Note: this is a local MCP server. It runs as a stdio subprocess on the developer's or partner's machine and authenticates to a QuickBooks Online company.
Before you start: This MCP server is easy to run once authenticated, but QuickBooks Online integration is gated by Intuit's OAuth app setup. You must register an app on the Intuit Developer Portal and complete a one-time, browser-based OAuth handshake. Sandbox supports
http://localhostredirect URIs; production requires a public HTTPS callback for the initial authorization. After that initial handshake, the server runs locally without further browser interaction (until the 100-day refresh window lapses). See Authentication for full details.
Quick Start
Installation
# Clone the repository
git clone https://github.com/your-username/mcp-quickbooks-online.git
cd mcp-quickbooks-online
# Install dependencies
npm install
# Build the project
npm run buildConfiguration
Copy the template .env.example to .env in the root directory and fill in your values:
cp .env.example .envQUICKBOOKS_CLIENT_ID=your_client_id
QUICKBOOKS_CLIENT_SECRET=your_client_secret
QUICKBOOKS_ENVIRONMENT=sandbox
QUICKBOOKS_REFRESH_TOKEN=your_refresh_token
QUICKBOOKS_REALM_ID=your_realm_id
# Optional: restrict which tool categories are registered (default: all enabled)
# QUICKBOOKS_DISABLE_WRITE=true # suppress create_* tools
# QUICKBOOKS_DISABLE_UPDATE=true # suppress update_* tools
# QUICKBOOKS_DISABLE_DELETE=true # suppress delete_* tools.env is gitignored so your real credentials stay local.
Claude Code Integration
Add to your Claude Code MCP configuration:
{
"mcpServers": {
"quickbooks": {
"command": "node",
"args": ["path/to/mcp-quickbooks-online/dist/index.js"],
"env": {
"QUICKBOOKS_CLIENT_ID": "your_client_id",
"QUICKBOOKS_CLIENT_SECRET": "your_client_secret",
"QUICKBOOKS_REFRESH_TOKEN": "your_refresh_token",
"QUICKBOOKS_REALM_ID": "your_realm_id",
"QUICKBOOKS_ENVIRONMENT": "sandbox",
"QUICKBOOKS_DISABLE_WRITE": "false",
"QUICKBOOKS_DISABLE_UPDATE": "false",
"QUICKBOOKS_DISABLE_DELETE": "false"
}
}
}
}Set any of the DISABLE_* flags to "true" to prevent that category of tools from being registered. Read tools (get_*, search_*) are always available.
Available Tools
Entities
Complete CRUD operations are available for all entity types:
Entity | Create | Get | Update | Delete | Search |
Customer | ✅ | ✅ | ✅ | ✅ | ✅ |
Invoice | ✅ | ✅ | ✅ | ✅ | ✅ |
Estimate | ✅ | ✅ | ✅ | ✅ | ✅ |
Bill | ✅ | ✅ | ✅ | ✅ | ✅ |
Vendor | ✅ | ✅ | ✅ | ✅ | ✅ |
Employee | ✅ | ✅ | ✅ | ✅ | ✅ |
Account | ✅ | ✅ | ✅ | - | ✅ |
Item | ✅ | ✅ | ✅ | ✅ | ✅ |
Journal Entry | ✅ | ✅ | ✅ | ✅ | ✅ |
Bill Payment | ✅ | ✅ | ✅ | ✅ | ✅ |
Purchase | ✅ | ✅ | ✅ | ✅ | ✅ |
Payment | ✅ | ✅ | ✅ | ✅ | ✅ |
Sales Receipt | ✅ | ✅ | ✅ | ✅ | ✅ |
Credit Memo | ✅ | ✅ | ✅ | ✅ | ✅ |
Refund Receipt | ✅ | ✅ | ✅ | ✅ | ✅ |
Purchase Order | ✅ | ✅ | ✅ | ✅ | ✅ |
Vendor Credit | ✅ | ✅ | ✅ | ✅ | ✅ |
Deposit | ✅ | ✅ | ✅ | ✅ | ✅ |
Transfer | ✅ | ✅ | ✅ | ✅ | ✅ |
Time Activity | ✅ | ✅ | ✅ | ✅ | ✅ |
Class | ✅ | ✅ | ✅ | - | ✅ |
Department | ✅ | ✅ | ✅ | - | ✅ |
Term | ✅ | ✅ | ✅ | - | ✅ |
Payment Method | ✅ | ✅ | ✅ | - | ✅ |
Tax Code | - | ✅ | - | - | ✅ |
Tax Rate | - | ✅ | - | - | ✅ |
Tax Agency | - | ✅ | - | - | ✅ |
Company Info | - | ✅ | ✅ | - | - |
Attachable | ✅ | ✅ | ✅ | ✅ | ✅ |
Reports
Report | Tool Name | Description |
Balance Sheet |
| Assets, liabilities, and equity snapshot |
Profit & Loss |
| Income and expenses over a period |
Cash Flow |
| Cash inflows and outflows |
Trial Balance |
| Debit and credit balances |
General Ledger |
| Complete transaction history |
Customer Sales |
| Sales by customer |
Aged Receivables |
| Outstanding customer invoices |
Aged Receivables Detail |
| Detailed aging breakdown |
Customer Balance |
| Current customer balances |
Aged Payables |
| Outstanding vendor bills |
Vendor Expenses |
| Expenses by vendor |
Tool Reference
Tool | Description |
| Create a new customer |
| Get customer by ID |
| Update customer details |
| Delete a customer |
| Search customers with filters |
Tool | Description |
| Create a new invoice |
| Get invoice by ID |
| Update invoice details |
| Delete/void an invoice |
| Search invoices with filters |
| Download an invoice as a PDF (inline base64, or to disk when |
Tool | Description |
| Record a customer payment |
| Get payment by ID |
| Update payment details |
| Void a payment |
| Search payments with filters |
Tool | Description |
| Create a new bill |
| Get bill by ID |
| Update bill details |
| Delete a bill |
| Search bills with filters |
| Create a new vendor |
| Get vendor by ID |
| Update vendor details |
| Delete a vendor |
| Search vendors with filters |
| Create a bill payment |
| Get bill payment by ID |
| Update bill payment |
| Delete a bill payment |
| Search bill payments |
Tool | Description |
| Create a sales receipt |
| Get sales receipt by ID |
| Update sales receipt |
| Void a sales receipt |
| Search sales receipts |
| Create a credit memo |
| Get credit memo by ID |
| Update credit memo |
| Void a credit memo |
| Search credit memos |
| Create a refund receipt |
| Get refund receipt by ID |
| Update refund receipt |
| Void a refund receipt |
| Search refund receipts |
Tool | Description |
| Create a bank deposit |
| Get deposit by ID |
| Update deposit details |
| Delete a deposit |
| Search deposits |
| Create an account transfer |
| Get transfer by ID |
| Update transfer details |
| Delete a transfer |
| Search transfers |
Tool | Description |
| Create a purchase order |
| Get purchase order by ID |
| Update purchase order |
| Delete a purchase order |
| Search purchase orders |
| Create a vendor credit |
| Get vendor credit by ID |
| Update vendor credit |
| Delete a vendor credit |
| Search vendor credits |
Tool | Description |
| Create a time activity |
| Get time activity by ID |
| Update time activity |
| Delete a time activity |
| Search time activities |
Tool | Description |
| Create a class |
| Get class by ID |
| Update class details |
| Search classes |
| Create a department |
| Get department by ID |
| Update department |
| Search departments |
Tool | Description |
| Create a payment term |
| Get term by ID |
| Update term details |
| Search terms |
| Create a payment method |
| Get payment method by ID |
| Update payment method |
| Search payment methods |
Tool | Description |
| Get tax code by ID |
| Search tax codes |
| Get tax rate by ID |
| Search tax rates |
| Get tax agency by ID |
| Search tax agencies |
Tool | Description |
| Get company information |
| Update company info |
| Create an attachment |
| Get attachment by ID |
| Update attachment |
| Delete an attachment |
| Search attachments |
Authentication
This server uses OAuth 2.0 to authenticate to a QuickBooks Online company. You'll set up an app on the Intuit Developer Portal and connect it to either a sandbox (for development) or your production QBO company.
Important: Sandbox vs Production
Mode | When to use | Redirect URI accepted | Setup difficulty |
Sandbox | Development, testing, demos |
| Easy |
Production | Real company data | Localhost rejected — must be a public HTTPS URL | Harder (see below) |
If you only want to read your own company's data, you still need to set up an app — Intuit does not offer per-user API keys. There is no shortcut around the OAuth + app-creation flow.
Sandbox Setup (recommended for first run)
Go to the Intuit Developer Portal and create a new app
Open the app → Settings (left sidebar) → Redirect URIs → add:
http://localhost:8000/callbackGet your Client ID and Client Secret from the app's Keys & Credentials page (Development keys)
Create or use a sandbox company under the Sandbox top-level menu item in the dev portal
Set
QUICKBOOKS_ENVIRONMENT=sandboxin your.envRun
npm run authto complete the OAuth handshake — your browser will open, you sign in to the sandbox company, tokens are saved to.env
Production Setup
The Intuit Developer Portal rejects http://localhost redirect URIs in production mode — every contributor hits this. Two known workarounds:
ngrok tunnel (most common): run
ngrok http 8000, then on your Intuit app go to Settings → Redirect URIs and add the generatedhttps://<id>.ngrok-free.app/callbackURL. Use that URL for the OAuth handshake, then revert to localhost afterwards.Deploy a small public callback handler (e.g., on a VPS or serverless function) that captures the auth code and hands it back to your local setup. More involved; only needed if you can't use ngrok.
After completing the production OAuth handshake, the refresh token is what matters — once it's in .env, you no longer need the public redirect URL for day-to-day use. Refresh tokens auto-rotate; the server persists the new token on each refresh.
Once you have tokens
QUICKBOOKS_CLIENT_ID=your_client_id
QUICKBOOKS_CLIENT_SECRET=your_client_secret
QUICKBOOKS_REFRESH_TOKEN=your_refresh_token
QUICKBOOKS_REALM_ID=your_realm_id
QUICKBOOKS_ENVIRONMENT=sandbox # or 'production'Common pitfalls
.envloaded from the wrong directory. The server resolves.envrelative to the compiled module, not your shell's CWD. If you launch via Claude Desktop, this matters — make sure you're on currentmain.Redirect URI mismatch. The URI you register in the Intuit portal must match exactly — protocol, host, port, path.
http://localhost:8000/callback.
Development
Building
npm run buildTesting
npm testThe test suite includes 396 tests with 100% code coverage across all metrics (statements, branches, functions, lines).
Project Structure
src/
├── clients/ # QuickBooks API client
├── handlers/ # Business logic handlers (87 files)
├── tools/ # MCP tool definitions
├── helpers/ # Utility functions
├── types/ # TypeScript types
└── index.ts # Server entry point
tests/
├── unit/ # Unit tests (396 tests)
│ ├── handlers/ # Handler tests (15 test files)
│ └── helpers/ # Helper tests
└── mocks/ # Test mocks
docs/
├── ARCHITECTURE.md # System architecture & design patterns
├── TESTING.md # Testing guide & patterns
└── plans/ # Development plansDocumentation
Document | Description |
Version history and all changes | |
System architecture, patterns, and design decisions | |
Testing strategy, ESM patterns, and coverage guide |
Error Handling
If you encounter connection errors:
Verify all environment variables are set correctly
Check that tokens are valid and not expired
Ensure the QuickBooks app has the correct redirect URIs
For sandbox testing, use
QUICKBOOKS_ENVIRONMENT=sandbox
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Tool naming convention
All tool names must follow the {verb}_{entity} convention using underscores. The verb prefix determines CRUD Restriction Mode behaviour:
Prefix | Category | Suppressed by |
| WRITE |
|
| UPDATE |
|
| DELETE |
|
| READ | never |
New tools that do not follow this convention will not be correctly categorised and may appear or be suppressed unexpectedly.
License
MIT License - see LICENSE for details.
Acknowledgments
Built with the Model Context Protocol
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nichewizard/quickbooks-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server