Connect LangChain, CrewAI, or Any AI Agent to QuickBooks Online

Published on August 17, 2026

Give an AI agent real QuickBooks Online access with one MCP server URL and an API key: working configurations for LangChain, CrewAI, the OpenAI Agents SDK, and the MCP TypeScript SDK, with accounting guardrails and logging built in.

Chat assistants are how most people meet AI bookkeeping. Agent frameworks are how you make it run without you: a nightly categorization sweep, a close-prep bot, a Slack assistant that answers "what did we spend on contractors this quarter?" from the live ledger.

This guide shows how to give an agent built with LangChain, CrewAI, the OpenAI Agents SDK, or any MCP-capable framework real access to QuickBooks Online. One URL, one API key, and 26 accounting-shaped tools load into your framework as native tools. No Intuit developer app, no OAuth plumbing, no entity modeling.

How It Works

DeepLedger runs a hosted MCP server at:

https://mcp.deepledger.ai/mcp

It speaks Streamable HTTP, the current MCP transport standard, and exposes QuickBooks Online as structured tools: bills, invoices, payments, journal entries, deposits, transfers, reports, master data, plus platform tools for the bank feed, documents, per-client memory, a shared human/AI task list, and the month-end close workflow. Chat clients like Claude and ChatGPT connect to the same server interactively; frameworks connect headless.

Because frameworks run without a browser, they skip the interactive OAuth sign-in and authenticate with an API key.

Step 1: Create an API Key

In the DeepLedger portal, go to Settings → API Keys and create a key. Two things to know:

  • Scope. Each key is bound to exactly one QuickBooks organization. An agent holding the key can only touch that company's books.
  • Lifecycle. Keys can be set to expire, and any key can be revoked from the portal instantly. Every call made with a key is logged the same way chat-client calls are.

Store the key in your secret manager or environment, never in code. The examples below use dl_live_... as a placeholder.

LangChain and LangGraph (Python)

The official langchain-mcp-adapters package turns every DeepLedger tool into a LangChain tool:

from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain.agents import create_agent

client = MultiServerMCPClient(
    {
        "deepledger": {
            "transport": "streamable_http",
            "url": "https://mcp.deepledger.ai/mcp",
            "headers": {"Authorization": "Bearer dl_live_..."},
        }
    }
)

tools = await client.get_tools()
agent = create_agent("anthropic:claude-sonnet-5", tools)

result = await agent.ainvoke({
    "messages": "Pull this week's bank feed and categorize what you can. "
                "Escalate anything you're not confident about, with reasoning."
})

The same client plugs into a LangGraph graph wherever you bind tools. Nothing about the tools is LangChain-specific: schemas, descriptions, and guardrails all come from the server.

CrewAI (Python)

crewai-tools ships an MCP adapter that takes the same URL-plus-header configuration:

from crewai import Agent, Crew, Task
from crewai_tools import MCPServerAdapter

server_params = {
    "url": "https://mcp.deepledger.ai/mcp",
    "transport": "streamable-http",
    "headers": {"Authorization": "Bearer dl_live_..."},
}

with MCPServerAdapter(server_params) as tools:
    bookkeeper = Agent(
        role="Staff bookkeeper",
        goal="Keep the books current and escalate anything uncertain",
        backstory="Works the bank feed daily against QuickBooks Online.",
        tools=tools,
    )
    crew = Crew(
        agents=[bookkeeper],
        tasks=[Task(
            description="Categorize this week's bank transactions.",
            expected_output="A summary of recorded items and escalated tasks.",
            agent=bookkeeper,
        )],
    )
    crew.kickoff()

OpenAI Agents SDK (Python)

The Agents SDK supports remote MCP servers directly:

from agents import Agent, HostedMCPTool

bookkeeper = Agent(
    name="Bookkeeper",
    tools=[
        HostedMCPTool(
            tool_config={
                "type": "mcp",
                "server_label": "deepledger",
                "server_url": "https://mcp.deepledger.ai/mcp",
                "headers": {"Authorization": "Bearer dl_live_..."},
            }
        )
    ],
)

TypeScript, LlamaIndex, and Everything Else

Anything built on the MCP SDKs connects with the Streamable HTTP client and the same header:

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("https://mcp.deepledger.ai/mcp"),
  { requestInit: { headers: { Authorization: "Bearer dl_live_..." } } },
);

const client = new Client({ name: "bookkeeping-agent", version: "1.0.0" });
await client.connect(transport);
const { tools } = await client.listTools();

And for any framework that takes a JSON server config (LlamaIndex, the Claude Agent SDK, custom hosts), it is the standard shape:

{
  "mcpServers": {
    "deepledger": {
      "type": "http",
      "url": "https://mcp.deepledger.ai/mcp",
      "headers": {
        "Authorization": "Bearer dl_live_..."
      }
    }
  }
}

Designing a Safe Autonomous Loop

The mistake to avoid is building an agent that guesses. The DeepLedger toolset is designed around a different loop: read, propose, escalate, record on approval.

A nightly sweep looks like this:

  1. The agent pulls the bank feed. Transactions that already have a pending task arrive pre-flagged, so nothing is double-worked.
  2. For each transaction it checks QuickBooks history and the per-client memory of your policies, then records the clear items, running duplicate checks first.
  3. Anything ambiguous becomes a task in the shared task list, with a proposed category, a confidence level, and written reasoning.
  4. A human reviews the escalations in the DeepLedger portal: approve, correct, or reject. Corrections are written back to memory as policy.
  5. On its next run, the agent picks up approved tasks, records them in QuickBooks, and completes each one with the resulting transaction ID.

The agent does the data entry; human judgment gates every write it was not sure about. That review loop is the same one chat users get, so an autonomous agent and a person working in ChatGPT or Claude share one task list, one memory, and one audit trail.

What the Server Enforces

Autonomy is only as safe as the tool layer underneath it. The guarantees, briefly:

  • No delete. No tool can delete a posted transaction; void (which preserves the record) is the only destructive operation.
  • Duplicate and open-document checks are built into the recording tools' contracts.
  • Per-organization rate limits keep a runaway loop from hammering your books.
  • Complete logging. Every call lands in a worklog beside QuickBooks Online's native audit trail, reviewable at any time.
  • Instant revocation. Delete the API key in the portal and the agent is out, immediately.

Why Not Just Use the QuickBooks API Directly?

You can, and for some products you should. But an agent needs more than endpoints. Building this yourself means an Intuit developer app, OAuth token management, modeling thirty-odd entity types, writing your own duplicate detection, and inventing a review workflow from scratch. The MCP route gives your framework tools that are already shaped like accounting work, with the guardrails and the human review loop included. Our QuickBooks MCP server guide covers the trade-offs honestly, including when a raw API integration is the better call.


DeepLedger connects QuickBooks Online to LangChain, CrewAI, and any MCP-capable agent, with API keys scoped per organization, human review built into the workflow, and a complete audit trail. The first month is free, no credit card required.

Create your DeepLedger account or read how the whole system works.

Ready to get started?

Give your firm the superpower of an AI Accountant. Try the integration today.

Create an Account