Skip to main content
Glama
SirGreed808
by SirGreed808
README.md
# zoho-mail-mcp

A [Model Context Protocol](https://modelcontextprotocol.io) server for Zoho Mail. Lets Claude (or any MCP client) read, search, and send email from a Zoho Mail account without browser automation.

No equivalent exists in the official MCP registry — this fills that gap.

## Tools

| Tool | Description |
|------|-------------|
| `list_inbox` | List recent inbox messages — returns sender, subject, date, messageId, folderId |
| `search_emails` | Search by keyword, sender email, or subject fragment |
| `read_email` | Read full email body given a messageId and folderId |
| `send_email` | Send an email from your configured sender address |

## Prerequisites

- A [Zoho Mail](https://mail.zoho.com) account
- Node.js 18+

## Setup

### 1. Create a Zoho OAuth app

1. Go to [Zoho API Console](https://api-console.zoho.com/)
2. Create a **Self Client** application
3. Under **Generate Code**, add these scopes:
   ```
   ZohoMail.messages.READ,ZohoMail.messages.CREATE,ZohoMail.folders.READ,ZohoMail.accounts.READ
   ```
4. Set expiry to **10 minutes**, add a description, click **Create**
5. Copy the generated `client_id`, `client_secret`, and grant `code`

### 2. Exchange the grant code for a refresh token

Run immediately (grant code expires in 10 minutes):

```bash
curl -X POST https://accounts.zoho.com/oauth/v2/token \
  -d "grant_type=authorization_code" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "code=YOUR_GRANT_CODE"
```

Save the `refresh_token` from the response — it doesn't expire.

### 3. Get your account ID

```bash
curl -X GET https://mail.zoho.com/api/accounts \
  -H "Authorization: Zoho-oauthtoken YOUR_ACCESS_TOKEN"
```

Use the `accountId` value from the first object in `data[]`.

### 4. Install

```bash
git clone https://github.com/SirGreed808/zoho-mail-mcp
cd zoho-mail-mcp
npm install
```

### 5. Add to Claude Code

```bash
claude mcp add --scope user \
  -e "ZOHO_CLIENT_ID=..." \
  -e "ZOHO_CLIENT_SECRET=..." \
  -e "ZOHO_REFRESH_TOKEN=..." \
  -e "ZOHO_ACCOUNT_ID=..." \
  -e "ZOHO_SENDER=you@yourdomain.com" \
  zoho-mail -- node /absolute/path/to/zoho-mail-mcp/index.js
```

`ZOHO_SENDER` must be a verified address or alias on the account.

## Environment Variables

| Variable | Description |
|----------|-------------|
| `ZOHO_CLIENT_ID` | OAuth app client ID |
| `ZOHO_CLIENT_SECRET` | OAuth app client secret |
| `ZOHO_REFRESH_TOKEN` | Long-lived refresh token (from step 2) |
| `ZOHO_ACCOUNT_ID` | Zoho Mail account ID (from step 3) |
| `ZOHO_SENDER` | Email address to send from |

## Notes

- Access tokens are refreshed automatically — no manual intervention needed
- `read_email` requires both `messageId` and `folderId`, both returned by `list_inbox` and `search_emails`
- Only REST API — no IMAP/SMTP

## License

MIT

TDQS

A3.7/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose with no overlap: list_inbox retrieves inbox metadata, read_email accesses full email content, search_emails finds specific emails, and send_email handles outgoing messages. The descriptions clearly differentiate their functions, making misselection unlikely.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern (list_inbox, read_email, search_emails, send_email) with snake_case throughout. The naming is predictable and readable, adhering to a uniform convention across the set.

Tool Count5/5

With 4 tools, this server is well-scoped for email management, covering core workflows: listing, reading, searching, and sending emails. Each tool earns its place without feeling thin or bloated, fitting typical email interaction needs.

Completeness4/5

The tool set provides strong coverage for basic email operations, including CRUD-like actions (list, read, send) and search functionality. A minor gap exists in lacking update/delete operations for emails (e.g., marking as read or moving to folders), but agents can work around this for most use cases.

Maintenance

ActivityInactive
ResponsivenessResponsive