Skip to main content
Glama
martijnstegink

apple-notes-reminders-mcp

apple-notes-reminders-mcp

macOS에서 MCP(Model Context Protocol) 호환 클라이언트(예: Claude Desktop)에 Apple NotesApple 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 메시지입니다. 디코더는:

  1. ZDATA를 압축 해제하고 결정론적으로 노트 텍스트 메시지(document → field 2 → field 3)로 이동한 후 텍스트 문자열(field 2)을 읽습니다. 이는 이전에 가장 "깨끗한" 문자열 후보를 스캔하고 체크리스트가 포함된 노트에 대해 손상된 바이너리를 반환하던 휴리스틱을 대체했습니다.

  2. 반복되는 스팬별 단락 메타데이터를 탐색하여 체크리스트 항목과 완료/미완료 상태를 감지하고, 체크된 항목 앞에 - [x] , 체크되지 않은 항목 앞에 - [ ] 를 추가합니다.

올바른 동작을 위해 두 가지 세부 사항이 중요합니다:

  • Varint<< 연산자 대신 곱셈(* 2 ** shift)으로 누적됩니다. JavaScript의 비트 시프트는 32비트로 자르기 때문에 큰 오프셋을 손상시킵니다.

  • 스팬 길이는 UTF-16 코드 단위로 측정되며, Apple이 저장하는 방식과 일치하므로 텍스트에 멀티바이트 문자나 이모지가 포함되어 있어도 체크리스트 마커가 정렬된 상태를 유지합니다.

SQLite 디코딩이 어떤 이유로든 실패하면, notes_get은 AppleScript를 통해 노트 본문을 읽는 것으로 대체됩니다. 이는 깨끗한 텍스트를 반환하지만 체크박스 상태는 복구할 수 없습니다(Apple의 AppleScript body 속성은 이를 인코딩하지 않습니다).

첨부 파일

이미지 첨부 파일은 ZICCLOUDSYNCINGOBJECTICAttachment/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/ICMediaZ_ENT 값은 안정적이지 않습니다). notesStore.tsdetectSchema()는 이러한 값을 하드코딩하지 않고 캐시 미스가 발생할 때마다 다시 감지합니다. 새 열 이름을 하드코딩하기 전에 해당 파일의 주석을 참조하세요. 이 코드는 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>)가 조사되었지만, 제로 설정 도구로는 실행 가능하지 않음이 확인되었습니다. 정확히 하나의 입력 파일을 허용하며 대상 노트를 전달할 방법이 없고, shortcuts CLI는 이미 존재하는 단축키만 실행할 수 있을 뿐 생성할 수 없습니다. 자세한 내용은 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_foldersisSmartFolder). 태그 기반 그룹화(notes_list_tags)가 Notes의 "저장된 스마트 목록"에 더 가까운 유사 기능입니다.

  • 미리 알림 "목록 섹션"(최신 Reminders.app 그룹화 기능)은 읽히지 않습니다. EventKit이 이를 노출하지 않으며, 이를 수행하려면 Reminders 자체의 별도 디스크 저장소를 역공학해야 하며, 이번 패스에서는 시도되지 않았습니다.

도구

Notes

도구

목적

notes_list_folders

모든 폴더 조회 — id, 이름, 중첩 경로, 계정, 스마트 폴더 여부, 노트 수

notes_list

노트 조회, 선택적 폴더 필터, 정렬 + limit/offset 페이지네이션 포함

notes_get

이름이나 id로 노트 조회, 첨부 파일 메타데이터 포함

notes_get_attachment

이미지 첨부 파일을 MCP 이미지 블록으로 가져오기

notes_get_folder

폴더 내 모든 노트를 한 번에 읽어 디코딩된 본문 포함, 정렬 + 페이지네이션

notes_search

전체 폴더에서 제목/본문/OCR 텍스트 검색, 정렬 + 페이지네이션

notes_create

노트 생성 (markdown/html/text 본문)

notes_update

노트 업데이트 (바꾸기/추가/앞에 추가, 첨부 파일 안전 장치)

notes_delete

노트 삭제

notes_create_folder

폴더 생성

notes_rename_folder

폴더 이름 변경 (최상위 또는 중첩, 경로 기준)

notes_delete_folder

폴더 삭제 (해당 폴더의 노트는 최근 삭제됨으로 이동)

notes_move

노트를 다른 폴더로 이동

notes_list_tags

노트 전체에서 사용된 #hashtags 조회, 노트 수 포함

notes_recently_deleted

최근 삭제됨 폴더의 노트 조회

notes_restore_note

최근 삭제됨에서 노트 복원

notes_query_where

단어 기반 필터(폴더, 검색, 태그)로 일치하는 노트 개수/조회

notes_delete_where

일치하는 노트 일괄 삭제 (확인 게이트 있음)

notes_move_where

일치하는 노트 일괄 이동 (확인 게이트 있음)

미리 알림

도구

목적

reminders_list_lists

모든 미리 알림 목록 조회

reminders_list

미리 알림 조회, 선택적 목록 필터, 정렬 + limit/offset 페이지네이션

reminders_get

이름이나 id로 미리 알림 조회

reminders_search

이름/메모/목록으로 미리 알림 검색

reminders_view

Reminders.app 스타일 스마트 목록: 오늘/예정/지연/긴급/깃발/완료

reminders_create

미리 알림 생성 (자연어 마감일, 깃발, 반복, 이른/위치 알람)

reminders_create_batch

한 번의 기본 호출로 여러 미리 알림 생성 (단일 DB 커밋)

reminders_update

미리 알림 업데이트

reminders_complete

완료/미완료로 표시

reminders_delete

미리 알림 삭제

reminders_create_list

목록 생성

reminders_rename_list

목록 이름 변경

reminders_delete_list

목록과 해당 미리 알림 삭제

reminders_add_subtask

하위 작업 추가 (AppleScript — EventKit에 공개 하위 작업 API 없음)

reminders_complete_subtask

하위 작업 완료/복원

reminders_delete_completed

완료된 미리 알림 일괄 삭제, 선택적으로 목록 범위 지정

reminders_query_where

단어 기반 필터로 일치하는 미리 알림 개수/조회

reminders_delete_where

일치하는 미리 알림 일괄 삭제 (확인 게이트 있음)

reminders_complete_where

일치하는 미리 알림 일괄 완료/미완료 처리 (확인 게이트 있음)

reminders_move_where

일치하는 미리 알림을 다른 목록으로 일괄 이동 (확인 게이트 있음)

reminders_save_template

이름 있는 미리 알림 템플릿 저장

reminders_list_templates

저장된 템플릿 조회

reminders_delete_template

저장된 템플릿 삭제

reminders_create_from_template

템플릿에서 미리 알림 생성, 호출별 재정의 가능

reminders_save_view

이름 있는 단어 기반 필터를 재사용 가능한 보기로 저장

reminders_list_views

저장된 보기 조회

reminders_delete_view

저장된 보기 삭제

reminders_run_view

저장된 보기를 실행하여 일치하는 미리 알림 반환

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    -
    quality
    C
    maintenance
    An 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.
    82
    MIT
  • F
    license
    -
    quality
    C
    maintenance
    An MCP server that gives AI assistants access to your Apple Notes, Reminders, and Contacts — with optional BERT-powered semantic search.
    2

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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