zoho-bookkeeper-mcp
MCP server for Zoho Books integration, enabling AI agents to perform bookkeeping operations like managing journals, expenses, bills, invoices, and file attachments.
README
Zoho Bookkeeper MCP Server
A Model Context Protocol (MCP) server for Zoho Books integration, designed for bookkeeping workflows with AI agents.
Why This Exists
The official Zoho MCP service (zohomcp.com) has limitations:
- Cannot upload file attachments - The MCP schema incorrectly maps binary file parameters as query strings
- Too many tools - 100+ tools exhaust AI tool limits quickly
- Difficult control over tool selection - The mcp.zoho.com interface is troublesome and cannot be used by agents
This custom MCP server provides:
- Proper multipart/form-data file uploads for attachments
- Curated set of 49 tools for bookkeeping workflows
- Auto-refreshing OAuth tokens (1-hour lifetime with 5-minute buffer)
- Both stdio (CLI) and HTTP stream transports
Features
- Full CRUD operations for journals, expenses, bills, and invoices
- File attachments with proper multipart upload support (PDF, images, Office documents)
- Chart of accounts management and transaction queries
- Bank account integration and transaction listing
- Contact management for customers and vendors
- OAuth 2.0 with automatic token refresh
- Health checks for container orchestration
Available Tools (49 total)
| Category | Tools | Description |
|---|---|---|
| Organizations | 2 | List orgs, get org details |
| Chart of Accounts | 4 | List/get/create accounts, list transactions |
| Journals | 9 | Full CRUD + publish + attachments |
| Expenses | 6 | Full CRUD + receipt attachments |
| Bills | 6 | Full CRUD + attachments |
| Invoices | 5 | List/get + attachments |
| Contacts | 2 | List/get customers and vendors |
| Vendors | 4 | Vendor-specific list/get/create/update workflows |
| Bank Accounts | 11 | List accounts/transactions + matching + categorization workflows |
Prerequisites
- Node.js 20+
- Zoho Books account with API access
- Zoho OAuth 2.0 credentials (see Configuration)
Installation
Option 1: Run with npx (Recommended for Desktop Agents)
npx zoho-bookkeeper-mcp
Option 2: Install globally
npm install -g zoho-bookkeeper-mcp
zoho-bookkeeper-mcp
Option 3: Docker
docker build -t zoho-bookkeeper-mcp .
docker run -p 8004:8004 \
-e ZOHO_CLIENT_ID=your_client_id \
-e ZOHO_CLIENT_SECRET=your_client_secret \
-e ZOHO_REFRESH_TOKEN=your_refresh_token \
zoho-bookkeeper-mcp
Option 4: From source
git clone https://github.com/bu5hm4nn/zoho-bookkeeper-mcp.git
cd zoho-bookkeeper-mcp
pnpm install
pnpm build
Configuration
Run the interactive setup:
pnpm setup
This will guide you through:
- Creating a Zoho Self-Client application
- Entering your Client ID and Secret
- Generating and exchanging an authorization code
- Saving credentials to
.env
Manual Configuration
If you prefer manual setup, copy .env.example to .env and follow the Zoho OAuth Documentation to obtain:
ZOHO_CLIENT_ID- from Zoho API ConsoleZOHO_CLIENT_SECRET- from Zoho API ConsoleZOHO_REFRESH_TOKEN- obtained via OAuth authorization code flow with scopeZohoBooks.fullaccess.all
Environment Variables
The .env file should contain:
# Required
ZOHO_CLIENT_ID=1000.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ZOHO_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ZOHO_REFRESH_TOKEN=1000.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional
ZOHO_API_URL=https://www.zohoapis.com/books/v3 # Default (US datacenter)
ZOHO_ORGANIZATION_ID=123456789 # Default org ID (optional)
PORT=8004 # HTTP server port
HOST=0.0.0.0 # HTTP server host
Regional API URLs:
- US (default):
https://www.zohoapis.com/books/v3 - EU:
https://www.zohoapis.eu/books/v3 - IN:
https://www.zohoapis.in/books/v3 - AU:
https://www.zohoapis.com.au/books/v3
Integration with Chat Agents
Claude Desktop
Add to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"zoho-bookkeeper": {
"command": "npx",
"args": ["zoho-bookkeeper-mcp"],
"env": {
"ZOHO_CLIENT_ID": "your_client_id",
"ZOHO_CLIENT_SECRET": "your_client_secret",
"ZOHO_REFRESH_TOKEN": "your_refresh_token"
}
}
}
}
Or if installed globally:
{
"mcpServers": {
"zoho-bookkeeper": {
"command": "zoho-bookkeeper-mcp",
"env": {
"ZOHO_CLIENT_ID": "your_client_id",
"ZOHO_CLIENT_SECRET": "your_client_secret",
"ZOHO_REFRESH_TOKEN": "your_refresh_token"
}
}
}
}
LibreChat
Add to your librechat.yaml:
mcpServers:
zoho-bookkeeper:
type: streamable-http
url: http://mcp-zoho-bookkeeper:8004/mcp
timeout: 30000
And to your docker-compose.yml:
services:
mcp-zoho-bookkeeper:
build:
context: ./path/to/zoho-bookkeeper-mcp
container_name: mcp-zoho-bookkeeper
restart: unless-stopped
environment:
PORT: 8004
ZOHO_CLIENT_ID: ${ZOHO_CLIENT_ID}
ZOHO_CLIENT_SECRET: ${ZOHO_CLIENT_SECRET}
ZOHO_REFRESH_TOKEN: ${ZOHO_REFRESH_TOKEN}
ports:
- "8004:8004"
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8004/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
Generic MCP Client (HTTP)
Start the HTTP server:
# Using pnpm
pnpm serve
# Or directly
node dist/server.js
Connect to http://localhost:8004/mcp using streamable-http transport.
Generic MCP Client (stdio)
# Using pnpm
pnpm start
# Or directly
node dist/bin.js
Usage Examples
Get Organization ID (Required First Step)
Most tools require an organization_id. Get it first:
Use the list_organizations tool to get your Zoho organization ID
Create a Journal Entry
Create a journal entry dated 2025-01-15 with:
- Debit Office Supplies (account_id: 123456) for $150
- Credit Business Checking (account_id: 789012) for $150
Reference: "Office supplies purchase"
Attach a Receipt
Upload the file /path/to/receipt.pdf to journal 4567890123456
List Recent Expenses
List all expenses from the last 30 days
Development
Setup
git clone https://github.com/bu5hm4nn/zoho-bookkeeper-mcp.git
cd zoho-bookkeeper-mcp
pnpm install
Commands
pnpm build # Build TypeScript to dist/
pnpm dev # Run with hot reload (HTTP server)
pnpm serve:dev # Same as dev
pnpm start # Run stdio transport
pnpm serve # Run HTTP server
pnpm test # Run all tests
pnpm test:unit # Run unit tests only
pnpm test:watch # Run tests in watch mode
pnpm test:coverage # Run tests with coverage
pnpm lint # Check for linting errors
pnpm lint:fix # Fix linting errors
pnpm format # Format code with Prettier
pnpm format:check # Check formatting
Project Structure
zoho-bookkeeper-mcp/
├── src/
│ ├── index.ts # Main MCP server setup
│ ├── server.ts # HTTP server entry point
│ ├── bin.ts # CLI entry point (stdio)
│ ├── config.ts # Configuration management
│ ├── api/
│ │ ├── client.ts # Zoho API client helpers
│ │ └── types.ts # TypeScript type definitions
│ ├── auth/
│ │ └── oauth.ts # OAuth token management
│ ├── tools/
│ │ ├── organizations.ts
│ │ ├── chart-of-accounts.ts
│ │ ├── journals.ts
│ │ ├── expenses.ts
│ │ ├── bills.ts
│ │ ├── invoices.ts
│ │ ├── contacts.ts
│ │ └── bank-accounts.ts
│ ├── utils/
│ │ ├── errors.ts
│ │ ├── mime-types.ts
│ │ └── response-parser.ts
│ └── __tests__/ # Test files
├── dist/ # Compiled JavaScript
├── Dockerfile
├── package.json
└── tsconfig.json
API Endpoints
When running as HTTP server:
| Endpoint | Description |
|---|---|
GET /health |
Health check (returns JSON status) |
POST /mcp |
MCP protocol endpoint (streamable-http) |
Troubleshooting
"Invalid OAuth token" errors
- Verify your refresh token is valid
- Check that your Zoho app has the
ZohoBooks.fullaccess.allscope - Ensure the correct regional API URL is set
"Organization not found" errors
- Use
list_organizationsfirst to get valid org IDs - Set
ZOHO_ORGANIZATION_IDenv var for default org
Attachment upload fails
- Verify the file path is accessible to the server
- Check file type is supported (PDF, PNG, JPG, GIF, DOC, DOCX, XLS, XLSX)
- Ensure file size is within Zoho's limits
Rate limiting
This server uses ~3k tokens per request vs ~30k for the hosted Zoho MCP (100+ tools). If you still hit rate limits, add delays between requests.
Tech Stack
- Runtime: Node.js 20+
- Framework: FastMCP
- Language: TypeScript
- Auth: OAuth 2.0 with refresh token flow
- Build: tsup
- Testing: Vitest
- Linting: ESLint + Prettier
License
MIT License - see LICENSE for details.
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Related Projects
- Model Context Protocol - The protocol specification
- FastMCP - The MCP framework used by this server
- Zoho Books API - Official Zoho Books API documentation
Recommended Servers
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.
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.
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.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
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.
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.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
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.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.