Repository navigation
Releases: shadow173/imessage-mcp
Releases · shadow173/imessage-mcp
Release list
v0.2.1: fix sign-outs after a dropped refresh response
Fixed
- Connected clients could be signed out with "auth failed" after a network blip. Refresh tokens rotate, and a client
that presented its previous token more than a minute after a refresh was treated as replaying a stolen token, which
revoked its whole sign-in. When the refresh response is lost in transit (a dropped connection or a hosting-provider
incident), the client never receives the new token and retries with the old one. The previous token is now accepted
as a retry until its replacement is first used; only a token two generations old ends the sign-in.
v0.2.0: first public release
The first public release.
Added
- A remote MCP server for Messages on macOS: an OAuth 2.1 gateway (PKCE, client ID metadata documents, dynamic client
registration, audience-bound tokens) that relays tool calls to a bridge on the Mac over a WebSocket the Mac opens. - A local-only mode: without
GATEWAY_URLthe bridge serves just its local socket, for theimessageCLI and
imessage mcpin Claude Code. No gateway or internet exposure needed. - 30 tools in five tiers: reading and search, sending and drafts, organizing (labels, aliases, notes, reminders),
ChatGPTsearch/fetch, and the optional Private API tier through imsg. - The
imessageCLI, with a required--intent, documented exit codes andimessage watch, plus a Claude Code skill
inskills/imessage. - A tool-call journal on the Mac (
imessage journal) recording each call's intent and outcome. - Mock mode with seeded fake data, for trying the tools without a Mac.
SECURITY.mdwith the threat model, docs for architecture, operations and the Private API tier, and
.env.example/bridge.env.example.
Security
- Fails closed: the gateway refuses to start until every required secret is set, on any host, and a configuration
value that doesn't parse stops the gateway or the bridge at startup.DEV=1is the only way to run without
secrets, and it prints a random one-time password. HIDE,SEND_ENABLED, an explicitSEND_ALLOWLISTand the hourly rate limit are enforced on the Mac. An explicit
list is a hard boundary the model-setuser_confirmedflag can't override, and it covers sends, scheduled drafts,
tapbacks, edits and group changes.- Every send is confirmed in
chat.db, idempotency keys stop double sends, and a send interrupted by a crash is
never sent again. Parallel sends reserve their rate-limit slot before they start. - Refresh tokens rotate on every use, and presenting a rotated-out one ends that sign-in; so does reusing an
authorization code. Clients that declareprivate_key_jwtmust sign their token requests. Failed sign-ins are
throttled per address and overall, and every gateway response carries security headers. - File links expire after 15 minutes and display only images, audio, video and plain text inline, sandboxed; anything
else downloads. ChatGPT citation links last 30 days and never show messages newer than the link. - Message text is marked as untrusted data, every kind of line break is folded so a message can't fake a transcript
line, and extracted attachment text is fenced with markers that change on every response. - Paging values reach SQL only as bound parameters, cursors are validated, and attachment URLs are checked against an
SSRF blocklist that includes the IPv6 ranges wrapping IPv4 addresses. - The bridge passes none of its secrets to the processes it starts, and
textutilnever loads remote resources. - The bridge deletes tool-call journal and audit rows after 30 days and stored send results after 7.