Skip to content

Integrate BlueBubbles with OpenClaw in 5 Minutes

The BlueBubbles plugin is a bundled component that communicates with the BlueBubbles macOS server over HTTP. It is the recommended choice for iMessage integration because it provides a richer API and an easier setup process compared to the legacy imsg channel.

  1. Current OpenClaw releases come with BlueBubbles pre-installed, so you do not need to perform a separate openclaw plugins install step.
  2. This ensures that standard packaged builds are ready to go as soon as you finish the initial installation.

The OpenClaw BlueBubbles integration is the best way to handle iMessage because it offers a much more capable API than older methods. It works by connecting your Gateway to a Mac running the BlueBubbles helper app.

  1. The system runs on macOS via the BlueBubbles helper app, which you can download at bluebubbles.app.
  2. We recommend using macOS Sequoia (15) for the best experience, although macOS Tahoe (26) is supported despite current issues with message editing and group icon syncing.
  3. OpenClaw communicates with the server through its REST API using endpoints such as GET /api/v1/ping, POST /message/text, and POST /chat/:id/*.
  4. Incoming messages arrive via webhook calls, while outgoing replies, typing indicators, read receipts, and tapbacks are handled through REST calls.
  5. All attachments and stickers are ingested as inbound media and are surfaced to the agent whenever possible.
  6. Pairing and allowlist management works the same way as other channels using channels.bluebubbles.allowFrom and pairing codes.
  7. Reactions are surfaced as system events just like Slack or Telegram, allowing agents to “mention” them before sending a reply.
  8. You have access to advanced features including message editing, unsending, reply threading, message effects, and group management.

Setting up your connection takes just a few minutes once you have the server running on your Mac. You can use the CLI to automate the process or update your JSON configuration manually.

  1. Install the BlueBubbles server on your Mac by following the official instructions at bluebubbles.app/install.
  2. Inside the BlueBubbles configuration settings, enable the web API and set a secure password.
  3. Run the openclaw onboard command and select BlueBubbles, or manually add the following configuration to your JSON file:
{
channels: {
bluebubbles: {
enabled: true,
serverUrl: "http://192.168.1.100:1234",
password: "example-password",
webhookPath: "/bluebubbles-webhook",
},
},
}
  1. Point your BlueBubbles webhook settings to your Gateway host, for example: https://your-gateway-host:3000/bluebubbles-webhook?password=<password>.
  2. Start the Gateway to register the webhook handler and begin the pairing process.
  3. For security, you must always set a webhook password as authentication is always required.
  4. OpenClaw will reject any BlueBubbles webhook requests unless they include a password or guid that matches your channels.bluebubbles.password.
  5. The system checks for password authentication before it even attempts to read or parse the full webhook body.

If you are running a Mac in a data center or as a virtual machine, you might find that the Messages app stops responding after a while. You can fix this by setting up a small script that keeps the app active in the background.

  1. Save the AppleScript
  1. Create a new file at ~/Scripts/poke-messages.scpt and save the following script.
  2. This script is designed to be non-interactive so it does not steal focus from your active windows.
try
tell application "Messages"
if not running then
launch
end if
-- Touch the scripting interface to keep the process responsive.
set _chatCount to (count of chats)
end tell
on error
-- Ignore transient failures (first-run prompts, locked session, etc).
end try
  1. Install a LaunchAgent
  1. Save the following configuration to ~/Library/LaunchAgents/com.user.poke-messages.plist to automate the process.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.user.poke-messages</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-lc</string>
<string>/usr/bin/osascript &quot;$HOME/Scripts/poke-messages.scpt&quot;</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>300</integer>
<key>StandardOutPath</key>
<string>/tmp/poke-messages.log</string>
<key>StandardErrorPath</key>
<string>/tmp/poke-messages.err</string>
</dict>
</plist>
  1. This setup ensures the script runs every 300 seconds and whenever you log into the system.
  2. The first run may trigger macOS Automation prompts for osascript to access Messages, which you must approve in the same user session.
  3. Use the following CLI commands to load the agent and start the process:
Terminal window
launchctl unload ~/Library/LaunchAgents/com.user.poke-messages.plist 2>/dev/null || true
launchctl load ~/Library/LaunchAgents/com.user.poke-messages.plist

Getting your BlueBubbles server connected to OpenClaw is a breeze with the built-in interactive setup wizard. This tool helps you configure the essential connection details so you can start routing messages quickly.

  1. Run the interactive wizard by typing openclaw onboard in your CLI.
  2. Provide the Server URL, which is the address where your BlueBubbles server is hosted (for example, http://192.168.1.100:1234).
  3. Enter the Password found in your BlueBubbles Server API settings.
  4. Optionally set a webhook path, though it defaults to /bluebubbles-webhook if you leave it blank.
  5. Choose a DM policy from the available options: pairing, allowlist, open, or disabled.
  6. Define your Allow list by adding specific phone numbers, emails, or chat targets.

If you prefer a direct approach without the wizard, you can also add the channel using a single command:

openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>

Configure Access control for DMs and groups

Section titled “Configure Access control for DMs and groups”

Managing who can interact with your agent is vital for keeping your setup secure. OpenClaw provides granular settings for both private direct messages and busy group chats.

For Direct Messages (DMs):

  1. The default setting is channels.bluebubbles.dmPolicy = "pairing".
  2. When an unknown sender reaches out, they receive a pairing code, and their messages are ignored until you approve them.
  3. Note that these codes expire after 1 hour.
  4. You can manage these by running openclaw pairing list bluebubbles to see active codes.
  5. Use openclaw pairing approve bluebubbles <CODE> to authorize a sender.
  6. This pairing process is the standard way to exchange tokens; you can find more details at Pairing.

For Group Chats:

  1. You can set the group policy using channels.bluebubbles.groupPolicy = open | allowlist | disabled. The default is allowlist.
  2. Use channels.bluebubbles.groupAllowFrom to specify exactly who is allowed to trigger the agent within those groups.

If you are running on macOS, you can make group chats much easier to read by enabling local contact lookups. This helps replace raw participant addresses with familiar names from your contact list.

  1. Set channels.bluebubbles.enrichGroupParticipantsFromContacts = true in your configuration to enable this feature.
  2. These lookups only happen after the message has passed all other security checks like group access and mention gating.
  3. The system specifically targets unnamed phone participants for enrichment.
  4. If no match is found in your local contacts, the raw phone number stays as the fallback.
{
channels: {
bluebubbles: {
actions: {
reactions: true, // tapbacks (default: true)
edit: true, // edit sent messages (macOS 13+, broken on macOS 26 Tahoe)
unsend: true, // unsend messages (macOS 13+)
reply: true, // reply threading by message GUID
sendWithEffect: true, // message effects (slam, loud, etc.)
renameGroup: true, // rename group chats
setGroupIcon: true, // set group chat icon/photo (flaky on macOS 26 Tahoe)
addParticipant: true, // add participants to groups
removeParticipant: true, // remove participants from groups
leaveGroup: true, // leave group chats
sendAttachment: true, // send attachments/media
},
},
},
}

Here are the specific actions you can use once you have them enabled:

  1. react: Add or remove tapback reactions using messageId, emoji, and remove.
  2. edit: Change a message you already sent with messageId and text.
  3. unsend: Completely remove a message using its messageId.
  4. reply: Start a thread by replying to a specific message with messageId, text, and to.
  5. sendWithEffect: Add some flair with an iMessage effect using text, to, and effectId.
  6. renameGroup: Change the name of a group chat via chatGuid and displayName.
  7. setGroupIcon: Update the group photo with chatGuid and media (note that this is buggy on macOS 26 Tahoe because the API might report success without syncing).
  8. addParticipant: Bring someone new into a group using chatGuid and address.
  9. removeParticipant: Kick someone out of a group with chatGuid and address.
  10. leaveGroup: Exit a group chat yourself using the chatGuid.
  11. upload-file: Send media or files with to, buffer, filename, and asVoice.
  12. For voice memos, set asVoice: true and use MP3 or CAF files; OpenClaw will handle the conversion for you.
  13. While sendAttachment still works as a legacy alias, you should use upload-file as the standard name.

OpenClaw often uses short message IDs like 1 or 2 to keep things efficient and save tokens. You should know how these differ from the full versions:

  1. MessageSid and ReplyToId are usually short IDs stored in-memory.
  2. MessageSidFull and ReplyToIdFull contain the complete provider IDs.
  3. Short IDs are fast but can disappear if you restart the service or the cache clears.
  4. If you are building long-term automations or storage, always use the full IDs like {{MessageSidFull}} or {{ReplyToIdFull}} to ensure they stay valid.

Check out the Configuration page for more details on template variables.

Enable Block streaming for better responses

Section titled “Enable Block streaming for better responses”

You can decide whether you want your responses to hit the chat all at once or come through in pieces. Enabling Block streaming in OpenClaw gives you more control over the delivery rhythm of your messages.

{
channels: {
bluebubbles: {
blockStreaming: true, // enable block streaming (off by default)
},
},
}

Manage Media and Message Limits in OpenClaw

Section titled “Manage Media and Message Limits in OpenClaw”

Handling media files and message length is a key part of keeping your Gateway running efficiently. You can easily adjust how OpenClaw processes attachments and splits long texts to suit your needs.

  1. Inbound attachments are automatically downloaded and kept in the media cache for quick access.
  2. You can control the media size limit using the channels.bluebubbles.mediaMaxMb setting for both incoming and outgoing files, which defaults to 8 MB.
  3. If you send long messages, the system chunks outbound text based on the channels.bluebubbles.textChunkLimit, which defaults to 4000 characters.

BlueBubbles Configuration Reference for OpenClaw

Section titled “BlueBubbles Configuration Reference for OpenClaw”

Getting your settings right is essential for a stable connection between OpenClaw and your BlueBubbles server. This reference covers all the provider-specific options you can use to fine-tune your setup.

Full configuration: Configuration

Provider options:

  1. channels.bluebubbles.enabled: Use this to enable or disable the channel.
  2. channels.bluebubbles.serverUrl: This is the base URL for your BlueBubbles REST API.
  3. channels.bluebubbles.password: Your API password goes here.
  4. channels.bluebubbles.webhookPath: The webhook endpoint path, which defaults to /bluebubbles-webhook.
  5. channels.bluebubbles.dmPolicy: Set this to pairing, allowlist, open, or disabled (the default is pairing).
  6. channels.bluebubbles.allowFrom: Your allowlist for direct messages, supporting handles, emails, E.164 numbers, or specific IDs like chat_id:* and chat_guid:*.
  7. channels.bluebubbles.groupPolicy: Choose between open, allowlist, or disabled (the default is allowlist).
  8. channels.bluebubbles.groupAllowFrom: The allowlist specifically for group senders.
  9. channels.bluebubbles.enrichGroupParticipantsFromContacts: If you are on macOS, you can set this to true to pull names for unnamed participants from your local Contacts after they pass the gating check. The default is false.
  10. channels.bluebubbles.groups: Configuration for individual groups, such as requireMention.
  11. channels.bluebubbles.sendReadReceipts: Controls whether read receipts are sent (the default is true).
  12. channels.bluebubbles.blockStreaming: Enable this to support streaming replies (the default is false).
  13. channels.bluebubbles.textChunkLimit: Defines the size of outbound text chunks in characters (the default is 4000).
  14. channels.bluebubbles.sendTimeoutMs: This sets the timeout in milliseconds for outbound text sent via /api/v1/message/text. The default is 30000 ms, but you might want to increase it to 45000 or 60000 on macOS 26 setups where the iMessage framework might stall for over a minute. You can also override this per account using channels.bluebubbles.accounts.<accountId>.sendTimeoutMs. While this covers text, broadening coverage to reactions and edits is planned for later.
  15. channels.bluebubbles.chunkMode: The default is length, which splits text only when it hits the limit. You can switch to newline to split at blank lines or paragraph boundaries first.
  16. channels.bluebubbles.mediaMaxMb: Sets the cap for inbound and outbound media in MB (the default is 8).
  17. channels.bluebubbles.mediaLocalRoots: An explicit allowlist of absolute local directories for outbound media paths. Sending from local paths is blocked unless you configure this. This can be overridden per account with channels.bluebubbles.accounts.<accountId>.mediaLocalRoots.
  18. channels.bluebubbles.historyLimit: The maximum number of group messages used for context (set to 0 to disable).
  19. channels.bluebubbles.dmHistoryLimit: The limit for direct message history.
  20. channels.bluebubbles.actions: Toggle specific actions on or off.
  21. channels.bluebubbles.accounts: Used for multi-account configuration.

Related global options:

  1. agents.list[].groupChat.mentionPatterns (or messages.groupChat.mentionPatterns).
  2. messages.responsePrefix.

Use OpenClaw delivery targets for message routing

Section titled “Use OpenClaw delivery targets for message routing”

When you want to send a message, you need to tell OpenClaw exactly where it is going. Using the right delivery targets ensures your messages land in the correct chat every time without any guesswork.

  1. You should prefer using chat_guid for stable routing, especially when you are dealing with groups. An example of this format is chat_guid:iMessage;-;+15555550123.
  2. You can use chat_id:123 if you have that specific identifier available from your database.
  3. You can also use the chat_identifier:... field to point to your destination.
  4. You can use direct handles like +15555550123 or user@example.com. If a direct handle does not have an existing DM chat, OpenClaw will create one via POST /api/v1/chat/new, though this requires the BlueBubbles Private API to be enabled.

Configure security for BlueBubbles webhooks

Section titled “Configure security for BlueBubbles webhooks”

Keeping your messaging pipeline safe is a top priority when you connect services over a network. You should treat your API password and webhook endpoint secret with the same care you give to your primary login credentials.

  1. webhook requests are authenticated by comparing the guid or password query parameters or headers against your channels.bluebubbles.password configuration.
  2. You must keep the API password and webhook endpoint secret private at all times, treating them like any other sensitive credential.
  3. There is no localhost bypass for BlueBubbles webhook authentication. If you proxy your webhook traffic, you need to keep the BlueBubbles password on the request from end-to-end because gateway.trustedProxies does not replace channels.bluebubbles.password here. You can find more details in the Gateway security guide.
  4. You should enable HTTPS and set up firewall rules on your BlueBubbles server if you plan on exposing it outside of your local network to keep your data protected.

Fix Common OpenClaw Troubleshooting Issues

Section titled “Fix Common OpenClaw Troubleshooting Issues”

You might run into a few bumps while configuring your setup, but most OpenClaw troubleshooting issues are easy to resolve with the right commands. This guide helps you fix common problems with BlueBubbles integration and macOS compatibility.

  1. If typing or read events stop working, you should check your BlueBubbles webhook logs. You need to verify that your Gateway path matches the channels.bluebubbles.webhookPath setting.
  2. Keep in mind that pairing codes expire after one hour. If you need to manage them, use the CLI commands openclaw pairing list bluebubbles and openclaw pairing approve bluebubbles <code>.
  3. Sending reactions requires the BlueBubbles private API (POST /api/v1/message/react). You must ensure your server version actually exposes this endpoint.
  4. Features like edit and unsend require macOS 13 or newer and a compatible BlueBubbles server version. If you are on macOS 26 (Tahoe), the edit feature is currently broken because of changes in the private API.
  5. Updating group icons can be unreliable on macOS 26 (Tahoe). The API might say it succeeded, but the new icon often fails to sync.
  6. OpenClaw tries to auto-hide actions that are known to be broken based on your macOS version. If the edit option still shows up on macOS 26 (Tahoe), you can disable it manually by setting channels.bluebubbles.actions.edit=false.
  7. To get a full picture of your system health, run openclaw status --all or openclaw status --deep in your terminal.
  8. For general channel workflow reference, you can check out the Channels page and the Plugins guide.
Section titled “Explore Related OpenClaw Documentation and Guides”

Once you have everything running smoothly, you can explore these resources to better understand how OpenClaw handles your data. These links provide deeper context on routing, security, and group management.

  1. Channels Overview — check out all the supported channels available.
  2. Pairing — learn about the DM authentication and pairing flow.
  3. Groups — understand group chat behavior and how mention gating works.
  4. Channel Routing — see how session routing works for your messages.
  5. Security — read about the access model and how to harden your setup.
openclaw onboard
{
channels: {
bluebubbles: {
enrichGroupParticipantsFromContacts: true,
},
},
}
{
channels: {
bluebubbles: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"*": { requireMention: true }, // default for all groups
"iMessage;-;chat123": { requireMention: false }, // override for specific group
},
},
},
}
{
agents: {
list: [
{
id: "codex",
runtime: {
type: "acp",
acp: { agent: "codex", backend: "acpx", mode: "persistent" },
},
},
],
},
bindings: [
{
type: "acp",
agentId: "codex",
match: {
channel: "bluebubbles",
accountId: "default",
peer: { kind: "dm", id: "+15555550123" },
},
acp: { label: "codex-imessage" },
},
],
}
{
channels: {
bluebubbles: {
sendReadReceipts: false, // disable read receipts
},
},
}
OpenClaw

OpenClaw Expert

Still stuck?

If this page didn't answer your case, ask OpenClaw Expert for step-by-step guidance.