|
@@ -6,99 +6,138 @@ This file provides guidance for AI agents (Claude, etc.) when using this MCP ser
|
|
|
|
|
|
|
|
This MCP server enables AI assistants to interact with Apple Mail on macOS via AppleScript. All operations are local - no data leaves the user's machine.
|
|
This MCP server enables AI assistants to interact with Apple Mail on macOS via AppleScript. All operations are local - no data leaves the user's machine.
|
|
|
|
|
|
|
|
|
|
+## Critical: Backslash Escaping
|
|
|
|
|
+
|
|
|
|
|
+**When sending content with backslashes to any tool, you MUST escape them.**
|
|
|
|
|
+
|
|
|
|
|
+The MCP protocol uses JSON for parameters. In JSON, `\` is an escape character. To include a literal backslash:
|
|
|
|
|
+
|
|
|
|
|
+| You want | Send in JSON parameter |
|
|
|
|
|
+|----------|------------------------|
|
|
|
|
|
+| `\` | `\\` |
|
|
|
|
|
+| `\\` | `\\\\` |
|
|
|
|
|
+| `C:\Users\` | `C:\\Users\\` |
|
|
|
|
|
+
|
|
|
|
|
+### Why This Matters
|
|
|
|
|
+
|
|
|
|
|
+If you send a single backslash without escaping:
|
|
|
|
|
+- The JSON parser interprets `\` as an escape sequence
|
|
|
|
|
+- Invalid sequences like `\ ` (backslash-space) cause silent failures
|
|
|
|
|
+- The email send/draft may fail with no clear error
|
|
|
|
|
+
|
|
|
|
|
+### Examples
|
|
|
|
|
+
|
|
|
|
|
+**Correct - Windows path in email:**
|
|
|
|
|
+```
|
|
|
|
|
+body: "The file is at C:\\Users\\Documents\\report.pdf"
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Incorrect - Will fail:**
|
|
|
|
|
+```
|
|
|
|
|
+body: "The file is at C:\Users\Documents\report.pdf"
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
## Tool Usage Tips
|
|
## Tool Usage Tips
|
|
|
|
|
|
|
|
-### Message Operations
|
|
|
|
|
|
|
+### Using Message IDs (Required)
|
|
|
|
|
|
|
|
-#### search-messages
|
|
|
|
|
-- Use `query` for general text search across subject, sender, content
|
|
|
|
|
-- Use `from` to filter by sender email address
|
|
|
|
|
-- Use `subject` for subject line matching
|
|
|
|
|
-- Combine `mailbox` and `account` to narrow search scope
|
|
|
|
|
-- Default limit is 50 messages
|
|
|
|
|
|
|
+All message operations require an `id` parameter. **Always get IDs first** using `list-messages` or `search-messages`:
|
|
|
|
|
|
|
|
-#### send-email
|
|
|
|
|
-- `to` must be an array of email addresses, even for single recipient
|
|
|
|
|
-- `body` is plain text by default
|
|
|
|
|
-- Specify `account` to send from a specific account
|
|
|
|
|
|
|
+```
|
|
|
|
|
+# List messages returns IDs
|
|
|
|
|
+list-messages mailbox="INBOX"
|
|
|
|
|
+→ Messages with IDs like "12345", "12346", etc.
|
|
|
|
|
+
|
|
|
|
|
+# Use ID for all subsequent operations
|
|
|
|
|
+get-message id="12345"
|
|
|
|
|
+mark-as-read id="12345"
|
|
|
|
|
+delete-message id="12345"
|
|
|
|
|
+reply-to-message id="12345" body="Thanks!"
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-#### create-draft
|
|
|
|
|
-- Same parameters as `send-email`
|
|
|
|
|
-- Saves to Drafts folder without sending
|
|
|
|
|
-- User can review and send manually from Mail.app
|
|
|
|
|
|
|
+### Recipient Arrays
|
|
|
|
|
|
|
|
-#### reply-to-message
|
|
|
|
|
-- Requires message `id` to reply to
|
|
|
|
|
-- Set `replyAll: true` to reply to all recipients
|
|
|
|
|
-- Set `send: false` to save as draft instead of sending
|
|
|
|
|
|
|
+The `to`, `cc`, and `bcc` parameters must always be arrays:
|
|
|
|
|
|
|
|
-#### forward-message
|
|
|
|
|
-- Requires message `id` to forward
|
|
|
|
|
-- `to` must be an array of recipient addresses
|
|
|
|
|
-- Optional `body` to prepend a message
|
|
|
|
|
-- Set `send: false` to save as draft instead of sending
|
|
|
|
|
|
|
+**Correct:**
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "to": ["bob@example.com"],
|
|
|
|
|
+ "subject": "Hello"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-#### mark-as-read / mark-as-unread / flag-message / unflag-message / delete-message
|
|
|
|
|
-- All require a message `id`
|
|
|
|
|
-- Get message IDs from `search-messages` or `list-messages`
|
|
|
|
|
|
|
+**Incorrect:**
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "to": "bob@example.com",
|
|
|
|
|
+ "subject": "Hello"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-#### move-message
|
|
|
|
|
-- Requires message `id` and destination `mailbox` name
|
|
|
|
|
-- Specify `account` if mailbox is in a specific account
|
|
|
|
|
|
|
+### send-email vs create-draft
|
|
|
|
|
|
|
|
-### Mailbox Operations
|
|
|
|
|
|
|
+- Use `send-email` for immediate sending
|
|
|
|
|
+- Use `create-draft` when the user should review first
|
|
|
|
|
+- **Recommendation**: For important emails, use `create-draft` and tell the user to review in Mail.app
|
|
|
|
|
|
|
|
-#### list-mailboxes
|
|
|
|
|
-- Returns all mailboxes (folders) for an account
|
|
|
|
|
-- Common mailboxes: INBOX, Sent, Drafts, Trash, Junk, Archive
|
|
|
|
|
|
|
+### reply-to-message
|
|
|
|
|
|
|
|
-#### get-unread-count
|
|
|
|
|
-- Omit parameters to get total unread across all accounts
|
|
|
|
|
-- Specify `mailbox` for specific folder count
|
|
|
|
|
|
|
+- Set `replyAll: true` to reply to all recipients
|
|
|
|
|
+- Set `send: false` to save as draft instead of sending immediately
|
|
|
|
|
+- Default behavior: reply to sender only, send immediately
|
|
|
|
|
+
|
|
|
|
|
+### forward-message
|
|
|
|
|
+
|
|
|
|
|
+- Requires message `id` and `to` array
|
|
|
|
|
+- Optional `body` to prepend a message
|
|
|
|
|
+- Set `send: false` to save as draft
|
|
|
|
|
|
|
|
### Multi-account
|
|
### Multi-account
|
|
|
|
|
|
|
|
|
|
+- Default account is typically the first configured
|
|
|
- Use `list-accounts` to see available accounts
|
|
- Use `list-accounts` to see available accounts
|
|
|
- Pass `account` parameter to target specific account
|
|
- Pass `account` parameter to target specific account
|
|
|
-- Default account is typically the first configured account
|
|
|
|
|
|
|
|
|
|
## Error Handling
|
|
## Error Handling
|
|
|
|
|
|
|
|
| Error | Likely Cause |
|
|
| Error | Likely Cause |
|
|
|
|-------|--------------|
|
|
|-------|--------------|
|
|
|
| "Mail.app not responding" | Mail.app frozen or not running |
|
|
| "Mail.app not responding" | Mail.app frozen or not running |
|
|
|
-| "Message not found" | Message ID is invalid or message was deleted |
|
|
|
|
|
|
|
+| "Message not found" | Message ID is invalid or message was deleted/moved |
|
|
|
| "Permission denied" | macOS automation permission needed |
|
|
| "Permission denied" | macOS automation permission needed |
|
|
|
-| "Account not found" | Account name doesn't match exactly |
|
|
|
|
|
|
|
+| "Account not found" | Account name doesn't match exactly (case-sensitive) |
|
|
|
| "Failed to send email" | Network issue or Mail.app configuration problem |
|
|
| "Failed to send email" | Network issue or Mail.app configuration problem |
|
|
|
|
|
+| Silent failure | Backslash not escaped in content |
|
|
|
|
|
|
|
|
## Security Considerations
|
|
## Security Considerations
|
|
|
|
|
|
|
|
-- **Sending emails**: Always confirm with user before sending
|
|
|
|
|
-- **Deleting messages**: Warn user that deletion may be permanent
|
|
|
|
|
-- **Reading emails**: May contain sensitive information
|
|
|
|
|
|
|
+- **Sending emails**: Always confirm with user before sending. Recommend `create-draft` for review.
|
|
|
|
|
+- **Deleting messages**: Warn user that deletion moves to Trash (can be recovered).
|
|
|
|
|
+- **Reading emails**: May contain sensitive information - summarize rather than display full content when appropriate.
|
|
|
|
|
|
|
|
## Example Workflows
|
|
## Example Workflows
|
|
|
|
|
|
|
|
### Check for important emails
|
|
### Check for important emails
|
|
|
```
|
|
```
|
|
|
1. list-accounts → get available accounts
|
|
1. list-accounts → get available accounts
|
|
|
-2. search-messages from="boss@company.com" → find emails from boss
|
|
|
|
|
|
|
+2. search-messages query="boss@company.com" → find emails from boss
|
|
|
3. get-message id="..." → read the full content
|
|
3. get-message id="..." → read the full content
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-### Send a reply
|
|
|
|
|
|
|
+### Send a reply safely
|
|
|
```
|
|
```
|
|
|
1. get-message id="..." → read original message
|
|
1. get-message id="..." → read original message
|
|
|
-2. reply-to-message id="..." body="Thanks for the update!" → reply to sender
|
|
|
|
|
- OR
|
|
|
|
|
- reply-to-message id="..." body="..." replyAll=true → reply to all
|
|
|
|
|
|
|
+2. reply-to-message id="..." body="..." send=false → save as draft
|
|
|
|
|
+3. Tell user to review in Mail.app before sending
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-### Create a draft for user review
|
|
|
|
|
|
|
+### Compose and send
|
|
|
```
|
|
```
|
|
|
1. create-draft to=["recipient@example.com"] subject="..." body="..."
|
|
1. create-draft to=["recipient@example.com"] subject="..." body="..."
|
|
|
-2. Tell user to review the draft in Mail.app before sending
|
|
|
|
|
|
|
+2. Tell user: "I've created a draft. Review it in Mail.app and send when ready."
|
|
|
|
|
+ OR if user confirms they want to send immediately:
|
|
|
|
|
+3. send-email to=["recipient@example.com"] subject="..." body="..."
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
### Forward an email
|
|
### Forward an email
|
|
@@ -109,6 +148,14 @@ This MCP server enables AI assistants to interact with Apple Mail on macOS via A
|
|
|
|
|
|
|
|
### Organize inbox
|
|
### Organize inbox
|
|
|
```
|
|
```
|
|
|
-1. search-messages isRead=false → find unread
|
|
|
|
|
-2. For each: get-message, then move-message to appropriate folder
|
|
|
|
|
|
|
+1. search-messages query="newsletter" → find newsletters
|
|
|
|
|
+2. For each: move-message id="..." mailbox="Archive"
|
|
|
```
|
|
```
|
|
|
|
|
+
|
|
|
|
|
+## Testing Your Understanding
|
|
|
|
|
+
|
|
|
|
|
+Before sending emails with paths or special characters, verify escaping:
|
|
|
|
|
+
|
|
|
|
|
+- `~/path/to/file` - No escaping needed (no backslashes)
|
|
|
|
|
+- `C:\Users\` - Needs escaping: `C:\\Users\\`
|
|
|
|
|
+- `file\ name.txt` - Needs escaping: `file\\ name.txt`
|