# Reported issues for che-apple-mail-mcp

Pod holds 24 of 214 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to [che-apple-mail-mcp](/mcp/che-apple-mail-mcp).

## Most discussed

### [refactor] AppleScript fallback display_name disambiguation — apply account_id resolution sweep to ~14 remaining tools (sister concern from #101)

## Problem

> **Source**: surfaced during `/idd-diagnose #101 #102` sister concern surfacing (Step 3.6) on 2026-05-15. See PsychQuant/che-apple-mail-mcp#101 diagnosis comment for the root cause analysis.

The display_name collision defect documented in #101 affects `save_attachment` because it falls through to Tier 2 AppleScript when Tier 1 throws. The same defect — `mailboxRef`/`msgRef` building `(first mailbox of account "<display_name>" whose name is "...")` at `Sources/CheAppleMailMCP/AppleS

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/104) · 2026-05-15 · closed · 17 comments

### bug(create_draft/compose_email): MCP 寫入的 body 被包成 <blockquote type="cite"> 引文格式（Apple-Mail-URLShare* wrapper）— 收件端顯示為被引用內容，手機版尤其嚴重

## Problem

透過 MCP（`create_draft` / `compose_email` / `reply_email`）寫入的 email **本文內容**會被包進 `<blockquote type="cite">`，並帶 `Apple-Mail-URLShareUserContentTopClass` / `Apple-Mail-URLShareWrapperClass` 這些 class。結果收件端（尤其手機版 Mail / Gmail app 等會對 `blockquote type=cite` 套用引用樣式的 client）把**你自己寫的新內容**顯示成「被引用的內容」（縮排、灰底、左側直線、或摺疊成「⋯」），看起來像在回覆／引述別人，而不是正文。

使用者原話：

> 還有一個 che-apple-mail mcp 的大問題，寫出來好像都會變成引文格式，手機版看就會有大問題

### 第一手證據（本 session 實際寄出的信）

`create_draft(format="plain")` 建立、之後寄出的 issue（中研院計算資源申請，sent m

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/175) · 2026-06-02 · closed · 12 comments

### 移除 legacy compose path — display-name cc/bcc 靜默觸發 cite-block wrapper，對外正式信件已實際受害（#277 的後果）

## Problem

> **Original text**（2026-07-29 00:53）：
> 「legacy path 我覺得要整個全部砍掉，不然又匯出這個問題，因為這問題很嚴重，保留legency會直接爆炸」

`create_draft` / `update_draft` 在 clean（wrapper-free）path 前提不滿足時會**靜默退回 legacy path**，把 body 包進 `<blockquote type="cite">`。觸發條件之一是 **cc/bcc 帶 display name**（`姓名 <email>`）—— #277 已記載 clean path 的 GUI fill 是 **To-only**。

呼叫端在組信時，沒有理由預期「幫 cc 加上人名」會關掉 clean body。

## Type

refactor

## Priority

P1 — 已造成不可回收的對外損害，且觸發條件平凡（幫收件人加名字）。

## Expected

compose 類工具（`create_draft` / `update_draft`

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/304) · 2026-07-28 · closed · 9 comments

### archive-mail 大批歸檔應強制走 export_emails_markdown（考慮改名 batch_export_emails_markdown）

## Problem

> **Original text**（使用者，2026-07-06，於一次大批郵件歸檔中）:
> 「63 封逐一 get_email 會很吃 token——mail MCP 有 export_emails_markdown 批次匯出工具（search 說明有提到）。... 我覺得必須要強迫使用 export_emails_markdown 來匯出信件欸，是不是要改名 batch_export_emails_markdown」

`export_emails_markdown`（server-side bulk export，#193 / binary v2.13.0）已存在，但 `/archive-mail` 的文件流程 **Step 5「生成 Markdown」仍以 per-email `get_email(format='text')` 逐封 fetch + client-side transcription 為主路徑**。

結果：AI 執行大批歸檔（實測一次 63 封）時，會照 Step 5 的文字逐封 `get_email`，浪費 token 且慢—

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/232) · 2026-07-06 · closed · 8 comments

### feat(compose): verified sender-popup so custom from_address can use the clean mailto path (follow-up from #175)

## Problem

#175 (PR #217) routes `compose_email` / `create_draft` through the wrapper-free `mailto:` path, but **only when no custom `from_address` is set** — `mailto:` always composes from the default account, and selecting a different account would require driving the compose window's sender popup. A wrong pick would **send from the wrong account**, so #175 conservatively falls back to the legacy `set sender` path (correct sender, but body wrapped) whenever `from_address` is given.

## Direct

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/219) · 2026-06-24 · closed · 7 comments

### bug(AppleScript fallback): SQLite 工具輸出的 account_name（email）與 Mail AppleScript account name（帳號描述）namespace 不同 — ~14 工具 display_name fallback 結構性 -1728 (sister concern from #173)

## Problem

`save_attachment` 的診斷（#173 缺陷 (3)）發現一個**系統性** namespace 落差，影響範圍不限於 save_attachment：

- SQLite 路徑工具（`search_emails` / `list_attachments` / `list_emails` 等）輸出的 `account_name` 來自 `AccountMapper`（`Sources/MailSQLite/AccountMapper.swift:35-36`，AccountsMap.plist 解析出的 **email**，如 `kiki830621@gmail.com`）
- AppleScript-routed 工具的 display_name fallback（`resolveAccountRef`，`Sources/CheAppleMailMCP/AppleScript/AppleScriptRefBuilder.swift`）產出 `account "<name>"`，比對的是 Mail AppleScript 的 account `na

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/176) · 2026-06-10 · closed · 7 comments

### bug: get_email returns raw base64 instead of decoded body for multipart messages from Android Gmail

## Problem

`get_email(format='text')` 對某些 email(觀察到從 Android Gmail app 寄出的 multipart 郵件)回傳 `html_body` 是**未解碼的 base64 MIME 字串**,而非預期的 plain text 或 decoded HTML。

## Type
bug

## Reproducer

呼叫:
```
mcp__plugin_che-apple-mail-mcp_mail__get_email(
  id: "272572",
  mailbox: "收件匣",
  account_name: "d06227105@ntu.edu.tw",
  format: "text"
)
```

對應 email metadata:
- subject: `Re: Solution? (affine repre + Iverson's law of similarity)`
- sender: `Yung-Fong Hsu <yfhsu@ntu.edu.tw>`
- message_id: `<177

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/72) · 2026-05-07 · closed · 7 comments

### feat: reply-as-draft mode (preserve thread + cc + attachments + queue for human review)

## Use case (使用者原話)

> 我發現她好像無法真的用回信，只能用草稿，這有辦法克服嗎

實際情境（2026-05-02）:
- 使用者要 reply 一個現存 thread（yijulee@stat.sinica.edu.tw 的 4/29 onboarding paperwork 信件）
- 需要的 combo: **保留 thread**（In-Reply-To 連續）+ **加 CC**（cchen + 林助理）+ **附 3 個 PDF**（cv-llt + 博士證書 + reprint）+ **存 draft 等手動審後再寄出**

目前可用的 tool 都各缺一塊，combo 不存在。

## Current tool gap

| Tool | 保留 thread | CC param | Attachments param | Draft (vs send) | account_name |
|------|------------|---------|------------------|----------------|--------------|

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/33) · 2026-05-02 · closed · 7 comments

## Most recent

### first-run FDA assist 把四值的 --check-fda --quiet 當布林用：noMailData 會謊報未授權並燒掉 once-only marker

## 症狀

`plugin/hooks/session-start.sh` 的 first-run FDA assist 把一個**四值**的結束碼契約當成布林用，因此在兩個狀態下**說了不實的話，並且燒掉 once-only marker**——使用者之後再也不會拿到這個 assist。

## 契約 vs 用法

`Sources/CheAppleMailMCP/SetupCLI.swift` 明確定義四個狀態（#355 加的，正是為了讓 script 不必 parse 散文）：

```swift
enum ExitStatus: Int32 {
    case granted      = 0
    case denied       = 1
    case noMailData   = 2
    case undetermined = 3
}
```

hook 端只有一行：

```bash
"$binary" --check-fda --quiet >/dev/null 2>&1 && return 0
```

`0` 以外全部落進「未授權 → 提示 + 開設

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/403) · 2026-08-26 · open · 0 comments

### save_attachment 的 save_path 無 path containment — 寄件人可控檔名可寫任意路徑

## 症狀

`save_attachment` 的 `save_path` **沒有任何 path containment**：不限制 root、不檢查 `..`、不檢查 symlink，而且會主動 `mkdir -p` 把父目錄建出來再寫檔。攻擊者控制的字串（MIME `Content-Disposition: filename=`、inline `cid:`、HTML `alt`）若被呼叫端拿去組 `save_path`，就是一條**直達的任意檔案寫入**。

## 證據

`Sources/CheAppleMailMCP/Server.swift:1497` 的 handler 對 `save_path` 只做一件事：

```swift
try ensureSaveDestinationDirectory(savePath)
```

而該函式（`Server.swift:2932-2964`）的全部檢查是：

1. `savePath.hasPrefix("/") && !savePath.hasSuffix("/")` — 只驗「絕對路徑且不以 `/` 結尾」
2. `f

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/402) · 2026-08-26 · open · 0 comments

### docs: 版本敘事四個表面互相矛盾 — plugin.json 巨型 description、plugin/README 版本表、plugin/CHANGELOG、實際 pin 各說各話 (#335 verify)

## Problem

#335 verify 發現對外可見的**版本敘事**在多個表面互相矛盾（marketplace entry 那一面已在 verify fix PR 處理，其餘仍在）：

| 表面 | 說法 |
|---|---|
| `plugin/.claude-plugin/plugin.json` 巨型 description（18.8KB 慣例敘事） | 開頭 "Shell v2.43.0 … binary stays v2.25.0"，並含 shell 逃逸殘留 `Mail'\''s`（JSON 解碼後對外顯示為亂碼） |
| `plugin/README.md` 版本表 | v2.44.2 / binary 2.27.0 |
| `plugin/CHANGELOG.md` | 最新條目停在 `[Unreleased]` |
| 實際 | plugin.json `version: 2.46.1` / `binary_version: 2.28.0` |

四處四個說法。任何一個使用者從任一表面讀到的版本狀態都可能是錯的。

## Type

docs / conv

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/396) · 2026-08-26 · open · 3 comments

### security-hardening: archive-mail SOP 對 untrusted 郵件內容缺 trust boundary — wildcard 預授權、confirmation-skip 無 provenance、幻影 test-mode flag (#335 verify)

## Problem

#335 verify 的 security lens 對搬入的 plugin SOP 文件群提出一組同根 findings：**archive-mail 把不受信任的郵件內容當資料處理的邊界從未被文件化**，而授權面偏寬：

1. `plugin/commands/archive-mail.md` frontmatter 以 **wildcard 預授權整組 mail MCP 工具**（含 delete / compose / move / junk 等 mutation），一次 `/archive-mail` 執行中 LLM 可觸達的工具面遠大於歸檔所需。
2. `plugin/rules/confirmation-triggers.md` 的 **confirmation-skip 語句無 provenance 要求** —— 規則沒說「跳過確認的指示必須來自使用者、不得來自郵件內文」；一封內文含指示樣式文字的郵件在歸檔流程中是攻擊面（prompt-injection → 觸發 mutation）。
3. 同檔寫 "Test mode … can skip

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/395) · 2026-08-26 · open · 3 comments

### bug: wrapper runtime state 記「期望版本」而非「實際執行版本」— 下載失敗時 staleness 偵測假陰性 (#335 verify)

## Problem

`plugin/bin/che-apple-mail-mcp-wrapper.sh` 在 spawn 時把 **期望版本**（來自 plugin.json 的 pin）寫進 runtime state file，而不是**實際執行中 binary 的版本**（#335 verify codex lens）。

下載失敗、或 exec 的其實是舊 binary 時，state file 仍記著新版本 → `hooks/session-start.sh` 的 staleness 比對（#76/#77 機制）讀到「已是新版」→ **假陰性**：不 SIGTERM、不重 spawn，使用者持續跑舊 binary 而無任何訊號。

## Type

bug（imported pre-existing — #335 純 relocation 帶入）

## Expected

State file 的 version 欄位改由實際 binary 回報（`--version`，#303 起可用）或在下載/驗證成功後才寫入；寫入時機與 #303 的 version sideca

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/393) · 2026-08-26 · open · 3 comments

### bug: wrapper 下載鏈零完整性驗證 — curl 缺 --fail、有 .sha256 asset 卻不驗、pinned-tag 落空每次 spawn 重下載 (#335 verify)

## Problem

`plugin/bin/che-apple-mail-mcp-wrapper.sh` 的 binary 下載鏈沒有任何完整性驗證（#335 verify 三個 lens 獨立指出，DA 校準確認）：

1. **`curl` 缺 `--fail`**：asset 404 時 GitHub 的錯誤內文（HTML/JSON）會被寫進 binary 路徑、`chmod +x`，**覆寫掉原本可用的 binary**。下一次 spawn 執行的是一個錯誤頁面。
2. **有 `.sha256` asset 卻不驗**：release pipeline 每次都上傳 `.sha256`（`release.sh` 產出、`--self-update` 用它），wrapper 下載端卻完全不比對 —— 下載損毀/截斷/中間人內容一律照裝照跑。
3. **pinned tag 落空 → 每次 spawn 重下載**：`releases/download/<tag>` miss 時 fallback 不 cache 失敗狀態，每次 MCP spawn 都重新打 GitHub（DA 

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/392) · 2026-08-26 · open · 3 comments

### bug: marketplace clone 夾帶 22MB 過期 v2.7.1 build artifacts — tracked 的 mcpb bundle 與 server binary 是雙擊即中的安裝陷阱 (#335 verify)

## Problem

`#335` 把本 repo 變成自營 marketplace 之後，`claude plugin marketplace add PsychQuant/che-apple-mail-mcp` 會把整個 repo clone 到每個使用者的 `~/.claude/plugins/marketplaces/` 底下 —— 連同 **22MB 被 tracked 的過期 build artifacts**：

```
~/.claude/plugins/marketplaces/che-apple-mail-mcp   36M   ← 本 repo（#335 之後）
~/.claude/plugins/marketplaces/che-ical-mcp        3.6M  ← pilot 先例
其中 mcpb/ 佔 22M；實際交付的 plugin 只有 420K
```

tracked 的兩個 artifact（`.gitignore` 規則存在但對已追蹤檔無效）：

- `mcpb/che-apple-mail-mcp.mcpb`（4.6MB）— bun

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/391) · 2026-08-26 · open · 3 comments

### bug: archive-mail-repair-synthetic-ids 在無 Full Disk Access 環境完全跑不動 — Step 2 唯一 relocation 路徑依賴 FDA-gated projection/dedup，且指令文件零揭露

## Problem

`/archive-mail-repair-synthetic-ids` 是 #319 為既有 synthetic `message_id` 佔位符提供的一次性修復工具。但它 **Step 2「重新定位真 Message-ID」的唯一路徑**依賴兩個需要 Full Disk Access 的能力，而指令全文（67 行）沒有任何 fallback、前置檢查或降級揭露。

指令 Step 2 原文：

> ### Step 2: 重新定位真 Message-ID（保守階梯）
>
> 對每檔依序嘗試，**第一個成功即停**：
>
> 1. **Subject 精確搜尋**：`search_emails(field: "subject", query: <bare subject>, projection: "summary", dedup: "logical")` → 候選中 **sender 相同且 date 相差 < 2 分鐘** 者恰好一封 → 用該 id 呼叫 `get_email_headers` 取真 Message-ID。
> 2. 候選為零或多於一封（

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/389) · 2026-08-25 · open · 0 comments

### mailto 8000-char 上限對 CJK body ≈ 850 字：#304 移除 legacy path 後超長無退路，且錯誤是 generic scriptFailed 而非具名可行動類別

## Problem

`maxMailtoURLLength = 8000` 對 CJK body 實際上是 **約 850 個中文字**的天花板：一個 CJK 字元 UTF-8 佔 3 bytes，percent-encode 後成 9 個 ASCII 字元（`%XX%XX%XX`）。一封普通的中文正式書信（多事項請示、開會通知、請假申請）很容易超過。

實測（v2.28.0，`format=plain`，無 attachments，單一 bare-address 收件人，無 `from_address`）：

| 項目 | 值 |
|---|---|
| body 字元數（中文純文字） | 1,279 |
| 產出的 mailto URL 長度 | 9,588 |
| 結果 | `mailto URL too long (9588 > 8000 chars)` → 落 legacy path → body 被包 `<blockquote type="cite">` |

> v2.28.0 **尚未含** #304 的移除 commit `9d04afd`（該 commit 目前

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/388) · 2026-08-21 · open · 0 comments

### repo owner 遷移的殘留掃尾：mcpb/manifest.json、PRIVACY、PROMOTION、plugin/README 仍指 kiki830621（#383 doc-sync sweep 發現）

## Problem

`#383` 修好了兩份 README 的 owner 過時問題，但它的 `/idd-close` Step 6.3 doc-sync sweep 在**完整掃描全 repo** 後發現：`github.com/kiki830621/che-apple-mail-mcp` 的過時引用**不只在 README**，還散落 5 個檔約 15 處，其中包含 **Claude Desktop extension 的發佈 metadata**。

GitHub 的 redirect 讓這些**現在都還能動**，所以沒有任何回饋管道會指出它們 —— 與 `#383` 的失效模式同源：沉默、單向、只能靠人掃。

## Type

docs

## Actual — 逐處清單（已分類，非全部都要改）

### ✅ 要改（repo owner 已遷移至 `PsychQuant`）

| 檔案 | 行 | 性質 |
|---|---|---|
| `plugin/README.md` | 169 | **live 指令** — `### Option 1: From Release

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/387) · 2026-08-18 · open · 0 comments

### 加一道檢查：README 教的安裝指令失效時要發訊號，而不是等使用者撞到

## Problem

**沒有任何機制在檢查「README 教的安裝指令是否還有效」。** 這次（`#383`）是靠人肉發現的——使用者問「這個我安裝嗎」，順手查了一下才撞見。

失效方式是**單向且沉默**的：

- aggregator 端移除 marketplace entry → README 不會產生任何警告
- README 教的指令變成必然失敗 → 沒有 CI、沒有 test、沒有 hook 在對帳
- 唯一的回饋管道是**新使用者實際照做然後失敗**，而失敗訊息（`not found in marketplace`）不指出正確來源

換句話說：這個缺口的偵測延遲 = 「下一個新使用者嘗試安裝並回報」的時間。`#335` 的遷移發生在 2026-08-05 前後，`#383` 修好是 2026-08-18——中間十幾天，任何照 README 走的人都會卡在第二行。

## Type

feature

## Expected

有一個可自動執行的檢查，能在「README 教的安裝指令不再可解析」時**發出訊號**，而不是等人撞到。

## Actual

零檢查。`#3

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/386) · 2026-08-18 · open · 0 comments

### README / README_zh-TW 的 Quick Start 仍教 psychquant umbrella 安裝指令，#335 自營 marketplace 後第二行必然失敗

## Problem

`README.md` 與 `README_zh-TW.md` 的 **Quick Start**（最顯眼的安裝入口）仍教使用者從 `psychquant-claude-plugins` aggregator 安裝。#335 的自營 marketplace 遷移完成後，該 aggregator **已不再列出這個 plugin**，所以照 README 抄的第二行**必然失敗**。

### 逐字原文（`README.md` L36–39，`README_zh-TW.md` 同位置）

> Install the **plugin**. It brings the signed binary, the `/archive-mail` command
> family, the safety rules, and the staleness hook as one unit:
>
> ```bash
> claude plugin marketplace add PsychQuant/psychquant-claude-plugins
> claude plugi

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/383) · 2026-08-17 · closed · 6 comments

### stdout-shutdown has no bounded-exit test because shutdown latency is not deterministic

**Source**: residue from #349 at `/idd-close` time (Step 3.6)

#349 made a failed stdout write end the session, so the server stops executing tool calls whose responses nobody will receive. Measured on the real binary with the stdout read end closed: **before, still running after 30s; after, a diagnostic and a clean exit (~11s).**

That contrast lives in the PR, **not in a test**. `SigpipeDispositionTests` already documents why: shutdown latency is highly variable on the *unmodified* binary too 

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/377) · 2026-08-13 · open · 1 comment

### get_special_mailboxes: two ordinary folders under one parent can corroborate each other

**Source**: residue from #345 at `/idd-close` time (Step 3.6)

#345 made a nested `<type>_path` believable only when **another** special mailbox resolves under the same parent container — `[Gmail]` holds drafts/sent/junk/trash, an ordinary folder that happens to share one leaf name holds exactly one.

That heuristic has a hole it cannot see: **two** ordinary folders under one parent carrying two special leaf names — `Projects/Drafts` + `Projects/Sent`, with the real mailboxes absent from the ind

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/376) · 2026-08-13 · open · 0 comments

### feat(api): expose per-message draft status — no projection surfaces it, so archive-mail cannot exclude drafts without bypassing the MCP

## Problem

> Tracking primary: **PsychQuant/psychquant-claude-plugins#127** — `archive-mail` must exclude drafts by default. That fix is **blocked here**: no MCP tool surfaces draft status, so the SOP has no way to identify a draft.

Apple Mail marks drafts in two places, both currently below the API surface:

| Discriminator | Where | Exposed by any tool today? |
|---|---|---|
| `messages.type = 5` | Envelope Index (SQLite) | ❌ no |
| `X-Uniform-Type-Identifier: com.apple.mail-draft` | per-mes

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/374) · 2026-08-13 · open · 0 comments

### bug(list_attachments): SQLite-seeded enumeration returns [] for Apple-Mail-sent messages whose .emlx has attachments — silent, and the #115 observability guard excludes this path

## Problem

> **Original report** (from a `/archive-mail` run on 2026-08-12):
> 「`list_attachments` 已證實不可信，其餘 3 封也改用 raw `.emlx` 核對（Step 8a）。`.emlx` 裡面有辦法看到附件嗎？還是有什麼 bug」

`list_attachments` returns `[]` for messages that **demonstrably carry attachments** in their on-disk `.emlx`. It fails **silently** — no stderr warning, no error — and the failure is invisible to the `/archive-mail` Coverage Audit that is supposed to catch exactly this.

In one archive run, **3 of 4** messages were affected, 

[Read the thread](https://github.com/PsychQuant/che-apple-mail-mcp/issues/365) · 2026-08-12 · closed · 2 comments

The remaining reports are on [the project's issue tracker](https://github.com/kiki830621/che-apple-mail-mcp/issues).
