Skip to main content
Glama
nighomni123

imessage-bridge

by nighomni123

iMessage Bridge for DeepSeek Harness

A dependency-free MCP stdio server that bridges agent harnesses to iMessage via BlueBubbles, enabling human-in-the-loop conversations through your Android device. It speaks plain MCP stdio (newline-delimited JSON-RPC), so it mounts under any MCP client — the examples below use DeepSeek Harness (DSH), where it runs in production daily.

Architecture

DSH Agent (Mac) ──MCP stdio──▶ imessage-bridge ──REST API──▶ BlueBubbles Server (Mac)
                                                                      │
                                                                      ▼
                                                              iMessage Network
                                                                      │
                                                                      ▼
                                              Android (BlueMessage/BlueBubbles app)

Flow:

  1. DSH agent calls imessage_send → bridge sends iMessage via BlueBubbles

  2. Message appears in your Android iMessage app (BlueMessage/BlueBubbles client)

  3. You reply on the same chat on Android

  4. Bridge's imessage_receive polls for new messages and returns your replies

  5. DSH agent continues with your response

Related MCP server: bluebubbles-mcp

What it looks like in action

A real exchange over iMessage relayed by the bridge: the agent checks in mid-run, a one-line reply unblocks it, the work continues

This bridge is the human-in-the-loop channel my agent fleet reports through — research, code and status updates arrive on the phone, and a one-line reply unblocks the run. Orchestration in the background, not chat-by-chat micromanagement.

Prerequisites

  1. BlueBubbles server running on your Mac (the same Mac running DSH)

  2. Android iMessage client paired to your BlueBubbles server

    • BlueBubbles app, BlueMessage, or similar

  3. Node.js 18+ (for global fetch support)

Setup

1. Configure the bridge

Copy .env.example to .env and fill in your values:

cp .env.example .env

Edit .env:

BLUEBUBBLES_URL=http://127.0.0.1:1234
BLUEBUBBLES_API_KEY=your-bluebubbles-server-password
BLUEBUBBLES_SELF_HANDLE=+15551234567  # or you@icloud.com
  • BLUEBUBBLES_API_KEY: Your BlueBubbles server password (from Settings → Users/API)

  • BLUEBUBBLES_SELF_HANDLE: Your own phone number or email (the one you'll message yourself from)

2. Test the bridge standalone

node index.mjs

You should see: imessage-bridge ready (BASE=http://127.0.0.1:1234, defaultChat=iMessage;+15551234567)

The bridge is now listening on stdin for MCP JSON-RPC messages. Press Ctrl+C to stop.

3. Register with DeepSeek Harness

Add this entry to your DSH web profile's cordis.patch.yml (typically ~/.dsh/profiles/web/cordis.patch.yml):

- id: imessage-bridge
  name: '@deepseek-ai/dsh-mcp-client'
  config:
    transport: stdio
    serverName: imessage
    command: /usr/local/bin/node
    args:
      - /path/to/imessage-bridge/index.mjs
    env: {}
    cwd: /path/to/imessage-bridge
    toolCallTimeoutMs: 300000
    failOnStartupError: false

Important: The bridge reads secrets from its .env file (not from DSH config), so env: {} is safe.

Restart the DSH web GUI to load the new MCP server.

Usage

The bridge exposes four tools to the DSH agent:

imessage_send

Send an iMessage to a recipient (defaults to yourself for self-chat).

Parameters:

  • message (required): Text to send

  • recipient (optional): Phone or email. Omit to use BLUEBUBBLES_SELF_HANDLE (message yourself)

Example:

{
  "message": "Need your input on this design decision...",
  "recipient": "+15551234567"
}

Returns the sent message GUID and confirmation.

imessage_receive

Read new human replies since the last activity. In a self-chat, the agent's own sent messages are filtered out, so only your replies come back.

Parameters:

  • waitMs (optional): Max milliseconds to block waiting for a reply (default 0 = return immediately)

  • since (optional): Epoch ms to read from. Omit to use last activity time

  • chatGuid (optional): Chat GUID. Omit to use the default (self) chat

  • limit (optional): Max messages to scan (default 50)

Example (blocking wait for reply):

{
  "waitMs": 180000
}

Returns an array of messages: { guid, date, text, handle, chatGuid }

Tip: Call imessage_receive with waitMs right after imessage_send to wait for the human's reply. The DSH tool call timeout is set to 5 minutes (300000ms), so you can wait up to ~280 seconds.

imessage_find_chat

Look up BlueBubbles chat GUIDs for a participant. Use this once to confirm the self-chat GUID if the default iMessage;<handle> form is wrong.

Parameters:

  • participant (required): Phone or email to search for

Example:

{
  "participant": "+15551234567"
}

Returns matching chats with their GUIDs.

imessage_ping

Health check: verifies the BlueBubbles server is reachable and the API key works.

Parameters: None

Example:

{}

Returns { ok: true, server, chatCount, defaultChat } on success.

How It Works

Self-Chat Message Filtering

When you message yourself, both the agent's sent messages and your replies have isFromMe: true (since they're all from your Apple ID). The bridge tracks sent message GUIDs in memory and filters them out in imessage_receive, so only your replies (new GUIDs not in the sent set) are returned.

Polling with Blocking

imessage_receive polls BlueBubbles every 3 seconds when waitMs > 0. It returns as soon as it finds new messages or when the timeout expires. This lets the agent wait for your reply without busy-looping.

Zero Dependencies

The bridge implements the MCP stdio protocol (newline-delimited JSON-RPC 2.0) by hand — no SDK, no build step, no node_modules. This keeps it lightweight and avoids dependency conflicts with DSH.

Troubleshooting

Bridge won't start in DSH

Check the DSH logs. Common issues:

  • Node path wrong: Update command in cordis.patch.yml to your actual Node path (which node)

  • Bridge path wrong: Verify the absolute path to index.mjs

  • Permission denied: Ensure index.mjs is executable (chmod +x index.mjs)

imessage_ping fails

  • 401 Unauthorized: Wrong BLUEBUBBLES_API_KEY in .env

  • Connection refused: BlueBubbles server not running, or wrong BLUEBUBBLES_URL

  • 404 Not Found: BlueBubbles API version mismatch (this bridge targets BlueBubbles v1 API)

imessage_receive returns empty

  • No default chat: Set BLUEBUBBLES_SELF_HANDLE in .env, or pass chatGuid explicitly

  • Messages filtered out: The bridge only returns messages with GUIDs not in its sent set. If you're testing by sending messages from the same Apple ID, they may be filtered. Use a different chat or restart the bridge.

Agent times out waiting for reply

The DSH tool call timeout is 5 minutes (300000ms). If you need longer, increase toolCallTimeoutMs in cordis.patch.yml. Alternatively, have the agent call imessage_receive with waitMs: 0 in a loop (less efficient but avoids timeout).

Security Notes

  • Secrets in .env: The bridge reads BLUEBUBBLES_API_KEY from .env (not DSH config). Keep .env out of git (it's in .gitignore).

  • Local-only: The bridge assumes BlueBubbles runs on 127.0.0.1. If you expose BlueBubbles to the network, use HTTPS and strong credentials.

  • Apple ToS: Relay setups (BlueBubbles, AirMessage) operate in a gray area of Apple's Terms of Service. Use at your own risk.

Development

The bridge is a single file (index.mjs) with no build step. To modify:

  1. Edit index.mjs

  2. Restart the DSH web GUI (or HMR if enabled)

To test the MCP protocol manually:

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | node index.mjs

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables reading, searching, and sending iMessages directly from MCP-compatible clients by accessing the local macOS iMessage database, supporting conversations, attachments, and both individual and group chats.
    258 npm
    10
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables interaction with iMessage through a BlueBubbles server, allowing users to read, search, and send messages directly from MCP clients. It supports comprehensive chat management features including reactions, group chat moderation, message scheduling, and contact lookups.
    33
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables reading and sending iMessages on macOS through MCP, with tools for managing chats, messages, and attachments via AI agents.
    MIT