Apple Messages MCP
Apple Messages MCP
Claude에서 macOS의 iMessage, SMS, RCS 대화를 읽고 검색합니다.
claude-connector-apple-mail 및 claude-connector-apple-reminders 의 동반 도구입니다.
상태: 읽기와 검색은 안정적입니다. 보내기는 구현되어 있지만 실제 전송은 검증되지
않았습니다 — 스크립팅 호출은 구현되었고 구문도 검증되었지만, Apple이 이전에
send를 깨뜨린 적이 있으므로 첫 실제 전송은 테스트로 간주하세요. 메시지 보내기를 참조하세요.
도구
도구 | 설명 |
| 총계, 읽지 않은 수, 서비스별 분류(iMessage/SMS/RCS), 날짜 범위 |
| 대화 목록, 최근 활동 순, 참가자 및 미리보기 포함 |
| 한 대화의 메시지, 오래된 순, 페이지 단위 |
| 전체 기록에 대한 부분 문자열 검색, 채팅·발신자·날짜 범위로 필터링 |
| 첨부 파일 및 전송 타임스탬프를 포함한 단일 메시지 전체 |
| 첨부 파일 바이트, base64 인코딩 |
| 로컬 검색 인덱스 워밍업 또는 재구축 |
| 텍스트가 미리 채워진 Messages 열기 — 사용자가 보내기 버튼을 누름 |
| 기존 대화로 전송; 즉시 전달됨 |
Related MCP server: jons-mcp-imessage
요구 사항
macOS 13 Ventura 이상. RCS는 macOS 26 이상이 필요합니다.
Claude 앱에 대한 전체 디스크 접근 권한 — 읽기에 필요합니다.
Messages에 대한 자동화 권한 — 보내기 및 연락처 이름에 필요합니다. macOS가 이 권한은 자동으로 요청합니다.
전체 디스크 접근 권한 부여
시스템 설정 → 개인정보 보호 및 보안 → 전체 디스크 접근 권한
Claude 활성화(목록에 없으면 **+**로
/Applications/Claude.app추가)Claude를 종료하고 다시 엽니다. macOS는 프로세스 시작 시 이 권한을 캐시하므로 재시작이 필수입니다 — 재시작하지 않으면 확장 프로그램이 계속 실패합니다.
Apple Mail과 달리 전체 디스크 접근 권한이 필요한 이유
Apple Mail 확장 프로그램은 Mail.app과 전적으로 스크립팅으로 통신하므로 특별한 권한이 필요 없습니다. Messages는 그렇게 할 수 없습니다.
Messages의 AppleScript 사전은 정확히 네 가지 클래스 — account, chat,
participant, file transfer — 만 노출하며 메시지 클래스는 없습니다.
macOS 26.5.2에서 확인됨:
$ osascript -e 'tell application "Messages" to get every text message of first chat'
syntax error: Expected "from", etc. but found identifier. (-2741)채팅과 참가자는 정상적으로 열거되지만 메시지 본문은 단순히 노출되지 않습니다.
따라서 유일한 읽기 경로는 ~/Library/Messages/chat.db의 SQLite이며, 이는
TCC로 보호됩니다. 자동화와 달리 전체 디스크 접근 권한은 프로그래밍 방식으로
요청할 수 없습니다 — 사용자가 직접 수동으로 부여해야 합니다.
따라서 확장 프로그램은 서로 다른 작업에 두 권한을 모두 사용합니다:
항목 | 메커니즘 | 권한 |
메시지, 채팅, 검색, 첨부 파일 |
| 전체 디스크 접근 |
원시 핸들의 연락처 이름 | Messages 스크립팅 | 자동화 |
보내기 | Messages 스크립팅( | 자동화 |
작성 창, 미리 채우기 |
| 없음 |
연락처 이름은 Messages의 participant 클래스(full name)에서 가져오며, 이는
사용자의 연락처 카드를 읽습니다. 이렇게 하면 별도로 보호되는 주소록 데이터베이스를
우회합니다 — 자동화가 거부되면 핸들은 단순히 원시 숫자로 표시됩니다.
구현 참고 사항
attributedBody. Ventura 이후로 message.text는 자주 NULL이며 본문은
Apple typedstream 형식의 message.attributedBody에 있습니다 — 이는
plistlib이 읽을 수 없는 레거시 NSArchiver 형식입니다. typedstream.py는
순수 Python으로 이를 디코딩하므로 번들에 PyObjC 의존성이 필요 없습니다.
NSString/NSMutableString 클래스 이름에 앵커를 두고 + 타입 마커 뒤의
길이 접두사 UTF-8 페이로드를 읽습니다. 디코딩은 완전합니다: 디코딩할 수 없는
본문은 쿼리 실패 대신 None을 반환합니다.
타임스탬프. message.date는 Apple epoch(2001-01-01) 기준이며, macOS 13
이전에는 초, 이후에는 나노초 단위입니다. 둘 다 감지되어 처리됩니다.
검색. chat.db에는 텍스트 인덱스가 없으며 대부분의 본문은 SQL이 볼 수 없는
attributedBody에만 있습니다. 이 조합은 보기보다 훨씬 까다롭습니다.
첫 번째 구현은 조건을 m.text LIKE ? OR m.attributedBody IS NOT NULL로
넓히고 디코딩된 텍스트를 Python에서 다시 필터링했습니다. 두 번째 절이 거의 모든
최신 행에 대해 참이므로 쿼리의 LIMIT가 Python 필터가 실행되기 전에 스캔을
최신 수백 개 메시지로 잘라냈습니다 — 따라서 더 오래된 일치 항목은 조용히
사라졌습니다. 실제 메시지에 대한 검색은 느리기보다는 결과 0개를 반환했습니다.
916 MB 기록에서 검색은 사실상 지난 며칠만 커버했습니다.
해결책은 쿼리마다 디코딩하는 대신 한 번만 디코딩하는 것입니다. index.py는
디코딩된 casefold 본문을 ~/Library/Caches/apple-messages-mcp/search-index.db에
미러링하며, 검색은 이에 조인합니다 — 따라서 일치, 필터, 정렬 및 LIMIT 모두
SQL에서 전체 기록에 적용됩니다. 미러는 다음과 같습니다:
증분식. 새 메시지는
message.ROWID워터마크로 찾습니다. 편집 및 unsend는 기존 ROWID를 재사용하므로 각 새로고침은 가장 최근 2000개 행도 확인합니다 — 하지만date_edited가 설정되었거나 두 본문 열이 모두 NULL인 행만 확인합니다. 매 검색마다 2000개 blob을 다시 디코딩하는 것은 실제 작업이며 거의 항상 아무것도 찾지 못하기 때문입니다. Messages가 어떤 이유로 스탬프를 찍지 않은 편집이나 해당 창보다 오래된 편집은refresh_search_index(rebuild=True)가 필요합니다.attributedBody디코더를 개선하는 것도 재구축이 필요하며,SCHEMA_VERSION을 올리면 강제로 재구축됩니다.Casefold만 적용. 표시 텍스트는 여전히 chat.db에서 오므로 미러는 순수하게 일치 판별기입니다.
str.casefold()를 저장하면 크기가 절반으로 줄고 비ASCII에 대해 대소문자 무시 일치가 정확해집니다 — SQLite의LIKE는 ASCII에 대해서만 대소문자를 접습니다.일회용.
~/Library/Caches에 있으며 삭제되면 재구축됩니다. 여기서 chat.db에 쓰는 일은 없습니다.
이전 계획과 달리 FTS5가 아닙니다: FTS5는 전체 토큰을 일치시키므로
MATCH 'dentist'는 "mydentist"를 찾지 못하며, 이는 search_messages가
문서화하는 부분 문자열 의미론보다 좁습니다. 컴팩트한 casefold 텍스트에 대한
부분 문자열 스캔은 이미 빠르므로 FTS5는 사용할 수 없는 의미론을 위해 인덱스를
두 배로 늘리는 셈입니다. 나중에 쿼리가 실제로 느려지면 추가하는 것은 제한된
변경입니다.
읽기 전용 및 비잠금. 연결은 mode=ro로 열리며 어떤 문도 데이터베이스를
변경하지 않습니다. SQLite가 라이브 WAL을 읽기 전용으로 열 수 없으면 비공개
스냅샷 복사본으로 폴백하므로 실행 중인 Messages.app을 방해하지 않습니다.
탭백, 편집, 답글. 반응은 associated_message_type(2000–2007, 3000번대는
해당 반응의 제거)에서 디코딩되고, 스레드 답글은 thread_originator_guid에서,
편집은 date_edited에서 디코딩됩니다.
메시지 보내기
Messages에는 초안 객체가 없으므로 Mail 확장 프로그램의 초안 우선 설계와 정확히 동일한 방식은 없습니다. 따라서 쓰기 경로는 두 수준으로 제공되며, 의도적으로 동일하지 않습니다.
compose_message — 안전한 기본값. imessage: / sms: URL 스킴을 통해
수신자와 본문이 미리 채워진 Messages를 열고 멈춥니다. 사람이 읽고 보내기
버튼을 누르므로 Claude의 지시만으로는 어떤 것도 기기 밖으로 나가지 않습니다.
이것은 새 대화를 시작하는 유일한 방법이기도 합니다. 권한이 전혀 필요 없습니다.
send_message — 즉시 전달. 스크립팅 인터페이스의 send를 사용하며
취소할 수 없습니다. 전화번호가 아닌 chat_id를 받는데, 이는 제한이 아니라
핵심입니다: 사전은 participant 또는 chat을 모두 허용하며, 기존 채팅을
GUID로 지정하면 호출자가 추측하여 iMessage 사용자에게 SMS를 조용히 보내는
대신 Messages가 전송 수단(iMessage / SMS / RCS)을 선택하게 합니다. 또한
우연한 트리거를 방지하기 위한 순수한 보호 장치로 confirm=True가 필요합니다.
검증된 것과 검증되지 않은 것
macOS 26.5.2에서 확인됨 — 사전이 노출하는 것은
send : direct-parameter (file | text), to: (participant | chat)service type 열거형은 SMS, iMessage, RCS 이고, chat에는 주소
지정을 위한 GUID id 속성이 있으며, 생성된 AppleScript가 컴파일됩니다.
확인되지 않음: 실제 전송이 실제로 전달되는지. Apple은 이전에 AppleScript
send를 깨뜨린 적이 있으며, 사전에 존재한다고 해서 작동한다는 증거는 된 적이
없습니다. 테스트 스위트에는 메시지를 전달하는 것이 없으므로 첫 실제 전송이
실험입니다. 실패하면 "Send Message" 동작이 있는 shortcuts run이 다음으로
시도할 가치가 있는 폴백입니다.
메시지 텍스트는 스크립트 소스에 삽입되는 대신 osascript 인수(on run argv)로
AppleScript에 도달하므로 큰따옴표가 포함된 본문은 구문 오류나 주입이 아니라
단순히 무해합니다.
첨부 파일 보내기는 연결되어 있지 않지만, file 직접 매개변수가 있으므로
도달 가능한 범위에 있습니다.
개발
python3 tests/test_db.py # SQL, decoder, and search-index tests
python3 tests/test_send.py # compose URLs, send guards, argv safety
python3 tools/probe_schema.py # verify the real chat.db (needs Full Disk Access)
./build.sh # test, validate manifest, pack the .mcpbtests/test_db.py는 실제 스키마로 임시 데이터베이스를 구축하므로 전체 디스크
접근 권한이나 실제 메시지 기록 없이 SQL을 검증할 수 있습니다. 그 중 하나는
3000개의 최신 메시지 아래에 일치 항목을 묻어 두는데, 이는 위에서 설명한
잘린 검색 버그에 대한 회귀 테스트입니다.
tests/test_send.py는 아무것도 보내지 않거나 창을 열지 않습니다: URL 빌더,
가드 절, 정확한 osascript argv를 다룹니다 — 따라서 어디서나 안전하며, 그에
따라 Apple의 send가 작동하는지 여부는 알 수 없습니다.
두 스위트 모두 실제 검색 인덱스를 건드리지 않으며, 둘 다 임시 인덱스를 주입합니다.
라이선스
MIT
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
- AlicenseNot gradedqualityCmaintenanceEnables Claude to send and read iMessages on macOS, with smart contact lookup, message history retrieval, and cross-conversation search using natural language commands.5MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to read iMessage history and send messages on macOS. Supports conversation listing, message search with keyword and semantic modes, contact lookup, and sending messages to existing conversations.1311MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude to read and search through iMessage, SMS, and RCS conversations, including mixed-protocol group chats with Android users. It decodes binary message data from the macOS Messages database to provide a comprehensive view of message history.19MIT
- AlicenseNot gradedqualityBmaintenanceEnables Claude to send and read iMessages on macOS, with human approval required for sending and no auto-replies.51Apache 2.0
Related MCP Connectors
Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.
MCP connector for iMessage & Contacts via a local Mac agent + Vercel relay
Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.
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/falconbradley/claude-connector-apple-messages'
If you have feedback or need assistance with the MCP directory API, please join our Discord server