zoho-books-mcp
Provides tools for interacting with the Zoho Books API, enabling AI agents to perform general-ledger operations, bank-feed categorization, receipt attachment, and more on Zoho Books accounts.
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., "@zoho-books-mcpcategorize the latest uncategorized bank feed line"
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.
zoho-books-mcp
A local, safety-gated Model Context Protocol server for Zoho Books — it gives an AI agent the general-ledger writes, bank-feed categorization, and receipt attachment that Zoho's native connector doesn't expose, with hard guardrails so it can't run wild on your live books.
⚠️ This lets an AI create, update, and (optionally) delete real records in your live accounting. It ships read-only by default — every write is off until you deliberately turn it on. Read the Safety model before enabling anything, and supervise your agent.
Unofficial — not affiliated with, endorsed by, or sponsored by Zoho Corporation. "Zoho" and "Zoho Books" are trademarks of their respective owner. This is an independent community tool that talks to the public Zoho Books API using your own credentials.
Human-written note
Neither QBO nor Xero expose live bank feeds via their APIs, and by all indications never will. This is directly contradictory to their AI-native marketing posture, and functionally useless to an autonomous bookkeeping agent responsible for monitoring an email inbox for invoices and receipts, booking them against a bank feed, and maintaining the ledger. Zoho does expose this, but their native MCP and Claude connectors are equally impotent, with respect to their tool calls and permission gates; they can't create accounts, post certain transactions, or delete stuff. It seems to me, as of July 2026, that they want their connectors to do data analysis and modeling, where I want my agents to actually do my books.
You could get the same bank feed data straight from Plaid or Yodlee, but that's another subscription to pay for, another MCP to manage, and another set of credentials to care about. Yuck. This MCP expands the capabilities of the agent to basically whatever the Zoho API allows, while keeping write permissions toggled off by default and routing everything through an inference-level approval gate. It's incredibly useful, but powerful enough to be dangerous, if you're irresponsible or lazy. Use this tool intelligently.
On file uploads: Zoho, like most accounting software, lets you attach documents to transactions, like invoices or receipts. When you give your bookkeeping agent that document, it wants to convert it to base64 or binary and pipe it through the API, which blows your context window. The solution is serverside, so your agent can pass POSTs straight from your Google Drive or Dropbox or whatever; this requires OAuth and possibly GCP-esque configuration, and is not included in this repo. In other words: if you want your agent to do the document-attaching for you, you'll need to configure its access to your cloud drive yourself.
Cheers, and happy accounting. Steven
Related MCP server: safedb-mcp
Why this exists
We built this for our own AI bookkeeper, then cleaned it up to share. The short version:
Autonomous bookkeeping lives or dies on API access to the bank feed — the stream of real bank activity an agent must see in order to categorize and reconcile it. In our experience (as of 2026), Xero and QuickBooks Online don't expose that feed through their public APIs: you can push and pull transactions, but you can't reach the live bank feed itself, which leaves an agent blind to the one thing it most needs to act on.
Zoho Books does expose it — its bank feeds are Plaid-sourced and reachable via the API — which makes it the one mainstream option an agent can drive end-to-end. The catch was the tooling around it: the native connectors we tried couldn't post journals, build the chart of accounts, categorize feed lines, or attach source docs. So we wrote a thin, guarded server that does — straight against Zoho's public v3 API, no third-party SDK, no broker. Your credentials stay on your machine and leave only as ordinary HTTPS calls to Zoho.
What it's for: running behind a hosted AI-employee agent (e.g. Openclaw or Hermes), ideally on a VPS, under strict permission gates and human supervision. It ships read-only by default for exactly that reason.
A word of caution: this is genuinely useful and genuinely powerful — enough to make a real mess of real financial records if you point it at production with the gates open and walk away. Don't. Keep writes off until you trust your setup, scope the Zoho user's role tightly, and watch what your agent does. Treated with that respect it's a capable teammate; treated carelessly it's a footgun.
Shared freely by Operamatix, LLC as a contribution to the broader agentic-bookkeeping community.
Features
Verb-split passthrough —
zoho_read/zoho_write/zoho_deletereach any Zoho Books v3 endpoint.Guarded GL wrappers — manual journals (balance-enforced) and chart-of-accounts creation.
Bank-feed workflow — categorize an uncategorized feed line in place, or match it to existing transactions. (Includes the endpoints and request bodies Zoho's docs don't render — see Bank-feed categorization.)
Attachments — upload receipts / source docs to expenses, bills, and journals (by base64 or local file path).
Safety-first — every mutating action sits behind an env flag that is off by default and enforced in code.
Safety model
The guardrails are hard floors enforced in the server — not suggestions the model can talk its way past:
Control | Default | Effect |
|
| All create/update refuse until set to |
|
| All |
Balanced journals | always on |
|
Verbatim errors | always on | Zoho's error response is surfaced as-is — writes fail loud, never silently. |
Recommended posture: keep ZOHO_ALLOW_WRITES=false while you learn the tool; enable writes once you trust your agent and prompts; leave ZOHO_ALLOW_DELETE=false unless you have a specific need. Zoho also enforces the role of the user your credentials belong to, on top of these flags — scope that user to the minimum the agent needs.
Requirements
Node.js ≥ 20
A Zoho Books organization and API credentials (below)
Setup
1. Get Zoho credentials (Self Client / client-credentials)
Go to the Zoho API Console → Self Client.
Generate a grant token with a Zoho Books scope (e.g.
ZohoBooks.fullaccess.all, or something narrower).Exchange the grant token for a refresh token — a standard OAuth
authorization_codePOST tohttps://accounts.zoho.com/oauth/v2/token. Keep therefresh_token.Note your organization_id (Zoho Books → Settings, or
GET /organizations).
The credentials operate as the Zoho user who created the Self Client, so create it under the account/role you want the agent to act as. (Non-US data centers: use the matching
accounts.zoho.*/zohoapis.*domains — see env vars.)
2. Install
npm install3. Configure your MCP client
Example Claude Desktop claude_desktop_config.json entry. Use an absolute node path — desktop apps launch MCP servers with a minimal PATH, so a bare node won't resolve:
"zoho-books": {
"command": "/absolute/path/to/node",
"args": ["/absolute/path/to/zoho-books-mcp/zoho-books-mcp.mjs"],
"env": {
"ZOHO_CLIENT_ID": "...",
"ZOHO_CLIENT_SECRET": "...",
"ZOHO_REFRESH_TOKEN": "...",
"ZOHO_ORGANIZATION_ID": "...",
"ZOHO_ALLOW_WRITES": "false"
}
}See .env.example for every variable.
Tools
Tool | Action | Gate |
| GET any endpoint | always on |
| POST/PUT any endpoint |
|
| DELETE any endpoint |
|
| manual journal (balance-enforced) |
|
| chart-of-accounts account |
|
| categorize an uncategorized feed line |
|
| match a feed line to existing transactions |
|
| upload a receipt/doc (base64 or path) |
|
Bank-feed categorization
Zoho's Banking API docs don't fully render the request bodies for categorizing an uncategorized transaction, so here is what this server confirmed against the live API:
Route (note the singular
uncategorized):POST /banktransactions/uncategorized/{transaction_id}/categorize, or.../categorize/{expenses|customerpayments|vendorpayments}for module types.A deposit / owner contribution is a from/to model, not a flat account field:
{ "transaction_type": "deposit", "from_account_id": "<offset, e.g. equity>", // credited "to_account_id": "<bank account>", // debited "amount": 500, "date": "2026-06-30" }An expense (money out): use
categorize_as: "expenses"withaccount_id(the expense account),paid_through_account_id(the bank),amount, anddate.
The zoho_categorize_bank_txn wrapper handles this for you: pass offset_account_id and it maps to the correct field per type, auto-deriving amount/date/bank from the feed line.
Confirmed vs. inferred
This server was validated against a live US Zoho Books organization. Some behavior is confirmed, some inferred — treat inferred rows as "probably right, not yet verified," and remember every write can be reviewed in Zoho:
Area | Status |
Auth, read, write, delete, journals, accounts, contacts, expenses | ✅ confirmed |
Categorize: deposit / owner_contribution (from/to model) | ✅ confirmed |
Categorize: expenses, vendorpayments | ✅ confirmed |
Attach: expense receipt (field | ✅ confirmed (live round-trip) |
Attach: bill (field | ⚠️ inferred — same pattern, untested |
Categorize: money-OUT directions (owner_drawings, transfer_fund, …) | ⚠️ inferred — pass explicit |
Non-US data centers | ⚠️ untested — set |
Environment variables
Variable | Required | Default | Notes |
| ✅ | — | Self Client id |
| ✅ | — | Self Client secret |
| ✅ | — | long-lived refresh token |
| recommended | — | auto-added to every call |
|
|
| |
|
|
| |
|
| change for non-US DC | |
|
| change for non-US DC |
Testing
npm install
npm testThe smoke test spawns the server with dummy credentials and asserts the tool surface plus that every guard trips before any network call — so it never touches Zoho.
License
MIT. Provided as-is, without warranty — you are responsible for what your agent does to your books. Test with ZOHO_ALLOW_WRITES=false first.
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
- 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/Operamatix/zoho-books-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server