che-apple-mail-mcp
che-apple-mail-mcp
가장 포괄적인 Apple Mail MCP 서버 — SQLite 기반 밀리초 검색으로 25만 통 이상의 이메일을 처리하는 53개 도구를 제공합니다.
왜 che-apple-mail-mcp인가?
기능 | 기타 MCP들 | che-apple-mail-mcp |
전체 도구 수 | ~20 | 53 |
언어 | Python | Swift (네이티브) |
검색 속도 | 초 단위 (AppleScript) | 밀리초 단위 (SQLite) |
검색 필드 | 제목/발신자 | 제목/발신자/수신자/날짜 |
일괄 작업 | 없음 | 호출당 최대 50개 이메일 |
사서함 관리 | 없음 | 전체 CRUD |
이메일 색상 | 없음 | 7가지 플래그 색상 + 배경색 |
VIP 관리 | 없음 | 있음 |
규칙 관리 | 없음 | 전체 CRUD |
서명 | 없음 | 있음 |
원시 헤더/소스 | 없음 | 있음 |
Related MCP server: apple-mail-mcp
빠른 시작
플러그인을 설치하세요. 서명된 바이너리, /utils (archive-명령줄군), 안전 규칙, 그리고 오래된 세션(스테일)을 끝내는 훅을 하나의 단위로 제공합니다.
claude plugin marketplace add PsychQuant/che-apple-mail-mcp
claude plugin install che-apple-mail-mcp@che-apple-mail-mcp그런 다음 권한을 부여하세요 — 설정 창은 실시간 상태를 표시하며 올바른 시스템 설정 패널로 바로 연결됩니다.
~/bin/CheAppleMailMCP --setup💡 전체 디스크 접근 권한(Full Disk Access) 이 빠른 SQLite 읽기 경로와
batch_export_emails_markdown이 작동하게 만듭니다. 이 권한이 없으면 도구는 실행은 되지만 읽는 것이 거의 없어서, 권한 문제를 버그로 오인하기 쉽습니다. macOS에서 모든 앱이 FDA(FULL_DISK_ACCESS)를 프로그래밍으로 요청할 수는 없기 때문에 — 수동으로 켜야 합니다 — 설정 창이 그 과정을 빠르게 하기 위해 존재하는 것입니다.
플러그인 vs MCP 전용
MCP 서버만 등록하는 방식은 지원되는 고급 경로이지만, 구성이 분명히 축소된 설치의 파생이 있습니다. 인지하고 선택하세요 — 실행 중에 아무것도 빠져 있다는 것을 알려주지 않습니다. (#353):
| 플러그인에 포함되는 것 | MCP 전용일 때의 내용 |
| -------------------------------------------------------------------------------------------- | ---------------------------------------------------- ------- |
| 모든 53개 MCP 도구 | 지원함 |
| archive-mail + users/메시지 / -재건축-스레드 / -고장-가상-ID / -보기 | 소실: 아카이브(Standard Operating) 절차 사실 없다. |
| rules/compose-wrapper-free.md — 이 것이 아니었을까 / 메일 호출 거부하면 무엇을 뜻하는지 | 배경: #304 이후 보낸사람 항목은 구조적으로 불가능해서, 이 규칙은 지금부터 사일런트 폴백을 방어하기보다 여섯 가지 거부 이유와 각각의 해결책을 설명합니다. |
| rules/confirmation-triggers.md, rules/false-positive-detection.md | ❌ 파괴적 작업에 대한 확인 의무가 없음. |
| hooks/session-start.sh — 오래된 세션 종료 | ❌ 업그레이드 후에도 세션이 옛 버전 바이너리로 실행될 수 있음. |
| Developer ID로 서명 + 공증된 바이너리 | ❌ 손수 빌드한 바이너리는 ad-hoc 서명. macOS 26에서 TCC가 그 바이너리에 FDA/자동화 권한을 유지하지 못하여, 권한을 준 것처럼 보여도 이내 동작을 중단합니다. (#211) |
| 버전 사이드카 → --self-update + #303 스테일 상태 자체 점검 | ❌ 손으로 만든 바이너리 옆에는 사이드카가 없어 그 점검은 항상 조용히 비활성화되어 있습니다. |
git clone https://github.com/PsychQuant/che-apple-mail-mcp.git
cd che-apple-mail-mcp
swift build -c release
# --scope user : available across all projects (stored in ~/.claude.json)
# --transport stdio: local binary execution via stdin/stdout
# -- : separator between claude options and the command
mkdir -p ~/bin
cp .build/release/CheAppleMailMCP ~/bin/
claude mcp add --scope user --transport stdio che-apple-mail-mcp -- ~/bin/CheAppleMailMCP~/bin/ 같은 로컬 디렉터리에 바이너리를 설치하세요. 클라우드 동기화 폴더(Dropbox, iCloud, OneDrive)는 피하세요 — 동기화 작업이 MCP 연결 타임아웃을 유발합니다.
직접 빌드한 바이너리가 재빌드한 뒤에도 TCC 권한을 지키도록 Developer ID로 서명하세요 — Signing & Notarization 를 참고하지 않으면 빌드마다 권한을 다시 허용해야 합니다.
최근 릴리스
자세한 내용은 CHANGELOG.md에서 확인하세요.
v2.7.2 (2026-05-10) — attachmentFragment 묶음 + 폴백 대응
attachmentFragment들여쓰기를 3곳의 호출부 모두에서 강화하고, v2.7.0의 경합 완화 지연을 무시하던 죽은 헬퍼MailController.attachmentScript를 제거했습니다. (#61, #62)첨부 개수 상한(50) +
CHE_MAIL_ATTACHMENT_DELAY_BETWEEN/_TRAILING환경 변수로 지연 설정 가능 (#63, #64)get_email_metadata의 SQLite 경로가 오류 시 AppleScript로 되돌아갑니다 — 마지막으로 남았던 읽기 도구 공백이 닫혔고, SQLite 우선 8개의 읽기 도구 모두가 동일한 폴백을 갖습니다. (#71)
v2.7.1 (2026-05-09) — base64 문제 해결 + .partial.emlx + 관측 가능성
중대한: RFC822 헤더/본문 분할 시 절대
Data인덱스가 아닌 상대 배열 인덱스를 받게 되어, 일부 Android Gmail 메시지에서html_body가"sion: 1.0\n\n<base64>"로 시작하는 현상이 일어났습니다 — 원시 base64가 LLM 문맥에 유출되어 다음 AUP 오탐지를 만듭니다. (#72)save_attachment은 이제.partial.emlx본문이 비어 있을 경우Attachments/<rowId>/<part_id>/<filename>캐시를 읽습니다 — 바이너리가 제거된 IMAP 메시지에서 조용히 0바이트 파일 쓰기가 사라집니다. (#66)SQLite 고속 경로 오류가 이제 오류 출력(stderr)으로 기록됩니다 (
SQLite ... fast path failed for rowId=...; falling through to AppleScript) (#69)
v2.7.0 (2026-05-04) — Mail.app 경합 완화
다중 첨부 AppleScript에 0.3초 사이 간격 + 0.5초 마지막 지연을 두어, Mail.app이 경합 상태에서 첨부를 조용히 버리는 문제를 완화했습니다. (#60)
v2.6.0 (2026-05-03) — 보안 & 검증 강화 (8 PRs, 16 issues)
forward_emailplain 방식은 이제 RFC 3676>인용문을 포함합니다 (reply_email의 #43 수정사항과 동일). (#44)도구 매개변수 타입이 다르면 무조건 실패 —
bool/[String]은 이제 조용히 변환하지 않습니다. (#35)수신자 이메일 유효성 검사는 프로토콜 인젝션(제어 문자,
@누락/여러 개)을 거부합니다. (#41)cc_addition는 대소문자 무시 중복 제거. (#34)첨부 경로 차단 목록(
~/.ssh, Keychains, TCC db, browser cookies) + 심볼릭 링크 확인 + 새MAIL_MCP_ATTACHMENT_ROOTS환경 변수 허용 목록 (#38)id를 취하는 모든 도구 17개를 핸들러 경계에서
id를 Int로 강하게 검증 — AppleScript 술어 주입을 막습니다. (#50)reply_email실행시간에 대한 게이트 처리된 통합 테스트 (#37 , #45) + smoke matrix 템플릿 (#46, #47)
v2.5.0 (2026-04-17) — 메일 작성의 format 매개변수
작성 도구 4개(
compose_email/create_draft/out_golden) /forward_email)에format: "plain" | "markdown" | "html"파라미터를 추가했습니다. (이슈 #14, #15 종결)새
message-composition능력 사양 추가
전체 53개 도구
도구 | 설명 |
| 모든 메일 계정 나열 |
| 계정 세부 정보 가져오기 |
도구 | 설명 |
| 모든 사서함(폴더) 나열 |
| 새 사서함 만들기 |
| 사서함 삭제 |
| 특수 사사함 이름 가져오기 (받은 풀지, 초안함, 보낸함, 낡음함, 임시함, 발송 대기함) |
도구 | 설명 |
| 사서함 목록에 있는 이메일 나열 |
| 이메일 전체 내용 가져오기 |
| 제목/내용으로 검색 |
| 안 읽은 메일 수 가져오기 |
| 모든 이메일 헤더 가져오기 |
| 원시 이메일 소스 가져오기 |
| 메타데이터 가져오기 (전달됨, 답장됨, 크기) |
도구 | 설명 |
| 읽음/읽지 않음으로 표시 |
| 이메일 플래그 지정/해제 |
| 플래그 색상 설정(7가지 색상) |
| 이메일 배경색 설정 |
| 정크/정크 아님으로 표시 |
| 다른 사서함으로 이동 |
| 다른 사서함으로 복사 |
| 이메일 삭제(휴지통으로) |
도구 | 설명 |
| 새 이메일 전송(cc/bcc/첨부 파일 지원; |
| 이메일에 답장합니다. 선택사항: |
| 이메일 전달. 선택사항 |
| 이메일 리디렉션(원본 발신자 유지) |
| mailto URL 열기 |
답장을 초안으로 저장하는 예시 (v2.4.0+)
스레드에 답장하고, 추가 참조(CC)를 넣고, 파일을 첨부한 다음, 전송 전에 사람이 검토할 수 있도록 초안으로 저장합니다:
reply_email(
id="<message id from search_emails>",
mailbox="INBOX",
account_name="iCloud",
body="Reply text",
cc_additional=["x@y.com"],
attachments=["/path/to/file.pdf"],
save_as_draft=true
)도구 | 설명 |
| 초안 이메일 목록 — 각 항목에는 |
| 초안 생성(첨부 파일 지원; 다중 계정 발신자 선택을 위한 선택적 |
| 기존 초안 교체(upsert, #276): |
도구 | 설명 |
| 이메일 첨부 파일 목록 |
| 첨부 파일을 디스크에 저장 |
도구 | 설명 |
| VIP 발신자 목록 |
도구 | 설명 |
| 메일 규칙 목록 |
| 규칙 세부 정보 가져오기 |
| 새 규칙 만들기 |
| 규칙 삭제 |
| 규칙 활성화/비활성화 |
도구 | 설명 |
| 이메일 서명 목록 |
| 서명 내용 가져오기 |
도구 | 설명 |
| SMTP 서버 목록 |
도구 | 설명 |
| 새 메일 확인 |
| IMAP 계정 동기화 |
도구 | 설명 |
| 호출 한 번에 최대 50개 이메일 가져오기(항목별 오류) |
| 최대 50개 이메일의 첨부 파일 목록 나열 |
| 서버 측에서 원문 그대로의 Markdown과 첨부 파일로 일괄 내보내기(frontmatter 매니페스트 고정, |
| 사용되지 않음 — |
도구 | 설명 |
| 이메일 주소에서 이름 추출 |
| 전체 주소에서 이메일 추출 |
| Mail.app 정보 가져오기 |
| 파일에서 사서함 가져오기 |
도구 | 설명 |
| 전체 디스크 접근(Full Disk Access) 상태 확인(SQLite 빠른 경로 사용 가능 여부) |
| 손쉬운 사용 권한 확인(작성/답장 GUI 경로, 이 권한이 없으면 해당 도구들은 거부됨) |
| 자동화(Automation) 권한 확인(Apple Events를 통한 Mail 제어) — 프롬프트를 띄우지 않는 프로브이며 4가지 상태와 해결 방법을 제공합니다(#293); 바이너리는 고유의 권한을 보유하므로, osascript가 동작해도 바이너리가 승인된 것은 아닙니다(#288) |
search_emails / list_emails 응답 형태
두 도구 모두 envelope 객체 { results, returned, limit, truncated }를 반환합니다. — 단순 배열이 아니라, 일반 배열은 아닙니다(v2.14.0/ #204에서 변경). 매칭 결과는 .results에서 읽으세요.
필드 | 설명 |
| 결과 객체 배열(객체별 필드는 envelope 도입 이전의 형태와 동일). |
|
|
| 쿼리에 적용된 실제 |
| 반환된 결과보다 더 많은 결과가 있을 때 |
truncated는 SQLite 빠른 경로에서는 확정적입니다(내부적으로 limit + 1개를 가져옵니다). AppleScript fallback에서는 returned == limit을 기준으로 한 표시 없는 휴리스틱입니다. truncated가 전체 집합을 받았다고 가정하기 전에 어떤 “열거 → 일괄 처리”를 하는 쪽이라도 모두 truncated를 확인해야 합니다.
설치
먼저 빠른 시작부터 하셨다면 — 플러그인 설치를 하는 것이 지원되는 경로이며, 명령어, 안전 규칙, staleness 후크, 서명된 바이너리를 얻을 수 있습니다. 아래 내용은 모두 고급/개발용 경로입니다: MCP 서버만 등록하는, 확실히 범위가 좁은 설치입니다(플러그인 vs MCP 전용에서 무엇이누락되는지 확인하세요. 실행 중에는 알려주는 것이 없으므로).
요구 사항
macOS 13.0+
Xcode Command Line Tools(아래 직접 빌드 경로 필요)
계정이 하나 이상 구성된 Apple Mail
1단계: 빌드
git clone https://github.com/PsychQuant/che-apple-mail-mcp.git
cd che-apple-mail-mcp
swift build -c release2단계: 구성 (Configure)
Claude Desktop의 경우
~/Library/Application Support/Claude/claude_desktop_config.json을 편집하세요:
{
"mcpServers": {
"che-apple-mail-mcp": {
"command": "/full/path/to/che-apple-mail-mcp/.build/release/CheAppleMailMCP"
}
}
}Claude Code(CLI)의 경우
# Copy to ~/bin and register (user scope = available in all projects)
mkdir -p ~/bin
cp .build/release/CheAppleMailMCP ~/bin/
claude mcp add --scope user --transport stdio che-apple-mail-mcp -- ~/bin/CheAppleMailMCP3단계: 권한 부여
가장 빠른 방법은 setup 창을 사용하는 것입니다. 현재 전체 Disk Access / 자동화 / 손쉬운 사용 상태를 실시간으로 보여주고, 권한을 부여할 때마다 다시 확인하며, 올바른 시스템 설정 패널을 열어줍니다:
~/bin/CheAppleMailMCP --setup수동으로 하려면 다음 단계를 따르세요:
자동화 (Automation) (Mail.app 제어):
open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"CheAppleMailMCP를 찾아 Mail.app 권한을 켜세요.
Claude Code를 사용하는 경우 Terminal 또는 iTerm도 추가하세요.
전체 디스크 접근 (Full Disk Access) (SQLite 빠른 경로 및 export_emails_markdown가 ~/Library/Mail을 읽습니다):
open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"macOS는 전체 디스크 접근 권한을 responsible process — 이 서버를 시작한 앱 — 에 부여하거나 바이너리 자체에 부여하지 않습니다. **Claude Code and 터미널에서 실행되는 MCP 서버의 경우, 그 responsible process는 터미널입니다(Ghostty / Terminal / iTerm). 따라서 여기에 터미널 앱을 추가하고 활성화하세요. 터미널 하나에 부여한 권한은 그 터미널이 실행하는 모든 MCP 서버에게 적용됩니다. (대신 바이너리를 직접 실행하거나 Claude Desktop 번들을 사용하는 경우에는 해당 바이너리 — ~/bin/CheAppleMailMCP — 를 추가하세요. 이 경우 그 바이너리가 responsible process가 되기 때문입니다.) FDA가 거부된 오류 메시지는 이러한 대상들을 안내해 주지만, 정확한 한 앱을 자동으로 찾지는 않습니다. macOS가 그렇게 할 수 있는 안정적인 프로세스 내부 API를 노출하지 않기 때문입니다(#214). 전체 디스크 접근 권한이 없으면 읽기 도구들은 자동으로 느린 AppleScript 대체 경로를 사용하며, SQLite 전용 기능(projection, export_emails_markdown)은 실패합니다. 직접 실행 경로를 사용하는 경우 Developer ID 서명 빌드는 버전 업데이트가 있어도 권한이 유지되도록 합니다 — 서명과 공증을 참조하세요.
안내형 설정(Guided setup) (#213) — 위 수동 단계 대신 바이너리에 설정 도우미가 들어 있습니다:
CheAppleMailMCP --setup— 실제 실시간으로 전체 Disk Access 상태를 표시하는 작은 창이 열립니다(타이머로 다시 확인하여 권한을 부여하는 **즉시 “준비 완료 ✅”로 전환됨), 요청 시 자동화(Automation) 확인도 제공하며 “전체 디스크 접근 설정 열기”/“바이너리 경로 복사” 버튼이 포함되어 있습니다.CheAppleMailMCP --check-fda— 헤드리스 상태를 현 상태를 출력합니다(접근이 거부된 경우 패널도 열림) — 터미널이나 스크립트에서 손쉽게 사용할 수 있습니다.check_fdaMCP 도구 — Claude에게 동일한 상태를 요청 시 보고합니다(SQLite 전용 기능이 오류를 내면 이를 호출하세요).
이 중 어느 것도 하나의 수동 토글을 없애지는 못합니다(Apple은 전체 디스크 접근을 손쉬운 사용·화면 기록과 함께 수동 전용 범주로 분류합니다). 하지만 “무엇을 하면 되는지”를 명확하게 해주고, 켜는 순간 실시간 피드백을 줍니다.
접근성(작성하기, #175/#304) — 전체 디스크 접근 권한과는 별개이며 선택적인 권한입니다. Mail.app은 AppleScript로 주입된 발신 메시지 본문을 <blockquote type="cite">로 감싸는데, 일부 모바일 클라이언트는 이를 자기 텍스트를 인용한 것으로 렌더링합니다. 그리고 이 래퍼의 인라인 스타일에는 테두리가 없어서 발신자가 로컬에서는 볼 수 없습니다. #304부터 이 래퍼를 만드는 코드는 더 이상 존재하지 않습니다. 모든 작성 도구는 본문을 Mail 자체 편집기에서 가져옵니다 — compose_email / create_draft는 mailto: 전달 방식이고, reply_email / forward_email은 네이티브 답장/전달 동사와 붙여넣기를 사용합니다 — 그리고 저장/보내기/첨부는 키보드 단축키로 실행하므로 손쉬운 사용(접근성) 권한(시스템 설정 → 개인정보 보호 및 보안 → 손쉬운 사용)이 필요하며, 이때 접근성 권한은 FDA와 동일한 책임 프로세스(터미널 / Claude Desktop)에 부여됩니다. check_accessibility MCP 도구와 --setup 창의 Accessibility 행에서 상태를 확인할 수 있습니다. 이 권한이 없으면 이 도구들은 대체 경로로 동작하지 않고 실패합니다. — 대체할 수 있는 경로가 전혀 없으므로, 정상적으로 실행할 수 없는 호출은 명명된 오류를 반환하고 아무것도 생성하지 않습니다. 오류가 가리키는 open_mailto는 TCC 승인(권한 요청)이 전혀 필요하지 않습니다. (첨부 파일을 전달할 수 없으며, 창을 직접 저장하거나 전송해야 합니다.) 호출을 거부하는 조건은 정확히 여섯 가지입니다: plain이 아닌 format; 제목이 비어 있는 경우; 접근성 권한이 없는 경우; from_address가 단순한 addr-spec이 아닌 경우; 비ASCII 문자가 포함된 첨부 파일 경로 (#220); 그리고 이 경로가 채울 수 없는 표시 이름을 포함새로운 수신자입니다(cc/bcc는 항상, 보내기의 경우 to도 — 초안의 to 표시 이름은 GUI로 채워집니다, #277). 기본 계정이 아닌 계정에서 깨끗한 본문을 보내려면 from_address를 전달하세요. GUI에서는 Mail의 "보내는 사람" 팝업에서 해당 계정을 선택하고 선택 결과값을 다시 읽은 뒤, 잘못된 보낸 이가 될 수 있는 경우 호출을 중단합니다 (#219). 레거시 경로와 함께 제거된 기능: format: "markdown" / "html" — 오늘날 제공되는 경로 중 삭제된 본문 할당 없이 서식 있는 텍스트를 전달하는 경로는 없습니다. 이는 현재 존재하는 사실이지, 불가능함을 증명하는 것은 아닙니다 (#310): 붙여넣기 경로(#218)는 래퍼 없는 두 번째 경로이며 NSPasteboard는 서식 있는 콘텐츠를 전달할 수 있지만, 그때 생성되는 MIME은 검증되지 않았습니다 — #306이 이 문제를 확정합니다. #308 / #309는 대안이며, require_wrapper_free와 sanitize_links 파라미터와 CHE_MAIL_DISABLE_MAILTO_COMPOSE / CHE_MAIL_DISABLE_PASTE_REPLY 탈출구도 있습니다. 이와 함께 두 가지 기능도 사라집니다: 보이는 창 없이 작성하는 것(탈출구의 원래 목적)은 더 이상 불가능하며, compose_email은 더 이상 Name <addr> 로 보낼 수 없습니다 — 대신 create_draft를 사용해 직접 초안을 보내십시오.
Automation TCC(-1743)와 TCC TCC의 탈출구
AppleScript 기반 도구를 실행할 때 AppleScript 오류 (-1743): Mail에 Apple 이벤트를 보낼 권한이 없습니다. 오류가 발생하면 이 바이너리에대한 자동이라는 표시가 누락된 것입니다. 서명된 MCP 바이너리는 자체적으로 자동으로 제어 로써의 권한을 갖습니다. — TCC 정체성은 바이너리의 서명 정체성(#211FDA 유산 중 자동화 축)에 키로 설정되며, 터미널의 권한과는 별개입니다. 실제로 확인된 결과: 셸에서 Mail을 제어하는 osascript가 반드시 바이너리의 권한이인 것을 보장하지는 않습니다. 시스템 설정 → 개인정보 보호 및 보안 →
자동이라는 에서 권한을 부여하세요 — 바이너리/해당 호스트(Claude Desktop 확장 프로그램: Claude.app 아래)를 카지서 Mail을 활성화하십시오. 항목이 없다면 이전에 거부했던 이력이 기억되고 macOS가 다시 재시작되지 않으므로 tccutil reset AppleEvents를 거친 후 Mail 도구를 재시도하여 권한 요청을 트리기하세요. 부여된 권한은 설치마다 개별로 유지되며, 바이너리 업데이트로 인해 항목이 무효화될 수 있습니다(#211).
권한이 부여될 때까지 open_mailto는 여전히 동작합니다. LaunchServices경로(제로 T CC, #287)를 통하며 시스템 기본 메일 클라이언트에서 구분되지 않는 인용 블록 없이 작성 창이 열립니다. mailto는 게재 파일을 전달할 수 없습니다(RFC 6068). 파일은 직접 드래그하세요.
4단계: Claude 다시 시작
# For Claude Desktop
osascript -e 'quit app "Claude"' && sleep 2 && open -a "Claude"
# For Claude Code - start a new session
claude사용 예제
자연 언어(Claude Desktop)
"List all my mail accounts"
"Show unread emails in Gmail inbox"
"Search for emails about 'quarterly report'"
"Send an email to john@example.com about the meeting"
"Flag important emails in red"
"Create a rule to move newsletters to a folder"직접 도구 호출(Claude Code)
"Use list_accounts to show my accounts"
"Use search_emails to find emails containing 'invoice'"
"Use set_flag_color to mark email ID 12345 as blue"
"Use check_for_new_mail to refresh"플래그 색상 및 배경 색상
플래그 색상 (set_flag_color)
인덱스 | 색상 |
0 | 색상 |
1 | 주황 |
2 | 노랑 |
3 | 초록 |
4 | 파랑 |
5 | 보라 |
6 | 회색 |
-1 | 없음 |
배경 색상 (set_background_color)
blue, gray, green, none, orange, purple, red, yellow
성능 및 저장
SQLite + .emlx 고속 경로
대부분의 읽기 도구는 AppleScript IPC 대신 Apple Mail의 로컬 Envelope Index(SQLite)와 디스크에 저장된 .emlx 메시지 파일을 우선 사용하며, SQLite 경로로 요청을 처리할 수 없으면 AppleScript로 대체합니다.
도구 | SQLite/.emlx 경로 | AppleScript 대체 경로 |
| ✓ | ✓ (오류가 발생할 때) |
| ✓ (항목별) | ✓ (항목별) |
| ✓ | ✓ (오류가 발생할 때) |
| ✓ | ✓ (오류가 발생할 때) |
| ✓ | ✓ (리더 기능을 사용 불가할 때) |
| ✓ | ✓ (오류가 발생할 때) |
| ✓ | ✓ (오류가 발생할 때) |
| ✓ | ✓ (오류가 발생할 때) (#71 이후) |
save_attachment의 읽기 경로에서 고속 경로는 AppleScript보다 10배에서 100배 정도 더 빠르며 (#12 실측 기준). 다른 도구의 속도 향상 비율은 요청 형태에 따라 달라집니다. 일반적으로 큰 일괄 읽기에서 가장 큰 성능 향상이 있습니다.
고속 경로가 필요로 하는 조건:
호스트 프로세스에 전체 디스크 접근 권한(시스템 설정 → 개인정보 보호 및 보안 → 전체 디스크 접근 권한)이 있어야 한다.
Apple Mail의 로컬 저장소가
~/Libraries/Mail/V10/...에 있어야 한다.메시지가 로컬
.emlx파일로 동기화되어 있어야 한다.
EWS / Exchange 계정은 의도적으로 고속 경로를 사용하지 않는다
Apple Mail에서 Exchange(EWS) 계정은 .emlx 파일을 만들지 않습니다. 메시지 본문은 서버에 있고 요청할 때마다 가져옵니다. 이 계정의 경우 8가지 읽기 도구 모두(#71 이후 get_email_metadata 포함)는 자동으로 AppleScript IPC(정상 기능이지만 더 느린 방식)로 대체합니다. 특징:
EWS 메시지 500개를 일괄 요청하면 IMAP/Gmail 메시지 500개 요청보다 상당히 느립니다.
이는 결함이 아닙니다 — Apple Mail 저장 방식의 구조적 제약입니다 (#9).
고속 경로 우회 진단
고속 경로에서 일반 계정에 대한 우회가 실패하면 #69부터 이 실패가 stderr에 기록됩니다. 터미널에서 바이너를 실행하고 stderr의 로그를 보면 무엇을 구분할 수 있습니다:
EnvelopeIndexReader init failed: ...— DB에 접근 불가 (주로 전체 디스크 접근 권한 누락)SLite get_email fast path failed for rowId=N: ...— 메시지별 실패(예:.partial.emlx`만 존재, 잘못된 MIME, 아직 동기화되지 않은 파일)
두 경우 모두 로그에 ... falling through to AppleScript 라는 메시지와 함께 AppleScript로 대체되므로 동작은 유지되면서 관찰 가능성이 복원됩니다.
문제 해결
Problem | Solution |
서버 연결 끊김 |
|
Apple 이벤트 전송이 허용되지 않음 | 시스템 설정 > 자동화에서 권한을 추가 |
Mail.app이 응답하지 않음 | Mail.app이 실행 중이고 계정이 구성되어 있는지 확인 |
명령 시간 초과 | 대용량 사서함은 시간이 더 걸리므로 특정 검색을 시도 |
대량 가져오기가 예상보다 느림 | stderr에서 |
| #173 이후로 두 오류 모두 실패한 참조(account/mailbox/message)를 지목하는 실행 가능한 힌트와 함께 반환됩니다. 일반적인 원인: 두 Mail.app 계정이 동일한 |
계정 모호성 해소
Mail.app의 AppleScript account "<display_name>" 선택자는 두 계정이 동일한 display_name을 공유하면 유일하지 않습니다 — iCloud catch-all 별칭이 Gmail 주소를 다시 자기 자신에게 전달하거나 Google Workspace와 개인 Gmail이 겹치는 일반적인 패턴입니다. 그러면 AppleScript 라우팅 도구(save_attachment 폴백, get_email, mark_read 등)가 비결정적으로 잘못된 계정을 선택하여 -1728 / -1719 오류가 발생합니다.
해결책: account_name과 함께 account_id(Mail.app의 전역 고유 UUID)를 전달하세요. 제공되면 save_attachment는 Mail.app의 account id "<UUID>" 선택자를 대신 사용하여 모호성을 우회합니다:
// Tool call: save_attachment with account_id
{
"id": "273214",
"mailbox": "[Gmail]/全部郵件",
"account_name": "alice@example.com",
"account_id": "C38E0583-47F8-4468-BE70-43155C15549D", // ← disambiguates
"attachment_name": "report.pdf",
"save_path": "/tmp/report.pdf"
}account_id 확인 방법:
search_emails결과에서 —results배열의 각 객체(SearchResult)는account_name과 함께account_id필드를 가집니다 (MailboxURL.decode를 통해 SQLitemailboxes.urlauthority에서 계정 UUID를 디코딩하여 채워집니다. Mail.app의 저장 규약은 사서함 URL authority에 계정 UUID를 인코딩하며, 직접SELECT mailboxes.account_id는 없습니다). 그대로 전달하는 것을 권장합니다.수동으로 —
~/Library/Mail/V10/MailData/Signatures/AccountsMap.plist를 읽으세요. 최상위 키가 UUID이며AccountURL값에 일치하는 이메일 주소가 authority에 percent-encoded되어 있습니다.AppleScript에서 —
tell application "Mail" to get id of every account가 UUID 목록을 반환합니다.
하위 호환성: account_id는 선택 사항입니다. 생략되거나(비어 있거나) 도구는 account "<display_name>" 경로로 폴백합니다 — #101 이전과 동일한 동작이며, 단 한 가지 save_attachment 예외(#173)가 있습니다: account_name에 @가 포함된 경우(이메일 형태, 즉 search_emails 같은 SQLite 경로 도구가 생성하는 형식) save_attachment는 AccountsMap에서 역방향 조회를 먼저 수행하여 자동으로 account id "<UUID>" 선택자로 업그레이드합니다(업그레이드는 stderr에 기록됩니다). 정확히 하나가 일치하면 → 해당 UUID, 주소 뒤에 여러 계정(iCloud catch-all + Gmail)이 있으면 → 원시 -1728 대신 모든 후보를 나열하는 실행 가능한 오류, 일치하는 것이 없으면 → 기존 display-name 경로가 변경 없이 사용됩니다. 설명에 정당하게 @가 포함된 Mail 계정이 우연히 다른 계정의 이메일과 일치하는 경우 이제 이메일 네임스페이스에서 먼저 해석되므로 account_id를 명시적으로 전달하여 선택자를 고정하세요. 다른 도구는 엄격한 pre-#101 폴백을 유지합니다(도구 전반에 걸친 정리는 #176 참조).
적용 범위: account_id는 계정으로 메일을 참조하는 AppleScript 라우팅 도구 전반에서 허용됩니다. save_attachment(#101)에서 시작되었으며, #104의 정리 작업에서 13개의 단일 메시지 / 이동 / 릴레이 / 사서함 도구가 추가되었습니다:
save_attachment(#101) — 선구 도구PR-A — 5개 단일 메시지 변경 도구:
mark_read,flag_email,set_flag_color,set_background_color,mark_as_junkPR-B — 3개 이동/삭제 도구:
move_email,copy_email,delete_emailPR-C — 3개 메시지 릴레이 도구:
reply_email,forward_email,redirect_emailPR-D — 2개 사서함 CRUD 도구:
create_mailbox,delete_mailbox
이후 범위는 #104 집합을 넘어 확장되었습니다:
#176 — 14개 AppleScript 라우팅 쓰기 핸들러 전반에서 email→UUID로 변환하는
resolveAccountIdForTool지점을 일반화하여, 이메일 형태의account_name이 단순히 허용된account_id뿐 아니라 UUID 선택자로도 해석되도록 했습니다.#180 — 읽기 도구의 AppleScript 폴백(
list_emails/search_emails/get_email/ headers / source / metadata / attachments /get_unread_count)에resolveMailboxRef/resolveMsgRef를 통해account_id를 연결했습니다(이전에 연기되었던 PR-E가 이제 완료되었습니다).#179 —
get_special_mailboxes는 계정별 특수 사서함의 실제 이름을 위해account_id/account_name을 받아들입니다.#191 — 계정 수준 작업 도구
check_for_new_mail와synchronize_account에account_id탈출구가 추가되었습니다(synchronize_account는account_id단독 수용).
여전히 account_id로 다뤄지지 않은(추적 중) 항목: get_account_info / list_mailboxes (#202).
compose_email / create_draft는 display_name 충돌 결함을 보이지 않습니다 — 기존 메일을 계정 기준으로 참조하지 않고 make new outgoing message를 생성하므로 account "<display_name>" 선택자를 절대 사용하지 않습니다. 다중 계정 발신자 선택은 이제 선택적 from_address 파라미터(#131)를 통해 사용할 수 있습니다. 구성된 Mail.app 이메일 주소 중 하나("alice@example.com" 또는 RFC 5322 형식 "Alice <alice@example.com>")를 전달하면 보내는 메시지의 sender를 설정할 수 있으며, 생략하면 Mail.app의 기본 계정을 사용합니다. list_accounts를 사용해 실행 중인 Mac에 구성된 주소를 확인할 수 있습니다.
account_id를 통한 계정 간 이동/복사는 지원되지 않습니다 (#129 — #127에서 확인). move_email과 copy_email은 단일 account_id를 받아들이며, 이는 소스 msgRef와 대상 mailboxRef 둘 모두에 적용됩니다. 구조적으로는 올바른 선택입니다(이동은 한 계정 내에서 유지되는데, Mail.app의 AppleScript 명령 move msg to <mailboxRef>가 대상 사서함을 단일 계정 컨텍스트 기준으로 표현하도록 요구하기 때문입니다). Mail.app의 UI는 드래그 앤 드롭으로 계정 간 이동을 지원하지만, AppleScript 경로를 사용하는 move_email / copy_email 도구는 이를 재현할 수 없습니다 — 한 계정의 account_id로 move_email을 호출하면서 대상 to_mailbox가 다른 계정 기준으로 해석되기를 기대하면, 그 이름을 가진 잘못된 계정의 사서함을 조용히 선택하거나(두 계정 모두 인그러한 이름이 있는 경우) -1719 "Invalid mailbox index" 오류가 발생합니다. 다른 계정 아래에 메시지 내용의 복사본이 필요하다면 save_attachment + compose_email으로 수동 재구성을 사용할 수 있지만, 실제 이동/복사가 아님에 유의하세요. 즉 원본 메타데이터 (Message-ID, 수신 날짜, 플래그, 라벨)와 메시지 정체성은 보존되지 않습니다.
기술적 세부 사항
프레임워크: MCP Swift SDK v0.10.0
읽기 경로: SQLite(Envelope Index) +
.emlx파일 파서, EWS 또는 파싱할 수 없는.emlx에는 AppleScript 폴백쓰기/상태 경로:
NSAppleScript를 통한 AppleScript전송: stdio
플랫폼: macOS 13.0+ (Ventura 이상)
서명 및 공증
배포되는 바이너리는 Developer ID 서명 및 공증을 받았으며, 이것은 순전한 장식이 아닙니다. 빠른 읽기 경로는 **Full Disk Access(FDA)**가 필요하며, macOS TCC는 FDA 허용을 바이너리의 designated requirement에 고정시킵니다. ad-hoc 바이너리의 경우 그 요구사항은 cdhash이므로, 버전 번호가 바뀔 때마다 허용이 무효화되어 발매 후마다 Full Disk Access 목록에 바이너리를 다시 추가해야 했습니다. 안정적인 Developer ID 서명은 그 Grant을 **서명 정체성(signing identity)**에 대신 고정하므로 버전이 올라가도 유지됩니다(#211) — 지속성을 제공하는 것은 공증이 아니라 그 서명입니다.
공증은 격리 상태 시작(quarantine-launch) 경로에서 중요합니다: 브라우저 다운로드 또는 .mcpb(Claude Desktop) 설치처럼 Gatekeeper가 첫 실행 시 바이너리를 평가하는 경우입니다. 플러그인 래퍼의 curl + exec 경로는 격리 속성을 설정하지 않으므로 Gatekeeper가 발화하지 않습니다. 그래도 우리는 공증을 합니다. 발행된 릴리스 자산이 어떤 경로로든 안전하게 실행될 수 있도록 하기 위해서입니다.
첫 번째 허용은 여전히 수동입니다. FDA(
kTCCServiceSystemPolicyAllFiles)에는 프로그래밍 방식 요청 API가 없으며, 앱은 설정 창으로 딥링크만 제공할 수 있습니다. 서명은 첫 번째 허용을 영구적으로 만들 뿐 자동으로 만들지 않습니다.
일회성 설정 (관리자용)
# 1. Developer ID Application cert in your login keychain (needs an Apple Developer account)
security find-identity -p codesigning -v # find your identity
# 2. notarytool keychain profile (prompts for an app-specific password — never pass it on the CLI)
xcrun notarytool store-credentials <profile-name> \
--apple-id <your-apple-id> --team-id <your-team-id>
# 3. Export both for the signed targets
export DEVELOPER_ID='Developer ID Application: Your Name (TEAMID)'
export NOTARY_PROFILE='<profile-name>'자체 머신에 개발자 설치 (빠름 — 공증 없음)
make install-signed # build + Developer ID sign + copy to ~/bin이것을 사용하면 Apple 공증(notarization)을 기다리지 않고도 자신의 Mac에서 안정적인 FDA 승인을 받을 수 있습니다. 자체 인증서는 로컬에서 정상적으로 실행되며, 해당 승인은 이후에 다시 빌드하더라도 유지됩니다. ~/bin/CheAppleMailMCP에 Full Disk Access를 한 번만 부여하면 완료됩니다.
배포 릴리스 (서명 + 공증 + 게시)
make release-signed VERSION=vX.Y.Z # wraps scripts/release.sh with REQUIRE_CODESIGN=1이 빌드는 유니버설(arm64 + x86_64) 바이너리를 빌드하고, 서명하고, 공증한 뒤(1~15분의 Apple 왕복 시간), GitHub 릴리스에 업로드합니다. 인증서가 없는 포크에서도 SKIP_CODESIGN=1 ./scripts/release.sh vX.Y.Z로 서명되지 않은 개발자 릴리스를 만들 수 있습니다.
기여하기
기여는 언제나 환영합니다! 자유롭게 Pull Request를 제출해 주세요.
라이선스
MIT License — 자세한 내용은 LICENSE를 참조하세요.
저자
Che Cheng(@kiki830621)이 만들었습니다.
유용하다고 생각하시면 별(star)을 눌러 주시기 바랍니다!
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables AI assistants to interact with Apple Mail through natural language, providing comprehensive email management including reading, searching, composing, organizing, and analyzing emails across all configured accounts. Includes an expert skill system that teaches intelligent email workflows and productivity strategies.26193MIT
- AlicenseAqualityAmaintenanceEnables AI assistants to read, send, search, and manage emails in Apple Mail on macOS.2599MIT
- AlicenseNot gradedqualityCmaintenanceEnables unified email management across Gmail, Outlook, iCloud, and IMAP providers with tools for search, send, organize, and batch operations via natural language.58MIT
- AlicenseNot gradedqualityAmaintenanceEnables using Apple Mail accounts to search, read, manage, draft, and send messages from Codex or Claude Code locally.MIT
Related MCP Connectors
Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…
Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.
Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/PsychQuant/che-apple-mail-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server