apple-mail-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Rob Sweet
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,522 @@
1
+ # Apple Mail MCP Server
2
+
3
+ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that enables AI assistants like Claude to read, send, search, and manage emails in Apple Mail on macOS.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/apple-mail-mcp)](https://www.npmjs.com/package/apple-mail-mcp)
6
+ [![CI](https://github.com/sweetrb/apple-mail-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/sweetrb/apple-mail-mcp/actions/workflows/ci.yml)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ ## What is This?
10
+
11
+ This server acts as a bridge between AI assistants and Apple Mail. Once configured, you can ask Claude (or any MCP-compatible AI) to:
12
+
13
+ - "Check my inbox for unread messages"
14
+ - "Find emails from john@example.com"
15
+ - "Send an email to the team about the meeting"
16
+ - "Create a draft email for me to review"
17
+ - "Reply to that message"
18
+ - "Forward this to my colleague"
19
+ - "Move old newsletters to the Archive folder"
20
+
21
+ The AI assistant communicates with this server, which then uses AppleScript to interact with the Mail app on your Mac. All data stays local on your machine.
22
+
23
+ ## Quick Start
24
+
25
+ ### Using Claude Code (Easiest)
26
+
27
+ If you're using [Claude Code](https://claude.com/product/claude-code) (in Terminal or VS Code), just ask Claude to install it:
28
+
29
+ ```
30
+ Install the sweetrb/apple-mail-mcp MCP server so you can help me manage my Apple Mail
31
+ ```
32
+
33
+ Claude will handle the installation and configuration automatically.
34
+
35
+ ### Using the Plugin Marketplace
36
+
37
+ Install as a Claude Code plugin for automatic configuration and enhanced AI behavior:
38
+
39
+ ```bash
40
+ /plugin marketplace add sweetrb/apple-mail-mcp
41
+ /plugin install apple-mail
42
+ ```
43
+
44
+ This method also installs a **skill** that teaches Claude when and how to use Apple Mail effectively.
45
+
46
+ ### Manual Installation
47
+
48
+ **1. Install the server:**
49
+ ```bash
50
+ npm install -g github:sweetrb/apple-mail-mcp
51
+ ```
52
+
53
+ **2. Add to Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "apple-mail": {
58
+ "command": "npx",
59
+ "args": ["apple-mail-mcp"]
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ **3. Restart Claude Desktop** and start using natural language:
66
+ ```
67
+ "Show me my unread emails"
68
+ ```
69
+
70
+ On first use, macOS will ask for permission to automate Mail.app. Click "OK" to allow.
71
+
72
+ ## Requirements
73
+
74
+ - **macOS** - Apple Mail and AppleScript are macOS-only
75
+ - **Node.js 20+** - Required for the MCP server
76
+ - **Apple Mail** - Must have at least one account configured (iCloud, Gmail, Exchange, etc.)
77
+
78
+ ## Features
79
+
80
+ | Feature | Description |
81
+ |---------|-------------|
82
+ | **List Messages** | List messages in any mailbox |
83
+ | **Search Messages** | Find emails by sender, subject, content |
84
+ | **Read Messages** | Get full email content |
85
+ | **Send Email** | Compose and send new emails |
86
+ | **Create Draft** | Save emails to Drafts folder |
87
+ | **Reply** | Reply to messages (with reply-all support) |
88
+ | **Forward** | Forward messages to new recipients |
89
+ | **Mark Read/Unread** | Change read status |
90
+ | **Flag/Unflag** | Flag or unflag messages |
91
+ | **Delete Messages** | Move messages to trash |
92
+ | **Move Messages** | Organize into mailboxes |
93
+ | **List Mailboxes** | Show all folders with counts |
94
+ | **List Accounts** | Show configured accounts |
95
+ | **Unread Count** | Get unread counts per mailbox |
96
+ | **Health Check** | Verify Mail.app connectivity |
97
+ | **Statistics** | Message and unread counts |
98
+
99
+ ---
100
+
101
+ ## Tool Reference
102
+
103
+ This section documents all available tools. AI agents should use these tool names and parameters exactly as specified.
104
+
105
+ ### Message Operations
106
+
107
+ #### `search-messages`
108
+
109
+ Search for messages matching criteria.
110
+
111
+ | Parameter | Type | Required | Description |
112
+ |-----------|------|----------|-------------|
113
+ | `query` | string | No | Text to search in subject/sender |
114
+ | `mailbox` | string | No | Mailbox to search in (default: INBOX) |
115
+ | `account` | string | No | Account to search in |
116
+ | `limit` | number | No | Max results (default: 50) |
117
+
118
+ ---
119
+
120
+ #### `get-message`
121
+
122
+ Get the full content of a message.
123
+
124
+ | Parameter | Type | Required | Description |
125
+ |-----------|------|----------|-------------|
126
+ | `id` | string | Yes | Message ID |
127
+
128
+ **Returns:** Subject line and plain text body of the message.
129
+
130
+ ---
131
+
132
+ #### `list-messages`
133
+
134
+ List messages in a mailbox.
135
+
136
+ | Parameter | Type | Required | Description |
137
+ |-----------|------|----------|-------------|
138
+ | `mailbox` | string | No | Mailbox name (default: INBOX) |
139
+ | `account` | string | No | Account name |
140
+ | `limit` | number | No | Max messages (default: 50) |
141
+
142
+ **Returns:** List of messages with ID, subject, sender, date, read status, and flagged status.
143
+
144
+ ---
145
+
146
+ #### `send-email`
147
+
148
+ Send a new email immediately.
149
+
150
+ | Parameter | Type | Required | Description |
151
+ |-----------|------|----------|-------------|
152
+ | `to` | string[] | Yes | Recipient addresses |
153
+ | `subject` | string | Yes | Email subject |
154
+ | `body` | string | Yes | Email body (plain text) |
155
+ | `cc` | string[] | No | CC recipients |
156
+ | `bcc` | string[] | No | BCC recipients |
157
+ | `account` | string | No | Send from specific account |
158
+
159
+ **Example:**
160
+ ```json
161
+ {
162
+ "to": ["colleague@company.com"],
163
+ "subject": "Meeting Tomorrow",
164
+ "body": "Hi, just confirming our meeting at 2pm tomorrow.",
165
+ "account": "Work"
166
+ }
167
+ ```
168
+
169
+ ---
170
+
171
+ #### `create-draft`
172
+
173
+ Save an email to Drafts without sending.
174
+
175
+ | Parameter | Type | Required | Description |
176
+ |-----------|------|----------|-------------|
177
+ | `to` | string[] | Yes | Recipient addresses |
178
+ | `subject` | string | Yes | Email subject |
179
+ | `body` | string | Yes | Email body (plain text) |
180
+ | `cc` | string[] | No | CC recipients |
181
+ | `bcc` | string[] | No | BCC recipients |
182
+ | `account` | string | No | Account for draft |
183
+
184
+ **Returns:** Confirmation that draft was created.
185
+
186
+ ---
187
+
188
+ #### `reply-to-message`
189
+
190
+ Reply to an existing message.
191
+
192
+ | Parameter | Type | Required | Description |
193
+ |-----------|------|----------|-------------|
194
+ | `id` | string | Yes | Message ID to reply to |
195
+ | `body` | string | Yes | Reply body |
196
+ | `replyAll` | boolean | No | Reply to all recipients (default: false) |
197
+ | `send` | boolean | No | Send immediately (default: true, false = save as draft) |
198
+
199
+ **Example - Reply to sender only:**
200
+ ```json
201
+ {
202
+ "id": "12345",
203
+ "body": "Thanks for the update!"
204
+ }
205
+ ```
206
+
207
+ **Example - Reply all, save as draft:**
208
+ ```json
209
+ {
210
+ "id": "12345",
211
+ "body": "I'll review this and get back to everyone.",
212
+ "replyAll": true,
213
+ "send": false
214
+ }
215
+ ```
216
+
217
+ ---
218
+
219
+ #### `forward-message`
220
+
221
+ Forward a message to new recipients.
222
+
223
+ | Parameter | Type | Required | Description |
224
+ |-----------|------|----------|-------------|
225
+ | `id` | string | Yes | Message ID to forward |
226
+ | `to` | string[] | Yes | Recipients to forward to |
227
+ | `body` | string | No | Message to prepend |
228
+ | `send` | boolean | No | Send immediately (default: true, false = save as draft) |
229
+
230
+ ---
231
+
232
+ #### `mark-as-read` / `mark-as-unread`
233
+
234
+ Change read status of a message.
235
+
236
+ | Parameter | Type | Required | Description |
237
+ |-----------|------|----------|-------------|
238
+ | `id` | string | Yes | Message ID |
239
+
240
+ ---
241
+
242
+ #### `flag-message` / `unflag-message`
243
+
244
+ Flag or unflag a message.
245
+
246
+ | Parameter | Type | Required | Description |
247
+ |-----------|------|----------|-------------|
248
+ | `id` | string | Yes | Message ID |
249
+
250
+ ---
251
+
252
+ #### `delete-message`
253
+
254
+ Delete a message (move to trash).
255
+
256
+ | Parameter | Type | Required | Description |
257
+ |-----------|------|----------|-------------|
258
+ | `id` | string | Yes | Message ID |
259
+
260
+ ---
261
+
262
+ #### `move-message`
263
+
264
+ Move a message to a different mailbox.
265
+
266
+ | Parameter | Type | Required | Description |
267
+ |-----------|------|----------|-------------|
268
+ | `id` | string | Yes | Message ID |
269
+ | `mailbox` | string | Yes | Destination mailbox |
270
+ | `account` | string | No | Account containing mailbox |
271
+
272
+ ---
273
+
274
+ ### Mailbox Operations
275
+
276
+ #### `list-mailboxes`
277
+
278
+ List all mailboxes for an account.
279
+
280
+ | Parameter | Type | Required | Description |
281
+ |-----------|------|----------|-------------|
282
+ | `account` | string | No | Account to list from |
283
+
284
+ **Returns:** List of mailbox names with unread counts.
285
+
286
+ ---
287
+
288
+ #### `get-unread-count`
289
+
290
+ Get unread message count.
291
+
292
+ | Parameter | Type | Required | Description |
293
+ |-----------|------|----------|-------------|
294
+ | `mailbox` | string | No | Mailbox to check (omit for total) |
295
+ | `account` | string | No | Account to check |
296
+
297
+ ---
298
+
299
+ ### Account Operations
300
+
301
+ #### `list-accounts`
302
+
303
+ List all configured Mail accounts.
304
+
305
+ **Parameters:** None
306
+
307
+ **Returns:** List of account names (e.g., "iCloud", "Gmail", "Exchange").
308
+
309
+ ---
310
+
311
+ ### Diagnostics
312
+
313
+ #### `health-check`
314
+
315
+ Verify Mail.app connectivity and permissions.
316
+
317
+ **Parameters:** None
318
+
319
+ **Returns:** Status of all health checks (app running, permissions, account access).
320
+
321
+ ---
322
+
323
+ #### `get-mail-stats`
324
+
325
+ Get mail statistics (total messages, unread counts per account).
326
+
327
+ **Parameters:** None
328
+
329
+ **Returns:** Total counts and per-account breakdown.
330
+
331
+ ---
332
+
333
+ ## Usage Patterns
334
+
335
+ ### Basic Workflow
336
+
337
+ ```
338
+ User: "Check my inbox for new emails"
339
+ AI: [calls list-messages with mailbox="INBOX"]
340
+ "You have 12 messages in your inbox. Here are the most recent..."
341
+
342
+ User: "Show me emails from Sarah"
343
+ AI: [calls search-messages with query="Sarah"]
344
+ "Found 3 emails from Sarah..."
345
+
346
+ User: "Read the first one"
347
+ AI: [calls get-message with id="..."]
348
+ "Subject: Project Update..."
349
+ ```
350
+
351
+ ### Working with Accounts
352
+
353
+ By default, operations use the first configured account. To work with specific accounts:
354
+
355
+ ```
356
+ User: "What email accounts do I have?"
357
+ AI: [calls list-accounts]
358
+ "You have 3 accounts: iCloud, Gmail, Work Exchange"
359
+
360
+ User: "Show unread emails in my Work account"
361
+ AI: [calls list-messages with account="Work Exchange", mailbox="INBOX"]
362
+ "Your Work account has 5 unread messages..."
363
+ ```
364
+
365
+ ### Sending Emails Safely
366
+
367
+ ```
368
+ User: "Draft an email to the team about the deadline"
369
+ AI: [calls create-draft with to=["team@..."], subject="...", body="..."]
370
+ "I've created a draft. Please review it in Mail.app before sending."
371
+
372
+ User: "Send it"
373
+ AI: [User opens Mail.app and sends manually, or AI calls send-email]
374
+ ```
375
+
376
+ ### Organizing Messages
377
+
378
+ ```
379
+ User: "Move all newsletters to Archive"
380
+ AI: [calls search-messages to find newsletters]
381
+ AI: [calls move-message for each, with mailbox="Archive"]
382
+ "Moved 8 newsletters to Archive"
383
+ ```
384
+
385
+ ---
386
+
387
+ ## Installation Options
388
+
389
+ ### npm (Recommended)
390
+
391
+ ```bash
392
+ npm install -g github:sweetrb/apple-mail-mcp
393
+ ```
394
+
395
+ ### From Source
396
+
397
+ ```bash
398
+ git clone https://github.com/sweetrb/apple-mail-mcp.git
399
+ cd apple-mail-mcp
400
+ npm install
401
+ npm run build
402
+ ```
403
+
404
+ If installed from source, use this configuration:
405
+ ```json
406
+ {
407
+ "mcpServers": {
408
+ "apple-mail": {
409
+ "command": "node",
410
+ "args": ["/path/to/apple-mail-mcp/build/index.js"]
411
+ }
412
+ }
413
+ }
414
+ ```
415
+
416
+ ---
417
+
418
+ ## Security and Privacy
419
+
420
+ - **Local only** - All operations happen locally via AppleScript. No data is sent to external servers.
421
+ - **Permission required** - macOS will prompt for automation permission on first use.
422
+ - **No credential storage** - The server doesn't store any passwords or authentication tokens.
423
+ - **Email safety** - Use `create-draft` to review emails before sending.
424
+
425
+ ---
426
+
427
+ ## Known Limitations
428
+
429
+ | Limitation | Reason |
430
+ |------------|--------|
431
+ | macOS only | Apple Mail and AppleScript are macOS-specific |
432
+ | Plain text only | Email body is plain text; HTML formatting not supported |
433
+ | No attachments | Cannot add or read attachments via AppleScript |
434
+ | Message ID scope | Message IDs are searched across all mailboxes (may be slow with large mailboxes) |
435
+ | No smart mailboxes | Cannot access Smart Mailboxes via AppleScript |
436
+
437
+ ### Backslash Escaping (Important for AI Agents)
438
+
439
+ When sending content containing backslashes (`\`) to this MCP server, **you must escape them as `\\`** in the JSON parameters.
440
+
441
+ **Why:** The MCP protocol uses JSON for parameter passing. In JSON, a single backslash is an escape character. To include a literal backslash in content, it must be escaped as `\\`.
442
+
443
+ **Example - Email with file path:**
444
+ ```json
445
+ {
446
+ "to": ["colleague@company.com"],
447
+ "subject": "File Location",
448
+ "body": "The file is at C:\\\\Users\\\\Documents\\\\report.pdf"
449
+ }
450
+ ```
451
+
452
+ The `\\\\` in JSON becomes `\\` in the actual string, which represents a single `\` in the email.
453
+
454
+ **Common patterns requiring escaping:**
455
+ - Windows paths: `C:\Users\` → `C:\\\\Users\\\\` in JSON
456
+ - Shell escaped spaces: `Mobile\ Documents` → `Mobile\\\\ Documents` in JSON
457
+ - Regex patterns: `\d+` → `\\\\d+` in JSON
458
+
459
+ **If you see errors** when sending emails with backslashes, double-check that backslashes are properly escaped in the JSON payload.
460
+
461
+ ---
462
+
463
+ ## Troubleshooting
464
+
465
+ ### "Mail.app not responding"
466
+ - Ensure Mail.app is not frozen
467
+ - Try opening Mail.app manually
468
+ - Restart the MCP server
469
+
470
+ ### "Permission denied"
471
+ - macOS needs automation permission
472
+ - Go to System Preferences > Privacy & Security > Automation
473
+ - Ensure your terminal/Claude has permission to control Mail
474
+
475
+ ### "Message not found"
476
+ - Message may have been deleted or moved
477
+ - Message IDs change if the message is moved between mailboxes
478
+ - Use `search-messages` to find the current message ID
479
+
480
+ ### "Account not found"
481
+ - Account names must match exactly (case-sensitive)
482
+ - Use `list-accounts` to see exact account names
483
+
484
+ ### "Failed to send email"
485
+ - Check your network connection
486
+ - Verify Mail.app can send emails manually
487
+ - Check if the account is configured correctly in Mail.app
488
+
489
+ ---
490
+
491
+ ## Development
492
+
493
+ ```bash
494
+ npm install # Install dependencies
495
+ npm run build # Compile TypeScript
496
+ npm test # Run test suite (28 tests)
497
+ npm run lint # Check code style
498
+ npm run format # Format code
499
+ ```
500
+
501
+ ---
502
+
503
+ ## Author
504
+
505
+ **Rob Sweet** - President, [Superior Technologies Research](https://www.superiortech.io)
506
+
507
+ A software consulting, contracting, and development company.
508
+
509
+ - Email: rob@superiortech.io
510
+ - GitHub: [@sweetrb](https://github.com/sweetrb)
511
+
512
+ ## License
513
+
514
+ MIT License - see [LICENSE](LICENSE) for details.
515
+
516
+ ## Contributing
517
+
518
+ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
519
+
520
+ ## Related Projects
521
+
522
+ - [apple-notes-mcp](https://github.com/sweetrb/apple-notes-mcp) - MCP server for Apple Notes
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Apple Mail MCP Server
4
+ *
5
+ * A Model Context Protocol (MCP) server that provides AI assistants
6
+ * with the ability to interact with Apple Mail on macOS.
7
+ *
8
+ * This server exposes tools for:
9
+ * - Reading and searching emails
10
+ * - Sending emails
11
+ * - Managing mailboxes
12
+ * - Managing multiple accounts (iCloud, Gmail, Exchange, etc.)
13
+ *
14
+ * Architecture:
15
+ * - Tool definitions are declarative (schema + handler)
16
+ * - The AppleMailManager class handles all AppleScript operations
17
+ * - Error handling is consistent across all tools
18
+ *
19
+ * @module apple-mail-mcp
20
+ * @see https://modelcontextprotocol.io
21
+ */
22
+ export {};
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;GAmBG"}