QBO-Multicompany-MCP

QBO-Multicompany-MCP

A self-hosted MCP server that provides AI assistants with secure access to multiple QuickBooks Online company files through a single connection, featuring a company registry, OAuth-based authorization, and comprehensive read/write tools.

Category
Visit Server

README

QBO Multicompany MCP

A self-hosted remote MCP server that gives an AI assistant access to many QuickBooks Online company files through a single connection.

Most QuickBooks MCP servers are single-tenant: the realm id and tokens come from environment variables, so one process serves one company file. If you keep the books for twenty clients, that is twenty processes and twenty connector entries. This one is built around a company registry — you authorize each QuickBooks company once, they all attach to your connector identity, and every tool call names the company it should act on.

list_companies                      → Acme Books (9130350000000001), Beta Holdings (…0002)
run_report  company="Acme Books"    report="ProfitAndLoss"  params={start_date: "2026-01-01", …}
query       company="Beta"          query="SELECT * FROM Invoice WHERE Balance > '0'"

You run it yourself, on your own Azure subscription, under your own Intuit app. Nobody else's infrastructure sits between the assistant and your books.

Is this for you?

It is a good fit if you keep books for several QuickBooks Online companies and want an assistant to work across them, and you are comfortable deploying a container and registering an app with Intuit.

It is not a fit for QuickBooks Desktop or Enterprise, which have no cloud API and need an entirely different (Windows-resident, polling) bridge. And it is more machinery than you need for a single company file — Intuit's own quickbooks-online-mcp-server is simpler for that case.

What you will need

Thing Why Cost
Intuit developer account To create the app your company files are authorized through Free
Azure subscription Container Apps, Key Vault, Table Storage, Log Analytics A few USD/month at low volume
A domain (optional) A stable hostname, so connections survive infrastructure moves Whatever your registrar charges
An MCP client Claude, or any client supporting remote MCP with OAuth

Setup takes about an hour, most of it waiting on Azure and on Intuit's review for production credentials.

Full setup guide — Intuit app, Azure deployment, Cloudflare DNS, and connecting your assistant.

How it works

The connector is an OAuth 2.1 authorization server for the assistant and an OAuth 2.0 client of Intuit. The two sides never meet: the assistant never receives an Intuit token, and Intuit never sees an assistant's client.

Assistant  ──OAuth 2.1──▶  Connector                ──OAuth 2.0──▶  Intuit
           ──MCP/HTTP───▶  (Azure Container Apps)   ──REST───────▶  QuickBooks Online
                                 │
                                 ├─ Key Vault      (wrapping key, app secrets)
                                 └─ Table Storage  (companies, clients, OAuth records)

Intuit authorizes one company file per sign-in, so each file is added the same way: run connect_company, follow the one-time link, pick the next company. They accumulate under one connector identity because that identity is derived from the Intuit OpenID sub — the same person signing in again resolves to the same user.

Intuit refresh tokens are the sensitive value at rest, and are envelope encrypted: a per-record AES-256-GCM key, itself wrapped by an RSA key that never leaves Key Vault. Compromising the storage account alone yields nothing usable.

Architecture for the full design.

Tools

Tool Access Notes
list_companies read Start here; returns the realm ids to pass as company.
connect_company Returns a one-time link for authorizing another file.
get_company_info read CompanyInfo for one file.
query read QuickBooks SQL. SELECT only, enforced.
get_entity read Includes the SyncToken the write tools need.
run_report read Financial statements and lists.
create_entity write
update_entity write Sparse by default.
void_transaction write Preferred over deleting — keeps the audit trail.
delete_entity write Permanent.
disconnect_company Revokes the grant at Intuit. Available even read-only, so access can always be cut.

company accepts a realm id or a company name (case-insensitive). An ambiguous name is an error listing the candidates rather than a guess — silently picking the wrong client's books is the worst failure this connector could have.

Deploy with ALLOW_WRITES=false and the write tools are not registered at all.

Security posture

  • Enrollment is gated by an allow-list of Intuit accounts or email domains (ALLOWED_INTUIT_EMAILS). Leave it empty and anyone who can reach your endpoint can enroll on your Intuit app's credentials and rate limits. The deploy script warns; set it.
  • The container holds no credentials of its own — Key Vault and Storage are reached through an Azure managed identity, and storage shared-key access is disabled.
  • Authorization codes and refresh tokens are stored as hashes, are single-use, and rotate on every use.
  • Logs are structured JSON carrying realm ids and hashed user ids. Tokens, codes, and sealed values are never logged.
  • QuickBooks accounting records are not copied into any database here; requests pass through to Intuit and results are returned.

To report a vulnerability, see SECURITY.md.

Quick start (local)

Requires Node.js 20+ (see .nvmrc).

npm install
npm run build
npm test

cp .env.example .env    # fill in at least QBO_CLIENT_ID and QBO_CLIENT_SECRET
npm start

Locally the connector uses an in-memory store and a local encryption key — state is lost on restart, and both are refused once STORAGE_ACCOUNT_NAME and KEY_VAULT_KEY_URL are set. Intuit will not redirect to a localhost callback unless you register it, and hosted assistants cannot reach localhost, so use a tunnel and point PUBLIC_BASE_URL at it for a full round trip.

Tests cover a full authorization-and-tool-call round trip over real HTTP against a scripted Intuit — no Azure resources or network access needed.

Documentation

Document What is in it
docs/setup.md Intuit app, Azure deploy, Cloudflare DNS, connecting a client
docs/architecture.md Design: OAuth flows, identity, storage, encryption, limits
docs/operations.md Logs, key rotation, revocation, troubleshooting, teardown
docs/configuration.md Every environment variable

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md and CODE_OF_CONDUCT.md.

License

MIT.

This project is not affiliated with, endorsed by, or supported by Intuit Inc. QuickBooks is a trademark of Intuit Inc. You are responsible for your own compliance with Intuit's developer terms, and for the accuracy of any books changed through this connector.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured