Skip to main content
Glama
NitinSharma077-echo

Zoho CRM MCP Server

Zoho CRM MCP Server (FastAPI + FastMCP)

A production-grade Model Context Protocol (MCP) server built with FastAPI + FastMCP that gives Claude and other AI clients complete, authenticated access to the Zoho CRM REST API v8 โ€” from reading records to designing modules and authoring workflow automation.

167 MCP tools covering records, COQL, schema design, workflow rules and their actions, webhooks, bulk/mass operations, tags, notes, email, security settings, and bulk import/export โ€” plus a generic zoho_api_request escape hatch for anything Zoho exposes that has no dedicated tool.


๐ŸŒŸ Key Features

  • FastAPI Web Framework: High-performance, production-ready ASGI app powered by Uvicorn.

  • Dual Transport: Runs as a Streamable HTTP MCP server (for remote/cloud hosting) and as a STDIO MCP server (for local Claude Desktop).

  • Full OAuth 2.0 Lifecycle: Automatic code exchange, browser redirect handler (/auth/callback), encrypted token storage, and a background loop that keeps the token fresh while the server runs.

  • Chat-Configurable Credentials: Supply a Zoho Client ID/Secret from chat (set_zoho_credentials, or inline on get_auth_url/exchange_auth_code) instead of .env โ€” useful for switching Zoho accounts without restarting.

  • Complete Automation Authoring: Build workflow rules end to end โ€” create field-update, email-notification, task, and webhook actions, then wire them into a rule with triggers and criteria.

  • Schema Design: Create custom modules (with the profiles Zoho mandates), fields, global picklists, layouts, and sales pipelines.

  • Scoped Session Mode: ID-based safety filter (activate_scope) restricting operations to specific record IDs.

  • Human-In-The-Loop Approvals: Destructive actions queue a pending request instead of executing. Toggle with ZOHO_REQUIRE_APPROVAL.

  • Structured Activity Logging: Every auth event, API call, and approval decision logged as JSON, retrievable via get_logs() / GET /logs.

  • Encrypted Token Storage: OAuth tokens encrypted at rest (Fernet/AES), never plaintext.

  • Resilient Network Client: Pooled httpx client with automatic 401 refresh-and-retry, clamped 429 backoff, exponential 5xx retry, an outbound rate limiter, and partial-failure detection on Zoho's per-record responses.

  • Automated Test Suite: 35 pytest tests covering the HTTP surface, tool registration, request-payload shapes, and client guards.


Related MCP server: Zoho CRM MCP Server

๐Ÿ“ Repository Structure

zoho-crm-mcp/
โ”œโ”€โ”€ server.py              # FastAPI app + all FastMCP tool definitions & REST endpoints
โ”œโ”€โ”€ auth_manager.py        # OAuth 2.0 flow, scopes & token refresh
โ”œโ”€โ”€ zoho_client.py         # Async HTTP client for Zoho CRM API v8 (151 methods)
โ”œโ”€โ”€ models.py              # Pydantic state & validation models
โ”œโ”€โ”€ token_store.py         # Encrypted (Fernet) token persistence
โ”œโ”€โ”€ approval_manager.py    # HITL approval queue for high-risk actions
โ”œโ”€โ”€ activity_log.py        # Structured JSON activity logger
โ”œโ”€โ”€ test_server.py         # pytest suite
โ”œโ”€โ”€ requirements.txt       # Dependencies
โ”œโ”€โ”€ .env.example           # Environment configuration template
โ”œโ”€โ”€ pyproject.toml         # Package metadata
โ””โ”€โ”€ README.md

โš™๏ธ Setup & Installation

1. Prerequisites

  • Python 3.10+

  • A Zoho CRM API Console app (Zoho API Console)

    • Client Type: Server-based Applications

    • Redirect URI: http://localhost:8000/auth/callback (or your deployment callback URL)

2. Environment Setup

cp .env.example .env

Minimum configuration:

ZOHO_CLIENT_ID=1000.xxxxxxx
ZOHO_CLIENT_SECRET=xxxxxxx
ZOHO_REDIRECT_URI=http://localhost:8000/auth/callback
ZOHO_DATA_CENTER=com
PORT=8000

See .env.example for every supported variable, including the approval gate, OAuth scope override, rate limit, and timeout settings.

Working with more than one Zoho account? ZOHO_CLIENT_ID/ZOHO_CLIENT_SECRET are optional. Leave them blank and ask Claude to call set_zoho_credentials(client_id, client_secret, redirect_uri?, data_center?), or pass client_id/client_secret directly to get_auth_url / exchange_auth_code. Switching client_id clears tokens saved for the previous account, avoiding Zoho's invalid_client error from reusing a refresh token issued to a different app.

3. Install Dependencies

pip install -r requirements.txt

๐Ÿš€ Running & Deploying

Option A: Local FastAPI Web Server

python server.py

Or with Uvicorn directly:

uvicorn server:app --host 0.0.0.0 --port 8000

Once running:

The MCP endpoint is served at the mount root, so the path is /mcp/ โ€” not /mcp/mcp. Keep the trailing slash: /mcp answers with a 307 redirect, which not every MCP client follows correctly on a POST.

Option B: Local STDIO

python server.py --stdio

Option C: Cloud Deployment (Render, Railway, Docker, AWS, Heroku)

  • Start Command: uvicorn server:app --host 0.0.0.0 --port $PORT

  • Health Check Path: /health

  • Environment Variables: set ZOHO_CLIENT_ID, ZOHO_CLIENT_SECRET, ZOHO_REDIRECT_URI, ZOHO_DATA_CENTER, and ZOHO_TOKEN_ENCRYPTION_KEY (so tokens survive restarts on ephemeral filesystems).

Live deployment

Dashboard

https://zoho-crm-mcp-07t7.onrender.com/

Health

https://zoho-crm-mcp-07t7.onrender.com/health

MCP endpoint

https://zoho-crm-mcp-07t7.onrender.com/mcp/

Staying authenticated on an ephemeral host. Render wipes the filesystem on every deploy and restart, taking ~/.zoho_crm_tokens.json with it โ€” and the Fernet key at ~/.zoho_crm_mcp.key is regenerated on each boot, so even a surviving token file could not be decrypted. Set both of these in the host's environment and the server re-authenticates itself instead of asking for tokens again:

  • ZOHO_REFRESH_TOKEN โ€” picked up on cold boot, so a fresh access token is minted automatically. Refresh tokens do not expire unless revoked.

  • ZOHO_TOKEN_ENCRYPTION_KEY โ€” a stable Fernet key, so the cached access token survives too. Generate one with:

    python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Token refresh itself is automatic and needs no configuration: get_valid_access_token() renews anything expiring within 5 minutes, and a background loop re-checks every ZOHO_TOKEN_REFRESH_INTERVAL seconds (default 120).


๐Ÿ–ฅ๏ธ Claude Desktop Integration

Mode 1: HTTP / Remote MCP Connection

Local:

{
  "mcpServers": {
    "zoho-crm": {
      "url": "http://localhost:8000/mcp/"
    }
  }
}

Deployed:

{
  "mcpServers": {
    "zoho-crm": {
      "url": "https://zoho-crm-mcp-07t7.onrender.com/mcp/"
    }
  }
}

The server has no MCP-level authentication, so leave any "OAuth Client ID" field in the connector settings blank. The Zoho OAuth inside the server authenticates it to Zoho; it does not gate the MCP endpoint. Pointing a client at the wrong path (/mcp/mcp) returns 404, which some clients report as a misleading sign-in or registration failure rather than as a bad URL.

Mode 2: Local STDIO Connection

{
  "mcpServers": {
    "zoho-crm": {
      "command": "python",
      "args": ["C:/Users/Lenovo/Desktop/zoho MCP/server.py", "--stdio"],
      "env": {
        "ZOHO_CLIENT_ID": "1000.YOUR_CLIENT_ID",
        "ZOHO_CLIENT_SECRET": "YOUR_CLIENT_SECRET",
        "ZOHO_REDIRECT_URI": "http://localhost:8000/auth/callback",
        "ZOHO_DATA_CENTER": "com"
      }
    }
  }
}

๐Ÿ”‘ First-Run OAuth Flow

  1. Start the server: python server.py

  2. Open http://localhost:8000/auth/url, or ask Claude to run get_auth_url().

  3. Open the returned URL, sign in to Zoho CRM, click Accept.

  4. Zoho redirects to /auth/callback?code=...; the server exchanges the code and saves encrypted tokens to ~/.zoho_crm_tokens.json.


๐Ÿงฉ Building Automation: The Workflow Recipe

Zoho models a workflow rule as a trigger plus conditions, where each condition points at pre-created action objects. Build them in that order:

1. get_workflow_configurations(module="Leads")
   -> see which triggers, comparators, and action types this org supports

2. create_field_update_action(
       name="Mark as Hot", module="Leads",
       field_api_name="Rating", value="Hot")
   -> returns the action id

3. create_workflow(
       name="Hot Lead Router",
       module="Leads",
       execute_when={"type": "create_or_edit"},
       conditions=[{
           "sequence_number": 1,
           "criteria_details": {"criteria": {"group_operator": "and", "group": [
               {"comparator": "equal",
                "field": {"api_name": "Lead_Source"},
                "value": "Web Form"}]}},
           "instant_actions": {"actions": [
               {"id": "<action id from step 2>", "type": "field_updates"}]}}])

4. activate_workflow(workflow_id="...")

The same pattern applies with create_email_notification_action, create_automation_task, and create_webhook as the action source.


๐ŸŽฏ Scoped Session Mode (Safety Filter)

Restrict every operation to specific record IDs:

  • Activate: activate_scope(module="Deals", record_ids=["4153...001", "4153...002"])

  • REST: POST /scope/activate with {"module": "Leads", "record_ids": ["123", "456"]}

  • Deactivate: deactivate_scope() or POST /scope/deactivate

While active, reads on that module are filtered to those IDs, and writes to any other ID are refused with OUT_OF_SCOPE.


โœ… Human-In-The-Loop (HITL) Approvals

By default, destructive actions queue a pending request and return a request_id instead of running:

delete_record, bulk_update_records, bulk_delete_records, mass_update_records, mass_delete_records, change_owner, mass_change_owner, merge_records, delete_workflow, delete_workflows, execute_blueprint, update_layout, activate_layout, delete_layout, delete_field, delete_user, delete_tag, bulk_write_create_job.

  • Review: list_pending_approvals() or GET /approvals

  • Approve & execute: approve_action(request_id="...") or POST /approvals/{id}/approve

  • Reject & discard: reject_action(request_id="...") or POST /approvals/{id}/reject

  • Disable the gate entirely: set ZOHO_REQUIRE_APPROVAL=false so these tools execute immediately.

Every request, approval, and rejection is written to the activity log.


๐Ÿ“œ Activity Logging

Auth events, outbound Zoho API calls, function executions, and approval decisions are recorded as {timestamp, action, status, details} entries โ€” held in memory and appended to ~/.zoho_crm_mcp_activity.log.jsonl.

  • Retrieve: get_logs(limit=50, action=None, status=None) or GET /logs


๐Ÿ” Token Security

  • Tokens are encrypted at rest (Fernet/AES) in ~/.zoho_crm_tokens.json.

  • The key is auto-generated into ~/.zoho_crm_mcp.key on first run (user-only permissions on POSIX), or set explicitly via ZOHO_TOKEN_ENCRYPTION_KEY for a stable key across container restarts.

  • Tokens are tagged with the client_id that issued them and discarded on mismatch, which prevents Zoho's invalid_client error after switching accounts.

  • Outbound calls are self-throttled (ZOHO_RATE_LIMIT_PER_SEC, default 10/sec) on top of 429/5xx backoff.


๐Ÿงช Testing

pytest -v

Covers the HTTP surface (/health, /, /auth/*, /scope/*, /approvals/*, /logs), registration of all 167 MCP tools, the exact request payloads sent for workflows/modules/notes/calls/webhooks/merges/locks, client-side validation guards, rate-limit clamping, and Zoho partial-failure detection.

Tests run entirely offline โ€” no Zoho credentials required.


๐Ÿ› ๏ธ MCP Tool Reference

Category

Tools

OAuth & Auth

get_auth_url, exchange_auth_code, set_zoho_credentials, get_auth_status, get_access_token, refresh_access_token, validate_token, get_token_expiry

Scoped Mode

activate_scope, deactivate_scope, get_scope_status

HITL & Logging

list_pending_approvals, approve_action, reject_action, get_logs

Escape Hatch

zoho_api_request โ€” call any Zoho v8 endpoint with full auth/retry handling

Record CRUD

create_record, get_record, update_record, delete_recordโ€ , list_records, search_records, upsert_record, clone_record, get_record_count, get_deleted_records, get_record_timeline

Bulk (โ‰ค100/call)

bulk_create_records, bulk_update_recordsโ€ , bulk_upsert_records, bulk_delete_recordsโ€ 

Mass (async jobs)

mass_update_recordsโ€ , get_mass_update_status, mass_delete_recordsโ€ , get_mass_delete_status, change_ownerโ€ , mass_change_ownerโ€ , merge_recordsโ€ 

Locking & Sharing

lock_record, unlock_record, get_record_locking_info, share_record, get_shared_record_details, revoke_shared_record

Related Records

get_related_records, get_related_records_count, link_related_records, delink_related_record

Query

execute_coql, composite_request

Metadata & Discovery

get_modules, get_module_details, get_fields, get_field_details, get_picklist_values, get_layouts, get_layout_structure, get_related_lists, get_custom_views, get_custom_view_details, get_features, get_organizations, get_business_hours, get_currencies, get_email_templates, get_recycle_bin

Schema Design

create_module, update_module, create_field, create_fields, update_field, delete_fieldโ€ , get_global_picklists, create_global_picklist, update_layoutโ€ , activate_layoutโ€ , deactivate_layout, delete_layoutโ€ , get_pipelines, create_pipeline, update_pipeline

Workflow Rules

get_workflows, get_workflow, get_workflow_configurations, create_workflow, update_workflow, activate_workflow, deactivate_workflow, delete_workflowโ€ , delete_workflowsโ€ 

Workflow Actions

get_field_update_actions, create_field_update_action, update_field_update_action, delete_field_update_action, get_email_notification_actions, create_email_notification_action, delete_email_notification_action, get_automation_tasks, create_automation_task, update_automation_task, get_assignment_rules

Webhooks

create_webhook, get_webhooks, update_webhook, delete_webhook

Files

upload_attachment, get_attachments, download_attachment, delete_attachment, upload_photo, delete_photo

Notes, Calls & Email

create_note, get_notes, update_note, delete_note, create_call, send_mail, get_from_addresses, get_emails

Tags

get_tags, create_tags, update_tag, delete_tagโ€ , merge_tags, get_tag_record_count, add_tags, remove_tags, add_tags_to_multiple_records

Lead Conversion

get_lead_conversion_options, convert_lead, mass_convert_leads, get_mass_convert_status

Blueprint

get_blueprints, execute_blueprintโ€ , create_blueprint, update_blueprint

Bulk Read/Write

bulk_read_create_job, bulk_read_job_status, bulk_read_download_result, bulk_write_upload_file, bulk_write_create_jobโ€ , bulk_write_job_status

Security & Users

get_users, create_user, update_user, delete_userโ€ , get_profiles, create_profile, get_roles, create_role, update_role, get_territories, get_variables, create_variables

Notifications

get_notification_details, enable_notifications, disable_notifications

Functions

execute_function, get_functions, create_function, update_function, delete_function

Reports & Dashboards

get_reports (proxies to Custom Views), create_report, export_report, get_dashboard, create_dashboard_widget

โ€  Approval-gated by default. Set ZOHO_REQUIRE_APPROVAL=false to execute immediately.

* Zoho CRM's public REST API has no endpoint for this operation โ€” blueprint authoring, Deluge function source, and report/dashboard creation are UI-only or belong to the separate Zoho Analytics product. These tools return a clear NOT_SUPPORTED_BY_ZOHO_API message naming a working alternative, rather than failing against a URL that doesn't exist.


๐Ÿงญ Reaching Anything Not Listed

Zoho's API is larger than any hand-written wrapper. zoho_api_request covers the rest with the same auth, throttling, and retry handling:

zoho_api_request(
    method="GET",
    endpoint="settings/territories")

zoho_api_request(
    method="POST",
    endpoint="settings/automation/scoring_rules",
    body={"scoring_rules": [{...}]})

zoho_api_request(
    method="GET",
    endpoint="read/1234567890",
    api_root="bulk")

api_root selects the URL base: crm โ†’ {domain}/crm/v8 (default), bulk โ†’ {domain}/crm/bulk/v8, root โ†’ {domain}.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • The HubSpot MCP Server acts as a bridge that enables AI assistants and Large Language Models to securely interact with HubSpot CRM data through natural conversation, without requiring users to understand complex API structures. It provides read-only access to standard CRM objects (contacts, companies, deals, tickets, products, invoices, and more) and their associations, secured via OAuth 2.0, allowing AI agents to perform tasks like summarizing deals, fetching company updates, and looking up record changes.

  • Connect Claude to your Platform7n workspaces โ€” chat, links, and tasks. One-click OAuth.

  • xmagnet โ€” AI-powered B2B CRM for Claude. 35 tools that turn natural-language prompts into real CRM actions: prospect, enrich, score leads, manage deals, scan buying intent, run email campaigns and sequences, build forms and landing pages, refine ICP, and analyze performance โ€” all directly inside Claude. ๐Ÿš€ ONE-CLICK INSTALL: https://api.xmagnet.ai/claude The install page guides Claude users through 3 steps in under a minute: open Claude Connectors, paste the connector name, paste the server URL, sign in. A reviewer workspace is auto-provisioned on first sign-in with sample contacts, deals, campaigns, and ICP suggestions, so every tool works end-to-end with zero setup. No 2FA. No paid plan required. Free tier exposes all 35 tools. What you can do: โ€ข Prospecting โ€” search_contacts, search_companies, search_investors, find_contacts_at_companies, enrich_contact, validate_email, find_competitors, company_intelligence โ€ข Pipeline โ€” get_deals_pipeline, scan_deal_intent, get_ghost_pipeline, create_deal โ€ข Campaigns & sequences โ€” create_campaign, generate_campaign_content, get_campaign_stats, get_bounce_stats, get_unsub_stats, create_sequence_draft, list_sequences โ€ข Top of funnel โ€” suggest_icp, get_icp, create_form, list_forms, create_landing_page, list_landing_pages, show_suggestions โ€ข Operations โ€” analyze_contacts, get_contact_details, update_contact, save_contacts_to_crm, export_contacts, get_dashboard_stats, get_credit_balance Example prompts to try: โ€ข "Find C-suite contacts at fintech companies that raised Series A in the last 6 months." โ€ข "Scan my open deals for buying intent and prioritize follow-ups." โ€ข "Generate a re-engagement campaign for contacts who opened my last newsletter but didn't reply." โ€ข "Show me my deals pipeline by stage with weighted value and win rate." โ€ข "Generate a landing page for my Q2 webinar with a registration form." Built for founders, SDRs, RevOps, and growth teams who want their CRM to take action โ€” not just store records. Install: https://api.xmagnet.ai/claude ยท Site: https://xmagnet.ai ยท Privacy: https://xmagnet.ai/privacy-policy ยท Terms: https://xmagnet.ai/terms-of-service ยท Support: ashish.sinha@xmagnet.ai

  • WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Connects Claude to Zoho CRM with read-only access, enabling natural language queries to search records, list modules, retrieve field information, and count records using OAuth authentication.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables read-only interaction with Zoho CRM data through natural language queries, allowing users to search records, list modules, retrieve field information, and count records using secure OAuth authentication.
    2
    -
  • F
    license
    B
    quality
    D
    maintenance
    Exposes Zoho CRM v6 REST API as structured tools for LLM agents via MCP, enabling CRUD operations, search, COQL queries, and more.
    11
    3
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to interact with Zoho CRM data through secure OAuth authentication, supporting comprehensive CRM operations including record management, search, bulk operations, and lead conversion.
    3
    MIT

Latest Blog Posts

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/NitinSharma077-echo/zoho-crm-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server