iMessage plugin: inbound notifications not delivered to Claude Code session (self-chat)

Resolved 💬 2 comments Opened Mar 26, 2026 by tommohide-kumekawa Closed Mar 26, 2026

Description

The iMessage channel plugin's inbound polling works correctly (detects new messages in chat.db), but mcp.notification({ method: 'notifications/claude/channel', ... }) calls silently fail — notifications never reach the Claude Code session. Outbound tools (reply, chat_messages) work fine.

Environment

  • macOS Darwin 25.3.0
  • Claude Code CLI (latest)
  • iMessage plugin (official, v0.0.1)
  • Bun runtime
  • Self-chat (sending from iPhone to own Mac)

Steps to Reproduce

  1. Install iMessage plugin, grant Full Disk Access
  2. Configure ~/.claude/channels/imessage/access.json with allowlist
  3. Start a Claude Code session (plugin auto-starts)
  4. Send a message from iPhone to yourself (self-chat)
  5. Expected: <channel source="imessage" ...> notification appears in Claude Code session
  6. Actual: No notification arrives. Message is recorded in chat.db but never delivered.

Debugging Done

What works:

  • reply tool: sends iMessage successfully via AppleScript ✅
  • chat_messages tool: reads chat.db history correctly ✅
  • Full Disk Access: confirmed (ls ~/Library/Messages/chat.db succeeds) ✅
  • Server process: running, stdio connected to Claude Code CLI ✅
  • access.json: correctly configured with allowFrom entries ✅

What doesn't work:

  • Inbound mcp.notification() calls from server → Claude Code session ❌

Detailed analysis:

  1. Server polls chat.db correctly: qPoll.all(watermark) returns new rows after watermark.
  1. handleInbound logic is correct: Simulated the full code path for self-chat messages — is_from_me=1 rows are skipped, is_from_me=0 rows pass through as isSelfChat=true, consumeEcho returns false (different text), and execution reaches mcp.notification().
  1. mcp.notification() silently fails: The void mcp.notification(...) call at line 795 of server.ts does not throw, but the notification never arrives at the Claude Code client. No error in stderr.
  1. chat.db GUID format: On this system, self-chat GUID is any;-;+81XXXXXXXXXX (not iMessage;-;...). This is correctly handled by allowedChatGuids() via qChatsForHandle.
  1. lsof shows no chat.db handle: The bun process doesn't show chat.db in lsof output, but SQLite queries succeed — likely bun's SQLite uses memory-mapped I/O that doesn't appear as a file descriptor.

Expected Behavior

When a message is sent to self-chat from a mobile device, the iMessage plugin server should deliver a notifications/claude/channel notification to the active Claude Code session, which should appear as a <channel source="imessage" ...> tag in the conversation.

Workaround

Direct AppleScript execution works for sending:

tell application "Messages"
    set targetService to 1st account whose service type = iMessage
    set targetBuddy to participant "+81XXXXXXXXXX" of targetService
    send "Hello!" to targetBuddy
end tell

But there is no workaround for receiving inbound messages in the Claude Code session.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗