Announcing CIMD support for MCP Client registration
Learn more

Should you use Zoho MCP or Zoho API for building AI Agents?

TL;DR

  • Zoho ships an official MCP surface and a mature REST API, and they are not the same object. Zoho CRM's official MCP arrives as four pre-built servers (Data Insights, Data Operations, Module Customization, and Workflow and Process Automation), all scoped to the signed-in user's CRM permissions. The REST API (v8) exposes the full surface: record CRUD, COQL, Bulk, Composite, metadata, and the Notification API for webhooks.
  • The pre-built CRM MCP servers authenticate per user through a browser OAuth flow on the first tool call. That is the right model for interactive and IDE-based agents; it is a hard blocker for headless, background, per-user runs, which the API's self-client and client-credentials flows handle without a browser.
  • Webhooks, composite requests, and high-volume asynchronous bulk live on the API, not the pre-built MCP servers. If your agent reacts to record changes or moves large volumes, that path is API-only.
  • Both paths issue one credential per user, and MCP tool calls draw down the same API credit pool as REST calls. Neither path stores, refreshes, or revokes tokens, and neither trims a large tool surface down to what a given user should see.
  • Scalekit's Zoho CRM connector wraps Zoho CRM API v8 as prebuilt, per-user tools, handles the OAuth flow and token lifecycle, and can expose a scoped subset through a Virtual MCP server; so the MCP vs API decision does not change your auth or credential infrastructure.

Your agent needs to work inside Zoho CRM: read the pipeline, update deals when a rep asks, and create leads and follow-up tasks on their behalf. Zoho now gives you two ways to get there. There is an official MCP surface, delivered as pre-built Zoho CRM MCP servers, and there is the REST API that integrations have used for years, now on v8. They cover overlapping ground, they put your agent on different auth paths, and for background and multi-tenant agents specifically, one of those paths has a hard limit. Here is how to choose.

What Zoho CRM MCP and Zoho CRM API actually are

These are the two objects the rest of this article compares. You have almost certainly called the REST API before. The MCP surface is newer, so it is worth being precise about what it is and how an agent connects to it.

Zoho CRM MCP

Zoho CRM's official MCP surface ships as pre-built MCP servers that you install in an MCP-compatible client. Zoho groups the capabilities into four servers: Data Insights (read-only queries, module lists, field schemas), Data Operations (record CRUD, related records, COQL search, batch operations), Module Customization (modules, fields, and layouts), and Workflow and Process Automation (workflow rules and task actions). Zoho hosts and maintains these, so there is no server for you to build or run.

How an agent connects to the MCP surface

Authentication is per user. On the first tool call, the server opens a browser OAuth flow and the user signs in to their Zoho account; every action is then scoped to that user's CRM role. Zoho states plainly that agents operate under user-level permissions and can only do what the user is authorized to do. The pre-built servers work with clients like Claude, Cursor, VS Code, and Windsurf.

Zoho CRM API

The Zoho CRM REST API is on v8 and exposes effectively every object in the CRM: leads, contacts, accounts, deals, tasks, custom modules, layouts, users, and metadata. Beyond record CRUD it adds COQL for SQL-style retrieval, a Composite API that combines up to five calls in one request, an asynchronous Bulk API for large volumes, and the Notification API for webhooks. Authentication is OAuth 2.0.

How an agent authenticates to the API

The API supports several OAuth client types: server-based (per-user, redirect-driven), self-client (server-to-server, no browser, for back-end jobs), client credentials (self-contained, no refresh token), and mobile or native with PKCE. Access tokens expire after exactly one hour; refresh tokens live until revoked. That range of grant types is what lets the API run both interactive and fully headless.

Comparing them where it matters for agents

The two surfaces overlap on records and metadata and diverge sharply on events, headless auth, and scale. The comparison below is drawn against Zoho's four pre-built CRM MCP servers, since that is the documented, first-party MCP surface.

What your agent can actually do

The pre-built MCP servers cover a wide slice of day-to-day CRM work: querying, record operations, schema changes, and even workflow automation. The gaps show up when an agent has to react to changes, move volume, or run without a person present.

Capability
Zoho CRM MCP (pre-built servers)
Zoho CRM API (v8)
Record CRUD across standard and custom modules
Yes (Data Operations)
Yes
COQL queries for SQL-style retrieval
Yes (Data Insights)
Yes
Read-only reporting and aggregation
Yes (Data Insights)
Yes
Metadata: modules, fields, layouts
Yes (Module Customization)
Yes
Workflow rule and task automation setup
Yes (Workflow and Process Automation)
Limited
High-volume asynchronous bulk read and write
Partial (batch operations)
Yes (Bulk API, up to 200,000 records per page)
Composite requests (several calls in one)
No
Yes (up to 5 calls per request)
Real-time change notifications (webhooks)
No
Yes (Notification API)
Send email from a record
Not in pre-built servers
Yes (Send Mail API)
Headless or background auth (no browser)
No (per-user browser OAuth)
Yes (self-client or client credentials)

Where the MCP ceiling is

The pre-built servers are built for a person working through an AI client. Anything event-driven or headless sits on the API. Webhooks are the clearest case: if your agent has to act when a deal stage changes or a lead is created, that requires the Notification API, which the pre-built servers do not expose. High-volume synchronization is the second case, and the Composite API is the third. None of these are missing tools that ship next month; they are surfaces the pre-built servers were not designed to carry.

The auth path each one puts you on

Auth is where the choice becomes structural rather than cosmetic. The MCP surface centers on per-user browser consent; the API gives you both interactive and non-interactive grants. Understanding the difference between MCP and APIs at a protocol level helps clarify why the auth models diverge so sharply.

MCP auth: per user, browser-first

The pre-built CRM MCP servers use OAuth per user, triggered by a browser window on the first tool call, and the resulting access is bound to that user's CRM role. Zoho's hosted MCP console adds an organization-level mode where a super admin authorizes once and shares tokens across a team; that removes the browser step but replaces per-user identity with one shared credential, and the server URL then behaves like a bearer token that anyone holding it can use. For per-user work, browser consent is the model.

API auth: interactive and headless both work

The API's self-client and client-credentials flows authenticate with no user in the loop, which is exactly what a scheduled or background agent needs. You run the consent once per user (or use a self-client for a back-end job), store the refresh token, and exchange it for a fresh access token as needed. That is the pattern the pre-built MCP servers cannot participate in. This is one reason handling token refresh for AI agents is a non-trivial infrastructure problem worth solving deliberately.

The multi-tenant reality

For a B2B agent serving 40 reps across several Zoho orgs, both paths land you at one credential per rep. Zoho enforces user-level identity, which is the correct security posture, but neither path stores those tokens, refreshes them before the one-hour expiry, or revokes them when a rep leaves. That is infrastructure you own regardless of the path.

What you own in production

The MCP path hands Zoho the hosting and schema maintenance. The API path hands you everything but gives you full control. On both, the token lifecycle and the credit budget are yours to manage.

On the MCP path

Zoho owns the server, the tool schemas, and updates to them. You own per-user token storage, refresh, and revocation, plus the fact that MCP tool schemas can change when Zoho updates a server, without a version you pin. For a stable, deterministic pipeline, an unannounced schema change is an incident you did not schedule.

On the API path

You own endpoint selection, request construction, pagination, retries, error handling, and the full token lifecycle. In return, v8 is explicitly versioned, so you migrate on your own timeline. When Zoho ships a new capability, you can use it immediately rather than waiting for a tool to appear.

API credits as a production constraint

Zoho CRM is credit-metered on a rolling 24-hour window, and most calls cost one credit while some cost more (a lead conversion costs five). The free tier allows 5,000 credits per day; paid editions add a per-user allotment on top of base credits, and Enterprise or Zoho One can scale to millions. The detail that catches agent teams: MCP tool calls consume the same credit pool as REST calls. An agent that lists, searches, reads, and then writes on every rep interaction spends several credits per turn, so watch the X-API-CREDITS-REMAINING header from day one and size your plan against real agent traffic.

When to use MCP, when to use the API

Use Zoho CRM MCP when:

  • Your agent is interactive and the user is present for OAuth: a rep querying pipeline or updating a deal from Claude, Cursor, or a similar client
  • The work is records, COQL, metadata, or workflow setup, which the pre-built servers cover well
  • You want Zoho to own server hosting and schema maintenance
  • You are prototyping a Zoho agent and want to skip integration code

Use the Zoho CRM API when:

  • Your agent runs headless: scheduled syncs, background scoring, or any run without a browser session, where self-client or client-credentials auth is required
  • You need webhooks (Notification API), the Composite API, or high-volume asynchronous Bulk operations
  • You are serving multiple orgs or reps and need per-user credential isolation, revocation, and versioned stability
  • You need capabilities outside the pre-built servers, such as sending email from a record

The credential problem that exists on both paths

Whichever path you pick, every rep in a multi-tenant agent has their own Zoho credential. Forty reps means forty tokens, forty refresh cycles, and forty revocations to handle when someone leaves. The token type differs by path; the infrastructure required does not. This is a classic example of the credential ownership problem across agent tool-calling patterns.

What Zoho gives you

Zoho enforces identity correctly. Every MCP tool call and every scoped API call runs as the authenticated user, so their CRM role, sharing rules, and field permissions apply. If a rep cannot edit a deal, the agent acting for them cannot either. That is the posture a security review wants to see.

What you still have to build

Zoho enforces identity, but it does not run the credential lifecycle for you. You still need a vault so tokens never sit in agent code, proactive refresh before the one-hour access-token expiry, revocation when a rep offboards, and tenant isolation so one rep's agent can never reach another rep's data. Access tokens expiring silently mid-run is a background-agent failure mode, not an edge case. Secure token management for AI agents at scale requires deliberate infrastructure decisions on all of these fronts.

Where Scalekit fits

Scalekit's Zoho CRM connector handles the OAuth flow, per-user token storage, and refresh for the API path, and can expose the same tools through a Virtual MCP endpoint. The connector is API-based: it wraps Zoho CRM API v8 as prebuilt, LLM-ready tools rather than repurposed API docs. Because it sits at the credential layer, the MCP vs API decision stops changing your auth infrastructure.

Building Zoho CRM agents the Scalekit way

The rest is code. The flow is the same one you would use for any connector: configure the connection once, authorize each user, load only their tools, then run the agent. One rule up front: the connection_name in code must match the connection name you create in the Scalekit dashboard exactly, since that string is how the connection is resolved at runtime.

Configure the connection once

In the Scalekit dashboard, create a Zoho CRM connection under AgentKit and register a Zoho API Console server-based app: paste Scalekit's redirect URI into the app, copy the client ID and secret back into Scalekit, enable the data centers your users belong to, and grant only the scopes your agent needs (for example ZohoCRM.modules.ALL). Then initialize the SDK with your Scalekit credentials.

import os from scalekit import ScalekitClient scalekit = ScalekitClient( env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], ) # "zohocrm" must match the connection name you created in # AgentKit > Connections in the Scalekit dashboard. CONNECTION_NAME = "zohocrm" identifier = "rep_42@acme.com" # your stable per-user identifier

Authorize the user and load only their tools

Before an agent can act for a rep, that rep authorizes Zoho once. The important step comes after consent: rather than handing the model the connector's full 89-tool catalog, you retrieve only the tools this rep's connected account is authorized to call. That scoped surface is what keeps tool selection accurate and token overhead low. This maps directly to how tool calling auth changes when you move from single-tenant to multi-tenant.

# 1) Ensure this rep has a connected account, then send them # through Zoho's OAuth consent once. scalekit.actions.get_or_create_connected_account( connection_name=CONNECTION_NAME, identifier=identifier, ) auth = scalekit.actions.get_authorization_link( connection_name=CONNECTION_NAME, identifier=identifier, ) print("Ask the rep to authorize Zoho CRM:", auth.link) # 2) After consent, load only the tools this rep can call. tools = scalekit.actions.langchain.get_tools( identifier=identifier, connection_names=[CONNECTION_NAME], )

Run the agent loop

With the scoped tools in hand, the agent loop is ordinary LangChain. Tool execution routes through Scalekit against the rep's connected account, so the credentials never touch your agent runtime. This example uses LangChain; the same pattern in other frameworks follows the same structure.

from langchain.agents import create_tool_calling_agent, AgentExecutor from langchain_anthropic import ChatAnthropic from langchain_core.prompts import ChatPromptTemplate llm = ChatAnthropic(model="claude-sonnet-4-5") # any tool-calling model works prompt = ChatPromptTemplate.from_messages([ ("system", "You are a sales assistant that works inside Zoho CRM."), ("human", "{input}"), ("placeholder", "{agent_scratchpad}"), ]) agent = create_tool_calling_agent(llm, tools, prompt) executor = AgentExecutor(agent=agent, tools=tools) result = executor.invoke({ "input": ( "Find deals in the Negotiation stage closing this month " "and add a follow-up task on each." ), }) print(result["output"])

Scope a Virtual MCP server for multi-tool, multi-tenant agents

When you want an MCP endpoint rather than in-process tools, a Virtual MCP server gives you one that exposes only the Zoho tools you choose and acts with the current user's credentials. A standard MCP server exposes everything it has; the connector alone ships 89 tools, and at roughly 200 tokens each that is close to 18,000 tokens of definitions before the agent does any work. You define the server once per agent role, then mint a short-lived, user-scoped session token before each run. There is no MCP server for you to deploy or host.

import os from datetime import timedelta from scalekit import ScalekitClient from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping scalekit = ScalekitClient( env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], ) # Setup: create the server once per agent role, not once per user. vmcp = scalekit.actions.mcp.create_config( name="deal-desk-agent", connection_tool_mappings=[ McpConfigConnectionToolMapping( connection_name="zohocrm", # must match your dashboard connection tools=[ "zohocrm_v8_deals_list", "zohocrm_v8_deal_search", "zohocrm_v8_records_query", "zohocrm_v8_task_create", ], ), ], ) config_id = vmcp.config.id mcp_server_url = vmcp.config.mcp_server_url # Runtime: before each run, confirm the rep's connection is active # and mint a short-lived, user-scoped session token. accounts = scalekit.actions.mcp.list_mcp_connected_accounts( config_id=config_id, identifier="rep_42@acme.com", include_auth_link=True, ) for account in accounts.connected_accounts: if account.connected_account_status != "ACTIVE": print(f"{account.connection_name} needs auth: {account.authentication_link}") session = scalekit.actions.mcp.create_session_token( mcp_config_id=config_id, identifier="rep_42@acme.com", expiry=timedelta(minutes=30), ) # Pass these to any MCP client as bearer auth. mcp_server = { "url": mcp_server_url, "headers": {"Authorization": f"Bearer {session.token}"}, }

Downstream tool-calling auth logs

Every tool call returns an execution_id, which is the correlation ID you carry into your own logs. Scalekit records structured, per-user tool-call events tied to the connection that authorized them, so you can answer who called which Zoho tool, on whose connected account, with what result, without building an audit pipeline yourself. That closes the accountability gap that shared service accounts leave open, since each action traces back to a real rep. Good agent tool observability depends on exactly this kind of per-call attribution.

result = scalekit.actions.execute_tool( tool_input={"criteria": "(Stage:equals:Negotiation)"}, tool_name="zohocrm_v8_deal_search", identifier="rep_42@acme.com", ) print(result.execution_id) # correlation id for this tool call in your logs

Which one to build against

The choice tracks a single question: is a person present when the agent runs?

The interactive case

If your agent is user-facing and the rep is there for consent, Zoho's pre-built MCP servers are a fast, legitimate path. The permission model already constrains the agent per user, and you skip integration code for records, COQL, metadata, and workflow setup.

The production multi-tenant case

If your agent runs headless, reacts to record changes, moves volume, or serves many reps across orgs, build on the Zoho CRM API. Route it through Scalekit's connector so per-user tokens, refresh, revocation, scoped tool surfaces, and a Virtual MCP endpoint are handled at the infrastructure layer. The credential problem is identical on both paths, and that is the part worth solving once. For a deeper look at the patterns that emerge at production scale, see agent tool calling auth production problems, patterns, and anti-patterns.

Build your Zoho CRM agent

Everything above ships as a connector plus the auth layer underneath it.

Connector, templates, and docs

  • Start from the Scalekit Zoho CRM connector, or the wider CRM and sales connectors.
  • For runnable starting points, see the CRM AI agent, the deal intelligence agent, the sales call prep agent, and the outbound prospecting agent.
  • Implementation detail lives in the Zoho CRM connector docs.

Talk to the team

Bring questions to the Scalekit Slack community, or talk to us for help wiring your first Zoho CRM agent.

No items found.
Agent
Auth Quickstart
On this page
Share this article
Agent
Auth Quickstart

Acquire enterprise customers with
‍zero upfront cost.

Every feature unlocked. No hidden fees.