npm package: @joserilla/agentmail-mcp-secure
Description: Secure AgentMail MCP server with whitelist protection and auto-read functionality
Author: Jose Rilla
Latest version: 0.5.0

# AgentMail MCP Secure

Secure AgentMail MCP server with whitelist protection and auto-read functionality.

## Features

- **Smart Auto-Pagination**: Automatically handles large threads (>10 messages) with no try-fail-retry
- **Selective Mark-as-Read**: Only marks messages you actually read, respects pagination bounds
- **Per-Message Unread Tracking**: See exactly which messages are unread at thread and message level
- **File-Based Attachments**: All attachments save to `~/agentmail-attachments/`, no token limits
- **Markdown to HTML**: Automatically converts markdown email bodies to both text and HTML versions
- **Attachment Support**: Send and receive email attachments
- **Whitelist Protection**: Blocks email sends to non-whitelisted addresses
- **Domain Wildcards**: Support for `*@domain.com` patterns
- **Bulk Operations**: Mark all unread emails as read in one operation
- **Audit Logging**: Logs all send attempts (successful and blocked)
- **Clear Error Messages**: Informative errors when sends are blocked

## Installation

```bash
npm install @joserilla/agentmail-mcp-secure
```

## Configuration

Create a whitelist configuration file at `~/.agentmail/email-whitelist.json`:

```json
{
  "allowed_recipients": [
    "user@example.com",
    "*@example.com",
    "*@yourdomain.com"
  ],
  "audit_log": "/home/user/.agentmail/logs/email-audit.log"
}
```

## MCP Tools

### `agentmail_list_threads`
List email threads with filtering.

**Parameters:**
- `filter` (optional): "all", "unread", or "sent"

### `agentmail_read_email`
Read email thread with smart auto-pagination. **Only marks returned messages as read.**

**Parameters:**
- `thread_id` (required): Thread ID to read
- `limit` (optional): Maximum number of messages to return
- `offset` (optional): Number of messages to skip (for pagination)

**Smart Behavior:**
- Threads ≤10 messages: Returns all messages
- Threads >10 messages: Automatically returns first 10 with clear "use offset: 10" message
- No try-fail-retry needed - just works!

**Selective Mark-as-Read:**
- Only marks the messages actually returned (respects pagination)
- Shows `[UNREAD]` indicator on each unread message
- Example: Reading page 1 of 3 only marks page 1 as read, pages 2-3 stay unread

**Pagination Example:**
```json
{
  "thread_id": "abc123",
  "limit": 5,
  "offset": 0
}
```
Returns messages 1-5, marks only those as read. Use `offset: 5` for next 5.

### `agentmail_list_messages`
List messages in a thread (metadata only, without full content). **Does NOT mark messages as read.**

**Parameters:**
- `thread_id` (required): Thread ID to list messages from

**Returns:**
- Thread metadata with unread count
- List of messages with ID, from, date, and preview
- `[UNREAD]` indicator on each unread message
- Attachment count per message

**Use case:** Preview a large thread to see which messages are unread before reading them.

### `agentmail_read_message`
Read a single message by ID. **Optionally marks as read (default: true).**

**Parameters:**
- `message_id` (required): Message ID to read
- `mark_as_read` (optional): Mark message as read (default: true)

**Returns:**
- Complete message content
- Attachments with download instructions

**Use case:** Read specific messages from a large thread without loading the entire thread.

**Example workflow for large threads:**
1. **Simple approach**: Just call `agentmail_read_email` - it auto-paginates!
2. **Advanced approach**: Use `agentmail_list_messages` to see all unread messages, then read specific ones
3. **Pagination**: If thread has 45 messages, first call returns 1-10 with clear "use offset: 10" message

### `agentmail_send_email`
Send email to whitelisted recipient. **Validates against whitelist.**

**Parameters:**
- `to` (required): Recipient email address
- `subject` (required): Email subject
- `body` (required): Email body in markdown format (automatically converted to text + HTML)
- `html` (optional): Raw HTML override (if provided, `body` is used as plain text and `html` is used as-is)
- `attachments` (optional): Array of attachments (see Attachments section below)

**Markdown Support:**
The MCP automatically converts markdown in the `body` parameter to:
- **Plain text** (with markdown formatting stripped)
- **HTML** (with email-safe inline styles)

Example:
```markdown
## Welcome

This is **bold** and this is *italic*.

- Feature one
- Feature two

Check out [our docs](https://example.com)
```

### `agentmail_reply_to_thread`
Reply to existing thread. **Validates recipient against whitelist.**

**Parameters:**
- `thread_id` (required): Thread ID to reply to
- `body` (required): Reply body in markdown format (automatically converted to text + HTML)
- `html` (optional): Raw HTML override (if provided, `body` is used as plain text and `html` is used as-is)
- `attachments` (optional): Array of attachments (see Attachments section below)

### `agentmail_mark_all_read`
Mark all unread emails as read in bulk. **Returns count of threads and messages processed.**

**Parameters:**
- None required

**Returns:**
- Count of threads processed
- Count of messages marked as read

### `agentmail_get_attachment`
Download attachment from a message. **Always saves to `~/agentmail-attachments/` directory.**

**Parameters:**
- `message_id` (required): Message ID containing the attachment
- `attachment_id` (required): Attachment ID to download (from read email response)
- `filename` (optional): Override filename (defaults to attachment's original filename)

**Returns:**
- File path where attachment was saved
- File size
- Metadata

**Behavior:**
- Automatically creates `~/agentmail-attachments/` if it doesn't exist
- Handles filename collisions by appending `-1`, `-2`, etc.
- No token limits - files of any size work perfectly
- Returns small response (~100 tokens) with file path

## Usage

The MCP server can be used with any MCP-compatible client. Agents can use the tools via the MCP interface.

### Markdown Email Formatting

The MCP automatically converts markdown to email-friendly HTML, making it easy for agents to send well-formatted emails without worrying about HTML generation.

**How it works:**
1. Agent provides email body in markdown format
2. MCP converts markdown to:
   - **Plain text version** (markdown stripped, readable in text-only clients)
   - **HTML version** (with inline CSS styles for email client compatibility)
3. Both versions are sent together (multipart email)

**Why this is better:**
- **Consistent formatting** - All agents get the same HTML output
- **Token efficient** - Agents just write markdown naturally
- **Reliable** - HTML generation is centralized and tested
- **Email-safe** - HTML includes inline styles that work across email clients

**Advanced usage:**
If you need custom HTML, you can provide the `html` parameter to override the automatic conversion. In this case, `body` is used as the plain text version.

## Working with Attachments

### Receiving Attachments

When reading emails with `agentmail_read_email`, attachments are automatically listed in the response with their message IDs:

```
Message ID: msg_xyz789
From: sender@example.com
To: you@example.com
Date: 2025-10-09T12:00:00Z
Attachments: 2
  - report.pdf (application/pdf, 245.3 KB)
    Attachment ID: att_abc123
    Use with Message ID: msg_xyz789
  - chart.png (image/png, 89.1 KB)
    Attachment ID: att_def456 [inline]
    Use with Message ID: msg_xyz789
```

**Important:** The Message ID is displayed for each message in the thread. You need both the **Message ID** and **Attachment ID** to download an attachment.

**Common Error - Thread ID vs Message ID:**
- ❌ **Thread ID** = ID of the entire conversation (e.g., from `agentmail_list_threads`)
- ✅ **Message ID** = ID of a specific message within the thread (shown in `agentmail_read_email` output)
- You MUST use the **Message ID**, not the Thread ID, to download attachments

To download an attachment, use `agentmail_get_attachment` with the message ID and attachment ID:

```json
{
  "message_id": "msg_xyz789",
  "attachment_id": "att_abc123"
}
```

**Result:**
```
✓ Attachment saved successfully
Filename: report.pdf
Size: 91.2 KB
Saved to: /home/user/agentmail-attachments/report.pdf

You can now read this file using the Read tool.
```

**That's it!** All attachments are automatically saved to disk - no token limits, no complexity.

### Sending Attachments

To send attachments with `agentmail_send_email` or `agentmail_reply_to_thread`, include an `attachments` array:

```json
{
  "to": "recipient@example.com",
  "subject": "Report",
  "body": "Please find the report attached.",
  "attachments": [
    {
      "filename": "report.pdf",
      "content_type": "application/pdf",
      "content": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9DcmVhdG9yKC..."
    }
  ]
}
```

**Attachment object properties:**
- `filename` (optional): Name for the attachment file
- `content_type` (optional): MIME type (e.g., `application/pdf`, `image/png`, `text/plain`)
- `content` (required): Base64 encoded file content

**Common MIME types:**
- PDF: `application/pdf`
- PNG: `image/png`
- JPEG: `image/jpeg`
- Text: `text/plain`
- CSV: `text/csv`
- JSON: `application/json`
- ZIP: `application/zip`

## Whitelist Patterns

- **Exact match**: `user@example.com` - Only matches this exact address
- **Domain wildcard**: `*@example.com` - Matches any address at this domain

**Note:** The whitelist system automatically extracts email addresses from display name formats like `"John Doe" <user@example.com>`, so you only need to whitelist the email address itself.

## Security

This MCP server prevents accidental data leaks by:
1. Blocking sends to non-whitelisted recipients
2. Logging all send attempts for audit purposes
3. Providing clear error messages when sends are blocked

## License

MIT