apple-mail-mcp 2.8.5 → 2.8.7
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/README.md +26 -14
- package/build/cli.js +11 -4
- package/build/index.js +175 -104
- package/docs/IMAP-SETUP.md +333 -0
- package/docs/NODE-RUNTIME-AND-TCC-PERMISSIONS.md +109 -0
- package/docs/STABILITY-PERF-AUDIT-2026-06-17.md +131 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that e
|
|
|
12
12
|
[](https://modelcontextprotocol.io)
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
|
-
<img src="codex/assets/screenshot.png" alt="Apple Mail MCP — read, search, send, and organize Apple Mail from Codex, Claude, and other AI assistants" width="680">
|
|
15
|
+
<img src="https://raw.githubusercontent.com/sweetrb/apple-mail-mcp/main/codex/assets/screenshot.png" alt="Apple Mail MCP — read, search, send, and organize Apple Mail from Codex, Claude, and other AI assistants" width="680">
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
18
|
> **Note:** This is the **npm/Node.js** package — install with `npx` or `npm`. There is an unrelated Python project of the same name on PyPI ([`imdinu/apple-mail-mcp`](https://github.com/imdinu/apple-mail-mcp)) installed via `pipx`/`uvx`. If you're using `uvx` and seeing a `cyclopts` dependency error, you're looking for that project, not this one.
|
|
@@ -43,6 +43,12 @@ Install the sweetrb/apple-mail-mcp MCP server so you can help me manage my Apple
|
|
|
43
43
|
|
|
44
44
|
Claude will handle the installation and configuration automatically.
|
|
45
45
|
|
|
46
|
+
Or register it deterministically in one command:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
claude mcp add apple-mail -s user -- npx -y apple-mail-mcp
|
|
50
|
+
```
|
|
51
|
+
|
|
46
52
|
### Using the Plugin Marketplace
|
|
47
53
|
|
|
48
54
|
Install as a Claude Code plugin for automatic configuration and enhanced AI behavior:
|
|
@@ -54,6 +60,11 @@ Install as a Claude Code plugin for automatic configuration and enhanced AI beha
|
|
|
54
60
|
|
|
55
61
|
This method also installs a **skill** that teaches Claude when and how to use Apple Mail effectively.
|
|
56
62
|
|
|
63
|
+
> **Configuring IMAP/SMTP for a plugin install:** a plugin install has no editable `env` block,
|
|
64
|
+
> so supply settings via the config file at `~/Library/Application Support/apple-mail-mcp/config.json`
|
|
65
|
+
> — Method B in the [IMAP / SMTP Setup Guide](https://github.com/sweetrb/apple-mail-mcp/blob/main/docs/IMAP-SETUP.md).
|
|
66
|
+
> Passwords stay in the macOS Keychain; run the `doctor` tool to verify.
|
|
67
|
+
|
|
57
68
|
### Using the Codex Marketplace
|
|
58
69
|
|
|
59
70
|
Install the same public marketplace in Codex:
|
|
@@ -69,14 +80,14 @@ The Codex package registers the same `apple-mail` MCP server through `npx -y app
|
|
|
69
80
|
|
|
70
81
|
Configuration for two more hosts is included — each registers the same `apple-mail` MCP server (`npx -y apple-mail-mcp`):
|
|
71
82
|
|
|
72
|
-
- **[Hermes Agent](https://hermes-agent.nousresearch.com/)** (NousResearch) — Hermes has no plugin/marketplace drop-in. Add the server with `hermes mcp add apple-mail --command npx --args -y apple-mail-mcp`, or merge [`.hermes-plugin/config.yaml`](.hermes-plugin/config.yaml) into `~/.hermes/config.yaml`. Details: [`.hermes-plugin/README.md`](.hermes-plugin/README.md).
|
|
73
|
-
- **[Antigravity](https://antigravity.google/)** (Google) — add the server entry from [`.antigravity-plugin/mcp_config.json`](.antigravity-plugin/mcp_config.json) to `~/.gemini/config/mcp_config.json` (or via Antigravity's MCP settings).
|
|
83
|
+
- **[Hermes Agent](https://hermes-agent.nousresearch.com/)** (NousResearch) — Hermes has no plugin/marketplace drop-in. Add the server with `hermes mcp add apple-mail --command npx --args -y apple-mail-mcp`, or merge [`.hermes-plugin/config.yaml`](https://github.com/sweetrb/apple-mail-mcp/blob/main/.hermes-plugin/config.yaml) into `~/.hermes/config.yaml`. Details: [`.hermes-plugin/README.md`](https://github.com/sweetrb/apple-mail-mcp/blob/main/.hermes-plugin/README.md).
|
|
84
|
+
- **[Antigravity](https://antigravity.google/)** (Google) — add the server entry from [`.antigravity-plugin/mcp_config.json`](https://github.com/sweetrb/apple-mail-mcp/blob/main/.antigravity-plugin/mcp_config.json) to `~/.gemini/config/mcp_config.json` (or via Antigravity's MCP settings).
|
|
74
85
|
|
|
75
86
|
### Manual Installation
|
|
76
87
|
|
|
77
88
|
**1. Install the server:**
|
|
78
89
|
```bash
|
|
79
|
-
npm install -g
|
|
90
|
+
npm install -g apple-mail-mcp
|
|
80
91
|
```
|
|
81
92
|
|
|
82
93
|
**2. Add to Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
@@ -113,7 +124,7 @@ Both are driven by non-secret `APPLE_MAIL_MCP_*` settings — supplied via an `e
|
|
|
113
124
|
block **or** a `config.json` file (for hosts like Claude Desktop that strip `env`)
|
|
114
125
|
— with passwords kept in the macOS **Keychain**, never in config.
|
|
115
126
|
|
|
116
|
-
👉 **[IMAP / SMTP Setup Guide](docs/IMAP-SETUP.md)** — step-by-step: app passwords,
|
|
127
|
+
👉 **[IMAP / SMTP Setup Guide](https://github.com/sweetrb/apple-mail-mcp/blob/main/docs/IMAP-SETUP.md)** — step-by-step: app passwords,
|
|
117
128
|
Keychain, both config methods, multi-account, SMTP, verification with the `doctor`
|
|
118
129
|
tool, and troubleshooting. Verify any time by running the **`doctor`** tool.
|
|
119
130
|
|
|
@@ -381,7 +392,7 @@ SMTP not configured.
|
|
|
381
392
|
|
|
382
393
|
##### IMAP backend — opt-in
|
|
383
394
|
|
|
384
|
-
> 📘 **For step-by-step setup (app passwords, Keychain, config methods, multi-account, upgrading, troubleshooting), see the [IMAP / SMTP Setup Guide](docs/IMAP-SETUP.md).** The summary below is the reference; the guide is the walkthrough.
|
|
395
|
+
> 📘 **For step-by-step setup (app passwords, Keychain, config methods, multi-account, upgrading, troubleshooting), see the [IMAP / SMTP Setup Guide](https://github.com/sweetrb/apple-mail-mcp/blob/main/docs/IMAP-SETUP.md).** The summary below is the reference; the guide is the walkthrough.
|
|
385
396
|
|
|
386
397
|
AppleScript runs `search`/`list` predicates client-side over the Apple Event
|
|
387
398
|
bridge, which is slow and can time out (false-empty) on large Gmail/IMAP
|
|
@@ -1133,7 +1144,7 @@ AI: [calls move-message for each, with mailbox="Archive"]
|
|
|
1133
1144
|
### npm (Recommended)
|
|
1134
1145
|
|
|
1135
1146
|
```bash
|
|
1136
|
-
npm install -g
|
|
1147
|
+
npm install -g apple-mail-mcp
|
|
1137
1148
|
```
|
|
1138
1149
|
|
|
1139
1150
|
### From Source
|
|
@@ -1145,6 +1156,8 @@ cd apple-mail-mcp
|
|
|
1145
1156
|
|
|
1146
1157
|
The repo ships prebuilt, dependency-free `build/index.js` and `build/cli.js` bundles, so a bare clone runs with nothing but Node installed. `npm install` and `npm run build` are only needed when you change the source.
|
|
1147
1158
|
|
|
1159
|
+
> You can also install straight from GitHub with `npm install -g github:sweetrb/apple-mail-mcp`, but that builds from source (requires pnpm) — prefer the registry package above.
|
|
1160
|
+
|
|
1148
1161
|
If installed from source, use this configuration:
|
|
1149
1162
|
```json
|
|
1150
1163
|
{
|
|
@@ -1189,13 +1202,12 @@ The entrypoint is written as:
|
|
|
1189
1202
|
| Limitation | Reason |
|
|
1190
1203
|
|------------|--------|
|
|
1191
1204
|
| macOS only | Apple Mail and AppleScript are macOS-specific |
|
|
1192
|
-
|
|
|
1205
|
+
| MCP `send-email` is plain-text | The `send-email` tool sends plain text (reading HTML content is supported). To send HTML, use the bundled `apple-mail-send` CLI with `--html-body-file` (sends `multipart/alternative` via SMTP) |
|
|
1193
1206
|
| Attachments require absolute paths | File attachments must use full absolute paths (e.g., `/Users/me/file.pdf`) |
|
|
1194
1207
|
| No smart mailboxes | Cannot access Smart Mailboxes via AppleScript |
|
|
1195
1208
|
| Very large mailboxes not searchable *via AppleScript* | Apple Mail's AppleScript bridge times out on mailboxes with tens of thousands of messages, so unscoped `search-messages` skips mailboxes above `APPLE_MAIL_MAX_SEARCH_MAILBOX` (default 5000) and reports them as a partial result. Scope with `mailbox` + a date window — or configure the [IMAP backend](#imap-backend--opt-in), which searches these server-side in well under a second. ([#24](https://github.com/sweetrb/apple-mail-mcp/issues/24)) |
|
|
1196
1209
|
| Can't delete/rename server-side mailboxes or mutate drafts *via AppleScript* | Mail.app's AppleScript bridge can only `delete`/`rename` **local "On My Mac"** mailboxes and cannot delete/move drafts — it throws `AppleEvent handler failed` for IMAP/Gmail/Workspace/iCloud/Exchange mailboxes (the GUI can do it). Without IMAP configured, `delete-mailbox`/`rename-mailbox`/`delete-message`/`move-message` return a clear "do it in Mail.app directly" error instead of a generic failure. With the [IMAP backend](#imap-backend--opt-in) configured for the account, these operations run via IMAP and succeed. ([#42](https://github.com/sweetrb/apple-mail-mcp/issues/42)) |
|
|
1197
|
-
|
|
|
1198
|
-
| Numeric-only message IDs | Message IDs must contain only digits (validated by schema) |
|
|
1210
|
+
| Message ID format | Message IDs must be numeric (AppleScript ids) or `imap:…` tokens from the IMAP read path (validated by schema) |
|
|
1199
1211
|
| Batch size cap | Batch operations are limited to 100 messages per request |
|
|
1200
1212
|
| Date filter format | Date filters must be valid parseable dates (e.g., "January 1, 2026" or "2026-03-15"); bare numbers or non-date strings are rejected |
|
|
1201
1213
|
| Attachment save path restrictions | `save-attachment` only allows saving to home directory, `/tmp`, `/private/tmp`, and `/Volumes`; path traversal is blocked |
|
|
@@ -1259,7 +1271,7 @@ The `\\\\` in JSON becomes `\\` in the actual string, which represents a single
|
|
|
1259
1271
|
|
|
1260
1272
|
### "Permission denied"
|
|
1261
1273
|
- macOS needs automation permission
|
|
1262
|
-
- Go to System
|
|
1274
|
+
- Go to System Settings > Privacy & Security > Automation
|
|
1263
1275
|
- Ensure your terminal/Claude has permission to control Mail
|
|
1264
1276
|
|
|
1265
1277
|
### "Message not found"
|
|
@@ -1315,11 +1327,11 @@ A software consulting, contracting, and development company.
|
|
|
1315
1327
|
|
|
1316
1328
|
## License
|
|
1317
1329
|
|
|
1318
|
-
MIT License - see [LICENSE](LICENSE) for details.
|
|
1330
|
+
MIT License - see [LICENSE](https://github.com/sweetrb/apple-mail-mcp/blob/main/LICENSE) for details.
|
|
1319
1331
|
|
|
1320
1332
|
## Contributing
|
|
1321
1333
|
|
|
1322
|
-
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
1334
|
+
Contributions are welcome! Please see [CONTRIBUTING.md](https://github.com/sweetrb/apple-mail-mcp/blob/main/CONTRIBUTING.md) for guidelines.
|
|
1323
1335
|
|
|
1324
1336
|
## Related Projects
|
|
1325
1337
|
|
|
@@ -1331,4 +1343,4 @@ Part of a family of macOS MCP servers:
|
|
|
1331
1343
|
|
|
1332
1344
|
## Recurring macOS permission prompts
|
|
1333
1345
|
|
|
1334
|
-
If macOS keeps re-prompting for Full Disk Access or Automation for `node` (often after a `brew upgrade`), see [docs/NODE-RUNTIME-AND-TCC-PERMISSIONS.md](docs/NODE-RUNTIME-AND-TCC-PERMISSIONS.md) — the fix is to run this server under the official, Developer-ID-signed Node so the grant survives Node updates.
|
|
1346
|
+
If macOS keeps re-prompting for Full Disk Access or Automation for `node` (often after a `brew upgrade`), see [docs/NODE-RUNTIME-AND-TCC-PERMISSIONS.md](https://github.com/sweetrb/apple-mail-mcp/blob/main/docs/NODE-RUNTIME-AND-TCC-PERMISSIONS.md) — the fix is to run this server under the official, Developer-ID-signed Node so the grant survives Node updates.
|
package/build/cli.js
CHANGED
|
@@ -11868,6 +11868,12 @@ var import_nodemailer = __toESM(require_nodemailer(), 1);
|
|
|
11868
11868
|
import { execFileSync } from "child_process";
|
|
11869
11869
|
import { isAbsolute } from "path";
|
|
11870
11870
|
import { existsSync } from "fs";
|
|
11871
|
+
|
|
11872
|
+
// src/utils/docsUrls.ts
|
|
11873
|
+
var SETUP_GUIDE_URL = "https://github.com/sweetrb/apple-mail-mcp/blob/main/docs/IMAP-SETUP.md";
|
|
11874
|
+
var SETUP_HINT = `Setup guide: ${SETUP_GUIDE_URL} \u2014 run the "doctor" tool to check your setup.`;
|
|
11875
|
+
|
|
11876
|
+
// src/services/smtpMailer.ts
|
|
11871
11877
|
var SMTP_ENV = {
|
|
11872
11878
|
host: "APPLE_MAIL_MCP_SMTP_HOST",
|
|
11873
11879
|
port: "APPLE_MAIL_MCP_SMTP_PORT",
|
|
@@ -11900,7 +11906,7 @@ function resolveSmtpConfig(env = process.env) {
|
|
|
11900
11906
|
if (!user) missing.push(SMTP_ENV.user);
|
|
11901
11907
|
if (missing.length > 0) {
|
|
11902
11908
|
throw new Error(
|
|
11903
|
-
`SMTP transport is not configured. Set ${missing.join(" and ")} (plus a password via ${SMTP_ENV.password} or the Keychain).
|
|
11909
|
+
`SMTP transport is not configured. Set ${missing.join(" and ")} (plus a password via ${SMTP_ENV.password} or the Keychain). ` + SETUP_HINT
|
|
11904
11910
|
);
|
|
11905
11911
|
}
|
|
11906
11912
|
const secure = /^(1|true|yes)$/i.test(env[SMTP_ENV.secure]?.trim() ?? "");
|
|
@@ -11917,7 +11923,7 @@ function resolveSmtpConfig(env = process.env) {
|
|
|
11917
11923
|
}
|
|
11918
11924
|
if (!pass) {
|
|
11919
11925
|
throw new Error(
|
|
11920
|
-
`No SMTP password found. Set ${SMTP_ENV.password}, or store an internet password in the Keychain for service "${env[SMTP_ENV.keychainService]?.trim() || host}" / account "${env[SMTP_ENV.keychainAccount]?.trim() || user}"
|
|
11926
|
+
`No SMTP password found. Set ${SMTP_ENV.password}, or store an internet password in the Keychain for service "${env[SMTP_ENV.keychainService]?.trim() || host}" / account "${env[SMTP_ENV.keychainAccount]?.trim() || user}". ` + SETUP_HINT
|
|
11921
11927
|
);
|
|
11922
11928
|
}
|
|
11923
11929
|
return { host, port, secure, user, pass, from };
|
|
@@ -12003,7 +12009,8 @@ Optional:
|
|
|
12003
12009
|
--help Show this help
|
|
12004
12010
|
|
|
12005
12011
|
SMTP connection comes from ${SMTP_ENV.host} / ${SMTP_ENV.user} (+ password via
|
|
12006
|
-
${SMTP_ENV.password} or the macOS Keychain).
|
|
12012
|
+
${SMTP_ENV.password} or the macOS Keychain). Setup guide:
|
|
12013
|
+
${SETUP_GUIDE_URL}`;
|
|
12007
12014
|
async function runCli(argv, deps = {}) {
|
|
12008
12015
|
const send = deps.send ?? sendViaSmtp;
|
|
12009
12016
|
const resolveConfig = deps.resolveConfig ?? resolveSmtpConfig;
|
|
@@ -12052,7 +12059,7 @@ async function runCli(argv, deps = {}) {
|
|
|
12052
12059
|
config = resolveConfig(env);
|
|
12053
12060
|
} catch (e) {
|
|
12054
12061
|
err(e instanceof Error ? e.message : String(e));
|
|
12055
|
-
err(`
|
|
12062
|
+
err(`Setup guide: ${SETUP_GUIDE_URL}`);
|
|
12056
12063
|
return EX_CONFIG;
|
|
12057
12064
|
}
|
|
12058
12065
|
let body;
|