
Your agent needs to read and write QuickBooks Online. It has to pull a profit and loss statement before a board meeting, create invoices when a deal closes, and reconcile bills across your customers' books. Intuit now ships both an official MCP server and a long-standing REST API, and they are not the same object: different capability coverage, a shared but differently operationalized auth model, and very different production surface area. The choice is less obvious than it looks, because QuickBooks breaks the usual "MCP is OAuth-only, the API adds service accounts" pattern. Here is how to pick.
Intuit published an official QuickBooks Online MCP server on GitHub, first shared as an early preview in October 2025. It is a local server: a stdio subprocess launched on the developer's machine by an MCP client, not a hosted remote endpoint. The repository currently lists 144 tools spanning 29 entity types with full create, read, update, delete, and search, plus 11 financial reports. Authentication runs through an Intuit Developer app using OAuth 2.0, with QUICKBOOKS_CLIENT_ID, QUICKBOOKS_CLIENT_SECRET, QUICKBOOKS_REFRESH_TOKEN, and QUICKBOOKS_REALM_ID supplied as environment variables. Each running process is bound to a single company. Intuit also ships a separate end-user QuickBooks connector inside Claude for non-developers; that is a consumer feature, not the developer artifact evaluated here.
The QuickBooks Online Accounting API is a REST API returning JSON, versioned by minor version, at https://quickbooks.api.intuit.com/v3/company/{realmId}/. It covers the full accounting surface: entity CRUD, a SQL-like query endpoint, financial reports, Batch operations, Change Data Capture, and webhooks. Authentication is OAuth 2.0 Authorization Code only, documented on the Intuit OAuth 2.0 page; there are no API keys, no basic auth, and no client-credentials option. Official SDKs exist for Node.js, Python, Java, .NET, PHP, and Ruby.
The MCP server covers the interactive accounting surface well: read, search, and mutate the core entities, and pull the standard reports. The gaps appear the moment an agent needs to sync at scale or react to change.
The most consequential gaps are Change Data Capture and Batch. CDC returns every entity changed since a timestamp, within a 30-day window, and is the recommended way to keep books in sync without re-reading everything. Batch submits up to 30 operations in a single call. Both live only in the REST API. The MCP server's tool surface is entity CRUD and reports; it has no CDC tool, no batch tool, and no event subscription. If your agent's job is incremental sync, high-volume writes, or reacting to a posted transaction, the MCP path cannot do it.
There is a second ceiling that matters for B2B builders: the local MCP server holds one refresh token and one realmId per process. A QuickBooks OAuth connection maps to exactly one company file, so one MCP process serves one company. Serving fifty customer companies means fifty processes or fifty reconfigurations. That is a fine shape for a developer's desktop; it is the wrong shape for a backend serving many tenants.
Here QuickBooks diverges from most tools in this series. There is no headless credential shortcut on either path, because QuickBooks does not offer one. Every integration, MCP or REST, obtains access the same way: a user grants consent through the browser-based Authorization Code flow, and your app receives tokens scoped to their company.
The access token is valid for one hour. The refresh token is the durable credential; a new value can be returned roughly once every 24 hours, and you must persist the latest one or the next refresh fails with invalid_grant. Under Intuit's November 2025 policy, refresh tokens carry a maximum validity of five years and must be rotated regularly. This lifecycle is identical whether the token was minted for the MCP server's .env or for a direct API client.
The difference is not the flow; it is who manages the result. The local MCP server hardcodes one company's refresh token in an environment variable and rotates it in place. The REST API lets you manage N per-company refresh tokens programmatically, which is the only way to build a real multi-tenant backend. So the structural point still holds: both paths hand you a credential per company, and neither one stores, refreshes, or revokes those credentials for you.
The MCP server manages tool schema definitions and endpoint normalization, and Intuit updates them when the API changes. What it does not manage: token storage beyond a single .env, per-tenant isolation, revocation on customer churn, and the operational reality of running one process per company.
The REST API path means you own endpoint selection, retries, pagination, SyncToken optimistic locking on every write, and rate-limit handling: 500 requests per minute per company, with Batch and report endpoints metered separately, returning HTTP 429 when exceeded. Intuit also introduced a tiered, metered API pricing model under its App Partner Program, so call volume now carries direct cost. Agentic workflows issue several sequential calls per user action, so this budget erodes faster than a traditional integration. MCP tool calls hit the same underlying API and the same limits.
Use QuickBooks MCP when:
Use the QuickBooks API directly when:
Whichever path you choose, a multi-tenant QuickBooks agent holds one OAuth grant per customer company. Fifty companies means fifty refresh tokens, each rotating roughly daily, each capped at five years, each revocable the moment a customer disconnects or an admin pulls access. That token has to live encrypted at rest, isolated per tenant, and revocable on demand.
The local MCP server persists a single token to a file. The REST API hands you raw tokens and walks away. Neither detects a revoked grant for you; your agent learns about it only when a call returns 401 or invalid_grant, and only if you are watching for it. The token type is the same across both paths, and so is the infrastructure you have to build.
Scalekit's QuickBooks connector handles the per-company OAuth flow, token vault, and automatic rotation for both paths, so the MCP vs API decision does not change your auth infrastructure.
Scalekit's QuickBooks connector is OAuth 2.0 based and treats every customer company as a connected account: a per-user token store tied to a specific identity. When a user authorizes, Scalekit mints and vaults their refresh token, then handles the one-hour access token expiry and the daily refresh-token rotation on your behalf. Credentials stay in the vault and are resolved at request time; they never touch the agent runtime or the LLM context. What the user can't do, the agent can't do.
You call one method and pass the connected account's identifier; Scalekit resolves the right company's credentials and executes the authenticated API call. The connectionName string must match the connection you configured in the Scalekit dashboard, which is the most common integration slip.
The capabilities missing from the MCP server, the query endpoint, Batch, and CDC, are still reachable through Scalekit's request proxy under the same managed OAuth. The agent never handles a token; Scalekit injects the vaulted credential and forwards the raw call.
Handing an LLM all 144 QuickBooks tools is a textbook tool-bloat problem: the model selects the wrong tool, hallucinates parameters, and burns thousands of tokens before doing any work. Scalekit's Virtual MCP Servers fix this at the tool level. You create one server definition per agent role and declare exactly which QuickBooks tools it can see, so a reconciliation agent gets the report and list tools and nothing that can delete a customer. The agent sees only the tools you explicitly allow, not everything the connector exposes.
There is no MCP server to deploy or host. You configure the server once and Scalekit generates a static endpoint of the form https://companyName.scalekit.com/mcp/v3/servers/18a22bed-3088-494e-8a99-f9ce8c7c04d2. Before each run, a short-lived session token is minted scoped to that specific company's connected account, so one server definition serves every tenant without credential sharing. The endpoint is static; the identity is per-user. The Claude managed agents example shows the full end-to-end flow, and the quickstart covers account setup.
Because every call is resolved through a connected account, Scalekit's Agent Auth logs carry full attribution: who authorized the call, which agent ran it, which company it touched, and what came back. For an agent writing journal entries across dozens of customers' books, that per-action, per-tenant trail is what a security reviewer asks for, and it is what standard logging cannot produce when four principals sit behind every action.
Scalekit's QuickBooks connector already covers CRUD across the core entities plus the aged receivables, aged payables, balance sheet, cash flow, general ledger, profit and loss, and trial balance reports. If a specific tool your agent needs is missing, request it in the Scalekit Slack community or talk to the team; new connector tools typically ship within a week.
If your agent is interactive, single-company, and developer-facing, the official MCP server is the faster route to a working prototype: Intuit maintains the tools, and a single OAuth handshake gets you querying live books. If your agent runs headless across many customer companies, needs Change Data Capture or Batch, or has to react to changes through webhooks, build against the REST API directly, because the local, single-process MCP server was not designed for that shape. Most production QuickBooks agents will use both: an interactive assistant on the MCP surface and a background sync on the API. Either way, you hold one rotating refresh token per company, and that credential problem is identical, which is exactly what needs production-grade infrastructure.
Browse the Scalekit QuickBooks connector: https://www.scalekit.com/connectors/quickbooks