Your custom AI agent can connect to DeepLedger using an API key and the hosted MCP endpoint. Connect your QuickBooks Online company in DeepLedger, create a personal key, and send it as a bearer token from your agent's server or local runtime.
| Connection setting | Value |
|---|---|
| Server URL | https://mcp.deepledger.ai/mcp |
| Transport | Streamable HTTP |
| Authentication header | Authorization |
| Header value | Bearer <your DeepLedger API key> |
This works with an agent host that supports remote MCP and custom authentication headers. If you already use LangChain or LangGraph or CrewAI, those guides show their framework-specific configuration. The example below uses the MCP SDK directly, so you can reuse the connection inside your own agent loop.
1. Connect Your QuickBooks Company
Sign in to DeepLedger. In Settings > Clients, choose Connect QB for the intended company and complete Intuit's authorization flow.
Your custom agent connects to DeepLedger; DeepLedger handles the connection to QuickBooks Online. You do not need a separate Intuit developer app for this hosted setup. The DeepLedger key is different from an Intuit access token and from your model provider's API key.
2. Create a DeepLedger API Key
A DeepLedger firm owner or admin can open Settings > API Access and select Create API Key. Enter a descriptive name, choose an expiration, and copy the full key when it appears. It is shown once.
Store the key in your runtime's secret manager. For the local example below, put it in a .env file:
DEEPLEDGER_API_KEY=your_full_key_here
Add .env to your project's .gitignore. Keep the key out of browser code, prompts, source control, and logs. The secret belongs in the process that makes the MCP request, not in the model's conversation.
A personal key acts as its creator and can reach every company that person can access. It is not a read-only key or automatically limited to the company visible when you created it. You can revoke it in Settings > API Access when the integration is retired or the key needs replacing.
3. Test the Connection with Node.js
Use Node.js 22 or newer. In a new project folder, install the SDK version used by this example:
npm init -y
npm install @modelcontextprotocol/sdk@1.30.0 zod@4
The imports below follow the MCP TypeScript SDK's v1 client API. Its Streamable HTTP transport accepts custom request headers through requestInit.
Save this as connect-deepledger.mjs:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const apiKey = process.env.DEEPLEDGER_API_KEY;
if (!apiKey) throw new Error("Set DEEPLEDGER_API_KEY before running.");
const client = new Client({ name: "custom-bookkeeping-agent", version: "1.0.0" });
const transport = new StreamableHTTPClientTransport(
new URL("https://mcp.deepledger.ai/mcp"),
{ requestInit: { headers: { Authorization: `Bearer ${apiKey}` } } },
);
try {
await client.connect(transport);
const tools = [];
let cursor;
do {
const page = await client.listTools(cursor ? { cursor } : {});
tools.push(...page.tools);
cursor = page.nextCursor;
} while (cursor);
if (!tools.some((tool) => tool.name === "qbCompanyProfile")) {
throw new Error("The company-profile tool was not returned.");
}
const result = await client.callTool({
name: "qbCompanyProfile",
arguments: { operation: "profile" },
});
if (result.isError) {
throw new Error("Company check failed. Review the connection and active company.");
}
const text = result.content.find((item) => item.type === "text");
const profile = result.structuredContent ?? JSON.parse(text?.text ?? "{}");
if (profile.success !== true) {
throw new Error(
`${profile.errorCode ?? "PROFILE_FAILED"}: ${profile.message ?? "Check your active company and QuickBooks connection."}`,
);
}
console.log(JSON.stringify(profile, null, 2));
} finally {
await client.close();
}
Run it from the folder containing your .env file:
node --env-file=.env connect-deepledger.mjs
This example discovers the tools and reads the active company's profile. It does not ask a model to make decisions or change QuickBooks records. Review the returned company identity and settings before adding a report or recording workflow. The output contains company information, so keep the terminal output private.
4. Select the Right Company
If no company is active, call qbCompanyProfile with operation: "list". Choose an accessible company from that result, then call the same tool with operation: "switch" and its returned organizationId. Read the profile again to confirm the selection.
A switch changes the person's active company across their connected AI clients. Separate keys created by the same person do not create separate company contexts. Coordinate jobs that switch companies, and verify the company returned with each result. See the multiple-company connection guide for details.
5. Use the Connection in Your Agent
Keep the MCP client connected for the duration of your agent run. Your host application connects the model's tool requests to MCP:
- Discover the tools with
listTools(). Each tool supplies a name, description, andinputSchema. - Give your model only the tools needed for its current task. For a first reporting workflow, start with company-profile reads and
qbReports. - Validate the model's requested tool name and arguments in your application, then dispatch it through
client.callTool({ name, arguments }). LimitqbCompanyProfileto theprofileoperation unless your application explicitly supports company switching. - Return the tool result to the model using your model provider's tool-result format. Preserve errors; an unsuccessful call is not an empty report.
- Close the client when the run finishes.
These are host responsibilities: an MCP connection alone does not implement a model loop. The MCP client concepts describe the distinction between the host application and its MCP client.
A local tool filter narrows what your agent can choose; it does not reduce the permissions of the underlying API key. Before adding writes, implement the review and validation flow for those specific operations, including the company, duplicate checks, and recovery from failed calls. Start in a demo company and check results in QuickBooks.
Troubleshooting
401 Unauthorized: Check that the key is complete, unexpired, and not revoked. The header must include Bearer before the key. Do not send an Intuit token or a model-provider key to the DeepLedger endpoint.
No active company: List accessible companies, select one explicitly, and repeat the profile check.
QuickBooks connection error: Reconnect the intended company in Settings > Clients. Repeatedly changing the MCP configuration will not repair a disconnected QuickBooks authorization.
The host asks for a local command instead of a URL: Use its remote HTTP/MCP option. This connection uses a hosted Streamable HTTP server, not a local stdio subprocess.
The company is different from the one you expected: Stop the workflow and check whether another client using the same person's access changed the active company. Creating another personal key for that person does not isolate the selection.
Browse the supported integrations for ready-made client guides, or read the QuickBooks MCP server overview to compare hosted and self-managed connections.