프로토타입 · 미리 보기: 공식 레지스트리의 모든 서버를 담고 있으며 30분마다 동기화해요. 리뷰와 계정 기능은 다음 단계에서 열려요.
PopNx MCPAI를 쓰는 사람을 위한 MCP 서버 · 쉬운 말로 설명해요

Apple Messages

제작자: mgcrea버전 1.37.1i★ –i내 컴퓨터에서 실행
레지스트리 이름io.github.mgcrea/mcp-apple-messages

설치

개요

제작자가 쓴 설명(영어 원문)

Search and read Apple Messages — chats and decoded text, sending off by default

PopNx MCP의 세 기둥

이 세 가지는 절대 하나의 점수로 합치지 않아요. 의견, 측정, 인기는 서로 다른 것이니까요.

할 수 있는 일

이 서버는 아직 쉬운 말로 된 요약을 쓰지 못했어요. 아래는 레지스트리에서 읽어 온 사실이에요.

  • 연결 방식: 내 컴퓨터에서 실행
  • 전송 방식: stdio
  • 카테고리: 검색 및 AI 기억

설치

쓰고 있는 AI 앱을 고른 다음 설정을 복사하세요.

설치하기 전에

  • 기본 점검: 1개 중 1개 통과
  • 내 컴퓨터에서 내 사용자 계정의 권한(파일, 네트워크, 앱)으로 실행돼요.
  • 직접 입력할 값: APPLE_MESSAGES_ALLOW_WRITES, APPLE_MESSAGES_ALLOW_CODES, APPLE_MESSAGES_ALLOW_FILE_SEND

필요한 것

  • npmNode.js 설치(npx 명령어용)

어떤 앱을 쓰세요?

위에서 앱을 고르세요. 기억해 두었다가 다음부터는 버튼에 “…에 설치”라고 표시해요.

Claude Desktop → Settings → Developer → Edit Config를 열고 claude_desktop_config.json에 이 내용을 붙여 넣으세요

{
  "mcpServers": {
    "apple-messages": {
      "command": "npx",
      "args": [
        "-y",
        "@mgcrea/mcp-apple-messages"
      ],
      "env": {
        "APPLE_MESSAGES_ALLOW_WRITES": "your-value",
        "APPLE_MESSAGES_ALLOW_CODES": "your-value",
        "APPLE_MESSAGES_ALLOW_FILE_SEND": "your-value"
      }
    }
  }
}

터미널에서 이 명령어를 실행하세요

claude mcp add apple-messages --env APPLE_MESSAGES_ALLOW_WRITES=your-value --env APPLE_MESSAGES_ALLOW_CODES=your-value --env APPLE_MESSAGES_ALLOW_FILE_SEND=your-value -- npx -y @mgcrea/mcp-apple-messages

실행하기 전에 빈 값을 채워 주세요.

Cursor에서 열기

또는 설정을 직접 복사하기

프로젝트의 .cursor/mcp.json 또는 ~/.cursor/mcp.json에 붙여 넣으세요

{
  "mcpServers": {
    "apple-messages": {
      "command": "npx",
      "args": [
        "-y",
        "@mgcrea/mcp-apple-messages"
      ],
      "env": {
        "APPLE_MESSAGES_ALLOW_WRITES": "your-value",
        "APPLE_MESSAGES_ALLOW_CODES": "your-value",
        "APPLE_MESSAGES_ALLOW_FILE_SEND": "your-value"
      }
    }
  }
}

브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.

VS Code에서 열기

또는 설정을 직접 복사하기

프로젝트의 .vscode/mcp.json에 붙여 넣으세요

{
  "servers": {
    "apple-messages": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@mgcrea/mcp-apple-messages"
      ],
      "env": {
        "APPLE_MESSAGES_ALLOW_WRITES": "your-value",
        "APPLE_MESSAGES_ALLOW_CODES": "your-value",
        "APPLE_MESSAGES_ALLOW_FILE_SEND": "your-value"
      }
    }
  }
}

브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.

이 서버는 내 컴퓨터에서 실행되는데, ChatGPT는 인터넷에 있는 서버에만 연결할 수 있어요. 다른 앱을 고르세요.

선택한 앱은 이 기기의 쿠키에만 저장돼요. 계정은 필요 없어요.

직접 입력할 값

  • APPLE_MESSAGES_ALLOW_WRITES env
    Register the mutating tools. Off by default, and the gate decides whether the write tools exist at all rather than merely refusing — an agent with writes off cannot see them.
  • APPLE_MESSAGES_ALLOW_CODES env
    Register apple_messages_find_codes, which reads one-time codes out of recent messages. Its own gate rather than allowWrites: it is a read, and the one read most worth an explicit decision.
  • APPLE_MESSAGES_ALLOW_FILE_SEND env
    Let apple_messages_send_message attach a local file. Off by default even with writes on, because a path argument is a way to send anything the server can read.

이 설정은 제작자의 레지스트리 정보로 만들었어요. README와 다르면 README를 따르세요.

할 수 있는 일

내 컴퓨터에서 실행돼요. 설치하면 AI 앱에 도구 목록이 나타나요.

기본 점검i

누구나 볼 수 있는 정보를 점검했고, 코드는 읽지 않았어요. 해당하지 않는 항목은 개수에서 뺐어요. · 2026년 11월 9일 점검

  • ✓ 통과

    제작자와 저장소 일치

    레지스트리 이름이 GitHub 계정 mgcrea 기준으로 확인되었고, 이 계정이 저장소를 소유하고 있어요

  • … 아직 점검 안 함

    계속 관리되고 있음

    아직 GitHub에서 이 저장소를 읽어 오지 않았어요

  • … 아직 점검 안 함

    라이선스 있음

    아직 GitHub에서 이 저장소를 읽어 오지 않았어요

  • – 해당 없음

    엔드포인트 응답

    내 컴퓨터에서 실행되는 서버라 인터넷 엔드포인트가 없어요

  • – 해당 없음

    OAuth로 로그인

    내 컴퓨터에서 실행되며, 대신 로컬 설정을 사용해요

  • … 아직 점검 안 함

    도구 설명에 숨겨진 지시 없음

    내 컴퓨터에서 실행돼요. 도구 목록은 인터넷 엔드포인트가 있는 서버에서만 읽을 수 있어요

검색 및 AI 기억 카테고리의 다른 서버와 비교i

  • 이 카테고리의 다른 서버 5744개 중 0%보다 스타가 많아요
  • 이 카테고리의 다른 서버 5744개 중 96%보다 최근에 레지스트리에 공개됐어요
  • 기본 점검 결과가 이 카테고리의 다른 서버 5744개 중 100%와 같거나 더 좋아요

레지스트리에서 이 카테고리의 활성 서버 전체와 비교했어요. 스타는 게시자가 저장소를 소유한 경우에만 세요.

자주 묻는 질문

Apple Messages, 안전한가요?

해당하는 기본 점검 1개 중 1개를 통과했어요. 코드는 읽지 않았어요. 키나 토큰을 넣기 전에 서버가 어떤 권한을 요구하는지 확인하고, 꼭 필요한 권한만 있는 키를 쓰세요.

어떤 키나 코드가 필요한가요?

레지스트리에 필수 키가 나와 있지 않아요. 다만 처음 쓸 때 로그인을 요구하는 서버도 있어요.

내 컴퓨터에서 실행되나요, 클라우드에서 실행되나요?

내 컴퓨터에서 실행돼요. AI 앱이 필요할 때 실행하고, 데이터는 제작자의 서버를 거치지 않아요(서버 자체가 온라인 서비스를 호출하는 경우는 제외).

아직 관리되고 있나요?

GitHub 저장소는 마지막으로 – 변경됐고, 최신 버전(1.37.1)은 어제 레지스트리에 올라왔어요.

어떤 앱에서 쓸 수 있나요?

Claude Desktop, Claude Code, Cursor, VS Code처럼 MCP를 지원하는 앱에서 쓸 수 있어요. 내 컴퓨터에 Node.js도 있어야 해요.

대신 쓸 수 있는 건 뭐가 있나요?

같은 카테고리에는: Context7, Codebase Memory, Exa

대안

같은 카테고리에서 다른 제작자가 만든 서버예요. 스타 순으로 정렬했어요.

카드 보는 법:↓ 주간 다운로드i★ GitHub 스타i세 기둥: 리뷰 · 점검 · 사용 정도i업데이트 = 최신 버전을 레지스트리에 공개한 날i

Context7

Up-to-date docs for AI agents

제작자: upstash널리 사용됨↓ 97.3만/주★ 6.4만그저께 업데이트

컴퓨터 또는 클라우드

Codebase Memory

Codebase knowledge graph for AI agents — 162 languages, sub-ms queries, 99% fewer tokens.

제작자: DeusData널리 사용됨↓ 1.8만/주★ 4.8만22일 전 업데이트

내 컴퓨터에서 실행

Exa

Connect AI agents to Exa for web search, content fetching, and multi-step research.

제작자: exa-labs널리 사용됨★ 5.2천2개월 전 업데이트

클라우드에서 실행✓ exa.ai

제작자의 README

README 열기

제작자의 저장소에서 쓰인 그대로 가져왔어요. PopNx MCP가 검토하거나 보증한 내용이 아니에요. HTML, 이미지, 스크립트는 제거했어요. 링크를 누르면 이 사이트를 벗어나요.

@mgcrea/mcp-apple-messages

Model Context Protocol server for Apple Messages — iMessage, SMS and RCS — on macOS.

Unofficial. Not affiliated with Apple. It reads the message store already on your Mac.

The surface with no second lane

Every other server in this family has two ways in and picks the faster one. This one has exactly one, and that is measured rather than assumed: every read through Messages' scripting dictionary fails. It answers Application isn't running even while NSRunningApplication reports it running, because it lives as a windowless background process that declines to wake for a script.

So Full Disk Access is mandatory, not an upgrade. Without it this server does nothing at all — there is no degraded mode to fall back to.

Apple Events is still here, for exactly one verb. send is the only command in the dictionary that works, which makes this the one surface where Apple Events is a write lane and nothing else — and therefore the one where the write gate is also a permission boundary. With APPLE_MESSAGES_ALLOW_WRITES off, no Apple Event is ever sent and no Automation grant is ever requested. There is no read to leak through the gate, because there is no read.

One message in thirty-two is invisible to SQL

chat.db keeps message text in two places, and the one you would reach for is the _incomplete_ one. Measured on a real 97,416-message store:

Messages97,416
With a plain text column94,043
With an attributedBody blob97,094
Blob only — no text3,051 (3.1%)

The blob is an NSArchiver _typedstream_, and no amount of SQL reaches inside one. A server that selects text returns nothing for one message in thirty-two, silently and with no error to notice.

And that ratio is a historical average. Measured through this server against a live store: 2016 through 2025 are ~99% plain text, and then it stops — from March 2026 every message is blob-only. Apple appears to have dropped the column between late February and late March. So the decoder is not handling an edge case; it is the only way to read anything recent, and a server without one would report that the conversation stopped in February.

This package decodes it. The decoder was written against ground truth — NSArchiver still ships on macOS 26 and is what wrote those blobs, so archiving a known string produces a fixture nobody has to guess at — and then validated against the whole store using text as an oracle on 94,043 labelled rows:

100.000% agreement. 97,094 of 97,094 blobs decoded, none failed. ~2 ms per thousand.

decodeAttributedBody() is exported from the package root.

Names come from Contacts

chat.db records a correspondent as +15551234567 and nothing else, so this server depends on @mgcrea/mcp-apple-contacts to turn that into a name. Every correspondent carries both, plus a resolution status.

`unknown` is normal, not an error. Measured against a real address book: 97.6% of the last year's messages resolve, but only ~84% of the twenty-five busiest correspondents — so roughly one in six of the people you talk to most has no contact card. Code that treats an unresolved handle as a failure will be wrong several times on any real inbox.

If the Contacts permission has not been granted, resolution is skipped and handles come back raw. That is a capability downgrade reported through diagnostics, never a throw.

The lookup runs with the Contacts package's defaults. The APPLE_CONTACTS_* settings configure the Contacts server, not this one: setting them here changes nothing, and APPLE_MESSAGES_RESOLVE_CONTACTS is the only switch Messages reads for it.

Tools

Read: diagnostics, list_chats, list_messages, search_messages, get_message, count_messages.

count_messages is the arithmetic lane: totals with a sent/received split, and groupBy for counts per day, month, chat, handle or direction. It aggregates in SQL over every match, so "who do I message most" costs one small result rather than a page of conversations tallied by hand — and grouping by handle spans the several chats one person can occupy, which the per-chat totals on list_chats cannot add together. Metadata only, deliberately: message bodies from 2026 onward live in an archived blob that SQL cannot read, so a text filter here would return a number that looks right and silently omits the recent half of the store.

Opt-in read: find_codes, behind APPLE_MESSAGES_ALLOW_CODES — see Configuration. Off by default, and not covered by the write gate.

Write: send_message, and that is the whole dictionary. sdef lists three commands — send, login and logout — and the other two would sign the user out of iMessage on every device they own. There is no edit, delete, mark-as-read or reaction verb to expose, so everything this server can show you, it cannot change.

send's direct parameter is typed file OR text, and both forms ship in two lanes with different bounds. attachmentId forwards a file that is already in this Mac's Messages store — the same guid save_attachment takes, through the same "inside ~/Library/Messages, or refuse" boundary — so it reaches no arbitrary path and needs no flag beyond ALLOW_WRITES. filePath names any local file, which is an exfiltration primitive whose blast radius, unlike the text form's, is not bounded by what the model can say; it exists as a parameter only when APPLE_MESSAGES_ALLOW_FILE_SEND is on, and it is off by default. There is no directory confinement on it on purpose — see docs/messages.md for why one would be a speed bump wearing a boundary's clothes.

One call sends one thing, so a captioned photo is two calls.

Sending, and how it reports what it sent

Prefer a chatRef from list_chats over a raw handle. Messages refuses to enumerate participants for a script, so an existing conversation is the only target that can be addressed reliably — but chat carries an id, and the store holds a guid for every conversation. The read lane picks the target and the write lane addresses it by id, which is the only arrangement where neither lane has to do the thing it cannot.

Apple Events then hands back nothing at all — no identifier for what it sent. So the client takes a timestamp before the send and polls chat.db for the outgoing row:

reconciliationmeaning
matchedthe row was found; the result carries a real message ref
pendingMessages accepted the send and has not written the row yet
unavailablethere was no existing chat to look in

`pending` is not a failure. Do not retry it — the message was sent, and a retry sends it twice.

No send has yet been executed against a live Messages. The lane is written from the dictionary and from the store, and its tests run against a fake osascript on purpose. docs/messages.md records exactly what that leaves open; the safe way to measure it is a message to your own handle.

Configuration

VariableDefault
APPLE_MESSAGES_RESOLVE_CONTACTSonLook names up in Contacts.
APPLE_MESSAGES_INDEX_MODEautoauto \ro \immutable \off.
APPLE_MESSAGES_STOREautoExplicit store path.
APPLE_MESSAGES_DEFAULT_RANGE_DAYS30Window when only a start is given.
APPLE_MESSAGES_MAX_RESULTS50Default page size.
APPLE_MESSAGES_ALLOW_WRITESoffRegister send_message at all.
APPLE_MESSAGES_ALLOW_CODESoffRegister find_codes at all.
APPLE_MESSAGES_ALLOW_WATCHESoffRegister watch and unwatch.
APPLE_MESSAGES_ALLOW_EVENTSoffServe the experimental messages.received event (draft MCP Events extension, 2026-07-28 only).
APPLE_MESSAGES_ALLOW_FILE_SENDoffAdd filePath to send_message.
APPLE_MESSAGES_SEND_RECONCILE_MS5000How long to wait for the sent row.

APPLE_MESSAGES_ALLOW_CODES gates find_codes, which extracts one-time 2FA codes from recently received messages. It is a read, and it is deliberately not folded into ALLOW_WRITES: reaching a read through the write gate would mean granting the right to send a message in order to get it.

It is gated at all because of what it combines with. This server already holds the conversation history and @mgcrea/mcp-apple-mail holds the inbox — between them, the password-_reset_ channel. Adding live authentication codes completes an account-takeover primitive out of parts that were each individually reasonable, so it defaults off and the two gates are independent in both directions.

Codes are matched by signal rather than by a \d{4,8} regex, and every result carries a confidence and a matched saying how it was found; anything below high should be checked against the message body before use. See src/codes.ts in @mgcrea/mcp-apple-core — the heuristic moved there when @mgcrea/mcp-apple-safari became its second caller — and docs/passwords.md in the repo for why the Passwords app itself is unreachable and this is what ships in its place.

Notes that will bite you

  • Dates do not fit in a JavaScript number. Every date column is nanoseconds since 2001 — eighteen digits, past Number.MAX_SAFE_INTEGER — and node:sqlite _throws_ rather than truncating. Swallowed by a try/catch that throw looks exactly like "this column is empty", and it is how a probe once reported "no dates present" for all seven columns across 97,414 messages. Every query here divides in SQL so the integer never reaches JavaScript.
  • Tapbacks are rows in the message table. 2,788 of them on the measured store, and a reader that does not filter them renders Liked "see you at 8" as if somebody typed it. They are excluded from conversations by default and reported on the message they target.
  • Search covers the blob-only messages. A LIKE pass over the column (16 ms across 97,416 rows) plus a decode pass over the 3,051 rows SQL cannot see (~6 ms). Completeness turned out to be nearly free; a search that silently omitted 3% would not have been.
  • Refs are GUIDs, not rowids. SQLite reuses a deleted row's id, and Messages deletes constantly, so a rowid handed out in one turn can resolve to a different message two turns later — plausible, wrong, and silent.
  • A send cannot be taken back, and nothing here pretends otherwise. There is no unsend, no draft and no preview in the dictionary; send delivers. The tool is gated on ALLOW_WRITES, requires `confirm: true

앞부분만 보여 드려요. 나머지는 저장소에서 읽어 보세요

PopNx에게 묻기