{"id":"c052abd8-84ff-4cac-8df7-880508a66cab","entityType":"agent","slug":"clawhub-sprintcx-zoho-crm-mcp","name":"Zoho CRM MCP","canonicalUrl":"https://www.xpersona.co/agent/clawhub-sprintcx-zoho-crm-mcp","canonicalPath":"/agent/clawhub-sprintcx-zoho-crm-mcp","generatedAt":"2026-10-12T15:48:13.408Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-12T00:30:31.450Z","emptyReason":null},"description":"Connect your agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Py...","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 967 downloads reported by the source. Last updated 10/12/2026.","installCommand":"clawhub skill install s174123a4hjjwc1tmxqs9vetzn89dfb5:zoho-crm-mcp","sourceUrl":"https://clawhub.ai/sprintcx/zoho-crm-mcp","homepage":"https://clawhub.ai/sprintcx/skills/zoho-crm-mcp","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/sprintcx/zoho-crm-mcp","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/sprintcx/skills/zoho-crm-mcp","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Zoho CRM MCP technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-12T00:30:31.450Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-12T00:30:31.450Z","emptyReason":null},"stars":null,"forks":null,"downloads":967,"likes":null,"task":null,"library":null,"packageName":null,"latestVersion":"1.4.1","tractionLabel":"967 downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-12T00:30:31.439Z","emptyReason":null},"lastUpdatedAt":"2026-10-12T00:30:31.450Z","lastCrawledAt":"2026-10-12T00:30:31.439Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-13T00:30:31.439Z","lastVerifiedAt":null,"highlights":[{"version":"1.4.1","createdAt":"2026-07-16T07:00:58.775Z","changelog":"Preserve the scripts/ directory layout in the published package so the documented script paths resolve after install.","fileCount":8,"zipByteSize":16840},{"version":"1.4.0","createdAt":"2026-07-16T06:59:20.498Z","changelog":"Consolidated release. Fixes Zoho CRM MCP response handling (normalizes the nested {data:{data,info}} shape returned by the COQL endpoint), adds automatic pagination for contacts/accounts, and adds --fields / --where for custom Zoho fields and filters. Drops OpenClaw-specific framing: the skill is agent-agnostic. Supersedes the zoho-crm-mcp-openclaw-skill listing.","fileCount":8,"zipByteSize":16661},{"version":"0.1.0","createdAt":"2026-07-13T15:16:52.777Z","changelog":"- Removed all bundled helper scripts and documentation files: LICENSE, README.md, sample scripts, and skill-card.md. - This version no longer includes ready-to-use Python scripts for CRM operations. - Retains core documentation in SKILL.md; all usage and instructions now provided there. - No changes to core MCP/Zoho CRM integration functionality.","fileCount":2,"zipByteSize":3518},{"version":"1.3.2","createdAt":"2026-07-13T14:06:12.866Z","changelog":"Expose GitHub source link in the skill documentation","fileCount":8,"zipByteSize":11797},{"version":"1.3.1","createdAt":"2026-07-13T14:02:24.694Z","changelog":"Move source to GitHub and remove shell-based mcporter calls","fileCount":8,"zipByteSize":11636},{"version":"1.3.0","createdAt":"2026-06-28T14:26:40.034Z","changelog":"Updated v1.3.0 - all English, env var requirement","fileCount":6,"zipByteSize":10060},{"version":"1.0.0","createdAt":"2026-06-28T14:17:46.960Z","changelog":"Initial release: CRM contact search, account listing, COQL queries, and mcporter usage patterns","fileCount":6,"zipByteSize":9687}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s174123a4hjjwc1tmxqs9vetzn89dfb5:zoho-crm-mcp","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s174123a4hjjwc1tmxqs9vetzn89dfb5:zoho-crm-mcp` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/sprintcx/zoho-crm-mcp before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sprintcx-zoho-crm-mcp/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sprintcx-zoho-crm-mcp/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sprintcx-zoho-crm-mcp/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-sprintcx-zoho-crm-mcp/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-sprintcx-zoho-crm-mcp/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-sprintcx-zoho-crm-mcp/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-12T15:48:13.406Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sprintcx-zoho-crm-mcp/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sprintcx-zoho-crm-mcp/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sprintcx-zoho-crm-mcp/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sprintcx-zoho-crm-mcp/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-12T00:30:31.450Z","emptyReason":null},"readme":"Skill: Zoho CRM MCP\n\nOwner: sprintcx\n\nSummary: Connect your agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Py...\n\nTags: latest:1.4.1\n\nVersion history:\n\nv1.4.1 | 2026-07-16T07:00:58.775Z | user\n\nPreserve the scripts/ directory layout in the published package so the documented script paths resolve after install.\n\nv1.4.0 | 2026-07-16T06:59:20.498Z | user\n\nConsolidated release. Fixes Zoho CRM MCP response handling (normalizes the nested {data:{data,info}} shape returned by the COQL endpoint), adds automatic pagination for contacts/accounts, and adds --fields / --where for custom Zoho fields and filters. Drops OpenClaw-specific framing: the skill is agent-agnostic. Supersedes the zoho-crm-mcp-openclaw-skill listing.\n\nv0.1.0 | 2026-07-13T15:16:52.777Z | auto\n\n- Removed all bundled helper scripts and documentation files: LICENSE, README.md, sample scripts, and skill-card.md.\n- This version no longer includes ready-to-use Python scripts for CRM operations.\n- Retains core documentation in SKILL.md; all usage and instructions now provided there.\n- No changes to core MCP/Zoho CRM integration functionality.\n\nv1.3.2 | 2026-07-13T14:06:12.866Z | user\n\nExpose GitHub source link in the skill documentation\n\nv1.3.1 | 2026-07-13T14:02:24.694Z | user\n\nMove source to GitHub and remove shell-based mcporter calls\n\nv1.3.0 | 2026-06-28T14:26:40.034Z | user\n\nUpdated v1.3.0 - all English, env var requirement\n\nv1.0.0 | 2026-06-28T14:17:46.960Z | user\n\nInitial release: CRM contact search, account listing, COQL queries, and mcporter usage patterns\n\nArchive index:\n\nArchive v1.4.1: 8 files, 16840 bytes\n\nFiles: package.json (294b), README.md (9486b), scripts/list_accounts.py (6591b), scripts/list_contacts.py (7276b), scripts/search_records.py (4766b), skill-card.md (2294b), SKILL.md (9318b), _meta.json (131b)\n\nFile v1.4.1:SKILL.md\n\n---\r\nname: zoho-crm-mcp\r\nversion: 1.4.0\r\ndescription: Connect your agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Python scripts with pagination and custom-field support for common CRM operations.\r\n---\r\n\r\n# Zoho CRM MCP\r\n\r\nConnect your agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\r\n\r\n## Source Repository\r\n\r\nGitHub source: [sprintberlin/openclaw-zoho-crm-mcp-skill](https://github.com/sprintberlin/openclaw-zoho-crm-mcp-skill)\r\n\r\n## Requirements\r\n\r\n| Requirement | Details |\r\n|---|---|\r\n| Zoho CRM MCP Server | A configured endpoint from [mcp.zoho.eu](https://mcp.zoho.eu) |\r\n| mcporter | MCP client CLI (bundled with OpenClaw; elsewhere install via `npm i -g mcporter`) |\r\n| Environment variable | `ZOHO_MCP_URL` must be set (see below) |\r\n\r\n### Environment Variable Setup\r\n\r\nThis skill requires the `ZOHO_MCP_URL` environment variable. Without it, the Python scripts will not work.\r\n\r\nAdd this to your shell profile (e.g. `~/.bashrc` or `~/.zshrc`):\r\n```bash\r\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\r\n```\r\n\r\nOr set it per session:\r\n```bash\r\nZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py\r\n```\r\n\r\nTo verify it's set:\r\n```bash\r\necho $ZOHO_MCP_URL\r\n```\r\n\r\n## How to Get Your MCP URL\r\n\r\n1. Go to [mcp.zoho.eu](https://mcp.zoho.eu) and sign in with your Zoho account.\r\n2. Click **\"Add Connection\"** (or \"New Connection\").\r\n3. Select **Zoho CRM** from the list of available apps.\r\n4. Choose the **data center** matching your Zoho account (EU, US, IN, AU, JP, CN).\r\n5. Grant the requested OAuth scopes (at minimum: read access to the modules you want to query).\r\n6. After authorization, copy the generated **MCP endpoint URL**. It looks like:\r\n   ```\r\n   https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message\r\n   ```\r\n7. Set it as `ZOHO_MCP_URL` as shown above.\r\n\r\n### Multiple Organizations\r\n\r\nIf you manage multiple Zoho CRM orgs, each gets its own MCP endpoint. You can:\r\n- Set one default via `ZOHO_MCP_URL`\r\n- Pass others explicitly in scripts or mcporter calls\r\n- Use a wrapper script or `.env` file per project\r\n\r\n## Quick Start\r\n\r\n### List available tools on your MCP server\r\n```bash\r\nmcporter list $ZOHO_MCP_URL\r\n```\r\n\r\n### Search for a contact by name\r\n```bash\r\ncat << 'EOF' > /tmp/zoho_search.json\r\n{\r\n  \"path_variables\": {\"module\": \"Contacts\"},\r\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\r\n```\r\n\r\n### Get a single record by ID\r\n```bash\r\ncat << 'EOF' > /tmp/zoho_record.json\r\n{\r\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_record.json)\"\r\n```\r\n\r\n### Run a COQL query (SQL-like)\r\n```bash\r\ncat << 'EOF' > /tmp/zoho_coql.json\r\n{\r\n  \"body\": {\"select_query\": \"SELECT Id, Account_Name, Website FROM Accounts WHERE Website != '' ORDER BY Account_Name LIMIT 50\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_executeCOQLQuery\" --args \"$(< /tmp/zoho_coql.json)\"\r\n```\r\n\r\n## Python Scripts\r\n\r\nReady-to-use scripts for common CRM operations. All scripts require `ZOHO_MCP_URL` to be set.\r\n\r\nThe bundled Python scripts call `mcporter` directly through `subprocess.run([...])` and do not invoke a shell. This avoids shell expansion of the credential-bearing `ZOHO_MCP_URL`.\r\n\r\n`list_contacts.py` and `list_accounts.py` paginate automatically (they follow `more_records` until the full result set is retrieved) and normalize the different Zoho CRM MCP response shapes, so large modules are never silently truncated.\r\n\r\n### Custom fields and filters\r\n\r\nEvery Zoho org has different custom fields. Instead of hard-coding them, the list scripts accept:\r\n\r\n- `--fields F1,F2,...` — request any Zoho field **API names** (comma-separated), including org-specific custom fields (e.g. `Google_Drive_URL`, `Trello_URL`). Unknown fields appear under their API name in the table header.\r\n- `--where \"<COQL clause>\"` (`list_accounts.py` only) — override the default WHERE filter, e.g. `--where \"Google_Drive_URL != ''\"`.\r\n\r\n```bash\r\n# Contacts with custom columns\r\npython3 scripts/list_contacts.py --fields First_Name,Last_Name,Email,Designation\r\n\r\n# Accounts filtered on a custom field, showing custom columns\r\npython3 scripts/list_accounts.py \\\r\n  --where \"Google_Drive_URL != ''\" \\\r\n  --fields Account_Name,Website,Google_Drive_URL,Trello_URL,Trello_ID\r\n```\r\n\r\nUse `getFields` (see below) to discover the exact API names of your custom fields.\r\n\r\n### list_contacts.py - Search and list contacts\r\n```bash\r\n# All contacts as table\r\npython3 scripts/list_contacts.py\r\n\r\n# Search by last name\r\npython3 scripts/list_contacts.py --search \"Smith\"\r\n\r\n# Raw JSON output\r\npython3 scripts/list_contacts.py --json\r\n\r\n# Full record data\r\npython3 scripts/list_contacts.py --search \"Smith\" --json --full\r\n```\r\n\r\n### list_accounts.py - List companies/accounts\r\n```bash\r\n# All accounts with website\r\npython3 scripts/list_accounts.py\r\n\r\n# Search by company name\r\npython3 scripts/list_accounts.py --search \"Acme\"\r\n\r\n# All accounts (including those without website)\r\npython3 scripts/list_accounts.py --all\r\n\r\n# JSON output\r\npython3 scripts/list_accounts.py --json\r\n```\r\n\r\n### search_records.py - Generic module search\r\n```bash\r\n# Search any module by name\r\npython3 scripts/search_records.py Contacts \"Smith\"\r\npython3 scripts/search_records.py Accounts \"Acme Corp\"\r\npython3 scripts/search_records.py Deals \"Project X\"\r\n\r\n# COQL query on any module\r\npython3 scripts/search_records.py Contacts --coql \"Email != ''\" --json\r\n```\r\n\r\n## mcporter Usage Patterns\r\n\r\n### Use temp files for shell-based JSON arguments\r\nWhen calling `mcporter` directly from a shell, escaping can break inline JSON. Write arguments to a temp file:\r\n```bash\r\ncat << 'EOF' > /tmp/args.json\r\n{\r\n  \"path_variables\": {\"module\": \"Contacts\"},\r\n  \"query_params\": {\"criteria\": \"(Email:equals:test@example.com)\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/args.json)\"\r\n```\r\n\r\n### Pagination\r\nFor large result sets, use `page` and `per_page`:\r\n```json\r\n{\r\n  \"path_variables\": {\"module\": \"Contacts\"},\r\n  \"query_params\": {\"page\": 2, \"per_page\": 200}\r\n}\r\n```\r\n\r\n### Field metadata\r\nGet all field names for a module (useful before writing scripts or Deluge code):\r\n```bash\r\ncat << 'EOF' > /tmp/args.json\r\n{\r\n  \"query_params\": {\"module\": \"Contacts\", \"include\": \"allowed_permissions_to_update\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getFields\" --args \"$(< /tmp/args.json)\"\r\n```\r\n\r\n## Recommended CRM Actions\r\n\r\nFor a fully capable CRM agent, enable these actions on your Zoho MCP server at [mcp.zoho.eu](https://mcp.zoho.eu):\r\n\r\n### Read-only (safe starting point)\r\n- `getModules` - List all CRM modules\r\n- `getFields` - Get field definitions for any module\r\n- `getRecord` / `getRecords` - Read individual or lists of records\r\n- `searchRecords` - Search by criteria (email, name, etc.)\r\n- `executeCOQLQuery` - SQL-like queries across modules\r\n- `getRecordCount` - Count records per module\r\n- `getRelatedRecords` - Read linked records (e.g., contacts of an account)\r\n- `getPickListValues` - Get dropdown options for fields\r\n\r\n### Read-write (for agents that create/update data)\r\n- `createRecords` - Create new records in any module\r\n- `updateRecord` - Update a single record by ID\r\n- `upsertRecords` - Insert or update (upsert)\r\n- `createNotes` - Add notes to records\r\n- `createEventsRecords` - Create calendar events\r\n- `createTags` / `postRemoveTags` - Manage tags\r\n\r\n### Avoid enabling by default\r\n- `deleteRecord` / `deleteRecords` - Only enable when specifically needed\r\n\r\n## COQL Reference\r\n\r\nCOQL (Zoho's SQL-like query language) differs from standard SQL in several ways:\r\n\r\n- No JOINs - query one module at a time\r\n- Use single quotes for strings: `WHERE Last_Name = 'Smith'`\r\n- DateTime format: `2026-01-01T00:00:00+01:00`\r\n- LIMIT format: `LIMIT 20 OFFSET 0`\r\n- Boolean: `true` / `false` (lowercase)\r\n\r\n### Common COQL examples\r\n```sql\r\n-- All contacts with email\r\nSELECT Id, Full_Name, Email FROM Contacts WHERE Email != '' LIMIT 100\r\n\r\n-- Deals from last 3 months\r\nSELECT Id, Deal_Name, Amount, Stage FROM Deals WHERE Created_Time >= '2026-04-01T00:00:00+01:00'\r\n\r\n-- Accounts by city\r\nSELECT Id, Account_Name, Billing_City FROM Accounts WHERE Billing_City = 'Berlin'\r\n```\r\n\r\n## Troubleshooting\r\n\r\n### \"ZOHO_MCP_URL not set\"\r\nSet the environment variable with your MCP endpoint URL. See \"Environment Variable Setup\" above.\r\n\r\n### \"Mandatory query param module is not present\"\r\nUse the temp-file approach with `--args \"$(< /tmp/args.json)\"` instead of inline JSON.\r\n\r\n### \"Invalid oauth scope to access this URL\"\r\nThe MCP connection token may have expired. Go to [mcp.zoho.eu](https://mcp.zoho.eu), revoke and reconnect the affected app to get a fresh token.\r\n\r\n### Field API name vs UI label\r\nZoho CRM shows display labels in the UI, but the API uses `api_name` values (e.g., `Account_Name` not \"Account Name\"). Always check field names with `getFields` before writing scripts or Deluge code.\n\nFile v1.4.1:README.md\n\n# Zoho CRM MCP\n\nConnect your agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\n\nThis repository contains the public source for the ClawHub skill [`@sprintcx/zoho-crm-mcp`](https://clawhub.ai/sprintcx/skills/zoho-crm-mcp).\n\n## What This Skill Includes\n\n- Agent Skill instructions in `SKILL.md` (portable SKILL.md format)\n- ClawHub release card metadata in `skill-card.md`\n- Ready-to-use Python helpers for contacts, accounts, generic module search, and COQL\n- Security-conscious `mcporter` calls through `subprocess.run([...])` without shell expansion\n\n## Requirements\n\n| Requirement | Details |\n|---|---|\n| Zoho CRM MCP Server | A configured endpoint from [mcp.zoho.eu](https://mcp.zoho.eu) |\n| mcporter | MCP client CLI (bundled with OpenClaw; elsewhere `npm i -g mcporter`) |\n| Environment variable | `ZOHO_MCP_URL` must be set |\n\n### Environment Variable Setup\n\nThis skill requires the `ZOHO_MCP_URL` environment variable. Without it, the Python scripts will not work.\n\nAdd this to your shell profile, for example `~/.bashrc` or `~/.zshrc`:\n\n```bash\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\n```\n\nOr set it per session:\n\n```bash\nZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py\n```\n\nTo verify that it is set:\n\n```bash\necho $ZOHO_MCP_URL\n```\n\nTreat `ZOHO_MCP_URL` like a password. It contains CRM access credentials.\n\n## How to Get Your MCP URL\n\n1. Go to [mcp.zoho.eu](https://mcp.zoho.eu) and sign in with your Zoho account.\n2. Click **Add Connection** or **New Connection**.\n3. Select **Zoho CRM** from the list of available apps.\n4. Choose the data center matching your Zoho account: EU, US, IN, AU, JP, or CN.\n5. Grant the requested OAuth scopes. Start with read-only access unless write actions are explicitly needed.\n6. After authorization, copy the generated MCP endpoint URL. It looks like:\n\n   ```text\n   https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message\n   ```\n\n7. Set it as `ZOHO_MCP_URL`.\n\n### Multiple Organizations\n\nIf you manage multiple Zoho CRM orgs, each gets its own MCP endpoint. You can:\n\n- Set one default via `ZOHO_MCP_URL`\n- Pass others explicitly in scripts or `mcporter` calls\n- Use a wrapper script or `.env` file per project\n\n## Quick Start\n\n### List available tools on your MCP server\n\n```bash\nmcporter list $ZOHO_MCP_URL\n```\n\n### Search for a contact by name\n\n```bash\ncat << 'EOF' > /tmp/zoho_search.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\n```\n\n### Get a single record by ID\n\n```bash\ncat << 'EOF' > /tmp/zoho_record.json\n{\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_record.json)\"\n```\n\n### Run a COQL query\n\n```bash\ncat << 'EOF' > /tmp/zoho_coql.json\n{\n  \"body\": {\"select_query\": \"SELECT Id, Account_Name, Website FROM Accounts WHERE Website != '' ORDER BY Account_Name LIMIT 50\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_executeCOQLQuery\" --args \"$(< /tmp/zoho_coql.json)\"\n```\n\n## Python Scripts\n\nReady-to-use scripts for common CRM operations. All scripts require `ZOHO_MCP_URL` to be set.\n\nThe bundled Python scripts call `mcporter` directly through `subprocess.run([...])` and do not invoke a shell. This avoids shell expansion of the credential-bearing `ZOHO_MCP_URL`.\n\n### `list_contacts.py`\n\n```bash\n# All contacts as table\npython3 scripts/list_contacts.py\n\n# Search by last name\npython3 scripts/list_contacts.py --search \"Smith\"\n\n# Raw JSON output\npython3 scripts/list_contacts.py --json\n\n# Full record data\npython3 scripts/list_contacts.py --search \"Smith\" --json --full\n```\n\n### `list_accounts.py`\n\n```bash\n# All accounts with website\npython3 scripts/list_accounts.py\n\n# Search by company name\npython3 scripts/list_accounts.py --search \"Acme\"\n\n# All accounts, including those without website\npython3 scripts/list_accounts.py --all\n\n# JSON output\npython3 scripts/list_accounts.py --json\n\n# Custom fields and a custom WHERE filter (e.g. org-specific fields)\npython3 scripts/list_accounts.py \\\n  --where \"Google_Drive_URL != ''\" \\\n  --fields Account_Name,Website,Google_Drive_URL,Trello_URL,Trello_ID\n```\n\nBoth `list_contacts.py` and `list_accounts.py` paginate automatically and accept\n`--fields F1,F2,...` to request any Zoho field API names, including org-specific\ncustom fields.\n\n### `search_records.py`\n\n```bash\n# Search any module by name\npython3 scripts/search_records.py Contacts \"Smith\"\npython3 scripts/search_records.py Accounts \"Acme Corp\"\npython3 scripts/search_records.py Deals \"Project X\"\n\n# COQL query on any module\npython3 scripts/search_records.py Contacts --coql \"Email != ''\" --json\n```\n\n## mcporter Usage Patterns\n\n### Use temp files for shell-based JSON arguments\n\nWhen calling `mcporter` directly from a shell, escaping can break inline JSON. Write arguments to a temp file:\n\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Email:equals:test@example.com)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/args.json)\"\n```\n\n### Pagination\n\nFor large result sets, use `page` and `per_page`:\n\n```json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"page\": 2, \"per_page\": 200}\n}\n```\n\n### Field metadata\n\nGet all field names for a module. This is useful before writing scripts, Deluge code, or COQL queries:\n\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"query_params\": {\"module\": \"Contacts\", \"include\": \"allowed_permissions_to_update\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getFields\" --args \"$(< /tmp/args.json)\"\n```\n\n## Recommended CRM Actions\n\nFor a fully capable CRM agent, enable these actions on your Zoho MCP server at [mcp.zoho.eu](https://mcp.zoho.eu).\n\n### Read-only\n\nSafe starting point:\n\n- `getModules` - List all CRM modules\n- `getFields` - Get field definitions for any module\n- `getRecord` / `getRecords` - Read individual or lists of records\n- `searchRecords` - Search by criteria, for example email or name\n- `executeCOQLQuery` - SQL-like queries across modules\n- `getRecordCount` - Count records per module\n- `getRelatedRecords` - Read linked records, for example contacts of an account\n- `getPickListValues` - Get dropdown options for fields\n\n### Read-write\n\nOnly enable these when the agent should create or update CRM data:\n\n- `createRecords` - Create new records in any module\n- `updateRecord` - Update a single record by ID\n- `upsertRecords` - Insert or update records\n- `createNotes` - Add notes to records\n- `createEventsRecords` - Create calendar events\n- `createTags` / `postRemoveTags` - Manage tags\n\n### Avoid enabling by default\n\n- `deleteRecord` / `deleteRecords` - Only enable when specifically needed\n\n## COQL Reference\n\nCOQL, Zoho's SQL-like query language, differs from standard SQL in several ways:\n\n- No JOINs. Query one module at a time.\n- Use single quotes for strings: `WHERE Last_Name = 'Smith'`\n- DateTime format: `2026-01-01T00:00:00+01:00`\n- LIMIT format: `LIMIT 20 OFFSET 0`\n- Boolean values are lowercase: `true` / `false`\n\n### Common COQL examples\n\n```sql\n-- All contacts with email\nSELECT Id, Full_Name, Email FROM Contacts WHERE Email != '' LIMIT 100\n\n-- Deals from last 3 months\nSELECT Id, Deal_Name, Amount, Stage FROM Deals WHERE Created_Time >= '2026-04-01T00:00:00+01:00'\n\n-- Accounts by city\nSELECT Id, Account_Name, Billing_City FROM Accounts WHERE Billing_City = 'Berlin'\n```\n\n## Troubleshooting\n\n### `ZOHO_MCP_URL nicht gesetzt` / `ZOHO_MCP_URL not set`\n\nSet the environment variable with your MCP endpoint URL. See [Environment Variable Setup](#environment-variable-setup).\n\n### `Mandatory query param module is not present`\n\nUse the temp-file approach with `--args \"$(< /tmp/args.json)\"` instead of inline JSON.\n\n### `Invalid oauth scope to access this URL`\n\nThe MCP connection token may have expired or may not include the required scope. Go to [mcp.zoho.eu](https://mcp.zoho.eu), revoke and reconnect the affected app to get a fresh token.\n\n### Field API name vs UI label\n\nZoho CRM shows display labels in the UI, but the API uses `api_name` values, for example `Account_Name` rather than `Account Name`. Always check field names with `getFields` before writing scripts, Deluge code, or COQL queries.\n\n## Repository Files\n\n- `SKILL.md`: Agent Skill instructions.\n- `skill-card.md`: ClawHub release card metadata.\n- `scripts/list_contacts.py`: List or search Zoho CRM contacts.\n- `scripts/list_accounts.py`: List or search Zoho CRM accounts.\n- `scripts/search_records.py`: Generic Zoho CRM module search and COQL helper.\n\n## Security Notes\n\nEarlier ClawHub releases called `mcporter` through `bash -c`, which made the credential-bearing `ZOHO_MCP_URL` unsafe if a malicious value was injected into the environment.\n\nThe repository version calls `mcporter` directly through `subprocess.run([...])` without shell expansion.\n\n## Publish\n\nPublish under the SprintCX ClawHub organization:\n\n```bash\nclawhub skill publish . \\\n  --slug zoho-crm-mcp \\\n  --name \"Zoho CRM MCP\" \\\n  --owner sprintcx \\\n  --version 1.4.0 \\\n  --source-repo sprintberlin/openclaw-zoho-crm-mcp-skill \\\n  --source-ref main \\\n  --source-path . \\\n  --changelog \"Update release notes\"\n```\n\nFile v1.4.1:_meta.json\n\n{\n  \"ownerId\": \"kn76qytcmtbreh5tr5hy2gnmgs89hj1d\",\n  \"slug\": \"zoho-crm-mcp\",\n  \"version\": \"1.4.1\",\n  \"publishedAt\": 1784185258775\n}\n\nFile v1.4.1:skill-card.md\n\n## Description:\n\nConnect your agent to Zoho CRM via MCP to search contacts, list accounts, query records with COQL, and manage CRM data using mcporter with paginated, custom-field-aware helper scripts.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[sprintcx](https://clawhub.ai/user/sprintcx)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and CRM operators use this skill to connect an agent to Zoho CRM, inspect contacts and accounts, run COQL queries, and prepare controlled CRM read or write workflows through a configured MCP endpoint.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The Zoho MCP URL contains CRM access credentials and can expose customer data if logged, screenshotted, or stored carelessly.\n\nMitigation: Treat ZOHO_MCP_URL as a secret, avoid echoing it, prefer per-session storage where practical, and rotate it if exposed.\n\nRisk: Broad Zoho OAuth scopes or enabled write/delete tools can let an agent change or remove CRM records beyond the intended workflow.\n\nMitigation: Start with read-only scopes and enable create, update, or delete tools only for agents and tasks that explicitly require them.\n\nRisk: Fixed temporary-file examples can leave request arguments on disk or collide across sessions.\n\nMitigation: Prefer the bundled Python helpers or secure, unique temporary files for shell-based JSON arguments.\n\n## Reference(s):\n\n- [ClawHub release page](https://clawhub.ai/sprintcx/skills/zoho-crm-mcp)\n- [Zoho CRM MCP portal](https://mcp.zoho.eu)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown instructions with shell commands and Python helper scripts that can print tables or JSON]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires ZOHO_MCP_URL and mcporter; helper scripts may access CRM data according to the configured Zoho OAuth scopes.]\n\n## Skill Version(s):\n\n1.4.1 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.4.1:package.json\n\n{\n  \"name\": \"zoho-crm-mcp\",\n  \"version\": \"1.4.0\",\n  \"description\": \"Connect your agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Paginated, custom-field-aware helper scripts.\",\n  \"author\": \"SprintCX\",\n  \"license\": \"MIT\"\n}\n\nArchive v1.4.0: 8 files, 16661 bytes\n\nFiles: list_accounts.py (6591b), list_contacts.py (7276b), package.json (294b), README.md (9486b), search_records.py (4766b), skill-card.md (2127b), SKILL.md (9318b), _meta.json (131b)\n\nFile v1.4.0:SKILL.md\n\n---\r\nname: zoho-crm-mcp\r\nversion: 1.4.0\r\ndescription: Connect your agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Python scripts with pagination and custom-field support for common CRM operations.\r\n---\r\n\r\n# Zoho CRM MCP\r\n\r\nConnect your agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\r\n\r\n## Source Repository\r\n\r\nGitHub source: [sprintberlin/openclaw-zoho-crm-mcp-skill](https://github.com/sprintberlin/openclaw-zoho-crm-mcp-skill)\r\n\r\n## Requirements\r\n\r\n| Requirement | Details |\r\n|---|---|\r\n| Zoho CRM MCP Server | A configured endpoint from [mcp.zoho.eu](https://mcp.zoho.eu) |\r\n| mcporter | MCP client CLI (bundled with OpenClaw; elsewhere install via `npm i -g mcporter`) |\r\n| Environment variable | `ZOHO_MCP_URL` must be set (see below) |\r\n\r\n### Environment Variable Setup\r\n\r\nThis skill requires the `ZOHO_MCP_URL` environment variable. Without it, the Python scripts will not work.\r\n\r\nAdd this to your shell profile (e.g. `~/.bashrc` or `~/.zshrc`):\r\n```bash\r\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\r\n```\r\n\r\nOr set it per session:\r\n```bash\r\nZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py\r\n```\r\n\r\nTo verify it's set:\r\n```bash\r\necho $ZOHO_MCP_URL\r\n```\r\n\r\n## How to Get Your MCP URL\r\n\r\n1. Go to [mcp.zoho.eu](https://mcp.zoho.eu) and sign in with your Zoho account.\r\n2. Click **\"Add Connection\"** (or \"New Connection\").\r\n3. Select **Zoho CRM** from the list of available apps.\r\n4. Choose the **data center** matching your Zoho account (EU, US, IN, AU, JP, CN).\r\n5. Grant the requested OAuth scopes (at minimum: read access to the modules you want to query).\r\n6. After authorization, copy the generated **MCP endpoint URL**. It looks like:\r\n   ```\r\n   https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message\r\n   ```\r\n7. Set it as `ZOHO_MCP_URL` as shown above.\r\n\r\n### Multiple Organizations\r\n\r\nIf you manage multiple Zoho CRM orgs, each gets its own MCP endpoint. You can:\r\n- Set one default via `ZOHO_MCP_URL`\r\n- Pass others explicitly in scripts or mcporter calls\r\n- Use a wrapper script or `.env` file per project\r\n\r\n## Quick Start\r\n\r\n### List available tools on your MCP server\r\n```bash\r\nmcporter list $ZOHO_MCP_URL\r\n```\r\n\r\n### Search for a contact by name\r\n```bash\r\ncat << 'EOF' > /tmp/zoho_search.json\r\n{\r\n  \"path_variables\": {\"module\": \"Contacts\"},\r\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\r\n```\r\n\r\n### Get a single record by ID\r\n```bash\r\ncat << 'EOF' > /tmp/zoho_record.json\r\n{\r\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_record.json)\"\r\n```\r\n\r\n### Run a COQL query (SQL-like)\r\n```bash\r\ncat << 'EOF' > /tmp/zoho_coql.json\r\n{\r\n  \"body\": {\"select_query\": \"SELECT Id, Account_Name, Website FROM Accounts WHERE Website != '' ORDER BY Account_Name LIMIT 50\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_executeCOQLQuery\" --args \"$(< /tmp/zoho_coql.json)\"\r\n```\r\n\r\n## Python Scripts\r\n\r\nReady-to-use scripts for common CRM operations. All scripts require `ZOHO_MCP_URL` to be set.\r\n\r\nThe bundled Python scripts call `mcporter` directly through `subprocess.run([...])` and do not invoke a shell. This avoids shell expansion of the credential-bearing `ZOHO_MCP_URL`.\r\n\r\n`list_contacts.py` and `list_accounts.py` paginate automatically (they follow `more_records` until the full result set is retrieved) and normalize the different Zoho CRM MCP response shapes, so large modules are never silently truncated.\r\n\r\n### Custom fields and filters\r\n\r\nEvery Zoho org has different custom fields. Instead of hard-coding them, the list scripts accept:\r\n\r\n- `--fields F1,F2,...` — request any Zoho field **API names** (comma-separated), including org-specific custom fields (e.g. `Google_Drive_URL`, `Trello_URL`). Unknown fields appear under their API name in the table header.\r\n- `--where \"<COQL clause>\"` (`list_accounts.py` only) — override the default WHERE filter, e.g. `--where \"Google_Drive_URL != ''\"`.\r\n\r\n```bash\r\n# Contacts with custom columns\r\npython3 scripts/list_contacts.py --fields First_Name,Last_Name,Email,Designation\r\n\r\n# Accounts filtered on a custom field, showing custom columns\r\npython3 scripts/list_accounts.py \\\r\n  --where \"Google_Drive_URL != ''\" \\\r\n  --fields Account_Name,Website,Google_Drive_URL,Trello_URL,Trello_ID\r\n```\r\n\r\nUse `getFields` (see below) to discover the exact API names of your custom fields.\r\n\r\n### list_contacts.py - Search and list contacts\r\n```bash\r\n# All contacts as table\r\npython3 scripts/list_contacts.py\r\n\r\n# Search by last name\r\npython3 scripts/list_contacts.py --search \"Smith\"\r\n\r\n# Raw JSON output\r\npython3 scripts/list_contacts.py --json\r\n\r\n# Full record data\r\npython3 scripts/list_contacts.py --search \"Smith\" --json --full\r\n```\r\n\r\n### list_accounts.py - List companies/accounts\r\n```bash\r\n# All accounts with website\r\npython3 scripts/list_accounts.py\r\n\r\n# Search by company name\r\npython3 scripts/list_accounts.py --search \"Acme\"\r\n\r\n# All accounts (including those without website)\r\npython3 scripts/list_accounts.py --all\r\n\r\n# JSON output\r\npython3 scripts/list_accounts.py --json\r\n```\r\n\r\n### search_records.py - Generic module search\r\n```bash\r\n# Search any module by name\r\npython3 scripts/search_records.py Contacts \"Smith\"\r\npython3 scripts/search_records.py Accounts \"Acme Corp\"\r\npython3 scripts/search_records.py Deals \"Project X\"\r\n\r\n# COQL query on any module\r\npython3 scripts/search_records.py Contacts --coql \"Email != ''\" --json\r\n```\r\n\r\n## mcporter Usage Patterns\r\n\r\n### Use temp files for shell-based JSON arguments\r\nWhen calling `mcporter` directly from a shell, escaping can break inline JSON. Write arguments to a temp file:\r\n```bash\r\ncat << 'EOF' > /tmp/args.json\r\n{\r\n  \"path_variables\": {\"module\": \"Contacts\"},\r\n  \"query_params\": {\"criteria\": \"(Email:equals:test@example.com)\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/args.json)\"\r\n```\r\n\r\n### Pagination\r\nFor large result sets, use `page` and `per_page`:\r\n```json\r\n{\r\n  \"path_variables\": {\"module\": \"Contacts\"},\r\n  \"query_params\": {\"page\": 2, \"per_page\": 200}\r\n}\r\n```\r\n\r\n### Field metadata\r\nGet all field names for a module (useful before writing scripts or Deluge code):\r\n```bash\r\ncat << 'EOF' > /tmp/args.json\r\n{\r\n  \"query_params\": {\"module\": \"Contacts\", \"include\": \"allowed_permissions_to_update\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getFields\" --args \"$(< /tmp/args.json)\"\r\n```\r\n\r\n## Recommended CRM Actions\r\n\r\nFor a fully capable CRM agent, enable these actions on your Zoho MCP server at [mcp.zoho.eu](https://mcp.zoho.eu):\r\n\r\n### Read-only (safe starting point)\r\n- `getModules` - List all CRM modules\r\n- `getFields` - Get field definitions for any module\r\n- `getRecord` / `getRecords` - Read individual or lists of records\r\n- `searchRecords` - Search by criteria (email, name, etc.)\r\n- `executeCOQLQuery` - SQL-like queries across modules\r\n- `getRecordCount` - Count records per module\r\n- `getRelatedRecords` - Read linked records (e.g., contacts of an account)\r\n- `getPickListValues` - Get dropdown options for fields\r\n\r\n### Read-write (for agents that create/update data)\r\n- `createRecords` - Create new records in any module\r\n- `updateRecord` - Update a single record by ID\r\n- `upsertRecords` - Insert or update (upsert)\r\n- `createNotes` - Add notes to records\r\n- `createEventsRecords` - Create calendar events\r\n- `createTags` / `postRemoveTags` - Manage tags\r\n\r\n### Avoid enabling by default\r\n- `deleteRecord` / `deleteRecords` - Only enable when specifically needed\r\n\r\n## COQL Reference\r\n\r\nCOQL (Zoho's SQL-like query language) differs from standard SQL in several ways:\r\n\r\n- No JOINs - query one module at a time\r\n- Use single quotes for strings: `WHERE Last_Name = 'Smith'`\r\n- DateTime format: `2026-01-01T00:00:00+01:00`\r\n- LIMIT format: `LIMIT 20 OFFSET 0`\r\n- Boolean: `true` / `false` (lowercase)\r\n\r\n### Common COQL examples\r\n```sql\r\n-- All contacts with email\r\nSELECT Id, Full_Name, Email FROM Contacts WHERE Email != '' LIMIT 100\r\n\r\n-- Deals from last 3 months\r\nSELECT Id, Deal_Name, Amount, Stage FROM Deals WHERE Created_Time >= '2026-04-01T00:00:00+01:00'\r\n\r\n-- Accounts by city\r\nSELECT Id, Account_Name, Billing_City FROM Accounts WHERE Billing_City = 'Berlin'\r\n```\r\n\r\n## Troubleshooting\r\n\r\n### \"ZOHO_MCP_URL not set\"\r\nSet the environment variable with your MCP endpoint URL. See \"Environment Variable Setup\" above.\r\n\r\n### \"Mandatory query param module is not present\"\r\nUse the temp-file approach with `--args \"$(< /tmp/args.json)\"` instead of inline JSON.\r\n\r\n### \"Invalid oauth scope to access this URL\"\r\nThe MCP connection token may have expired. Go to [mcp.zoho.eu](https://mcp.zoho.eu), revoke and reconnect the affected app to get a fresh token.\r\n\r\n### Field API name vs UI label\r\nZoho CRM shows display labels in the UI, but the API uses `api_name` values (e.g., `Account_Name` not \"Account Name\"). Always check field names with `getFields` before writing scripts or Deluge code.\n\nFile v1.4.0:README.md\n\n# Zoho CRM MCP\n\nConnect your agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\n\nThis repository contains the public source for the ClawHub skill [`@sprintcx/zoho-crm-mcp`](https://clawhub.ai/sprintcx/skills/zoho-crm-mcp).\n\n## What This Skill Includes\n\n- Agent Skill instructions in `SKILL.md` (portable SKILL.md format)\n- ClawHub release card metadata in `skill-card.md`\n- Ready-to-use Python helpers for contacts, accounts, generic module search, and COQL\n- Security-conscious `mcporter` calls through `subprocess.run([...])` without shell expansion\n\n## Requirements\n\n| Requirement | Details |\n|---|---|\n| Zoho CRM MCP Server | A configured endpoint from [mcp.zoho.eu](https://mcp.zoho.eu) |\n| mcporter | MCP client CLI (bundled with OpenClaw; elsewhere `npm i -g mcporter`) |\n| Environment variable | `ZOHO_MCP_URL` must be set |\n\n### Environment Variable Setup\n\nThis skill requires the `ZOHO_MCP_URL` environment variable. Without it, the Python scripts will not work.\n\nAdd this to your shell profile, for example `~/.bashrc` or `~/.zshrc`:\n\n```bash\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\n```\n\nOr set it per session:\n\n```bash\nZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py\n```\n\nTo verify that it is set:\n\n```bash\necho $ZOHO_MCP_URL\n```\n\nTreat `ZOHO_MCP_URL` like a password. It contains CRM access credentials.\n\n## How to Get Your MCP URL\n\n1. Go to [mcp.zoho.eu](https://mcp.zoho.eu) and sign in with your Zoho account.\n2. Click **Add Connection** or **New Connection**.\n3. Select **Zoho CRM** from the list of available apps.\n4. Choose the data center matching your Zoho account: EU, US, IN, AU, JP, or CN.\n5. Grant the requested OAuth scopes. Start with read-only access unless write actions are explicitly needed.\n6. After authorization, copy the generated MCP endpoint URL. It looks like:\n\n   ```text\n   https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message\n   ```\n\n7. Set it as `ZOHO_MCP_URL`.\n\n### Multiple Organizations\n\nIf you manage multiple Zoho CRM orgs, each gets its own MCP endpoint. You can:\n\n- Set one default via `ZOHO_MCP_URL`\n- Pass others explicitly in scripts or `mcporter` calls\n- Use a wrapper script or `.env` file per project\n\n## Quick Start\n\n### List available tools on your MCP server\n\n```bash\nmcporter list $ZOHO_MCP_URL\n```\n\n### Search for a contact by name\n\n```bash\ncat << 'EOF' > /tmp/zoho_search.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\n```\n\n### Get a single record by ID\n\n```bash\ncat << 'EOF' > /tmp/zoho_record.json\n{\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_record.json)\"\n```\n\n### Run a COQL query\n\n```bash\ncat << 'EOF' > /tmp/zoho_coql.json\n{\n  \"body\": {\"select_query\": \"SELECT Id, Account_Name, Website FROM Accounts WHERE Website != '' ORDER BY Account_Name LIMIT 50\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_executeCOQLQuery\" --args \"$(< /tmp/zoho_coql.json)\"\n```\n\n## Python Scripts\n\nReady-to-use scripts for common CRM operations. All scripts require `ZOHO_MCP_URL` to be set.\n\nThe bundled Python scripts call `mcporter` directly through `subprocess.run([...])` and do not invoke a shell. This avoids shell expansion of the credential-bearing `ZOHO_MCP_URL`.\n\n### `list_contacts.py`\n\n```bash\n# All contacts as table\npython3 scripts/list_contacts.py\n\n# Search by last name\npython3 scripts/list_contacts.py --search \"Smith\"\n\n# Raw JSON output\npython3 scripts/list_contacts.py --json\n\n# Full record data\npython3 scripts/list_contacts.py --search \"Smith\" --json --full\n```\n\n### `list_accounts.py`\n\n```bash\n# All accounts with website\npython3 scripts/list_accounts.py\n\n# Search by company name\npython3 scripts/list_accounts.py --search \"Acme\"\n\n# All accounts, including those without website\npython3 scripts/list_accounts.py --all\n\n# JSON output\npython3 scripts/list_accounts.py --json\n\n# Custom fields and a custom WHERE filter (e.g. org-specific fields)\npython3 scripts/list_accounts.py \\\n  --where \"Google_Drive_URL != ''\" \\\n  --fields Account_Name,Website,Google_Drive_URL,Trello_URL,Trello_ID\n```\n\nBoth `list_contacts.py` and `list_accounts.py` paginate automatically and accept\n`--fields F1,F2,...` to request any Zoho field API names, including org-specific\ncustom fields.\n\n### `search_records.py`\n\n```bash\n# Search any module by name\npython3 scripts/search_records.py Contacts \"Smith\"\npython3 scripts/search_records.py Accounts \"Acme Corp\"\npython3 scripts/search_records.py Deals \"Project X\"\n\n# COQL query on any module\npython3 scripts/search_records.py Contacts --coql \"Email != ''\" --json\n```\n\n## mcporter Usage Patterns\n\n### Use temp files for shell-based JSON arguments\n\nWhen calling `mcporter` directly from a shell, escaping can break inline JSON. Write arguments to a temp file:\n\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Email:equals:test@example.com)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/args.json)\"\n```\n\n### Pagination\n\nFor large result sets, use `page` and `per_page`:\n\n```json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"page\": 2, \"per_page\": 200}\n}\n```\n\n### Field metadata\n\nGet all field names for a module. This is useful before writing scripts, Deluge code, or COQL queries:\n\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"query_params\": {\"module\": \"Contacts\", \"include\": \"allowed_permissions_to_update\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getFields\" --args \"$(< /tmp/args.json)\"\n```\n\n## Recommended CRM Actions\n\nFor a fully capable CRM agent, enable these actions on your Zoho MCP server at [mcp.zoho.eu](https://mcp.zoho.eu).\n\n### Read-only\n\nSafe starting point:\n\n- `getModules` - List all CRM modules\n- `getFields` - Get field definitions for any module\n- `getRecord` / `getRecords` - Read individual or lists of records\n- `searchRecords` - Search by criteria, for example email or name\n- `executeCOQLQuery` - SQL-like queries across modules\n- `getRecordCount` - Count records per module\n- `getRelatedRecords` - Read linked records, for example contacts of an account\n- `getPickListValues` - Get dropdown options for fields\n\n### Read-write\n\nOnly enable these when the agent should create or update CRM data:\n\n- `createRecords` - Create new records in any module\n- `updateRecord` - Update a single record by ID\n- `upsertRecords` - Insert or update records\n- `createNotes` - Add notes to records\n- `createEventsRecords` - Create calendar events\n- `createTags` / `postRemoveTags` - Manage tags\n\n### Avoid enabling by default\n\n- `deleteRecord` / `deleteRecords` - Only enable when specifically needed\n\n## COQL Reference\n\nCOQL, Zoho's SQL-like query language, differs from standard SQL in several ways:\n\n- No JOINs. Query one module at a time.\n- Use single quotes for strings: `WHERE Last_Name = 'Smith'`\n- DateTime format: `2026-01-01T00:00:00+01:00`\n- LIMIT format: `LIMIT 20 OFFSET 0`\n- Boolean values are lowercase: `true` / `false`\n\n### Common COQL examples\n\n```sql\n-- All contacts with email\nSELECT Id, Full_Name, Email FROM Contacts WHERE Email != '' LIMIT 100\n\n-- Deals from last 3 months\nSELECT Id, Deal_Name, Amount, Stage FROM Deals WHERE Created_Time >= '2026-04-01T00:00:00+01:00'\n\n-- Accounts by city\nSELECT Id, Account_Name, Billing_City FROM Accounts WHERE Billing_City = 'Berlin'\n```\n\n## Troubleshooting\n\n### `ZOHO_MCP_URL nicht gesetzt` / `ZOHO_MCP_URL not set`\n\nSet the environment variable with your MCP endpoint URL. See [Environment Variable Setup](#environment-variable-setup).\n\n### `Mandatory query param module is not present`\n\nUse the temp-file approach with `--args \"$(< /tmp/args.json)\"` instead of inline JSON.\n\n### `Invalid oauth scope to access this URL`\n\nThe MCP connection token may have expired or may not include the required scope. Go to [mcp.zoho.eu](https://mcp.zoho.eu), revoke and reconnect the affected app to get a fresh token.\n\n### Field API name vs UI label\n\nZoho CRM shows display labels in the UI, but the API uses `api_name` values, for example `Account_Name` rather than `Account Name`. Always check field names with `getFields` before writing scripts, Deluge code, or COQL queries.\n\n## Repository Files\n\n- `SKILL.md`: Agent Skill instructions.\n- `skill-card.md`: ClawHub release card metadata.\n- `scripts/list_contacts.py`: List or search Zoho CRM contacts.\n- `scripts/list_accounts.py`: List or search Zoho CRM accounts.\n- `scripts/search_records.py`: Generic Zoho CRM module search and COQL helper.\n\n## Security Notes\n\nEarlier ClawHub releases called `mcporter` through `bash -c`, which made the credential-bearing `ZOHO_MCP_URL` unsafe if a malicious value was injected into the environment.\n\nThe repository version calls `mcporter` directly through `subprocess.run([...])` without shell expansion.\n\n## Publish\n\nPublish under the SprintCX ClawHub organization:\n\n```bash\nclawhub skill publish . \\\n  --slug zoho-crm-mcp \\\n  --name \"Zoho CRM MCP\" \\\n  --owner sprintcx \\\n  --version 1.4.0 \\\n  --source-repo sprintberlin/openclaw-zoho-crm-mcp-skill \\\n  --source-ref main \\\n  --source-path . \\\n  --changelog \"Update release notes\"\n```\n\nFile v1.4.0:_meta.json\n\n{\n  \"ownerId\": \"kn76qytcmtbreh5tr5hy2gnmgs89hj1d\",\n  \"slug\": \"zoho-crm-mcp\",\n  \"version\": \"1.4.0\",\n  \"publishedAt\": 1784185160498\n}\n\nFile v1.4.0:skill-card.md\n\n## Description: <br>\nConnect your agent to Zoho CRM via MCP to search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[sprintcx](https://clawhub.ai/user/sprintcx) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and CRM operators use this skill to connect an agent to Zoho CRM through a configured MCP endpoint, retrieve contacts and accounts, run COQL queries, and work with custom CRM fields. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The Zoho MCP URL contains CRM access credentials and can expose CRM data if shared. <br>\nMitigation: Store ZOHO_MCP_URL as a secret, avoid printing it in shared logs or screenshots, and rotate the MCP token if exposed. <br>\nRisk: Overbroad Zoho CRM scopes can allow an agent to modify or delete CRM records beyond the intended workflow. <br>\nMitigation: Start with read-only Zoho scopes and enable write or delete tools only when the use case requires them. <br>\n\n\n## Reference(s): <br>\n- [ClawHub listing: Zoho CRM MCP](https://clawhub.ai/sprintcx/skills/zoho-crm-mcp) <br>\n- [Zoho MCP connection portal](https://mcp.zoho.eu) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with shell commands and Python helper code; helper scripts can print tables or JSON.] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires a configured Zoho CRM MCP endpoint, mcporter, and ZOHO_MCP_URL; contact and account helpers support pagination and custom fields.] <br>\n\n## Skill Version(s): <br>\n1.4.0 (source: server release evidence, SKILL.md frontmatter, package.json) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.4.0:package.json\n\n{\n  \"name\": \"zoho-crm-mcp\",\n  \"version\": \"1.4.0\",\n  \"description\": \"Connect your agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Paginated, custom-field-aware helper scripts.\",\n  \"author\": \"SprintCX\",\n  \"license\": \"MIT\"\n}\n\nArchive v0.1.0: 2 files, 3518 bytes\n\nFiles: SKILL.md (7870b), _meta.json (131b)\n\nFile v0.1.0:SKILL.md\n\n---\nname: zoho-crm-mcp\ndescription: Connect your OpenClaw agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Python scripts for common CRM operations.\n---\n\n# Zoho CRM MCP\n\nConnect your OpenClaw agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\n\n## Source Repository\n\nGitHub source: [sprintberlin/openclaw-zoho-crm-mcp-skill](https://github.com/sprintberlin/openclaw-zoho-crm-mcp-skill)\n\n## Requirements\n\n| Requirement | Details |\n|---|---|\n| Zoho CRM MCP Server | A configured endpoint from [mcp.zoho.eu](https://mcp.zoho.eu) |\n| mcporter | MCP client CLI (pre-installed with OpenClaw) |\n| Environment variable | `ZOHO_MCP_URL` must be set (see below) |\n\n### Environment Variable Setup\n\nThis skill requires the `ZOHO_MCP_URL` environment variable. Without it, the Python scripts will not work.\n\nAdd this to your shell profile (e.g. `~/.bashrc` or `~/.zshrc`):\n```bash\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\n```\n\nOr set it per session:\n```bash\nZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py\n```\n\nTo verify it's set:\n```bash\necho $ZOHO_MCP_URL\n```\n\n## How to Get Your MCP URL\n\n1. Go to [mcp.zoho.eu](https://mcp.zoho.eu) and sign in with your Zoho account.\n2. Click **\"Add Connection\"** (or \"New Connection\").\n3. Select **Zoho CRM** from the list of available apps.\n4. Choose the **data center** matching your Zoho account (EU, US, IN, AU, JP, CN).\n5. Grant the requested OAuth scopes (at minimum: read access to the modules you want to query).\n6. After authorization, copy the generated **MCP endpoint URL**. It looks like:\n   ```\n   https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message\n   ```\n7. Set it as `ZOHO_MCP_URL` as shown above.\n\n### Multiple Organizations\n\nIf you manage multiple Zoho CRM orgs, each gets its own MCP endpoint. You can:\n- Set one default via `ZOHO_MCP_URL`\n- Pass others explicitly in scripts or mcporter calls\n- Use a wrapper script or `.env` file per project\n\n## Quick Start\n\n### List available tools on your MCP server\n```bash\nmcporter list $ZOHO_MCP_URL\n```\n\n### Search for a contact by name\n```bash\ncat << 'EOF' > /tmp/zoho_search.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\n```\n\n### Get a single record by ID\n```bash\ncat << 'EOF' > /tmp/zoho_record.json\n{\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_record.json)\"\n```\n\n### Run a COQL query (SQL-like)\n```bash\ncat << 'EOF' > /tmp/zoho_coql.json\n{\n  \"body\": {\"select_query\": \"SELECT Id, Account_Name, Website FROM Accounts WHERE Website != '' ORDER BY Account_Name LIMIT 50\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_executeCOQLQuery\" --args \"$(< /tmp/zoho_coql.json)\"\n```\n\n## Python Scripts\n\nReady-to-use scripts for common CRM operations. All scripts require `ZOHO_MCP_URL` to be set.\n\nThe bundled Python scripts call `mcporter` directly through `subprocess.run([...])` and do not invoke a shell. This avoids shell expansion of the credential-bearing `ZOHO_MCP_URL`.\n\n### list_contacts.py - Search and list contacts\n```bash\n# All contacts as table\npython3 scripts/list_contacts.py\n\n# Search by last name\npython3 scripts/list_contacts.py --search \"Smith\"\n\n# Raw JSON output\npython3 scripts/list_contacts.py --json\n\n# Full record data\npython3 scripts/list_contacts.py --search \"Smith\" --json --full\n```\n\n### list_accounts.py - List companies/accounts\n```bash\n# All accounts with website\npython3 scripts/list_accounts.py\n\n# Search by company name\npython3 scripts/list_accounts.py --search \"Acme\"\n\n# All accounts (including those without website)\npython3 scripts/list_accounts.py --all\n\n# JSON output\npython3 scripts/list_accounts.py --json\n```\n\n### search_records.py - Generic module search\n```bash\n# Search any module by name\npython3 scripts/search_records.py Contacts \"Smith\"\npython3 scripts/search_records.py Accounts \"Acme Corp\"\npython3 scripts/search_records.py Deals \"Project X\"\n\n# COQL query on any module\npython3 scripts/search_records.py Contacts --coql \"Email != ''\" --json\n```\n\n## mcporter Usage Patterns\n\n### Use temp files for shell-based JSON arguments\nWhen calling `mcporter` directly from a shell, escaping can break inline JSON. Write arguments to a temp file:\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Email:equals:test@example.com)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/args.json)\"\n```\n\n### Pagination\nFor large result sets, use `page` and `per_page`:\n```json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"page\": 2, \"per_page\": 200}\n}\n```\n\n### Field metadata\nGet all field names for a module (useful before writing scripts or Deluge code):\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"query_params\": {\"module\": \"Contacts\", \"include\": \"allowed_permissions_to_update\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getFields\" --args \"$(< /tmp/args.json)\"\n```\n\n## Recommended CRM Actions\n\nFor a fully capable CRM agent, enable these actions on your Zoho MCP server at [mcp.zoho.eu](https://mcp.zoho.eu):\n\n### Read-only (safe starting point)\n- `getModules` - List all CRM modules\n- `getFields` - Get field definitions for any module\n- `getRecord` / `getRecords` - Read individual or lists of records\n- `searchRecords` - Search by criteria (email, name, etc.)\n- `executeCOQLQuery` - SQL-like queries across modules\n- `getRecordCount` - Count records per module\n- `getRelatedRecords` - Read linked records (e.g., contacts of an account)\n- `getPickListValues` - Get dropdown options for fields\n\n### Read-write (for agents that create/update data)\n- `createRecords` - Create new records in any module\n- `updateRecord` - Update a single record by ID\n- `upsertRecords` - Insert or update (upsert)\n- `createNotes` - Add notes to records\n- `createEventsRecords` - Create calendar events\n- `createTags` / `postRemoveTags` - Manage tags\n\n### Avoid enabling by default\n- `deleteRecord` / `deleteRecords` - Only enable when specifically needed\n\n## COQL Reference\n\nCOQL (Zoho's SQL-like query language) differs from standard SQL in several ways:\n\n- No JOINs - query one module at a time\n- Use single quotes for strings: `WHERE Last_Name = 'Smith'`\n- DateTime format: `2026-01-01T00:00:00+01:00`\n- LIMIT format: `LIMIT 20 OFFSET 0`\n- Boolean: `true` / `false` (lowercase)\n\n### Common COQL examples\n```sql\n-- All contacts with email\nSELECT Id, Full_Name, Email FROM Contacts WHERE Email != '' LIMIT 100\n\n-- Deals from last 3 months\nSELECT Id, Deal_Name, Amount, Stage FROM Deals WHERE Created_Time >= '2026-04-01T00:00:00+01:00'\n\n-- Accounts by city\nSELECT Id, Account_Name, Billing_City FROM Accounts WHERE Billing_City = 'Berlin'\n```\n\n## Troubleshooting\n\n### \"ZOHO_MCP_URL nicht gesetzt\" / \"ZOHO_MCP_URL not set\"\nSet the environment variable with your MCP endpoint URL. See \"Environment Variable Setup\" above.\n\n### \"Mandatory query param module is not present\"\nUse the temp-file approach with `--args \"$(< /tmp/args.json)\"` instead of inline JSON.\n\n### \"Invalid oauth scope to access this URL\"\nThe MCP connection token may have expired. Go to [mcp.zoho.eu](https://mcp.zoho.eu), revoke and reconnect the affected app to get a fresh token.\n\n### Field API name vs UI label\nZoho CRM shows display labels in the UI, but the API uses `api_name` values (e.g., `Account_Name` not \"Account Name\"). Always check field names with `getFields` before writing scripts or Deluge code.\n\nFile v0.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn76qytcmtbreh5tr5hy2gnmgs89hj1d\",\n  \"slug\": \"zoho-crm-mcp\",\n  \"version\": \"0.1.0\",\n  \"publishedAt\": 1783955812777\n}\n\nArchive v1.3.2: 8 files, 11797 bytes\n\nFiles: LICENSE (1069b), README.md (2039b), scripts/list_accounts.py (4019b), scripts/list_contacts.py (4590b), scripts/search_records.py (4023b), skill-card.md (2327b), SKILL.md (7870b), _meta.json (131b)\n\nFile v1.3.2:SKILL.md\n\n---\nname: zoho-crm-mcp\ndescription: Connect your OpenClaw agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Python scripts for common CRM operations.\n---\n\n# Zoho CRM MCP\n\nConnect your OpenClaw agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\n\n## Source Repository\n\nGitHub source: [sprintberlin/openclaw-zoho-crm-mcp-skill](https://github.com/sprintberlin/openclaw-zoho-crm-mcp-skill)\n\n## Requirements\n\n| Requirement | Details |\n|---|---|\n| Zoho CRM MCP Server | A configured endpoint from [mcp.zoho.eu](https://mcp.zoho.eu) |\n| mcporter | MCP client CLI (pre-installed with OpenClaw) |\n| Environment variable | `ZOHO_MCP_URL` must be set (see below) |\n\n### Environment Variable Setup\n\nThis skill requires the `ZOHO_MCP_URL` environment variable. Without it, the Python scripts will not work.\n\nAdd this to your shell profile (e.g. `~/.bashrc` or `~/.zshrc`):\n```bash\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\n```\n\nOr set it per session:\n```bash\nZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py\n```\n\nTo verify it's set:\n```bash\necho $ZOHO_MCP_URL\n```\n\n## How to Get Your MCP URL\n\n1. Go to [mcp.zoho.eu](https://mcp.zoho.eu) and sign in with your Zoho account.\n2. Click **\"Add Connection\"** (or \"New Connection\").\n3. Select **Zoho CRM** from the list of available apps.\n4. Choose the **data center** matching your Zoho account (EU, US, IN, AU, JP, CN).\n5. Grant the requested OAuth scopes (at minimum: read access to the modules you want to query).\n6. After authorization, copy the generated **MCP endpoint URL**. It looks like:\n   ```\n   https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message\n   ```\n7. Set it as `ZOHO_MCP_URL` as shown above.\n\n### Multiple Organizations\n\nIf you manage multiple Zoho CRM orgs, each gets its own MCP endpoint. You can:\n- Set one default via `ZOHO_MCP_URL`\n- Pass others explicitly in scripts or mcporter calls\n- Use a wrapper script or `.env` file per project\n\n## Quick Start\n\n### List available tools on your MCP server\n```bash\nmcporter list $ZOHO_MCP_URL\n```\n\n### Search for a contact by name\n```bash\ncat << 'EOF' > /tmp/zoho_search.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\n```\n\n### Get a single record by ID\n```bash\ncat << 'EOF' > /tmp/zoho_record.json\n{\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_record.json)\"\n```\n\n### Run a COQL query (SQL-like)\n```bash\ncat << 'EOF' > /tmp/zoho_coql.json\n{\n  \"body\": {\"select_query\": \"SELECT Id, Account_Name, Website FROM Accounts WHERE Website != '' ORDER BY Account_Name LIMIT 50\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_executeCOQLQuery\" --args \"$(< /tmp/zoho_coql.json)\"\n```\n\n## Python Scripts\n\nReady-to-use scripts for common CRM operations. All scripts require `ZOHO_MCP_URL` to be set.\n\nThe bundled Python scripts call `mcporter` directly through `subprocess.run([...])` and do not invoke a shell. This avoids shell expansion of the credential-bearing `ZOHO_MCP_URL`.\n\n### list_contacts.py - Search and list contacts\n```bash\n# All contacts as table\npython3 scripts/list_contacts.py\n\n# Search by last name\npython3 scripts/list_contacts.py --search \"Smith\"\n\n# Raw JSON output\npython3 scripts/list_contacts.py --json\n\n# Full record data\npython3 scripts/list_contacts.py --search \"Smith\" --json --full\n```\n\n### list_accounts.py - List companies/accounts\n```bash\n# All accounts with website\npython3 scripts/list_accounts.py\n\n# Search by company name\npython3 scripts/list_accounts.py --search \"Acme\"\n\n# All accounts (including those without website)\npython3 scripts/list_accounts.py --all\n\n# JSON output\npython3 scripts/list_accounts.py --json\n```\n\n### search_records.py - Generic module search\n```bash\n# Search any module by name\npython3 scripts/search_records.py Contacts \"Smith\"\npython3 scripts/search_records.py Accounts \"Acme Corp\"\npython3 scripts/search_records.py Deals \"Project X\"\n\n# COQL query on any module\npython3 scripts/search_records.py Contacts --coql \"Email != ''\" --json\n```\n\n## mcporter Usage Patterns\n\n### Use temp files for shell-based JSON arguments\nWhen calling `mcporter` directly from a shell, escaping can break inline JSON. Write arguments to a temp file:\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Email:equals:test@example.com)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/args.json)\"\n```\n\n### Pagination\nFor large result sets, use `page` and `per_page`:\n```json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"page\": 2, \"per_page\": 200}\n}\n```\n\n### Field metadata\nGet all field names for a module (useful before writing scripts or Deluge code):\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"query_params\": {\"module\": \"Contacts\", \"include\": \"allowed_permissions_to_update\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getFields\" --args \"$(< /tmp/args.json)\"\n```\n\n## Recommended CRM Actions\n\nFor a fully capable CRM agent, enable these actions on your Zoho MCP server at [mcp.zoho.eu](https://mcp.zoho.eu):\n\n### Read-only (safe starting point)\n- `getModules` - List all CRM modules\n- `getFields` - Get field definitions for any module\n- `getRecord` / `getRecords` - Read individual or lists of records\n- `searchRecords` - Search by criteria (email, name, etc.)\n- `executeCOQLQuery` - SQL-like queries across modules\n- `getRecordCount` - Count records per module\n- `getRelatedRecords` - Read linked records (e.g., contacts of an account)\n- `getPickListValues` - Get dropdown options for fields\n\n### Read-write (for agents that create/update data)\n- `createRecords` - Create new records in any module\n- `updateRecord` - Update a single record by ID\n- `upsertRecords` - Insert or update (upsert)\n- `createNotes` - Add notes to records\n- `createEventsRecords` - Create calendar events\n- `createTags` / `postRemoveTags` - Manage tags\n\n### Avoid enabling by default\n- `deleteRecord` / `deleteRecords` - Only enable when specifically needed\n\n## COQL Reference\n\nCOQL (Zoho's SQL-like query language) differs from standard SQL in several ways:\n\n- No JOINs - query one module at a time\n- Use single quotes for strings: `WHERE Last_Name = 'Smith'`\n- DateTime format: `2026-01-01T00:00:00+01:00`\n- LIMIT format: `LIMIT 20 OFFSET 0`\n- Boolean: `true` / `false` (lowercase)\n\n### Common COQL examples\n```sql\n-- All contacts with email\nSELECT Id, Full_Name, Email FROM Contacts WHERE Email != '' LIMIT 100\n\n-- Deals from last 3 months\nSELECT Id, Deal_Name, Amount, Stage FROM Deals WHERE Created_Time >= '2026-04-01T00:00:00+01:00'\n\n-- Accounts by city\nSELECT Id, Account_Name, Billing_City FROM Accounts WHERE Billing_City = 'Berlin'\n```\n\n## Troubleshooting\n\n### \"ZOHO_MCP_URL nicht gesetzt\" / \"ZOHO_MCP_URL not set\"\nSet the environment variable with your MCP endpoint URL. See \"Environment Variable Setup\" above.\n\n### \"Mandatory query param module is not present\"\nUse the temp-file approach with `--args \"$(< /tmp/args.json)\"` instead of inline JSON.\n\n### \"Invalid oauth scope to access this URL\"\nThe MCP connection token may have expired. Go to [mcp.zoho.eu](https://mcp.zoho.eu), revoke and reconnect the affected app to get a fresh token.\n\n### Field API name vs UI label\nZoho CRM shows display labels in the UI, but the API uses `api_name` values (e.g., `Account_Name` not \"Account Name\"). Always check field names with `getFields` before writing scripts or Deluge code.\n\nFile v1.3.2:README.md\n\n# OpenClaw Zoho CRM MCP Skill\n\nPublic source repository for the ClawHub skill `@sprintcx/zoho-crm-mcp`.\n\nThe skill connects an OpenClaw agent to Zoho CRM through Zoho's MCP endpoint and includes helper scripts for contacts, accounts, generic module searches, and COQL queries through `mcporter`.\n\nClawHub page: <https://clawhub.ai/sprintcx/skills/zoho-crm-mcp>\n\n## Files\n\n- `SKILL.md`: ClawHub/OpenClaw skill instructions.\n- `skill-card.md`: ClawHub release card metadata.\n- `scripts/list_contacts.py`: List or search Zoho CRM contacts.\n- `scripts/list_accounts.py`: List or search Zoho CRM accounts.\n- `scripts/search_records.py`: Generic Zoho CRM module search and COQL helper.\n\n## Requirements\n\n- OpenClaw with `mcporter` available.\n- A Zoho CRM MCP endpoint from <https://mcp.zoho.eu>.\n- `ZOHO_MCP_URL` set in the environment.\n\n```bash\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\n```\n\nTreat `ZOHO_MCP_URL` like a password. It contains CRM access credentials.\n\n## Usage\n\n```bash\npython3 scripts/list_contacts.py\npython3 scripts/list_contacts.py --search \"Smith\" --json\n\npython3 scripts/list_accounts.py\npython3 scripts/list_accounts.py --search \"Acme\"\n\npython3 scripts/search_records.py Contacts --search \"Smith\"\npython3 scripts/search_records.py Accounts --coql \"Website != ''\" --json\n```\n\n## Security Notes\n\nEarlier ClawHub releases called `mcporter` through `bash -c`, which made the credential-bearing `ZOHO_MCP_URL` unsafe if a malicious value was ever injected into the environment.\n\nThe repository version calls `mcporter` directly through `subprocess.run([...])` without shell expansion.\n\n## Publish\n\nPublish under the SprintCX ClawHub organization and attach GitHub source metadata:\n\n```bash\nclawhub skill publish . \\\n  --slug zoho-crm-mcp \\\n  --name \"Zoho CRM MCP\" \\\n  --owner sprintcx \\\n  --version 1.3.2 \\\n  --source-repo sprintberlin/openclaw-zoho-crm-mcp-skill \\\n  --source-ref main \\\n  --source-path . \\\n  --changelog \"Expose GitHub source link in the skill documentation\"\n```\n\nFile v1.3.2:_meta.json\n\n{\n  \"ownerId\": \"kn76qytcmtbreh5tr5hy2gnmgs89hj1d\",\n  \"slug\": \"zoho-crm-mcp\",\n  \"version\": \"1.3.2\",\n  \"publishedAt\": 1783951572866\n}\n\nFile v1.3.2:skill-card.md\n\n## Description: <br>\nConnect your OpenClaw agent to Zoho CRM via MCP to search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[sprintcx](https://clawhub.ai/user/sprintcx) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and CRM operations teams use this skill to let an OpenClaw agent access Zoho CRM through an MCP endpoint, run common contact and account lookups, and issue COQL-backed record searches. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The Zoho MCP endpoint URL can grant access to CRM data and should be treated as sensitive. <br>\nMitigation: Store ZOHO_MCP_URL only in trusted environments, avoid printing or sharing it, and rotate the Zoho MCP connection if exposure is suspected. <br>\nRisk: Script output can include CRM contact, account, and record data. <br>\nMitigation: Avoid placing output in public logs, screenshots, or shared transcripts unless the CRM records are approved for that audience. <br>\nRisk: Broad Zoho scopes or delete actions can allow more CRM access than the agent needs. <br>\nMitigation: Grant the minimum Zoho scopes needed for the workflow and avoid enabling delete actions unless they are specifically required. <br>\n\n\n## Reference(s): <br>\n- [Zoho CRM MCP on ClawHub](https://clawhub.ai/sprintcx/skills/zoho-crm-mcp) <br>\n- [Zoho MCP](https://mcp.zoho.eu) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, json, guidance] <br>\n**Output Format:** [Markdown instructions with shell commands, Python helper scripts, table output, and optional JSON CRM records] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires a configured ZOHO_MCP_URL endpoint and mcporter; helper scripts print CRM records to stdout and can return raw JSON.] <br>\n\n## Skill Version(s): <br>\n1.3.2 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.3.2:LICENSE\n\nMIT License\n\nCopyright (c) 2026 sprintberlin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v1.3.1: 8 files, 11636 bytes\n\nFiles: LICENSE (1069b), README.md (1955b), scripts/list_accounts.py (4019b), scripts/list_contacts.py (4590b), scripts/search_records.py (4023b), skill-card.md (2129b), SKILL.md (7728b), _meta.json (131b)\n\nFile v1.3.1:SKILL.md\n\n---\nname: zoho-crm-mcp\ndescription: Connect your OpenClaw agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Python scripts for common CRM operations.\n---\n\n# Zoho CRM MCP\n\nConnect your OpenClaw agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\n\n## Requirements\n\n| Requirement | Details |\n|---|---|\n| Zoho CRM MCP Server | A configured endpoint from [mcp.zoho.eu](https://mcp.zoho.eu) |\n| mcporter | MCP client CLI (pre-installed with OpenClaw) |\n| Environment variable | `ZOHO_MCP_URL` must be set (see below) |\n\n### Environment Variable Setup\n\nThis skill requires the `ZOHO_MCP_URL` environment variable. Without it, the Python scripts will not work.\n\nAdd this to your shell profile (e.g. `~/.bashrc` or `~/.zshrc`):\n```bash\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\n```\n\nOr set it per session:\n```bash\nZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py\n```\n\nTo verify it's set:\n```bash\necho $ZOHO_MCP_URL\n```\n\n## How to Get Your MCP URL\n\n1. Go to [mcp.zoho.eu](https://mcp.zoho.eu) and sign in with your Zoho account.\n2. Click **\"Add Connection\"** (or \"New Connection\").\n3. Select **Zoho CRM** from the list of available apps.\n4. Choose the **data center** matching your Zoho account (EU, US, IN, AU, JP, CN).\n5. Grant the requested OAuth scopes (at minimum: read access to the modules you want to query).\n6. After authorization, copy the generated **MCP endpoint URL**. It looks like:\n   ```\n   https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message\n   ```\n7. Set it as `ZOHO_MCP_URL` as shown above.\n\n### Multiple Organizations\n\nIf you manage multiple Zoho CRM orgs, each gets its own MCP endpoint. You can:\n- Set one default via `ZOHO_MCP_URL`\n- Pass others explicitly in scripts or mcporter calls\n- Use a wrapper script or `.env` file per project\n\n## Quick Start\n\n### List available tools on your MCP server\n```bash\nmcporter list $ZOHO_MCP_URL\n```\n\n### Search for a contact by name\n```bash\ncat << 'EOF' > /tmp/zoho_search.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\n```\n\n### Get a single record by ID\n```bash\ncat << 'EOF' > /tmp/zoho_record.json\n{\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_record.json)\"\n```\n\n### Run a COQL query (SQL-like)\n```bash\ncat << 'EOF' > /tmp/zoho_coql.json\n{\n  \"body\": {\"select_query\": \"SELECT Id, Account_Name, Website FROM Accounts WHERE Website != '' ORDER BY Account_Name LIMIT 50\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_executeCOQLQuery\" --args \"$(< /tmp/zoho_coql.json)\"\n```\n\n## Python Scripts\n\nReady-to-use scripts for common CRM operations. All scripts require `ZOHO_MCP_URL` to be set.\n\nThe bundled Python scripts call `mcporter` directly through `subprocess.run([...])` and do not invoke a shell. This avoids shell expansion of the credential-bearing `ZOHO_MCP_URL`.\n\n### list_contacts.py - Search and list contacts\n```bash\n# All contacts as table\npython3 scripts/list_contacts.py\n\n# Search by last name\npython3 scripts/list_contacts.py --search \"Smith\"\n\n# Raw JSON output\npython3 scripts/list_contacts.py --json\n\n# Full record data\npython3 scripts/list_contacts.py --search \"Smith\" --json --full\n```\n\n### list_accounts.py - List companies/accounts\n```bash\n# All accounts with website\npython3 scripts/list_accounts.py\n\n# Search by company name\npython3 scripts/list_accounts.py --search \"Acme\"\n\n# All accounts (including those without website)\npython3 scripts/list_accounts.py --all\n\n# JSON output\npython3 scripts/list_accounts.py --json\n```\n\n### search_records.py - Generic module search\n```bash\n# Search any module by name\npython3 scripts/search_records.py Contacts \"Smith\"\npython3 scripts/search_records.py Accounts \"Acme Corp\"\npython3 scripts/search_records.py Deals \"Project X\"\n\n# COQL query on any module\npython3 scripts/search_records.py Contacts --coql \"Email != ''\" --json\n```\n\n## mcporter Usage Patterns\n\n### Use temp files for shell-based JSON arguments\nWhen calling `mcporter` directly from a shell, escaping can break inline JSON. Write arguments to a temp file:\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Email:equals:test@example.com)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/args.json)\"\n```\n\n### Pagination\nFor large result sets, use `page` and `per_page`:\n```json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"page\": 2, \"per_page\": 200}\n}\n```\n\n### Field metadata\nGet all field names for a module (useful before writing scripts or Deluge code):\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"query_params\": {\"module\": \"Contacts\", \"include\": \"allowed_permissions_to_update\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getFields\" --args \"$(< /tmp/args.json)\"\n```\n\n## Recommended CRM Actions\n\nFor a fully capable CRM agent, enable these actions on your Zoho MCP server at [mcp.zoho.eu](https://mcp.zoho.eu):\n\n### Read-only (safe starting point)\n- `getModules` - List all CRM modules\n- `getFields` - Get field definitions for any module\n- `getRecord` / `getRecords` - Read individual or lists of records\n- `searchRecords` - Search by criteria (email, name, etc.)\n- `executeCOQLQuery` - SQL-like queries across modules\n- `getRecordCount` - Count records per module\n- `getRelatedRecords` - Read linked records (e.g., contacts of an account)\n- `getPickListValues` - Get dropdown options for fields\n\n### Read-write (for agents that create/update data)\n- `createRecords` - Create new records in any module\n- `updateRecord` - Update a single record by ID\n- `upsertRecords` - Insert or update (upsert)\n- `createNotes` - Add notes to records\n- `createEventsRecords` - Create calendar events\n- `createTags` / `postRemoveTags` - Manage tags\n\n### Avoid enabling by default\n- `deleteRecord` / `deleteRecords` - Only enable when specifically needed\n\n## COQL Reference\n\nCOQL (Zoho's SQL-like query language) differs from standard SQL in several ways:\n\n- No JOINs - query one module at a time\n- Use single quotes for strings: `WHERE Last_Name = 'Smith'`\n- DateTime format: `2026-01-01T00:00:00+01:00`\n- LIMIT format: `LIMIT 20 OFFSET 0`\n- Boolean: `true` / `false` (lowercase)\n\n### Common COQL examples\n```sql\n-- All contacts with email\nSELECT Id, Full_Name, Email FROM Contacts WHERE Email != '' LIMIT 100\n\n-- Deals from last 3 months\nSELECT Id, Deal_Name, Amount, Stage FROM Deals WHERE Created_Time >= '2026-04-01T00:00:00+01:00'\n\n-- Accounts by city\nSELECT Id, Account_Name, Billing_City FROM Accounts WHERE Billing_City = 'Berlin'\n```\n\n## Troubleshooting\n\n### \"ZOHO_MCP_URL nicht gesetzt\" / \"ZOHO_MCP_URL not set\"\nSet the environment variable with your MCP endpoint URL. See \"Environment Variable Setup\" above.\n\n### \"Mandatory query param module is not present\"\nUse the temp-file approach with `--args \"$(< /tmp/args.json)\"` instead of inline JSON.\n\n### \"Invalid oauth scope to access this URL\"\nThe MCP connection token may have expired. Go to [mcp.zoho.eu](https://mcp.zoho.eu), revoke and reconnect the affected app to get a fresh token.\n\n### Field API name vs UI label\nZoho CRM shows display labels in the UI, but the API uses `api_name` values (e.g., `Account_Name` not \"Account Name\"). Always check field names with `getFields` before writing scripts or Deluge code.\n\nFile v1.3.1:README.md\n\n# OpenClaw Zoho CRM MCP Skill\n\nPublic source repository for the ClawHub skill `@sprintcx/zoho-crm-mcp`.\n\nThe skill connects an OpenClaw agent to Zoho CRM through Zoho's MCP endpoint and includes helper scripts for contacts, accounts, generic module searches, and COQL queries through `mcporter`.\n\n## Files\n\n- `SKILL.md`: ClawHub/OpenClaw skill instructions.\n- `skill-card.md`: ClawHub release card metadata.\n- `scripts/list_contacts.py`: List or search Zoho CRM contacts.\n- `scripts/list_accounts.py`: List or search Zoho CRM accounts.\n- `scripts/search_records.py`: Generic Zoho CRM module search and COQL helper.\n\n## Requirements\n\n- OpenClaw with `mcporter` available.\n- A Zoho CRM MCP endpoint from <https://mcp.zoho.eu>.\n- `ZOHO_MCP_URL` set in the environment.\n\n```bash\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\n```\n\nTreat `ZOHO_MCP_URL` like a password. It contains CRM access credentials.\n\n## Usage\n\n```bash\npython3 scripts/list_contacts.py\npython3 scripts/list_contacts.py --search \"Smith\" --json\n\npython3 scripts/list_accounts.py\npython3 scripts/list_accounts.py --search \"Acme\"\n\npython3 scripts/search_records.py Contacts --search \"Smith\"\npython3 scripts/search_records.py Accounts --coql \"Website != ''\" --json\n```\n\n## Security Notes\n\nEarlier ClawHub releases called `mcporter` through `bash -c`, which made the credential-bearing `ZOHO_MCP_URL` unsafe if a malicious value was ever injected into the environment.\n\nThe repository version calls `mcporter` directly through `subprocess.run([...])` without shell expansion.\n\n## Publish\n\nPublish under the SprintCX ClawHub organization and attach GitHub source metadata:\n\n```bash\nclawhub skill publish . \\\n  --slug zoho-crm-mcp \\\n  --owner sprintcx \\\n  --version 1.3.1 \\\n  --source-repo sprintberlin/openclaw-zoho-crm-mcp-skill \\\n  --source-ref main \\\n  --source-path . \\\n  --changelog \"Move source to GitHub and remove shell-based mcporter calls\"\n```\n\nFile v1.3.1:_meta.json\n\n{\n  \"ownerId\": \"kn76qytcmtbreh5tr5hy2gnmgs89hj1d\",\n  \"slug\": \"zoho-crm-mcp\",\n  \"version\": \"1.3.1\",\n  \"publishedAt\": 1783951344694\n}\n\nFile v1.3.1:skill-card.md\n\n## Description: <br>\nConnect your OpenClaw agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Python scripts for common CRM operations. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[sprintcx](https://clawhub.ai/user/sprintcx) <br>\n\n### License/Terms of Use: <br>\nMIT <br>\n\n\n## Use Case: <br>\nDevelopers and CRM operators use this skill to connect an OpenClaw agent to Zoho CRM through MCP, inspect contacts and accounts, run COQL queries, and prepare common mcporter calls. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The MCP endpoint can expose Zoho CRM data to the agent. <br>\nMitigation: Install only when that access is intended, start with read-only Zoho scopes, and grant only the modules the agent needs. <br>\nRisk: ZOHO_MCP_URL contains credential-bearing access information. <br>\nMitigation: Treat it like a password: do not echo it, paste it into chats, commit it, or store it in unprotected files. <br>\nRisk: Delete or broad write permissions could let an agent make unwanted CRM changes. <br>\nMitigation: Avoid delete permissions unless specifically needed and enable write actions only after reviewing the operational workflow. <br>\n\n\n## Reference(s): <br>\n- [Zoho MCP portal](https://mcp.zoho.eu) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance] <br>\n**Output Format:** [Markdown with inline shell commands, JSON examples, and Python script guidance] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires a configured ZOHO_MCP_URL environment variable and the mcporter CLI.] <br>\n\n## Skill Version(s): <br>\n1.3.1 (source: server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.3.1:LICENSE\n\nMIT License\n\nCopyright (c) 2026 sprintberlin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\nArchive v1.3.0: 6 files, 10060 bytes\n\nFiles: list_accounts.py (4180b), list_contacts.py (4787b), search_records.py (4050b), skill-card.md (2355b), SKILL.md (7499b), _meta.json (131b)\n\nFile v1.3.0:SKILL.md\n\n---\nname: zoho-crm-mcp\ndescription: Connect your OpenClaw agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Python scripts for common CRM operations.\n---\n\n# Zoho CRM MCP\n\nConnect your OpenClaw agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\n\n## Requirements\n\n| Requirement | Details |\n|---|---|\n| Zoho CRM MCP Server | A configured endpoint from [mcp.zoho.eu](https://mcp.zoho.eu) |\n| mcporter | MCP client CLI (pre-installed with OpenClaw) |\n| Environment variable | `ZOHO_MCP_URL` must be set (see below) |\n\n### Environment Variable Setup\n\nThis skill requires the `ZOHO_MCP_URL` environment variable. Without it, the Python scripts will not work.\n\nAdd this to your shell profile (e.g. `~/.bashrc` or `~/.zshrc`):\n```bash\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\n```\n\nOr set it per session:\n```bash\nZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py\n```\n\nTo verify it's set:\n```bash\necho $ZOHO_MCP_URL\n```\n\n## How to Get Your MCP URL\n\n1. Go to [mcp.zoho.eu](https://mcp.zoho.eu) and sign in with your Zoho account.\n2. Click **\"Add Connection\"** (or \"New Connection\").\n3. Select **Zoho CRM** from the list of available apps.\n4. Choose the **data center** matching your Zoho account (EU, US, IN, AU, JP, CN).\n5. Grant the requested OAuth scopes (at minimum: read access to the modules you want to query).\n6. After authorization, copy the generated **MCP endpoint URL**. It looks like:\n   ```\n   https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message\n   ```\n7. Set it as `ZOHO_MCP_URL` as shown above.\n\n### Multiple Organizations\n\nIf you manage multiple Zoho CRM orgs, each gets its own MCP endpoint. You can:\n- Set one default via `ZOHO_MCP_URL`\n- Pass others explicitly in scripts or mcporter calls\n- Use a wrapper script or `.env` file per project\n\n## Quick Start\n\n### List available tools on your MCP server\n```bash\nmcporter list $ZOHO_MCP_URL\n```\n\n### Search for a contact by name\n```bash\ncat << 'EOF' > /tmp/zoho_search.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\n```\n\n### Get a single record by ID\n```bash\ncat << 'EOF' > /tmp/zoho_record.json\n{\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_record.json)\"\n```\n\n### Run a COQL query (SQL-like)\n```bash\ncat << 'EOF' > /tmp/zoho_coql.json\n{\n  \"body\": {\"select_query\": \"SELECT Id, Account_Name, Website FROM Accounts WHERE Website != '' ORDER BY Account_Name LIMIT 50\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_executeCOQLQuery\" --args \"$(< /tmp/zoho_coql.json)\"\n```\n\n## Python Scripts\n\nReady-to-use scripts for common CRM operations. All scripts require `ZOHO_MCP_URL` to be set.\n\n### list_contacts.py - Search and list contacts\n```bash\n# All contacts as table\npython3 scripts/list_contacts.py\n\n# Search by last name\npython3 scripts/list_contacts.py --search \"Smith\"\n\n# Raw JSON output\npython3 scripts/list_contacts.py --json\n\n# Full record data\npython3 scripts/list_contacts.py --search \"Smith\" --json --full\n```\n\n### list_accounts.py - List companies/accounts\n```bash\n# All accounts with website\npython3 scripts/list_accounts.py\n\n# Search by company name\npython3 scripts/list_accounts.py --search \"Acme\"\n\n# All accounts (including those without website)\npython3 scripts/list_accounts.py --all\n\n# JSON output\npython3 scripts/list_accounts.py --json\n```\n\n### search_records.py - Generic module search\n```bash\n# Search any module by name\npython3 scripts/search_records.py Contacts \"Smith\"\npython3 scripts/search_records.py Accounts \"Acme Corp\"\npython3 scripts/search_records.py Deals \"Project X\"\n\n# COQL query on any module\npython3 scripts/search_records.py Contacts --coql \"Email != ''\" --json\n```\n\n## mcporter Usage Patterns\n\n### Always use temp files for JSON arguments\nShell escaping breaks with inline JSON. Always write to a temp file:\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Email:equals:test@example.com)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/args.json)\"\n```\n\n### Pagination\nFor large result sets, use `page` and `per_page`:\n```json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"page\": 2, \"per_page\": 200}\n}\n```\n\n### Field metadata\nGet all field names for a module (useful before writing scripts or Deluge code):\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"query_params\": {\"module\": \"Contacts\", \"include\": \"allowed_permissions_to_update\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getFields\" --args \"$(< /tmp/args.json)\"\n```\n\n## Recommended CRM Actions\n\nFor a fully capable CRM agent, enable these actions on your Zoho MCP server at [mcp.zoho.eu](https://mcp.zoho.eu):\n\n### Read-only (safe starting point)\n- `getModules` - List all CRM modules\n- `getFields` - Get field definitions for any module\n- `getRecord` / `getRecords` - Read individual or lists of records\n- `searchRecords` - Search by criteria (email, name, etc.)\n- `executeCOQLQuery` - SQL-like queries across modules\n- `getRecordCount` - Count records per module\n- `getRelatedRecords` - Read linked records (e.g., contacts of an account)\n- `getPickListValues` - Get dropdown options for fields\n\n### Read-write (for agents that create/update data)\n- `createRecords` - Create new records in any module\n- `updateRecord` - Update a single record by ID\n- `upsertRecords` - Insert or update (upsert)\n- `createNotes` - Add notes to records\n- `createEventsRecords` - Create calendar events\n- `createTags` / `postRemoveTags` - Manage tags\n\n### Avoid enabling by default\n- `deleteRecord` / `deleteRecords` - Only enable when specifically needed\n\n## COQL Reference\n\nCOQL (Zoho's SQL-like query language) differs from standard SQL in several ways:\n\n- No JOINs - query one module at a time\n- Use single quotes for strings: `WHERE Last_Name = 'Smith'`\n- DateTime format: `2026-01-01T00:00:00+01:00`\n- LIMIT format: `LIMIT 20 OFFSET 0`\n- Boolean: `true` / `false` (lowercase)\n\n### Common COQL examples\n```sql\n-- All contacts with email\nSELECT Id, Full_Name, Email FROM Contacts WHERE Email != '' LIMIT 100\n\n-- Deals from last 3 months\nSELECT Id, Deal_Name, Amount, Stage FROM Deals WHERE Created_Time >= '2026-04-01T00:00:00+01:00'\n\n-- Accounts by city\nSELECT Id, Account_Name, Billing_City FROM Accounts WHERE Billing_City = 'Berlin'\n```\n\n## Troubleshooting\n\n### \"ZOHO_MCP_URL nicht gesetzt\" / \"ZOHO_MCP_URL not set\"\nSet the environment variable with your MCP endpoint URL. See \"Environment Variable Setup\" above.\n\n### \"Mandatory query param module is not present\"\nUse the temp-file approach with `--args \"$(< /tmp/args.json)\"` instead of inline JSON.\n\n### \"Invalid oauth scope to access this URL\"\nThe MCP connection token may have expired. Go to [mcp.zoho.eu](https://mcp.zoho.eu), revoke and reconnect the affected app to get a fresh token.\n\n### Field API name vs UI label\nZoho CRM shows display labels in the UI, but the API uses `api_name` values (e.g., `Account_Name` not \"Account Name\"). Always check field names with `getFields` before writing scripts or Deluge code.\n\nFile v1.3.0:_meta.json\n\n{\n  \"ownerId\": \"kn76qytcmtbreh5tr5hy2gnmgs89hj1d\",\n  \"slug\": \"zoho-crm-mcp\",\n  \"version\": \"1.3.0\",\n  \"publishedAt\": 1782656800034\n}\n\nFile v1.3.0:skill-card.md\n\n## Description: <br>\nConnects an OpenClaw agent to Zoho CRM through MCP so it can search contacts, list accounts, query records with COQL, and use mcporter-based helper scripts for common CRM operations. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[sprintcx](https://clawhub.ai/user/sprintcx) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and CRM operators use this skill to connect an OpenClaw agent to Zoho CRM via MCP, configure the required MCP endpoint, search CRM modules, list contacts and accounts, and run COQL queries through mcporter. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The ZOHO_MCP_URL endpoint is credential-bearing and could expose CRM access if echoed, logged, or shared. <br>\nMitigation: Treat the MCP URL like a password, avoid printing the full value, and start with read-only Zoho scopes. <br>\nRisk: The bundled Python scripts invoke mcporter through bash -c with ZOHO_MCP_URL in the shell command, creating command-injection exposure. <br>\nMitigation: Review before installing and avoid running the helper scripts until they call mcporter without bash -c and validate ZOHO_MCP_URL. <br>\nRisk: Read-write Zoho CRM actions can create or update business records if enabled on the MCP server. <br>\nMitigation: Enable only the CRM actions needed for the use case and avoid delete actions unless explicitly required. <br>\n\n\n## Reference(s): <br>\n- [Zoho CRM MCP ClawHub page](https://clawhub.ai/sprintcx/skills/zoho-crm-mcp) <br>\n- [Zoho MCP portal](https://mcp.zoho.eu) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [guidance, shell commands, configuration, code] <br>\n**Output Format:** [Markdown guidance with bash, JSON, SQL, and Python examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires a ZOHO_MCP_URL endpoint; bundled helper scripts can print table or JSON output from Zoho CRM MCP calls.] <br>\n\n## Skill Version(s): <br>\n1.3.0 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.0.0: 6 files, 9687 bytes\n\nFiles: scripts/list_accounts.py (4110b), scripts/list_contacts.py (4745b), scripts/search_records.py (4046b), skill-card.md (2207b), SKILL.md (6150b), _meta.json (131b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: zoho-crm-mcp\ndescription: Connect your OpenClaw agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Python scripts for common CRM operations.\n---\n\n# Zoho CRM MCP\n\nConnect your OpenClaw agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\n\n## Prerequisites\n\n1. **Zoho CRM MCP Server** - You need a configured Zoho CRM MCP endpoint. Set one up at [mcp.zoho.eu](https://mcp.zoho.eu).\n2. **mcporter** - The MCP client CLI for OpenClaw (pre-installed with OpenClaw).\n3. **Environment variable** - Set your MCP endpoint URL:\n   ```bash\n   export ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\n   ```\n\n## Quick Start\n\n### List available tools on your MCP server\n```bash\nmcporter list $ZOHO_MCP_URL\n```\n\n### Search for a contact by name\n```bash\ncat << 'EOF' > /tmp/zoho_search.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\n```\n\n### Get a single record by ID\n```bash\ncat << 'EOF' > /tmp/zoho_record.json\n{\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_record.json)\"\n```\n\n### Run a COQL query (SQL-like)\n```bash\ncat << 'EOF' > /tmp/zoho_coql.json\n{\n  \"body\": {\"select_query\": \"SELECT Id, Account_Name, Website FROM Accounts WHERE Website != '' ORDER BY Account_Name LIMIT 50\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_executeCOQLQuery\" --args \"$(< /tmp/zoho_coql.json)\"\n```\n\n## Python Scripts\n\nThis skill includes ready-to-use Python scripts for common operations. All scripts read the MCP URL from `ZOHO_MCP_URL`.\n\n### list_contacts.py - Search and list contacts\n```bash\n# All contacts as table\npython3 scripts/list_contacts.py\n\n# Search by last name\npython3 scripts/list_contacts.py --search \"Smith\"\n\n# Raw JSON output\npython3 scripts/list_contacts.py --json\n\n# Full record data\npython3 scripts/list_contacts.py --search \"Smith\" --json --full\n```\n\n### list_accounts.py - List companies/accounts\n```bash\n# All accounts with website\npython3 scripts/list_accounts.py\n\n# Search by company name\npython3 scripts/list_accounts.py --search \"Acme\"\n\n# All accounts (including those without website)\npython3 scripts/list_accounts.py --all\n\n# JSON output\npython3 scripts/list_accounts.py --json\n```\n\n### search_records.py - Generic module search\n```bash\n# Search any module\npython3 scripts/search_records.py Contacts \"Smith\"\npython3 scripts/search_records.py Accounts \"Acme Corp\"\npython3 scripts/search_records.py Deals \"Project X\"\n\n# COQL query\npython3 scripts/search_records.py Contacts --coql \"Email != ''\" --json\n```\n\n## mcporter Usage Patterns\n\n### Always use temp files for JSON arguments\nShell escaping breaks with inline JSON. Always write to a temp file:\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Email:equals:test@example.com)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/args.json)\"\n```\n\n### Pagination\nFor large result sets, use `page` and `per_page`:\n```json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"page\": 2, \"per_page\": 200}\n}\n```\n\n### Field metadata\nGet all field names for a module (useful for scripting):\n```bash\ncat << 'EOF' > /tmp/args.json\n{\n  \"query_params\": {\"module\": \"Contacts\", \"include\": \"allowed_permissions_to_update\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getFields\" --args \"$(< /tmp/args.json)\"\n```\n\n## Recommended CRM Actions (Agent Setup)\n\nFor a fully capable CRM agent, enable these actions on your Zoho MCP server:\n\n### Read-only (safe starting point)\n- `getModules` - List all CRM modules\n- `getFields` - Get field definitions for any module\n- `getRecord` / `getRecords` - Read individual or lists of records\n- `searchRecords` - Search by criteria (email, name, etc.)\n- `executeCOQLQuery` - SQL-like queries across modules\n- `getRecordCount` - Count records per module\n- `getRelatedRecords` - Read linked records (e.g., contacts of an account)\n- `getPickListValues` - Get dropdown options for fields\n\n### Read-write (for agents that create/update data)\n- `createRecords` - Create new records in any module\n- `updateRecord` - Update a single record by ID\n- `upsertRecords` - Insert or update (upsert)\n- `createNotes` - Add notes to records\n- `createEventsRecords` - Create calendar events\n- `createTags` / `postRemoveTags` - Manage tags\n\n### Avoid enabling by default\n- `deleteRecord` / `deleteRecords` - Only enable when specifically needed\n\n## COQL Reference\n\nCOQL (Zoho's SQL-like query language) differs from standard SQL in several ways:\n- No JOINs - query one module at a time\n- Use single quotes for strings: `WHERE Last_Name = 'Smith'`\n- DateTime format: `2026-01-01T00:00:00+01:00`\n- LIMIT format: `LIMIT 20 OFFSET 0`\n- Boolean: `true` / `false` (lowercase)\n\n### Common COQL examples\n```sql\n-- All contacts with email\nSELECT Id, Full_Name, Email FROM Contacts WHERE Email != '' LIMIT 100\n\n-- Deals from last 3 months\nSELECT Id, Deal_Name, Amount, Stage FROM Deals WHERE Created_Time >= '2026-04-01T00:00:00+01:00'\n\n-- Accounts by city\nSELECT Id, Account_Name, Billing_City FROM Accounts WHERE Billing_City = 'Berlin'\n```\n\n## Troubleshooting\n\n### \"ZOHO_MCP_URL nicht gesetzt\"\nSet the environment variable with your MCP endpoint URL.\n\n### \"Mandatory query param module is not present\"\nUse the temp-file approach with `--args \"$(< /tmp/args.json)\"` instead of inline JSON.\n\n### \"Invalid oauth scope to access this URL\"\nThe MCP connection token may have expired. Go to [mcp.zoho.eu](https://mcp.zoho.eu), revoke and reconnect the affected app to get a fresh token.\n\n### Fields API name vs UI label\nZoho CRM shows display labels in the UI, but the API uses `api_name` values (e.g., `Account_Name` not \"Account Name\"). Always check field names with `getFields` before writing scripts or Deluge code.\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn76qytcmtbreh5tr5hy2gnmgs89hj1d\",\n  \"slug\": \"zoho-crm-mcp\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1782656266960\n}\n\nFile v1.0.0:skill-card.md\n\n## Description: <br>\nConnect OpenClaw agents to Zoho CRM over MCP to search contacts, list accounts, run COQL queries, and manage CRM data with mcporter. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[sprintcx](https://clawhub.ai/user/sprintcx) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and CRM operations teams use this skill to connect an OpenClaw agent to Zoho CRM through MCP for contact search, account listing, COQL queries, and common CRM data workflows. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can access sensitive Zoho CRM data through the configured MCP endpoint. <br>\nMitigation: Install only when the CRM data access is intended, protect ZOHO_MCP_URL as a secret, and avoid sharing or logging the endpoint. <br>\nRisk: The included scripts use shell command construction around mcporter calls. <br>\nMitigation: Review and fix the scripts before using them in shared, automated, or untrusted environments. <br>\nRisk: The skill documents read-write CRM actions that can create, update, or delete live CRM records. <br>\nMitigation: Keep Zoho MCP scopes read-only unless write access is explicitly required, and avoid enabling delete actions by default. <br>\n\n\n## Reference(s): <br>\n- [Zoho CRM MCP Server](https://mcp.zoho.eu) <br>\n- [ClawHub Skill Page](https://clawhub.ai/sprintcx/skills/zoho-crm-mcp) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown instructions with Python scripts, shell commands, and JSON examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Scripts can print Zoho CRM records as tables or JSON and read the MCP endpoint from ZOHO_MCP_URL.] <br>\n\n## Skill Version(s): <br>\n1.0.0 (source: server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>","readmeExcerpt":"Skill: Zoho CRM MCP Owner: sprintcx Summary: Connect your agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Py... Tags: latest:1.4.1 Version history: v1.4.1 | 2026-07-16T07:00:58.775Z | user Preserve the scripts/ directory layout in the published package so the documented script paths resolve after install. v1.4.0 | 2026-07-16","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"export ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\""},{"language":"bash","snippet":"ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py"},{"language":"bash","snippet":"echo $ZOHO_MCP_URL"},{"language":"text","snippet":"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message"},{"language":"bash","snippet":"mcporter list $ZOHO_MCP_URL"},{"language":"bash","snippet":"cat << 'EOF' > /tmp/zoho_search.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\""}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\r\nname: zoho-crm-mcp\r\nversion: 1.4.0\r\ndescription: Connect your agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Includes ready-to-use Python scripts with pagination and custom-field support for common CRM operations.\r\n---\r\n\r\n# Zoho CRM MCP\r\n\r\nConnect your agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\r\n\r\n## Source Repository\r\n\r\nGitHub source: [sprintberlin/openclaw-zoho-crm-mcp-skill](https://github.com/sprintberlin/openclaw-zoho-crm-mcp-skill)\r\n\r\n## Requirements\r\n\r\n| Requirement | Details |\r\n|---|---|\r\n| Zoho CRM MCP Server | A configured endpoint from [mcp.zoho.eu](https://mcp.zoho.eu) |\r\n| mcporter | MCP client CLI (bundled with OpenClaw; elsewhere install via `npm i -g mcporter`) |\r\n| Environment variable | `ZOHO_MCP_URL` must be set (see below) |\r\n\r\n### Environment Variable Setup\r\n\r\nThis skill requires the `ZOHO_MCP_URL` environment variable. Without it, the Python scripts will not work.\r\n\r\nAdd this to your shell profile (e.g. `~/.bashrc` or `~/.zshrc`):\r\n```bash\r\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\r\n```\r\n\r\nOr set it per session:\r\n```bash\r\nZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py\r\n```\r\n\r\nTo verify it's set:\r\n```bash\r\necho $ZOHO_MCP_URL\r\n```\r\n\r\n## How to Get Your MCP URL\r\n\r\n1. Go to [mcp.zoho.eu](https://mcp.zoho.eu) and sign in with your Zoho account.\r\n2. Click **\"Add Connection\"** (or \"New Connection\").\r\n3. Select **Zoho CRM** from the list of available apps.\r\n4. Choose the **data center** matching your Zoho account (EU, US, IN, AU, JP, CN).\r\n5. Grant the requested OAuth scopes (at minimum: read access to the modules you want to query).\r\n6. After authorization, copy the generated **MCP endpoint URL**. It looks like:\r\n   ```\r\n   https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message\r\n   ```\r\n7. Set it as `ZOHO_MCP_URL` as shown above.\r\n\r\n### Multiple Organizations\r\n\r\nIf you manage multiple Zoho CRM orgs, each gets its own MCP endpoint. You can:\r\n- Set one default via `ZOHO_MCP_URL`\r\n- Pass others explicitly in scripts or mcporter calls\r\n- Use a wrapper script or `.env` file per project\r\n\r\n## Quick Start\r\n\r\n### List available tools on your MCP server\r\n```bash\r\nmcporter list $ZOHO_MCP_URL\r\n```\r\n\r\n### Search for a contact by name\r\n```bash\r\ncat << 'EOF' > /tmp/zoho_search.json\r\n{\r\n  \"path_variables\": {\"module\": \"Contacts\"},\r\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\r\n```\r\n\r\n### Get a single record by ID\r\n```bash\r\ncat << 'EOF' > /tmp/zoho_record.json\r\n{\r\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\r\n}\r\nEOF\r\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_record.json)\"\r\n```\r\n"},{"path":"README.md","content":"# Zoho CRM MCP\n\nConnect your agent to Zoho CRM through the Model Context Protocol (MCP). This skill provides everything you need to search, read, and manage CRM data using `mcporter`.\n\nThis repository contains the public source for the ClawHub skill [`@sprintcx/zoho-crm-mcp`](https://clawhub.ai/sprintcx/skills/zoho-crm-mcp).\n\n## What This Skill Includes\n\n- Agent Skill instructions in `SKILL.md` (portable SKILL.md format)\n- ClawHub release card metadata in `skill-card.md`\n- Ready-to-use Python helpers for contacts, accounts, generic module search, and COQL\n- Security-conscious `mcporter` calls through `subprocess.run([...])` without shell expansion\n\n## Requirements\n\n| Requirement | Details |\n|---|---|\n| Zoho CRM MCP Server | A configured endpoint from [mcp.zoho.eu](https://mcp.zoho.eu) |\n| mcporter | MCP client CLI (bundled with OpenClaw; elsewhere `npm i -g mcporter`) |\n| Environment variable | `ZOHO_MCP_URL` must be set |\n\n### Environment Variable Setup\n\nThis skill requires the `ZOHO_MCP_URL` environment variable. Without it, the Python scripts will not work.\n\nAdd this to your shell profile, for example `~/.bashrc` or `~/.zshrc`:\n\n```bash\nexport ZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\"\n```\n\nOr set it per session:\n\n```bash\nZOHO_MCP_URL=\"https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/YOUR_TOKEN/message\" python3 scripts/list_contacts.py\n```\n\nTo verify that it is set:\n\n```bash\necho $ZOHO_MCP_URL\n```\n\nTreat `ZOHO_MCP_URL` like a password. It contains CRM access credentials.\n\n## How to Get Your MCP URL\n\n1. Go to [mcp.zoho.eu](https://mcp.zoho.eu) and sign in with your Zoho account.\n2. Click **Add Connection** or **New Connection**.\n3. Select **Zoho CRM** from the list of available apps.\n4. Choose the data center matching your Zoho account: EU, US, IN, AU, JP, or CN.\n5. Grant the requested OAuth scopes. Start with read-only access unless write actions are explicitly needed.\n6. After authorization, copy the generated MCP endpoint URL. It looks like:\n\n   ```text\n   https://your-org-zoho-crm-xxxxx.zohomcp.eu/mcp/abc123def456/message\n   ```\n\n7. Set it as `ZOHO_MCP_URL`.\n\n### Multiple Organizations\n\nIf you manage multiple Zoho CRM orgs, each gets its own MCP endpoint. You can:\n\n- Set one default via `ZOHO_MCP_URL`\n- Pass others explicitly in scripts or `mcporter` calls\n- Use a wrapper script or `.env` file per project\n\n## Quick Start\n\n### List available tools on your MCP server\n\n```bash\nmcporter list $ZOHO_MCP_URL\n```\n\n### Search for a contact by name\n\n```bash\ncat << 'EOF' > /tmp/zoho_search.json\n{\n  \"path_variables\": {\"module\": \"Contacts\"},\n  \"query_params\": {\"criteria\": \"(Last_Name:equals:Smith)\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_searchRecords\" --args \"$(< /tmp/zoho_search.json)\"\n```\n\n### Get a single record by ID\n\n```bash\ncat << 'EOF' > /tmp/zoho_record.json\n{\n  \"path_variables\": {\"module\": \"Accounts\", \"recordID\": \"1234567890\"}\n}\nEOF\nmcporter call \"$ZOHO_MCP_URL.ZohoCRM_getRecord\" --args \"$(< /tmp/zoho_re"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn76qytcmtbreh5tr5hy2gnmgs89hj1d\",\n  \"slug\": \"zoho-crm-mcp\",\n  \"version\": \"1.4.1\",\n  \"publishedAt\": 1784185258775\n}"},{"path":"skill-card.md","content":"## Description:\n\nConnect your agent to Zoho CRM via MCP to search contacts, list accounts, query records with COQL, and manage CRM data using mcporter with paginated, custom-field-aware helper scripts.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[sprintcx](https://clawhub.ai/user/sprintcx)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and CRM operators use this skill to connect an agent to Zoho CRM, inspect contacts and accounts, run COQL queries, and prepare controlled CRM read or write workflows through a configured MCP endpoint.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The Zoho MCP URL contains CRM access credentials and can expose customer data if logged, screenshotted, or stored carelessly.\n\nMitigation: Treat ZOHO_MCP_URL as a secret, avoid echoing it, prefer per-session storage where practical, and rotate it if exposed.\n\nRisk: Broad Zoho OAuth scopes or enabled write/delete tools can let an agent change or remove CRM records beyond the intended workflow.\n\nMitigation: Start with read-only scopes and enable create, update, or delete tools only for agents and tasks that explicitly require them.\n\nRisk: Fixed temporary-file examples can leave request arguments on disk or collide across sessions.\n\nMitigation: Prefer the bundled Python helpers or secure, unique temporary files for shell-based JSON arguments.\n\n## Reference(s):\n\n- [ClawHub release page](https://clawhub.ai/sprintcx/skills/zoho-crm-mcp)\n- [Zoho CRM MCP portal](https://mcp.zoho.eu)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown instructions with shell commands and Python helper scripts that can print tables or JSON]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires ZOHO_MCP_URL and mcporter; helper scripts may access CRM data according to the configured Zoho OAuth scopes.]\n\n## Skill Version(s):\n\n1.4.1 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."},{"path":"package.json","content":"{\n  \"name\": \"zoho-crm-mcp\",\n  \"version\": \"1.4.0\",\n  \"description\": \"Connect your agent to Zoho CRM via MCP. Search contacts, list accounts, query records with COQL, and manage CRM data using mcporter. Paginated, custom-field-aware helper scripts.\",\n  \"author\": \"SprintCX\",\n  \"license\": \"MIT\"\n}"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1600,"uniquenessScore":39,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-12T00:30:31.450Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-12T00:30:31.450Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-12T15:48:13.408Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}