Zoho Mail CLI access — planning doc
Planning document for setting up terminal / CLI access to the Zoho Mail archive, matching the gws Google Workspace CLI setup already in place for Gmail. Not yet implemented. Revisit on a future session.
Update 2026-07-03: Revisited and confirmed still needed. The Proto Studio fall-booking session exposed the same gap again: Nicholas’s studio-rate email lived on
org@baseworks.com(Zoho) and was invisible to thegws(Google) CLI, so the rate had to be recovered from a screenshot Patrick sent. Patrick also expanded the scope beyond archive search (see Expanded scope 2026-07-03): durable non-expiring credentials, draft-only sending with guardrails, configuring Zoho Mail settings via API, staged deliverability/spam remediation, and migrating Baseworks mail off eM Client into provider-optimized clients. A ready-to-run execution prompt is at the bottom: Ready-to-run prompt for the execution session. Deferred again for time; this doc is the pickup point.
Current email topology (as of 2026-04-23)
Section titled “Current email topology (as of 2026-04-23)”- Google Workspace hosts the personal mailboxes for Patrick (pat@baseworks.com) and Asia, with aliases (pat@cevaco.co, pat@paraimpacto.com, pat@shaspo.org, po@paraimpacto.com) all routing into those accounts. Handled today via the
gwsCLI. - Zoho Mail hosts every other mailbox across the owned domains. One organization-admin account manages the domain configuration; each domain has its own Zoho login handling its aliases. Historical correspondence (trademarks, accounting, legal, vendor threads) mostly lives here. Thousands of messages across multiple domain mailboxes.
- DNS routing is a Google-primary configuration with exceptions that route specific mailboxes to Zoho’s MX records. Exact mechanism undocumented; needs to be reverse-engineered from the DNS zone (see open questions below).
Why this matters
Section titled “Why this matters”- Today, searching Zoho archives means logging into each domain’s webmail individually. Slow, error-prone, no cross-domain search.
- Today’s trademark workstream exposed the gap: Shobayashi correspondence was on a Zoho-hosted address and had to be manually forwarded to pat@baseworks.com (Gmail) for Claude to search through
gws. That workflow does not scale to other historical lookups (vendor contracts, early Baseworks contracts, accounting). - CLI access would let Claude cross-reference any archival thread in seconds during a session, the same way it does with Gmail now.
Options
Section titled “Options”Option A — IMAP via himalaya (per-account config)
Section titled “Option A — IMAP via himalaya (per-account config)”What it is: himalaya is a modern IMAP/SMTP CLI. Each Zoho login becomes an account block in its config file. Authenticates with app-specific passwords (not main Zoho password).
Pros:
- Simplest to set up — 1-2 hours for first account, 15 min per additional
- Works with any IMAP server, not Zoho-specific
- Search, read, send, reply, attachments all supported
- App passwords are revocable per-device (safer than main password)
Cons:
- N accounts × N configs to maintain
- IMAP search is slower than API search on large archives (Zoho has millions of indexed messages; IMAP grep is less efficient)
- Each Zoho login needs its own app password generated manually via Zoho security settings
- No Zoho-specific features (tags, org-wide admin queries)
Effort estimate: ~2-3 hours to set up for all domains.
Option B — Zoho Mail Admin API (single OAuth app, org-wide access)
Section titled “Option B — Zoho Mail Admin API (single OAuth app, org-wide access)”What it is: Zoho offers a REST API with admin-level scopes that let a single OAuth app read/send on behalf of any user in the organization. One app registered in Zoho API Console, one OAuth client ID/secret, one refresh token — access to every domain mailbox through admin impersonation.
Pros:
- Single credential handles all mailboxes — matches Patrick’s “unified access” goal directly
- API search is fast across large archives (Zoho’s server-side index)
- Supports Zoho-specific features (tags, threads, org filters)
- Cleanest long-term — adding a new domain = no new auth, just start querying
- Admin API lets Claude search Ksenia’s Zoho mailboxes too (when authorized by her) without separate logins
Cons:
- More initial setup: register OAuth app in Zoho API Console, configure scopes, handle token refresh, pick a credential store
- Requires building a small wrapper CLI (no
gws-equivalent ready to install) - Need to pick the right scope tier —
ZohoMail.accounts.READandZohoMail.messages.ALLat minimum; admin scopes cost more token-refresh complexity
Effort estimate: ~4-6 hours for a first working version; pays off quickly after that.
Option C — Hybrid: start with himalaya, upgrade to Admin API when needed
Section titled “Option C — Hybrid: start with himalaya, upgrade to Admin API when needed”Pattern: install himalaya for the 2-3 Zoho accounts used most often. Live with it. If it hits a ceiling (too slow on search, missing features, too many accounts to configure), invest in Option B.
Pros:
- Fastest time to working CLI
- Avoids over-engineering before use patterns are clear
- Easy migration path (Option B can coexist with or replace Option A)
Cons:
- Two setups to maintain short-term
- Incomplete coverage until upgrade happens
Recommendation
Section titled “Recommendation”Option C as an entry point, with Option B as the documented target. Install himalaya for the 2-3 highest-value mailboxes this week; use it for a month; if the pattern justifies it, build the Admin API wrapper on that evidence.
If it’s clear up front that cross-domain search across all mailboxes is the primary use case (not occasional per-account lookups), skip straight to Option B — it’s the correct shape for that workload and the extra setup time pays back quickly.
Open questions
Section titled “Open questions”- Which Zoho accounts are the highest-value targets? A ranked list would drive the himalaya setup order. Candidates based on what surfaced today: any Baseworks domain addresses that handle vendor/legal/accounting, any address that received Shobayashi correspondence, any address that held early contracts.
- DNS mechanism — who decides which addresses route to Zoho vs. Google? Needs a zone-file walkthrough. Likely a mix of MX priority, split-domain configuration with SPF/DKIM records, or Zoho Mail routing rules. Worth documenting in
00-inbox/claude-code-shared-context.mdonce understood. - Does Asia’s Zoho access need parity with Patrick’s? If yes, Option B becomes more attractive (one credential can serve both). If her use is lighter, himalaya on her own machine is fine.
- Credential storage: mac Keychain?
~/.config/baseworks/?pass? Same pattern asgws(encrypted credentials in~/.config/gws/credentials.enc) is probably the right model. - Retention and compliance: Zoho has per-mailbox retention settings. Any outbound email sent from the CLI needs to be archived the same way Zoho webmail archives it. Confirm before writing a “send” path.
What doing this enables
Section titled “What doing this enables”- Cross-reference any historical thread in seconds during a session (trademarks, contracts, vendor history, Para Impacto correspondence, Shaspo/Ceva business records, etc.)
- Draft replies to any Zoho-hosted conversation without bouncing through Gmail forwarding
- Archive-search questions like “what did we agree with X in Y year” become tractable
- Potential future automation: daily digest of unread Zoho mail into the vault, or auto-capture of specific senders
Not doing this now — why revisit?
Section titled “Not doing this now — why revisit?”Patrick flagged this as something to come back to on a separate day. The trademark workstream is the immediate priority and is now closed. This plan is a placeholder to pick up without re-deriving the shape of the problem.
Expanded scope (2026-07-03)
Section titled “Expanded scope (2026-07-03)”Beyond the archive-search goal above, Patrick wants the execution session to cover:
- Search all Zoho mailboxes (org@, asia@, and any other Zoho baseworks.com addresses) the way
gwssearches the Google ones. Highest priority. - Durable, non-expiring credentials stored securely on the Mac (not in any git repo, chmod 600, ideally migrated into macOS Keychain like
gws). Zoho IMAP app-specific passwords don’t expire; OAuth self-client with offline access yields a non-expiring refresh token. Likely both: IMAP for mail, OAuth for admin/config. - Draft-only sending with hard guardrails. Claude may create drafts in the Zoho Drafts folder but must never auto-send. Sending happens only on Patrick’s explicit instruction, or he sends from Drafts himself. (This resolves open question #5 below: build the “send” path as draft-create only.)
- Configuring Zoho Mail settings via API where possible (filters, folders, forwarding) vs what needs the admin console — assess and report.
- Deliverability / anti-spam, staged. Baseworks Zoho mail sometimes gets flagged as spam or fails to arrive. Audit SPF / DKIM / DMARC for baseworks.com; diagnose before any change; make no DNS change without walking Patrick through it.
- Email-client strategy. Move Baseworks off eM Client (slow/cumbersome): a Google-optimized client for the Google accounts (candidates: Mimestream, Apple Mail, Gmail web) and a plan for the Zoho accounts. Recommend, don’t just list.
Secure credential handoff: do NOT have Patrick paste keys/passwords into chat (they persist in transcripts). Tell him exactly what to create and where to put it (a chmod 600 file at a named path, read once then migrated into Keychain), and walk him through generating the Zoho credential (Self Client in api-console.zoho.com with offline access, or per-mailbox IMAP app passwords) and the required scopes.
Ready-to-run prompt for the execution session
Section titled “Ready-to-run prompt for the execution session”Paste this into a fresh session to start the work:
# Session goal: Connect me to Zoho Mail across all Baseworks mailboxes, then improve our whole email setup
Read these first for context:- ~/.claude/CLAUDE.md (global) and ~/Obsidian/baseworks-kb-shared-brain/CLAUDE.md (vault rules)- The Google Workspace CLI doc: ~/Obsidian/baseworks-kb-shared-brain/03-resources/executed-plans/google-workspace-cli-setup.md- This plan: ~/Obsidian/baseworks-kb-shared-brain/03-resources/plans/zoho-mail-cli-plan.md (options A/B/C, open questions, expanded scope)- The most recent changelog entry (2026-07-03) in ~/Documents/baseworks-changelog/CHANGELOG.md — explains why this is needed (a Proto Studio email on Zoho org@baseworks.com was invisible to the Google-only gws CLI).
## Background / current state- Baseworks email is SPLIT across two providers: - Google — pat@baseworks.com is on Google Workspace, reachable via the `gws` CLI (OAuth, creds in macOS Keychain). Personal Google accounts p.oancia@gmail.com (`gws-p`) and as.poancia@gmail.com (`gws-asia`) too. - Zoho — org@baseworks.com, asia@baseworks.com, and likely events@/team@/news@/newsjp@baseworks.com. NOT reachable by any tool right now. This is the gap to close.- I currently use eM Client on the Mac for everything and find it slow/cumbersome.
## What I want, in priority order1. Get you able to search all our Zoho mailboxes, the way `gws` already searches the Google ones. Most important outcome.2. Durable, non-expiring credentials. Don't want to re-auth constantly. Zoho OAuth refresh token with offline access and/or IMAP app-specific passwords. Store secrets securely (not in git, chmod 600, ideally migrated into macOS Keychain like `gws`).3. Draft-only sending with hard guardrails. You may CREATE drafts in the Zoho Drafts folder but must NEVER auto-send. Sending happens only when I explicitly say so, or I send from Drafts myself.4. Explore configuring Zoho Mail settings via API (filters, folders, forwarding) — tell me what's possible via the API vs the admin console.5. Deliverability / anti-spam cleanup, staged. Our Zoho mail sometimes gets flagged as spam or doesn't arrive. Audit SPF / DKIM / DMARC for baseworks.com and guide me in stages. Diagnose before changing anything; no DNS change without walking me through it.6. Email-client strategy. Help me move Baseworks off eM Client: a Google-optimized client for the Google accounts (Mimestream, Apple Mail, Gmail web) and a plan for the Zoho accounts. Recommend, don't just list.
## Secure credential handoffDo NOT ask me to paste API keys or passwords into chat (they persist in the transcript). Tell me precisely what to create and where to put it — e.g. a file at a specific path with chmod 600 that you read once and then migrate into Keychain. Walk me through generating whatever Zoho needs (Self Client in api-console.zoho.com for OAuth with offline access, or IMAP app-specific passwords per mailbox), including scopes.
## Resolve these unknowns before building anything- Which exact baseworks.com addresses are on Zoho vs Google? (Confirm org@, asia@, events@, team@, news@, newsjp@.)- Which Zoho data center / region are we in (.com / .eu / .in)? API and IMAP endpoints depend on it.- What Zoho Mail plan are we on, and do I have Zoho admin access (needed for org-wide/eDiscovery search and DNS/DKIM changes)?- Can one admin credential search all mailboxes, or do we need a credential per mailbox?
Propose a staged plan and check in at each stage. Get read/search access working end-to-end first (goal #1), then drafts (#3), then the rest.Status
Section titled “Status”Not yet executed. When executed, move this file to 03-resources/executed-plans/ and add an entry to 00-executed-plans-index.md.
Related
Section titled “Related”- Plans
- Japan trademark — Shobayashi correspondence is the concrete example that exposed the Zoho-access gap
- Shared operational context