Skip to content

v2.16.0

Choose a tag to compare

@kiki830621 kiki830621 released this 19 Jun 12:40

Developer ID signing + notarization so Full Disk Access survives version bumps — closes #211. The released binary was ad-hoc signed, so macOS TCC keyed the FDA grant to its cdhash and every release invalidated it; users had to re-add the binary to the Full Disk Access list after each upgrade, and SQLite-only features (#208 projection, export_emails_markdown) silently broke until they did. Adds scripts/sign-and-notarize.sh (adapted from che-ical-mcp; Full Disk Access is not a requestable entitlement, but controlling Mail.app via Apple events under a hardened runtime requires com.apple.security.automation.apple-events, so the entitlements file carries that key — without it a signed build would break all Mail AppleScript control, a regression the verify Codex cross-model lens caught), a Makefile (install-signed for a stable FDA grant on the maintainer's own machine without waiting for notarization; release-signed for distribution), an empty Sources/CheAppleMailMCP/Entitlements.plist, and a universal (arm64 + x86_64) build in scripts/release.sh behind a fork-friendly SKIP_CODESIGN / REQUIRE_CODESIGN gate. The FDA-denied failure is now loud and actionable: a shared FullDiskAccessHelp carries the Privacy_AllFiles deep-link plus the exact running-binary path into EnvelopeIndexReader, the init-failure log, and the projection / export_emails_markdown errors (no more "grant it to the terminal application"). Test suite 665 (50 env-skipped), 0 failures. The first FDA grant is still manual — signing makes it permanent, not automatic.

#214 — the FDA-denied error names the responsible process, not the binary. macOS TCC grants Full Disk Access to the responsible process (the app that launched the server — the terminal for Claude Code, or Claude Desktop), not to the binary itself; #211's message pointed at the binary, so users granted the wrong target and stayed denied. The message now leads with the responsible-process candidates (terminal / Claude Desktop) and keeps the binary as the direct-launch fallback. An auto-resolver via the libquarantine SPI responsibility_get_pid_responsible_for_pid was attempted and then removed — verification (the 6-AI ensemble's adversarial lens) proved it returns self for terminal- and CLI-launched processes, so there is no reliable in-process API to name the exact app; the message names candidates rather than guessing.

#213 — proactive Full Disk Access onboarding. CheAppleMailMCP --setup opens a SwiftUI window with live FDA status (re-checked on a timer; flips to "Ready ✅" the moment you grant), an on-demand Automation check, and "Open Full Disk Access settings" / "Copy binary path" buttons. CheAppleMailMCP --check-fda prints status headlessly and opens the pane when access is denied. A check_fda MCP tool reports the same status to Claude on demand. All three are gated behind their flag so the stdio MCP path is byte-for-byte untouched; AppKit/SwiftUI are linked but the runloop only starts under --setup. The functional FDA probe (fopen of the Envelope Index) discriminates granted / denied (EPERM/EACCES) / no-mail-data / undetermined, and the no-mail-data case honestly notes that a denial can hide ~/Library/Mail (so an FDA-denied user isn't told the opposite of the fix). None of this removes Apple's single manual FDA toggle — Apple puts FDA in the manual-only bucket — but it makes "what do I do?" obvious with live feedback.

Test suite 677, 0 failures. The --setup GUI is verified to launch (manual smoke-test; a window can't be CI-tested). Version is a suggestion; the maintainer picks the actual tag at release time.