wanas-zcrm-extractor
v1.8.1
Published
Local Zoho CRM V8 Metadata Extractor CLI and Web Dashboard Utility
Downloads
3,655
Readme
⚠️ Read-only — it never modifies your CRM
zcrm is strictly read-only: it never creates, updates, or deletes anything in Zoho CRM. By default it pulls schema / metadata only — module and field definitions, layouts, picklists, related lists, tags, profiles, roles, webhooks, org-wide settings, and custom function source code — with no access to your CRM records.
Reading actual record data is always opt-in and explicit: per-module record counts only with zcrm pull --with-counts (~50 API credits/module), and audit-log data only via the zcrm audit command. Even then, the tool only ever reads — it cannot change anything in your CRM.
🚀 Quick Start
# 1. Install globally
npm install -g wanas-zcrm-extractor
# 2. Authenticate (opens your browser for Zoho OAuth)
zcrm login
# 3. Pull all metadata into ./metadata
zcrm pull
# 4. (Optional) Generate an AI-assistant context file for your IDE
zcrm skill💡 Prefer not to install globally? Use
npx wanas-zcrm-extractor <command>instead.
🌟 Key Features
⚙️ Installation
npm install -g wanas-zcrm-extractor
zcrm login
zcrm pullnpm install wanas-zcrm-extractor
npx zcrm login
npx zcrm pullOn Windows you may need an Administrator terminal; on macOS/Linux you may need
sudofor a global install.
The same release is also published to GitHub Packages as the scoped package @wanas-apps/wanas-zcrm-extractor. GitHub Packages requires authentication even for public packages, so point the @wanas-apps scope at GitHub and authenticate with a GitHub token that has the read:packages scope:
# ~/.npmrc (or a project-local .npmrc)
@wanas-apps:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKENnpm install -g @wanas-apps/wanas-zcrm-extractorMost users should prefer the public npmjs package above — it needs no token. GitHub Packages is provided for org-internal/CI consumers.
🔑 Setup & Registration
To authenticate, register a Zoho API client in the Zoho Developer Console:
- Visit the Zoho Developer Console.
- Click Add Client → select Server-based Applications.
- Configure your application:
- Client Name:
Zoho CRM Metadata Extractor - Homepage URL:
http://localhost:3000 - Authorized Redirect URI:
http://localhost:3000/zoho/callback(or your preferred local port)
- Client Name:
- Click Create to receive your Client ID and Client Secret.
🚀 CLI Commands Reference
| Command | Purpose |
| :--- | :--- |
| zcrm login | Authenticate the CLI with Zoho OAuth2. |
| zcrm pull | Extract & sync all CRM metadata into a local folder. |
| zcrm skill | Generate an AI-assistant context file for your IDE. |
| zcrm audit | Export the CRM audit log (async job). |
| zcrm fn create · push | ⚠️ Create a Standalone function / push its code on the live CRM (writes). |
| zcrm fn test · pull | ⚠️ Execute a function (not read-only) · fetch one function's .ds (read-only). |
| zcrm dashboard | Launch the local web explorer dashboard. |
| zcrm whoami · zcrm llm · zcrm logout | Session info · AI guide · Sign out. |
Authenticates the CLI to access your Zoho CRM account.
zcrm login [options]Options
| Option | Description |
| :--- | :--- |
| --client-id <id> | Zoho OAuth Client ID. |
| --client-secret <secret> | Zoho OAuth Client Secret. |
| --dc <dc> | Data Center: com, eu, in, jp, com.au, com.cn. |
| --redirect-uri <uri> | Zoho OAuth Redirect URI. |
| --refresh-token <token> | Headless auth (bypasses the browser flow). |
# Interactive (prompts for missing details)
zcrm login
# Express login with explicit credentials
zcrm login --client-id 1000.x --client-secret x --dc com --redirect-uri http://localhost:3000/zoho/callback
# Headless login (CI/CD or servers)
zcrm login --client-id 1000.x --client-secret x --dc com --refresh-token 1000.xCrawls all Zoho CRM endpoints (read-only) and syncs metadata + Deluge scripts into your local folder.
zcrm pull [options]Options
| Option | Description |
| :--- | :--- |
| -o, --output <dir> | Destination folder (default ./metadata). |
| -c, --concurrency <n> | Max simultaneous Zoho API calls, 1–25 (default 5). |
| --with-counts | Also fetch each module's record count — reads record data and costs ~50 API credits/module, so it is off by default. |
Every pull also:
- 📋 Generates a
README.mdin the output folder describing the snapshot — org, counts, a per-module table, and the directory layout — rebuilt from the real data each run. - 📝 Writes a debug log to
<output>/.zcrm/.logs/ZCRM-CLI-<date>.log(includes the quiet "skipped" entries that aren't printed to the console).
Requests run in parallel under a global cap that respects Zoho's per-org concurrency limit: 5 (Free) · 10 (Standard/Starter) · 15 (Professional) · 20 (Enterprise/Zoho One) · 25 (Ultimate/CRM Plus). The default 5 is safe for every edition; raise it on higher tiers for faster pulls:
zcrm pull -o ./metadata --concurrency 15If the limit is hit (HTTP 429), the client backs off exponentially and retries — a pull never fails just because it was briefly throttled.
A pull is a one-way sync from Zoho into your folder:
- Existing files are overwritten in place.
- Files that no longer exist on Zoho are removed locally — but only within scopes whose authoritative fetch succeeded this run.
- If a fetch fails, the previous local data for that scope is kept — a partial or interrupted pull never wipes your data.
Launches the premium local web dashboard to explore the pulled metadata in a browser.
zcrm dashboard [options] # -p, --port <port> (default 3000)Open http://localhost:3000 to view live extraction logs, browse modules, inspect fields & picklists, search APIs, and download .zip archives.
Displays the authenticated user (name, email, role, profile), organization details, Org ID, and configured Data Center.
zcrm whoamiPrints the AI/LLM system reference guide — how an AI assistant should ingest the extracted schema to generate valid Zoho Deluge scripts and REST payloads.
zcrm llmGenerates an AI-assistant skill / rules file for your IDE, derived from the zcrm llm guide, so your assistant writes valid Deluge using exact API names.
zcrm skill [options]Options
| Option | Description |
| :--- | :--- |
| --ide <ide> | Target tool (skips the prompt): claude, cursor, windsurf, copilot, cline, gemini, codex, markdown. |
| -d, --dir <dir> | Project directory to write into (default: current). |
| -m, --metadata-dir <dir> | Path to your extracted metadata (default ./metadata). |
| -f, --force | Overwrite an existing dedicated skill file without prompting. |
| Tool | Generated file |
| :--- | :--- |
| Claude Code | .claude/skills/zoho-crm-deluge/SKILL.md |
| Cursor | .cursor/rules/zoho-crm-deluge.mdc |
| Windsurf | .windsurf/rules/zoho-crm-deluge.md |
| GitHub Copilot | .github/copilot-instructions.md |
| Cline / Roo Code | .clinerules/zoho-crm-deluge.md |
| Gemini CLI | GEMINI.md |
| Codex / generic | AGENTS.md |
| Plain Markdown | ZOHO_CRM_AI_CONTEXT.md |
zcrm skill # interactive menu
zcrm skill --ide claude --metadata-dir ./crm-metaTriggers an asynchronous export of the Zoho CRM audit log, polls until it completes (with a bounded timeout), and downloads the resulting CSV/ZIP into the result folder's CRM root — metadata/crm/audit_logs/ by default (override with -o, --output). A subsequent zcrm pull never deletes this folder.
zcrm audit # last 3 years by default → ./metadata/crm/audit_logs/
zcrm audit --filter input.json # custom export criteria
zcrm audit -o ./my-export # save into ./my-export/crm/audit_logs/Requires the audit-log OAuth scopes —
ZohoCRM.settings.audit_logs.CREATEandZohoCRM.settings.audit_logs.READ(both in the default scopes). If you authenticated before they were added you'll see401 invalid oauth scope— just re-authenticate:zcrm logoutthenzcrm login. (If the download step later reports a file-scope error, addZohoFiles.files.READtoZOHO_SCOPESand log in again.)
Clears stored credentials, OAuth tokens, and the active session.
zcrm logoutWork with one Deluge function at a time — the full loop: create a Standalone function, push code edits, pull the latest, and test-run it.
⚠️
fn create,fn push, andfn testwrite to / execute on your live Zoho CRM org and are outside the read-only guarantee. Each is confirm-gated (use--forceto skip in CI).fn pullis read-only.
Creates a new Standalone function on CRM and writes its .ds into your metadata tree. With --from, it also pushes that file's code; without it, you get an empty stub to edit and fn push later.
Names are lowercased. Zoho lowercases generated function code signatures, so
zcrmnormalizes api_names to lowercase end-to-end (My_Fn→my_fn, filestandalone.my_fn.ds) to keep the function, its code, and the filename consistent. Lookups (push/test/pull) are case-insensitive.
zcrm fn create My_Fn # empty stub + local .ds
zcrm fn create My_Fn --from ./My_Fn.ds # create + push code in one step
zcrm fn create My_Fn --return-type string # stub with a chosen return type| Option | Description |
| :--- | :--- |
| --from <file.ds> | Seed the function with code from a local .ds (its signature name must match <apiName>). |
| --return-type <t> | Return type for an empty stub (default void; ignored with --from). |
| -o, --output <dir> | Metadata root for the written .ds (default ./metadata). |
| --force | Skip the write-confirmation prompt. |
Reads a local .ds, resolves the function from its signature, and uploads the code to the matching existing function. Create it first with fn create if it doesn't exist yet.
zcrm fn push ./metadata/crm/functions/standalone/standalone.My_Fn.dsUnlike every other command, fn test executes Deluge in your live Zoho CRM org (the function editor's "test" action). It can create/update/delete records, send mail/SMS, and call external APIs — exactly what the script does. It is therefore an explicit, opt-in command, gated behind a confirmation prompt (use --force to skip it in CI).
<function> is either a local .ds file (runs your local edits) or the api_name of a Standalone function (fetches & runs the saved code). Only Standalone functions can be tested.
# Test local edits to a function before saving them in CRM:
zcrm fn test ./metadata/crm/functions/standalone/standalone.My_Fn.ds
# Run a live function with arguments:
zcrm fn test My_Fn --args '{"Data":"hello"}'
# No prompt + raw JSON (automation):
zcrm fn test My_Fn --force --json| Option | Description |
| :--- | :--- |
| --args <json> | Inline JSON argument map, e.g. '{"Data":"hi"}'. |
| --args-file <path> | JSON file containing the argument map. |
| -o, --output <dir> | Where to save the result artifact — <dir>/crm/function_tests/ (default ./metadata). |
| --json | Print Zoho's raw JSON response to stdout. |
| --force | Skip the execution warning + confirmation prompt (CI/automation). |
It prints the return value, info logs, every network/integration call (with its HTTP status), and execution metrics, and saves the full response to <output>/crm/function_tests/<api_name>-<timestamp>.json. The exit code is non-zero if the run failed.
Fetches a single function's Deluge code into <output>/crm/functions/<namespace>/<namespace>.<api_name>.ds — the same path zcrm pull uses — without running a full pull. Strictly read-only; never deletes anything.
zcrm fn pull My_Fn
zcrm fn pull My_Fn -o ./metadataTypical loop:
zcrm fn create My_Fn→ edit the.ds→zcrm fn push <file>→zcrm fn test My_Fn. Only Standalone functions are supported (the namespace these endpoints resolve).
📂 Generated Directory Structure
metadata/
├── README.md # 📋 auto-generated snapshot summary (org, counts, modules)
├── .zcrm/ # Internal ZCRM CLI stores
│ ├── .logs/ # 📝 per-pull debug log (ZCRM-CLI-<date>.log)
│ ├── .org/org.json # Organization metadata
│ └── .store/ # Consolidated indexes
│ ├── index.json # Master index of extracted modules
│ ├── field_map.json # { Module: { Field: data_type } } lookup
│ ├── complete_metadata.json # Unified database of all endpoints
│ ├── webhooks.json # Webhooks metadata
│ └── functions.json # Functions catalog
│
├── crm/ # Standard Zoho CRM metadata layout
│ ├── meta/
│ │ ├── modules/<Module_API_Name>/
│ │ │ ├── <Module>.modules-meta.json
│ │ │ ├── summary.json # counts, required/picklist/lookup/subform fields
│ │ │ ├── fields/ # <Field>.fields-meta.json
│ │ │ ├── layouts/ # + map_dependencies/
│ │ │ ├── custom_views/
│ │ │ ├── custom_links/ # module links/buttons
│ │ │ ├── related_lists/
│ │ │ ├── tags/
│ │ │ ├── record_locking_configurations/
│ │ │ └── workflow_configurations/
│ │ ├── profiles/ # permission profiles
│ │ ├── roles/ # role hierarchy
│ │ ├── email_templates/<Module>/ # .meta.json + .html (body)
│ │ ├── inventory_templates/<Module>/ # .meta.json + .html (body)
│ │ ├── workflow_rules/<Trigger_Module>/<Rule>.json
│ │ └── ... # variables, wizards, global picklists, data sharing, territories
│ └── functions/ # custom Deluge scripts (.ds), by namespace
│
├── zcrm-project.json # ZCRM project config
├── meta.json # resource configuration
└── .zcrmignore # cache ignore rules🏢 About Wanas Apps
Wanas Apps is an elite Zoho Premium Partner and advanced technical consulting firm serving the Middle East and North Africa (MENA) region. We bridge the gap between standard business processes and advanced technical architecture, specializing in end-to-end digital transformation.
We don't just implement software; we build custom features that fit seamlessly around your unique business blueprint.
🩺 Troubleshooting
Errors are reported in a single, consistent format: expected problems (e.g. not logged in, bad input) show a clean message with an actionable hint, while unexpected errors show the real underlying reason plus how to reach support — so you're never left with a raw stack trace.
Every command also writes a timestamped debug log to ~/.zcrm/logs/ (e.g. pull-<timestamp>.log, audit-<timestamp>.log) capturing all activity for that run — including the quiet "skipped" lines and the full API error bodies that aren't printed to the console. When a command fails, its log path is shown in the output. zcrm pull additionally writes a copy into its output folder at <output>/.zcrm/.logs/.
The CLI also checks npm for a newer version once a day in the background (never blocking your command) and shows a one-line update notice when one is available. To disable it, set NO_UPDATE_NOTIFIER=1 (or ZCRM_NO_UPDATE_CHECK=1); it is skipped automatically in CI.
✉️ Support & Feedback
Found a bug, have a feature request, or need custom Zoho integrations? Reach out:
- 🌐 Website: www.wanasapps.com
- ✉️ Email: [email protected]
- 🐛 Issues: GitHub Issues
