apple-notes-reminders-mcp
apple-notes-reminders-mcp
macOS에서 MCP(Model Context Protocol) 호환 클라이언트(예: Claude Desktop)에 Apple Notes 및 Apple Reminders를 노출하는 MCP 서버입니다.
기능
이 서버는 Notes와 Reminders를 읽고 쓰기 위한 일련의 도구를 등록합니다. Notes 도구는 노트 및 폴더 나열, 검색(이미지 첨부 파일의 인식된 텍스트 포함), 읽기, 생성, 업데이트, 이동, 삭제와 태그, 고정 상태, 이미지 첨부 파일, 최근 삭제 항목을 포함합니다. Reminders 도구는 동일한 작업 외에도 하위 작업, 일괄 생성, 완료, 기한, 플래그, 반복, 위치/조기 알림, 저장된 필터 보기, 템플릿, 대량 단어 기반 필터를 포함합니다.
Related MCP server: apple-reminders-mcp
아키텍처
두 도메인은 서로 다른 메커니즘을 통해 읽고 씁니다.
읽기는 가능한 경우 SQLite를 통해 수행됩니다. 노트는 디스크에 있는 NoteStore 데이터베이스에서 직접 읽습니다:
~/Library/Group Containers/group.com.apple.notes/NoteStore.sqlite데이터베이스는 임시 위치에 복사되어 읽기 전용으로 열리므로, 실제 저장소는 건드리거나 잠기지 않습니다. 노트 본문은 ZICNOTEDATA.ZDATA에 gzip 압축된 protobuf blob으로 저장됩니다. 디코더는 이를 압축 해제하고 protobuf 구조를 결정론적으로 탐색하여 텍스트 및 서식 메타데이터를 추출합니다.
쓰기는 AppleScript(osascript)를 통해 수행됩니다. NoteStore 데이터베이스는 Notes.app이 소유하므로 외부에서 안전하게 쓸 수 없습니다. 따라서 생성/업데이트/삭제/이동 작업은 AppleScript를 통해 Notes.app에 위임됩니다. 미리 알림 하위 작업도 AppleScript를 사용합니다. 공개 EventKit API가 이를 노출하지 않기 때문입니다.
노트 본문 디코딩
노트 본문을 올바르게 읽는 것은 이 프로젝트의 미묘한 부분입니다. 본문은 일반 텍스트가 아니라 gzip blob 안의 protobuf 메시지입니다. 디코더는:
ZDATA를 압축 해제하고 결정론적으로 노트 텍스트 메시지(document → field 2 → field 3)로 이동한 후 텍스트 문자열(field 2)을 읽습니다. 이는 이전에 가장 "깨끗한" 문자열 후보를 스캔하고 체크리스트가 포함된 노트에 대해 손상된 바이너리를 반환하던 휴리스틱을 대체했습니다.반복되는 스팬별 단락 메타데이터를 탐색하여 체크리스트 항목과 완료/미완료 상태를 감지하고, 체크된 항목 앞에
- [x], 체크되지 않은 항목 앞에- [ ]를 추가합니다.
올바른 동작을 위해 두 가지 세부 사항이 중요합니다:
Varint는
<<연산자 대신 곱셈(* 2 ** shift)으로 누적됩니다. JavaScript의 비트 시프트는 32비트로 자르기 때문에 큰 오프셋을 손상시킵니다.스팬 길이는 UTF-16 코드 단위로 측정되며, Apple이 저장하는 방식과 일치하므로 텍스트에 멀티바이트 문자나 이모지가 포함되어 있어도 체크리스트 마커가 정렬된 상태를 유지합니다.
SQLite 디코딩이 어떤 이유로든 실패하면, notes_get은 AppleScript를 통해 노트 본문을 읽는 것으로 대체됩니다. 이는 깨끗한 텍스트를 반환하지만 체크박스 상태는 복구할 수 없습니다(Apple의 AppleScript body 속성은 이를 인코딩하지 않습니다).
첨부 파일
이미지 첨부 파일은 ZICCLOUDSYNCINGOBJECT의 ICAttachment/ICMedia 행에서 읽습니다(Z_PRIMARYKEY/Z_ENT를 통해 동적으로 확인되며 하드코딩되지 않습니다. 숫자 엔터티 ID와 ZACCOUNT*/ZPARENT 열 이름은 macOS 버전에 따라 변경됩니다). 실제 파일은 디스크의 다음 경로에 있습니다:
~/Library/Group Containers/group.com.apple.notes/Accounts/{account}/Media/{media id}/{generation}/{filename}notes_get은 각 첨부 파일의 ID, 파일 이름, 유형, 확인된 파일 경로 및 인식된 OCR 텍스트를 반환합니다. notes_get_attachment는 이미지 첨부 파일을 MCP 이미지 콘텐츠 블록으로 가져옵니다. notes_search는 OCR 텍스트를 검색 코퍼스에 포함시켜 스크린샷 내에만 있는 텍스트도 검색 가능하게 합니다. 첨부 파일 추가는 지원되지 않습니다. 아래 "알려진 제한 사항"을 참조하세요.
미리 알림의 flagged 및 기타 AppleScript 전용 읽기
EventKit의 공개 API에는 flagged 속성이 없으므로, AppleScript를 통해 완전히 읽고 쓰며, id로 EventKit 기반 Reminder 객체에 병합됩니다. 전체 라이브러리 플래그 검색은 상대적으로 느립니다(AppleScript의 속성당 IPC 오버헤드). 따라서 reminders_list/reminders_search는 단일 목록으로 범위가 지정된 경우에만 flagged를 포함합니다. 모든 목록에서 필요할 때는 명시적인 flagged 필터와 함께 reminders_query_where/reminders_view를 사용하세요.
캐싱
notesStore.ts는 열린 SQLite 연결, 감지된 스키마, 각 노트의 디코딩된 본문을 캐시합니다. 모든 호출 시 원본 파일 및 해당 -wal/-shm 사이드카의 mtime을 비교하여 무효화됩니다. 실제 NoteStore에 쓰기가 발생하면 항상 캐시가 무효화되므로 이는 순수한 성능 향상이며, 데이터 부실 위험이 없습니다. 디코딩된 본문은 추가로 (Z_PK, 수정 날짜)를 키로 사용하므로, 편집된 노트는 오래된 캐시 히트 대신 새 캐시 항목을 얻습니다.
요구 사항 및 권한
macOS(macOS 26 / Tahoe에서 테스트됨)
Node.js 18+(SQLite 액세스를 위해
better-sqlite3사용)Notes.app 및 Reminders.app이 설정되어 있고 계정에 로그인되어 있어야 함
자동화 권한: 호스트 애플리케이션(예: Claude Desktop)이 Notes 및 Reminders를 제어할 수 있도록 허용해야 합니다. macOS가 처음 사용 시 프롬프트를 표시하거나 시스템 설정 › 개인정보 보호 및 보안 › 자동화에서 부여할 수 있습니다.
전체 디스크 접근: 호스트 애플리케이션이
~/Library/Group Containers/group.com.apple.notes/NoteStore.sqlite의 NoteStore 데이터베이스를 읽으려면 필요합니다. 시스템 설정 › 개인정보 보호 및 보안 › 전체 디스크 접근에서 부여하세요.
macOS 버전 참고 사항
ZICCLOUDSYNCINGOBJECT 내의 열 이름과 숫자 엔터티 ID는 macOS/Notes.app 버전에 따라 변경됩니다(예: 다른 시스템에서 ZACCOUNT1부터 ZACCOUNT8까지 모두 활성 폴더→계정 외래 키로 확인되었으며, ICAccount/ICAttachment/ICMedia의 Z_ENT 값은 안정적이지 않습니다). notesStore.ts의 detectSchema()는 이러한 값을 하드코딩하지 않고 캐시 미스가 발생할 때마다 다시 감지합니다. 새 열 이름을 하드코딩하기 전에 해당 파일의 주석을 참조하세요. 이 코드는 macOS 26(Tahoe)에 대해 개발 및 테스트되었습니다. 감지 로직은 이전 버전을 허용하도록 작성되었지만 확인되지는 않았습니다.
설치
npm install
npm run build실행
npm start또는 dist/index.js를 클라이언트 설정에서 MCP 서버 명령으로 등록하세요.
프로젝트 구조
src/
index.ts MCP server + tool registrations
notes.ts Notes tool implementations (SQLite reads, AppleScript writes)
notesStore.ts NoteStore SQLite access + protobuf body decoder
reminders.ts Reminders tool implementations + local template/saved-view storage
applescript.ts Shared runAppleScript() helper (argv-only, never string-spliced)
markdown.ts Markdown -> Notes-compatible HTML converter
swift/
reminders-daemon.swift Persistent EventKit daemon (NDJSON over stdio)
scripts/
test-phase2.mjs Protobuf/checklist decoder tests (+ pinned full-pipeline fixtures)
test-markdown.mjs Markdown -> HTML converter tests
test-schema-detection.mjs Schema-detection sanity checks against the live DB
dist/ Compiled output (generated by `npm run build`)미리 알림 템플릿과 저장된 필터 보기(reminders_save_template, reminders_save_view)는 ~/.apple-notes-reminders-mcp/ 아래에 JSON으로 저장됩니다. EventKit에는 이러한 개념이 없으므로 서버 측 데이터베이스는 없습니다.
권한 및 개인정보 보호에 관한 참고 사항
모든 읽기는 로컬 NoteStore 데이터베이스의 임시 복사본에 대해 로컬에서 수행됩니다. 서버 자체가 장치 외부로 데이터를 보내지 않습니다. 서버는 사용자가 자신의 Notes 및 Reminders에 이미 가지고 있는 동일한 액세스 권한을 필요로 합니다.
테스트
npm run build && node scripts/test-phase2.mjs # protobuf/checklist decoder
npm run build && node scripts/test-markdown.mjs # markdown -> Notes-HTML converter
npm run build && node scripts/test-schema-detection.mjs # schema detection sanity (live DB)test-markdown.mjs는 완전히 결정론적입니다. test-phase2.mjs의 단위 테스트 섹션(varint 안전성, 체크리스트 에지 케이스, 고정된 전체 파이프라인 픽스처)은 자체 포함되어 있습니다. 마지막 "Real DB notes" 섹션과 test-schema-detection.mjs 전체는 실제 라이브 Notes 데이터베이스를 읽으며, 전체 디스크 접근 권한과 실제 노트 데이터가 있어야만 통과합니다. 따라서 원저작자의 컴퓨터가 아닌 다른 기계에서는 실패/오류가 예상됩니다(test-phase2.mjs의 DB 섹션은 특히 해당 라이브러리에만 존재하는 노트 ID를 참조합니다).
알려진 제한 사항
폴더 재부모 설정이 구현되지 않았습니다. Notes.app의 AppleScript
move <folder> to <folder>가 신뢰할 수 없음이 확인되었습니다. 폴더 참조가folder id,whose필터, 또는 수동 스캔에서 오든 관계없이 간헐적으로 오류(item N of every folder kan niet worden opgevraagd)를 던지거나 조용히 아무 작업도 하지 않습니다. 폴더 이름 변경 및 삭제는 신뢰할 수 있으며 구현되어 있습니다. 한 폴더를 다른 폴더 아래로 다시 배치하는 것은, 예측할 수 없이 실패하는 도구를 제공하는 것이 없는 것보다 나쁘기 때문에 구현되지 않았습니다. 중첩된 폴더(Notes.app UI를 통해 생성된 것이지 이 서버에 의해 생성된 것이 아님)의 이름 변경/삭제는 전체"Parent/Child"경로를 전달하여 지원됩니다.이 서버를 통해 첨부 파일을 추가할 방법이 없습니다. 첨부 파일 읽기는 완전히 지원됩니다(위 참조). 추가하려면 Notes.app UI가 필요합니다. Shortcuts-CLI 기반 브리지(
shortcuts run <name> -i <path>)가 조사되었지만, 제로 설정 도구로는 실행 가능하지 않음이 확인되었습니다. 정확히 하나의 입력 파일을 허용하며 대상 노트를 전달할 방법이 없고,shortcutsCLI는 이미 존재하는 단축키만 실행할 수 있을 뿐 생성할 수 없습니다. 자세한 내용은notes.ts상단의 주석을 참조하세요.오디오 기록이 표시되지 않습니다. 이미지 첨부 파일의 OCR 텍스트는 표시됩니다(
notes_get,notes_search). DB에는 오디오 기록 모양의 열(ZTEMPORARYTRANSCRIPTDATA)도 있지만 불투명한 blob이며, 형식을 역공학할 수 있는 오디오 첨부 파일이 없었습니다. 실제 픽스처 데이터가 있는 미래 기여자를 위해 남겨둡니다.삭제된 폴더가
notes_list_folders에서 사라지는 데 1분 이상 걸릴 수 있습니다. 확인됨: 삭제 자체는 Notes.app에서 즉시(AppleScript에도 즉시 표시) 이루어지지만, SQLite 행의 소프트 삭제 플래그가 60초 이상 지연될 수 있습니다. 이는 iCloud 동기화 왕복을 기다리는 것으로 보이며, 다른 곳에서 일반적으로 보이는 ~5초 SQLite 지연보다 훨씬 깁니다. 이 서버가 단축할 수 있는 것이 아닙니다. 캐싱 버그처럼 보이는 현상을 추적하는 사람을 위해notesStore.ts에 문서화되어 있습니다."스마트 폴더"(PLAN의 원래 표현)는 Reminders가 가지고 있는 방식의 일반적인 Notes.app 기능으로 실제로 존재하지 않습니다. DB의
ZFOLDERTYPE=1은 기본 "최근 삭제된 항목" 폴더만 일반 폴더와 구분합니다. 해당 플래그에 대한 읽기 전용 지원이 존재합니다(notes_list_folders의isSmartFolder). 태그 기반 그룹화(notes_list_tags)가 Notes의 "저장된 스마트 목록"에 더 가까운 유사 기능입니다.미리 알림 "목록 섹션"(최신 Reminders.app 그룹화 기능)은 읽히지 않습니다. EventKit이 이를 노출하지 않으며, 이를 수행하려면 Reminders 자체의 별도 디스크 저장소를 역공학해야 하며, 이번 패스에서는 시도되지 않았습니다.
도구
Notes
도구 | 목적 |
| 모든 폴더 조회 — id, 이름, 중첩 경로, 계정, 스마트 폴더 여부, 노트 수 |
| 노트 조회, 선택적 폴더 필터, 정렬 + limit/offset 페이지네이션 포함 |
| 이름이나 id로 노트 조회, 첨부 파일 메타데이터 포함 |
| 이미지 첨부 파일을 MCP 이미지 블록으로 가져오기 |
| 폴더 내 모든 노트를 한 번에 읽어 디코딩된 본문 포함, 정렬 + 페이지네이션 |
| 전체 폴더에서 제목/본문/OCR 텍스트 검색, 정렬 + 페이지네이션 |
| 노트 생성 (markdown/html/text 본문) |
| 노트 업데이트 (바꾸기/추가/앞에 추가, 첨부 파일 안전 장치) |
| 노트 삭제 |
| 폴더 생성 |
| 폴더 이름 변경 (최상위 또는 중첩, 경로 기준) |
| 폴더 삭제 (해당 폴더의 노트는 최근 삭제됨으로 이동) |
| 노트를 다른 폴더로 이동 |
| 노트 전체에서 사용된 |
| 최근 삭제됨 폴더의 노트 조회 |
| 최근 삭제됨에서 노트 복원 |
| 단어 기반 필터(폴더, 검색, 태그)로 일치하는 노트 개수/조회 |
| 일치하는 노트 일괄 삭제 (확인 게이트 있음) |
| 일치하는 노트 일괄 이동 (확인 게이트 있음) |
미리 알림
도구 | 목적 |
| 모든 미리 알림 목록 조회 |
| 미리 알림 조회, 선택적 목록 필터, 정렬 + limit/offset 페이지네이션 |
| 이름이나 id로 미리 알림 조회 |
| 이름/메모/목록으로 미리 알림 검색 |
| Reminders.app 스타일 스마트 목록: 오늘/예정/지연/긴급/깃발/완료 |
| 미리 알림 생성 (자연어 마감일, 깃발, 반복, 이른/위치 알람) |
| 한 번의 기본 호출로 여러 미리 알림 생성 (단일 DB 커밋) |
| 미리 알림 업데이트 |
| 완료/미완료로 표시 |
| 미리 알림 삭제 |
| 목록 생성 |
| 목록 이름 변경 |
| 목록과 해당 미리 알림 삭제 |
| 하위 작업 추가 (AppleScript — EventKit에 공개 하위 작업 API 없음) |
| 하위 작업 완료/복원 |
| 완료된 미리 알림 일괄 삭제, 선택적으로 목록 범위 지정 |
| 단어 기반 필터로 일치하는 미리 알림 개수/조회 |
| 일치하는 미리 알림 일괄 삭제 (확인 게이트 있음) |
| 일치하는 미리 알림 일괄 완료/미완료 처리 (확인 게이트 있음) |
| 일치하는 미리 알림을 다른 목록으로 일괄 이동 (확인 게이트 있음) |
| 이름 있는 미리 알림 템플릿 저장 |
| 저장된 템플릿 조회 |
| 저장된 템플릿 삭제 |
| 템플릿에서 미리 알림 생성, 호출별 재정의 가능 |
| 이름 있는 단어 기반 필터를 재사용 가능한 보기로 저장 |
| 저장된 보기 조회 |
| 저장된 보기 삭제 |
| 저장된 보기를 실행하여 일치하는 미리 알림 반환 |
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
- Alicense-qualityCmaintenanceAn MCP server that enables AI assistants like Claude to access and manipulate Apple Notes on macOS, allowing for retrieving, creating, and managing notes through natural language interactions.82MIT
- AlicenseAqualityDmaintenanceAn MCP server that connects Claude Desktop to Apple Reminders on macOS via AppleScript.510MIT
- AlicenseAqualityBmaintenanceAn MCP server that enables LLM agents to list, read, create, update, delete, and search Apple Notes on macOS.611AGPL 3.0
- Flicense-qualityCmaintenanceAn MCP server that gives AI assistants access to your Apple Notes, Reminders, and Contacts — with optional BERT-powered semantic search.2
Related MCP Connectors
Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.
MCP connector for Apple Reminders — search, create, complete, and edit via your own Mac.
MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.
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/martijnstegink/apple-notes-reminders-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server