anthropics / anthropics/claude-plugins-official
imessage: self-chat over SMS service silently drops all inbound (ALLOW_SMS guard); configure skill says self-chat 'always works'
- Dominant language
- Python
- Stars
- 36.3k
- Forks
- 4.1k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 539
Description
## Bug
When a user's **self-chat thread is on the SMS service** (not iMessage), every inbound message is **silently dropped** by the `IMESSAGE_ALLOW_SMS` guard, so Claude never replies — even though **sending works fine**. There is no log line, no hint, and nothing in the chat to indicate why. Worse, the `configure` skill actively tells users this setup will work.
This is *not* a request to change the secure default (I understand from `README.md` that SMS is off by default because SMS sender IDs are spoofable and self-chat bypasses the access gate). The defect is the **silent failure + misleading documentation**, which makes this essentially undebuggable for a normal user.
## Environment
- Plugin `imessage` v0.1.0 (`external_plugins/imessage`)
- Claude Code 2.1.197
- macOS 15 (Darwin 25.5.0), Apple Silicon
- Full Disk Access granted ✅; MCP server connects ✅; `reply`/`chat_messages` tools available ✅
## Root cause
`server.ts`:
```ts
const ALLOW_SMS = process.env.IMESSAGE_ALLOW_SMS === 'true' // line ~38
...
function handleInbound(r: Row): void {
if (!r.chat_guid) return
if (!ALLOW_SMS && r.service !== 'iMessage') return // line ~779 ← drops here, silently
```
Texting **your own number from an iPhone very commonly lands as SMS**, not as a blue "Note to Self" iMessage. On this machine the self-thread is:
```sql
SELECT guid, chat_identifier, service_name FROM chat WHERE chat_identifier LIKE '%XXXXXXXXXX%';
-- any;-;+1XXXXXXXXXX | +1XXXXXXXXXX | SMS
```
So `r.service === 'SMS'` and, with the default `IMESSAGE_ALLOW_SMS` unset, line ~779 returns before the message is ever surfaced. Meanwhile the `reply` path uses `osascript`/Messages.app, which is service-agnostic, so **outbound works perfectly** — producing the maximally-confusing "Claude texts me but ignores everything I say" symptom.
## Steps to reproduce
1. On an iPhone, text your **own** number such that the thread is SMS (green bubble) — common default.
2. Configure the channel (allowlist your number, or rely on self-chat bypass) and run `claude --channels plugin:imessage@claude-plugins-official` **without** `IMESSAGE_ALLOW_SMS=true`.
3. From Claude, send yourself a message via the `reply` tool → **arrives**.
4. Text "ping" back → **no reply, no log, nothing**.
## Why this is a trap (documentation mismatch)
`skills/configure/SKILL.md` instructs:
> *"Text yourself from any device signed into your Apple ID — self-chat always bypasses the gate."*
It does **not** mention that if your self-thread is SMS (the common iPhone case), inbound is silently discarded unless `IMESSAGE_ALLOW_SMS=true`. A user follows the documented happy path and hits total silence with no diagnostic.
## Proposed fixes (none change the secure default)
1. **Emit a one-time stderr diagnostic** when a message in a self-chat or otherwise-allowlisted chat is dropped *solely* because of the SMS service guard, e.g.:
`imessage channel: dropping non-iMessage inbound from (service=SMS). Set IMESSAGE_ALLOW_SMS=true to enable (note: SMS sender IDs are spoofable).`
Right now line ~779 is the only fully-silent drop in `handleInbound`; the others at least have a rationale a user could discover.
2. **Document the SMS caveat** in `configure/SKILL.md` next to the "text yourself" guidance, and in the FDA/setup checklist: "If your self-thread is a green/SMS thread, inbound won't trigger unless you set `IMESSAGE_ALLOW_SMS=true`."
3. (Optional) In `configure`'s status output, detect when the only allowlisted/self chat is `service_name='SMS'` and surface a warning + the env-var instruction.
## Related
- #1037 — `any;-;` GUID prefix breaks the listener (related observation: this Mac also has `any;-;` GUIDs, but here the service is genuinely `SMS`, a different code path — the `ALLOW_SMS` guard, not GUID-prefix matching).
- #1676 — cross-device self-chat silently dropped (`is_from_me=1`): same "self-chat silently dropped, no feedback" family.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with external_plugins/imessage/server.ts and handleInbound at the ALLOW_SMS guard, then read skills/configure/SKILL.md and README.md for the documented security default. Reproduce the SMS self-chat path described in the issue and verify that the chosen diagnostic and documentation changes preserve the IMESSAGE_ALLOW_SMS behavior while making the drop discoverable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, documentation
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 58/100