Skip to content

daya0576/pi-imessage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

185 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@kingcrab/pi-imessage

A minimal and self-managing iMessage bot β€” powered by pi.

Features

  • Minimal: No BlueBubble, no webhooks, no extra dependencies
  • Self-managing: Turn the agent into whatever you need. He builds his own tools without pre-built assumptions
  • Transparent: tool calls and reasoning are sent to your iMessage chat, so you can see exactly what it's doing and why
  • iMessage Integration: Responds to DMs, SMS, and group chats; identifies who sent each message; understands quoted/reply-to messages
  • Web UI: browse chat history, toggle replies on/off per chat, live updates β€” disable with WEB_ENABLED=false and let the agent build your own web UI

Get Started

⚠️ Security note

  • Replies are off for all chats by default (blacklist: ["*"]) β€” only explicitly whitelisted chats get a response
  • The agent runs with Full Disk Access and can read/write your filesystem as part of its tool use
  • The web UI has no authentication and is accessible to anyone on your local network; set WEB_ENABLED=false if that's a concern

Prerequisites: macOS with Messages.app, Full Disk Access for the terminal, Pi Coding Agent authenticated

npm install -g @kingcrab/pi-imessage

pi-imessage             # run in foreground
pi-imessage install     # install as launchd service (auto-start on boot, restart on crash)

Usage

Web UI

Available at http://localhost:7750 (configurable via WEB_HOST and WEB_PORT).

  • Chat history with live updates
  • Logs (tail -f style)
  • Memory (global & per-chat)

P.S. Disable with WEB_ENABLED=false and let the agent build your own web UI

Structured Memory

Durable memories are stored as namespaced JSONL records under WORKING_DIR/skills/file-memory/namespaces/. Each record includes a stable ID, creation timestamp, factual event date when known, source, kind, subjects, importance, confidence, and status. This keeps every memory traceable without inventing dates for older facts.

The agent uses typed tools to load complete namespaces, search for specific records, and append validated memories. Corrections append a new record that supersedes the old ID, preserving an auditable history instead of silently rewriting it. Legacy global and per-chat MEMORY.md files remain read-only archives. See the structured memory flow for migration, retrieval, and write behavior.

API

The agent is aware of these endpoints via its system prompt and can use them as tools (e.g., scheduling a cron job that calls /prompt).

Endpoint Description Example
POST /send Send text and/or a local file attachment to a chat (bypasses the agent) curl -X POST localhost:7750/send -d '{"chatGuid": "iMessage;-;+11234567890", "text": "hello"}'
β†’ {"ok": true}
POST /prompt Feed a prompt to the agent asynchronously; replies are sent to the chat when ready curl -X POST localhost:7750/prompt -d '{"chatGuid": "iMessage;-;+11234567890", "prompt": "say hello"}'
β†’ {"ok": true}
GET /health/model Make a live request to the configured default AI model; returns HTTP 200 when healthy or 503 on failure curl localhost:7750/health/model
β†’ {"ok":true,"model":"openai/gpt-5","latencyMs":842,"checkedAt":"..."}

Commands

Send these as iMessage to interact with the bot:

Command Description Example Reply
/help List available slash commands Commands:
/help β€” list commands
/new Reset the session, starting a fresh conversation βœ“ New session started
/status Show session stats: tokens, context, model πŸ’¬ 3 msgs - ↑7.2k ↓505 1.1%/128k
πŸ€– anthropic/claude-sonnet-4 β€’ πŸ’­ minimal
/compact Compress session context to free up token space βœ“ Compacted: 15.2k β†’ 2.1k tokens
/stop Steer the agent to stop after current tool calls finish, then process the next queued message
/reload Reload models and clear all sessions βœ“ Models reloaded

Settings (WORKING_DIR/settings.json)

All fields are optional.

{
  "chatAllowlist": {
    "whitelist": ["iMessage;-;+11234567890"],
    "blacklist": ["*"]
  },
  "richText": {
    "enabled": false,
    "markdown": true
  }
}

Chat allowlist controls which chats receive replies (messages are always logged). By default, replies are off for all chats (blacklist: ["*"]) β€” opt in specific chats via the web UI or by adding their guid to whitelist. Resolution priority: blacklist[guid] > whitelist[guid] > blacklist["*"] > whitelist["*"].

Rich text is optional and disabled by default. When enabled, pi-imessage uses a UI automation fallback to open the target conversation, paste an RTF payload, and send it. Currently this is intended for direct-message iMessage chats. With markdown: true, pi-imessage interprets **bold** spans and renders them as actual bold text in Messages.

Environment Variables

Variable Required Default Description
WEB_ENABLED no true Set to false to disable the built-in web UI
WEB_HOST no localhost Web UI host
WEB_PORT no 7750 Web UI port
WORKING_DIR no ~/.pi/imessage Workspace directory
AGENT_IDLE_TIMEOUT_MS no 120000 Abort only after this much continuous agent inactivity; model and tool events reset the timer
AGENT_MAX_PROMPT_DURATION_MS no 1800000 Absolute ceiling for one prompt, independent of activity

Development

npm run check        # typecheck + lint (run after code changes)
npm test             # run tests

How It Works

  ~/Library/Messages/chat.db
        β”‚
  (poll every 2s for new rows)
        β”‚
        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              pi-imessage                         β”‚
β”‚                                                  β”‚
β”‚  Watcher (chat.db polling)                       β”‚
β”‚    β”‚                                             β”‚
β”‚    β”œβ”€ Filter: is_from_me=0, no reactions         β”‚
β”‚    β”œβ”€ Deduplicate via seenRowIds                 β”‚
β”‚    β”œβ”€ Read attachments from local disk           β”‚
β”‚    β”‚                                             β”‚
β”‚    β–Ό                                             β”‚
β”‚  AsyncQueue<IncomingMessage>                     β”‚
β”‚    β”‚                                             β”‚
β”‚    β–Ό                                             β”‚
β”‚  SessionManager (pi-coding-agent)                β”‚
β”‚    β”‚  per chatGuid, persistent on disk           β”‚
β”‚    β”‚  └─ data/<chatGuid>/                        β”‚
β”‚    β”‚       β”œβ”€ log.jsonl      (full history)      β”‚
β”‚    β”‚       └─ context.jsonl  (LLM context)       β”‚
β”‚    β”‚                                             β”‚
β”‚    β–Ό                                             β”‚
β”‚  Agent loop (pi-agent-core)                      β”‚
β”‚    β”‚                                             β”‚
β”‚    β”‚  β”Œβ”€ outer: follow-up messages ────┐         β”‚
β”‚    β”‚  β”‚  β”Œβ”€ inner: tool calls +      ┐ β”‚         β”‚
β”‚    β”‚  β”‚  β”‚  steering messages        β”‚ β”‚         β”‚
β”‚    β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚         β”‚
β”‚    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚    β”‚                                             β”‚
β”‚    β–Ό                                             β”‚
β”‚  Collect assistant reply text                    β”‚
β”‚    β”‚                                             β”‚
β”‚    β”œβ”€ sendMessage (AppleScript β†’ Messages.app)   β”‚
β”‚    └─ save logs (messages, digests)              β”‚
β”‚                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
  iMessage (user receives reply via Messages.app)

About

πŸ¦€ A minimal and self-managing iMessage bot β€” powered by pi

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages