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 CHANGED
@@ -12,7 +12,7 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that e
12
12
  [![MCP](https://img.shields.io/badge/MCP-server-blue)](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 github:sweetrb/apple-mail-mcp
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 github:sweetrb/apple-mail-mcp
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
- | No sending HTML email | Emails are sent as plain text; reading HTML content is supported |
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
- | In-memory templates | Email templates are not persisted across server restarts |
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 Preferences > Privacy & Security > Automation
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). See the README "SMTP transport" section.`
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). See the README "SMTP transport".`;
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(`See the README "SMTP transport" section.`);
12062
+ err(`Setup guide: ${SETUP_GUIDE_URL}`);
12056
12063
  return EX_CONFIG;
12057
12064
  }
12058
12065
  let body;