Guide - AI & Automation

How to Run Claude Code Channels 24/7 on a Dedicated Mac mini

Claude Code Channels is a research-preview feature of Anthropic's Claude Code CLI: a channel is an MCP server that pushes events into your running Claude Code session, so you can talk to the coding agent that has your repository open from Telegram, Discord or iMessage, and approve its tool calls from your phone. Events only arrive while the session is open, so it needs a machine that never sleeps. A dedicated Apple Silicon Mac mini is the natural always-on host, and, because the iMessage channel is macOS-only, the kind of host a Linux VPS can never be, from $85/month.

25 min read Updated September 28, 2026

1. Why Run Claude Code Channels on a Mac mini?

The official documentation is explicit: "Events only arrive while the session is open, so for an always-on setup you run Claude in a background process or persistent terminal." A laptop that goes to sleep, closes its lid or reboots for an update silently takes your bot offline; the Telegram Bot API offers no history or search, so Claude cannot fetch older messages, and Telegram holds undelivered updates for at most 24 hours. A dedicated Mac mini from MyRemoteMac keeps that session open 24/7 on Apple Silicon (Claude Code supports macOS 13+ on ARM64), with full root over SSH, VNC for the one-time macOS permission dialogs, 1 Gbps included and a flat monthly price. It is also the only kind of cloud host that can run the iMessage channel, which is macOS-only: it reads the Messages database and drives Messages.app through AppleScript, impossible on a Linux VPS.

Feature Cloud VPS (Linux) Mac mini (MyRemoteMac)
Monthly Cost Varies (see cost analysis) M4 from $85/mo · M6 from $149/mo (flat)
iMessage Channel Not possible (macOS only) Yes, Messages.app + Full Disk Access
Telegram / Discord Channels Yes Yes (outbound only, no inbound port)
Always-On Session Yes Yes (99.9% SLA)
Hardware Shared, virtualized Dedicated 1:1 physical Mac
Access & Toolchain SSH SSH + VNC, full root, Xcode and Simulator in the same session

Key Advantage: Channels bridges chat apps into a Claude Code session that already has your real project open. On a Mac mini that project can be an iOS or macOS app, the agent you message from your phone can build and test it with Xcode on the same machine (see our remote Xcode development guide). All three official plugins relay permission prompts, so you approve or deny each Bash, Write or Edit call from the chat.

2. Prerequisites

Claude Code Channels is a feature of Anthropic's proprietary Claude Code CLI, not a separate product, and it requires a paid Claude plan. It is a research preview: the --channels flag does not even appear in claude --help yet, and Anthropic says its syntax and protocol may change. Facts below were checked against the official documentation on September 28, 2026 (Claude Code 2.1.283).

  • A dedicated Mac mini from MyRemoteMac, M4 from $85/mo (16 GB / 256 GB) or M6 from $149/mo. Claude Code needs macOS 13.0+, 4 GB+ RAM and an ARM64 or x64 processor: any of them qualifies.
  • SSH and VNC access to your Mac mini (both provided with your MyRemoteMac subscription). SSH is for the terminal; VNC is for the browser login and the macOS Full Disk Access / Automation dialogs the iMessage channel needs.
  • A Claude account with Claude Code access: Pro ($20/mo), Max (from $100/mo), Team ($25/seat/mo), Enterprise, or a Console API key billed per token. The free claude.ai plan does not include Claude Code. Channels are not available on Amazon Bedrock, Google Cloud's Agent Platform or Microsoft Foundry. On Team/Enterprise, an Owner must first enable channels (claude.ai → Admin settings → Claude Code → Channels).
  • Bun on the Mac mini: "Each supported channel is a plugin that requires Bun" (installed in Step 1).
  • Bot credentials for your channel: a Telegram bot token from @BotFather, or a Discord bot application with the Message Content Intent enabled and invited to a server you share with it. iMessage needs no token: the docs require macOS, Full Disk Access, an Automation grant on the first reply, and "any device signed into your Apple ID" to message yourself, keeping the Mac mini's user logged in with Messages signed in is our inference from that mechanism (see Step 3), and we recommend a dedicated Apple ID with two-factor authentication rather than your personal one.
  • Basic familiarity with terminal commands, tmux and editing ~/.claude/settings.json.

3. Step 1: Connect via SSH, Install Claude Code and Bun

SSH into your Mac mini with the credentials from your MyRemoteMac dashboard, confirm the macOS version, then install Claude Code. The native installer is the method Anthropic recommends: it needs no Node.js and updates itself in the background. Homebrew and npm are documented alternatives (the npm package installs the same native binary and requires Node.js 22+; never run it with sudo).

Connect via SSH and Check the Requirements

# Connect to your Mac mini
ssh admin@your-server-ip

# Confirm Apple Silicon (Claude Code supports x64 and ARM64)
uname -m
# arm64

# Claude Code and Bun both need macOS 13.0+
sw_vers -productVersion

Install Claude Code (Official Native Installer)

Run the installer, then verify the version and let claude doctor run its read-only diagnostics. Homebrew's claude-code cask tracks the stable channel (about a week behind, skips regressions) and does not auto-update; claude-code@latest tracks latest.

# Recommended: official native installer (no Node.js needed, auto-updates in the background)
curl -fsSL https://claude.ai/install.sh | bash
# Pin a release channel or exact version at install time if you prefer:
#   curl -fsSL https://claude.ai/install.sh | bash -s stable

# Alternative A: Homebrew (stable channel; does not auto-update)
# brew install --cask claude-code

# Alternative B: npm (Node.js 22+, same native binary, never with sudo)
# npm install -g @anthropic-ai/claude-code

# Verify (prints e.g. "2.1.283 (Claude Code)") and run read-only diagnostics
claude --version && claude doctor

Install Bun (Required by Every Channel Plugin)

The official channel plugins are Bun scripts. Bun's own minimum is also macOS 13.0+. Both bun.com/install (from the Bun docs) and bun.sh/install (from the plugin READMEs) are official; Homebrew works too. The plugins state no minimum Bun version.

# Official Bun installer
curl -fsSL https://bun.com/install | bash
# Homebrew alternative: brew install oven-sh/bun/bun

# Open a new shell (or source ~/.zshrc), then verify
bun --version

4. Step 2: Authenticate and Choose a Permission Mode

Channels require Anthropic authentication: a claude.ai login (Pro, Max, Team, Enterprise) or a Console API key. Launch claude once and follow the browser login. Over SSH the browser may show a code to paste at the "Paste code here if prompted" prompt; on a headless Mac mini you can also complete the login in the VNC session. On macOS, credentials go to the Keychain; if the Keychain is locked (typical over SSH) Claude Code falls back to ~/.claude/.credentials.json with mode 0600.

Sign In (Subscription or API Key)

For an always-on session the subscription login is the weak point: it expires (Claude Code warns "Your login expires in 3 days · run /login to renew" at startup, and an unattended session "stops making progress once the credential expires"). Two documented remedies: generate a one-year OAuth token with claude setup-token (Pro/Max/Team/Enterprise; it can only make model requests) and export it where the session runs, or use an ANTHROPIC_API_KEY from the Console, billed per token.

# Option A: subscription login (Pro, Max, Team, Enterprise)
cd ~/project
claude
# Follow the browser login. Over SSH, paste the code shown at
# "Paste code here if prompted": or finish the login over VNC.

# Option B: Console API key, billed per token (Claude Code asks once to approve it)
export ANTHROPIC_API_KEY="sk-ant-YOUR_API_KEY_HERE"
claude

# Option C (always-on subscription box): one-year OAuth token, printed once, never saved
claude setup-token
export CLAUDE_CODE_OAUTH_TOKEN=your-token

# Check which credential is active
# inside Claude Code: /status   (see the "Login" row)

Model and Providers

The session uses the model your plan selects; change it with /model or claude --model <alias> (aliases such as opus, sonnet, haiku) and the effort level with /effort. There is no local-model or third-party-provider option for Channels: the Bedrock, Vertex and Foundry backends are excluded and routing to a non-Claude endpoint is not a supported configuration. If you want a local LLM on the same Mac mini, treat it as a separate workload, see our local LLM guide.

Choose a Permission Mode and Pin the Release Channel

Since Claude Code 2.1.283, auto mode (a classifier reviews actions) is the built-in starting mode for interactive sessions. For a channel session we recommend keeping human approval in the loop: in Manual mode (--permission-mode default) every Bash, Write or Edit prompt is relayed to your allowlisted chat, where you answer yes <id> or no <id>. In auto mode the classifier decides and "no dialog would open for the remote side to answer". Because the feature is a research preview, also pin the stable release channel and a minimum version in ~/.claude/settings.json (user settings, auto and bypass modes set in a project's .claude/settings.json are ignored):

# ~/.claude/settings.json (user settings: applies to every project on the Mac mini)
{
  "permissions": {
    "defaultMode": "default"
  },
  "sandbox": {
    "enabled": true
  },
  "autoUpdatesChannel": "stable",
  "minimumVersion": "2.1.211"
}

# minimumVersion = the version YOU validated on this Mac mini (the docs' example is "2.1.100").
# Auto-updates and `claude update` refuse to install anything below it, so never set it to a
# version you have not tested with --channels: 2.1.283 has an open launchd regression (#97701).

# Equivalent per-launch flag instead of defaultMode:
#   claude --permission-mode default --channels plugin:telegram@claude-plugins-official

Do not disable permissions. The docs' own warning on --dangerously-skip-permissions / bypassPermissions: "Only use this mode in isolated environments like containers, VMs, or dev containers without internet access, where Claude Code cannot damage your host system" and it "offers no protection against prompt injection or unintended actions". It is refused as root/sudo on macOS, deny rules still apply, and admins can block it with permissions.disableBypassPermissionsMode. If a fully trusted, dedicated, isolated Mac mini must run unattended, the documented pattern is claude -p "<prompt>" --dangerously-skip-permissions as a non-root user, a clearly warned option, never the default. The safer unattended pattern is -p --permission-mode auto --permission-prompts none (2.1.259+), which denies anything that would prompt instead of stalling.

5. Step 3: Connect Telegram, Discord or iMessage

The research preview ships three official channel plugins, Telegram, Discord and iMessage, plus a localhost demo called fakechat, all from the Anthropic marketplace claude-plugins-official (Apache-2.0). Each is installed as a plugin inside Claude Code, configured with your own bot credentials, and opted into a session with the --channels flag. Two rules apply to all of them: you must exit and restart Claude Code with --channels after installing a plugin, and the bot can only reply while that session is running. Every approved plugin maintains a sender allowlist: "only IDs you've added can push messages, and everyone else is silently dropped."

Telegram (recommended first channel)

Create the bot in Telegram: open @BotFather, send /newbot, give it a display name and a unique username ending in bot, and copy the token. Then, inside a Claude Code session on the Mac mini, install the plugin (choose the user scope when asked), store the token, restart with the channel flag, pair, and lock the policy down. The plugin long-polls the Bot API, so the Mac mini needs no inbound port.

# 1. In Telegram: open @BotFather, send /newbot, copy the token

# 2. Inside a Claude Code session on the Mac mini (choose the USER scope when asked)
/plugin install telegram@claude-plugins-official
# "Marketplace not found"? add it first, then retry:
#   /plugin marketplace add anthropics/claude-plugins-official
# If the summary says "Run /reload-plugins to activate.", do so.

# 3. Store the token (written to ~/.claude/channels/telegram/.env;
#    a TELEGRAM_BOT_TOKEN in the shell environment takes precedence)
/telegram:configure <token>

# 4. Exit Claude Code and restart with the channel flag
claude --channels plugin:telegram@claude-plugins-official

# 5. Send any message to your bot: it replies with a pairing code. Then, in Claude Code:
/telegram:access pair <code>
/telegram:access policy allowlist    # only your account can send from now on

Discord (alternative)

In the Discord Developer Portal create a New Application, open Bot, click Reset Token and copy it, enable Message Content Intent under Privileged Gateway Intents, then use OAuth2 → URL Generator with the bot scope and the permissions View Channels, Send Messages, Send Messages in Threads, Read Message History, Attach Files and Add Reactions to invite it to a server you are in, DMs only work if you share a server with the bot. Guild channels are opt-in per channel ID.

# Discord Developer Portal (https://discord.com/developers/applications):
# New Application > Bot > Reset Token (copy it) > enable Message Content Intent
# OAuth2 > URL Generator: scope "bot"; permissions View Channels, Send Messages,
#   Send Messages in Threads, Read Message History, Attach Files, Add Reactions
# Open the generated URL and invite the bot to a server you are in

# Inside Claude Code (token saved to ~/.claude/channels/discord/.env, or set DISCORD_BOT_TOKEN)
/plugin install discord@claude-plugins-official
/discord:configure <token>

# Restart with the channel, DM the bot for a pairing code, pair, lock down
claude --channels plugin:discord@claude-plugins-official
/discord:access pair <code>
/discord:access policy allowlist

# Several channels at once: pass the entries space-separated
# claude --channels plugin:telegram@claude-plugins-official plugin:discord@claude-plugins-official

iMessage (macOS only, the Mac mini advantage)

No bot token: the plugin reads ~/Library/Messages/chat.db directly and sends replies through AppleScript. The first read prompts for Full Disk Access, the prompt names whichever app launched Bun (Terminal, iTerm, your IDE), and the first reply triggers an Automation prompt ("Terminal wants to control Messages"). Both are GUI dialogs, so do this over VNC; without Full Disk Access the server exits with "authorization denied". Then open Messages on any device signed into your Apple ID and send a message to yourself: the self-chat bypasses access control, and other contacts must be allowlisted explicitly. The plugin polls chat.db once a second, starts from the latest row (no replay after a restart), appends "Sent by Claude" unless IMESSAGE_APPEND_SIGNATURE=false, and ignores SMS/RCS by default because "SMS sender IDs are spoofable". Our inference from that mechanism, not a docs sentence: keep the Mac mini's user logged in with Messages signed in.

# Over VNC: System Settings > Privacy & Security > Full Disk Access > add your terminal app
# (or click "Allow" when the first read of ~/Library/Messages/chat.db prompts)

# Inside Claude Code (user scope), then relaunch with the channel
/plugin install imessage@claude-plugins-official
claude --channels plugin:imessage@claude-plugins-official

# From any device signed into your Apple ID: open Messages and text yourself.
# The first reply triggers the macOS Automation prompt ("Terminal wants to control Messages"): click OK.

# Let another contact in (phone in +country format, or Apple ID email)
/imessage:access allow +15551234567

Optional Dry Run: fakechat on localhost

To test the flow without any external service, the official fakechat demo serves a chat UI at http://localhost:8787 (reach it through an SSH tunnel or over VNC). It has no tokens and no access control, so use it for testing only. If Claude Code asks for permission for the first reply, approve it.

/plugin install fakechat@claude-plugins-official
claude --channels plugin:fakechat@claude-plugins-official

# From your laptop, tunnel the demo UI (it listens on localhost only)
ssh -N -L 8787:127.0.0.1:8787 admin@your-server-ip
# then open http://localhost:8787

What you will see: the inbound message appears in your terminal, but the reply text does not, the terminal shows the tool call and a confirmation such as "sent", and the reply appears in the chat app. In -p (non-interactive) mode, tools that need terminal input, multiple-choice questions and plan-mode approval, are disabled so the session never stalls; in the interactive tmux session this guide recommends, plan mode works (restored for --channels sessions in 2.1.126). Project-trust and MCP-consent dialogs are never relayed, so trust the project folder and approve the plugin's MCP server locally first.

6. Step 4: Keep the Session Alive 24/7 and Update

Anthropic prescribes no service mechanism: the docs only say to run Claude "in a background process or persistent terminal", and there are no launchd, systemd, screen or nohup instructions on code.claude.com as of September 28, 2026. What is documented is a tmux configuration page, so tmux is a supported host. Everything in this section beyond the tmux settings is our recommendation for a MyRemoteMac Mac mini, clearly labelled as such.

Run the Channel Session in tmux (our recommendation)

Start the interactive claude --channels session inside a named tmux session over SSH and detach. You can reattach at any time to answer a prompt that was not relayed, renew the login with /login, or read the startup Channels notice. Add the three tmux settings Anthropic documents so notifications reach the outer terminal and Shift+Enter works:

# Install tmux
brew install tmux

# The three settings Anthropic documents for running Claude Code inside tmux
printf 'set -g allow-passthrough on\nset -s extended-keys on\nset -as terminal-features "xterm*:extkeys"\n' >> ~/.tmux.conf

# Start a named session in your project and launch the channel session inside it
tmux new -s claude -c ~/project
claude --channels plugin:telegram@claude-plugins-official

# Detach: Ctrl-b d      Reattach later: tmux attach -t claude
# Renew an expiring login from inside the session: /login

Optional Supervisor: a User LaunchAgent (ours, with a warning)

To recreate the tmux session after a reboot or crash you can register a user LaunchAgent with RunAtLoad and KeepAlive whose program is a small wrapper script. It must be a LaunchAgent, not a LaunchDaemon: the iMessage grants (Full Disk Access, Automation), Messages.app and the Keychain login belong to the logged-in user session, which on a headless Mac mini means Automatic login must be enabled (System Settings > Users & Groups). Two warnings: whether a Bun process launched this way receives its own Full Disk Access grant without a GUI prompt is untested, and open regression issue #97701 (2026-09-27) reports a launchd-supervised --channels daemon churning sessions every ~2 minutes on 2.1.283, with no maintainer reply at the time of writing. Test on your target version and keep the stable channel pinned.

# OUR RECOMMENDATION: not documented by Anthropic. See the warning about issue #97701 above.

# 1. Wrapper script: ~/bin/claude-channels.sh  (chmod 700)
#!/bin/zsh
export PATH="$HOME/.local/bin:$HOME/.bun/bin:/opt/homebrew/bin:/usr/bin:/bin"   # where `which claude` / `which bun` point
# Optional: one-year token from `claude setup-token`, stored in a chmod 600 file
[ -f "$HOME/.claude-channels.env" ] && source "$HOME/.claude-channels.env"
tmux has-session -t claude 2>/dev/null || \
  tmux new -d -s claude -c "$HOME/project" \
    'claude --permission-mode default --channels plugin:telegram@claude-plugins-official'
# Stay alive while the session exists, so launchd's KeepAlive relaunches us when it dies
while tmux has-session -t claude 2>/dev/null; do sleep 30; done

# 2. LaunchAgent: ~/Library/LaunchAgents/com.example.claude-channels.plist
<?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.example.claude-channels</string>
  <key>ProgramArguments</key><array><string>/Users/admin/bin/claude-channels.sh</string></array>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>ThrottleInterval</key><integer>30</integer>
  <key>StandardOutPath</key><string>/Users/admin/Library/Logs/claude-channels.log</string>
  <key>StandardErrorPath</key><string>/Users/admin/Library/Logs/claude-channels.log</string>
</dict></plist>

# 3. Load it into the logged-in user session (LaunchAgent, never a LaunchDaemon)
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.claude-channels.plist
launchctl print gui/$(id -u)/com.example.claude-channels
# Unload: launchctl bootout gui/$(id -u)/com.example.claude-channels

Keep the Mac mini Awake and Logged In

Generic macOS administration, not a Claude Code docs item: disable sleep so the session and the Messages poller never pause (run man pmset on the Mac for details), and enable Automatic login for your user so LaunchAgents and Messages.app come back after a reboot.

# Generic macOS administration (see `man pmset`): never sleep
sudo pmset -a sleep 0 disksleep 0 standby 0 powernap 0

# Automatic login for your user (needed for LaunchAgents and Messages.app after a reboot):
# System Settings > Users & Groups > Automatic login: set it over VNC

# Reboot-test once, then message the bot again
sudo reboot

Update Claude Code, Bun and the Plugins

The native installer checks for updates on startup and periodically, downloads in the background, and applies the new version the next time you start Claude Code, so a long-lived tmux session keeps its version until you restart it. claude update applies immediately. Because the --channels syntax "may change based on feedback", re-read the channels documentation after each update and re-check the startup Channels notice for a warning line.

# Claude Code (native installer): apply a pending update now
claude update
# "Successfully updated from X to version Y" or "Claude Code is up to date (X)"
claude doctor            # shows the last update attempt
# Homebrew: brew upgrade claude-code      npm: npm install -g @anthropic-ai/claude-code@latest

# Channel plugins: refresh the catalogue, then update
claude plugin marketplace update claude-plugins-official
claude plugin update telegram@claude-plugins-official
# (loads in the next session, or after /reload-plugins in a running one)

# Bun
bun upgrade              # curl install   |   brew upgrade bun  (Homebrew install)

# Restart the channel session so the new versions take effect
tmux kill-session -t claude
tmux new -s claude -c ~/project
claude --channels plugin:telegram@claude-plugins-official
# Re-read the startup "Channels" notice for any warning line

7. Security Hardening

Every inbound message lands in a session with filesystem, git and shell access, and "anyone who can reply through the channel can approve or deny tool use in your session". The reference documentation is blunt: "An ungated channel is a prompt injection vector." These are the documented controls, plus our recommendations where the docs are silent:

  • Allowlist immediately after pairing. Run /telegram:access policy allowlist (or the Discord equivalent) once your own account is paired. Once the list is final, TELEGRAM_ACCESS_MODE=static / IMESSAGE_ACCESS_MODE=static disable runtime pairing entirely.
  • Only allowlist senders you trust with approval authority. Relayed approvals cover Bash, Write and Edit; since 2.1.211 relayed text is sanitized and since 2.1.234 credentials are masked as [REDACTED] and relay goes only to servers registered via --channels, but the docs still say to treat the relayed fields as untrusted.
  • Keep permission prompts on. Manual mode plus relay, or auto mode with the classifier, never bypassPermissions on a box holding real code or credentials. Deny rules in settings block commands in every mode.
  • Enable the Bash sandbox (official feature, our recommendation to turn it on): on macOS there is nothing to install, it uses the built-in Seatbelt framework. Add sandbox.credentials entries for ~/.ssh and ~/.aws because the default read policy still allows them.
  • Restrict the token files (our recommendation, the docs do not state a file mode): the configure commands write ~/.claude/channels/<telegram|discord>/.env; environment variables TELEGRAM_BOT_TOKEN / DISCORD_BOT_TOKEN take precedence over the files. Never commit them; rotate via BotFather or the Discord portal if leaked.
  • iMessage privacy surface: Full Disk Access gives the terminal app and everything it launches read access to the entire Messages database, and the Automation grant lets it send iMessages as you. Use a dedicated Apple ID with 2FA on the dedicated Mac mini, and leave IMESSAGE_ALLOW_SMS at its default of false.
  • No inbound ports. The official plugins poll Telegram or connect outbound to Discord's gateway; fakechat listens on localhost only. If you build a custom webhook channel from the reference docs (loadable in the preview only with --dangerously-load-development-channels, which the docs say never to use for untrusted sources), expose its port only over the Mac mini's WireGuard VPN.
# Restrict the channel state and token files (our recommendation: no documented mode)
chmod 700 ~/.claude/channels
chmod 600 ~/.claude/channels/*/.env

# Freeze the allowlists once they are final (disables runtime pairing)
export TELEGRAM_ACCESS_MODE=static
export IMESSAGE_ACCESS_MODE=static

# Bash sandbox with strict mode and protected credential paths: ~/.claude/settings.json
{
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false,
    "credentials": {
      "files": [
        { "path": "~/.aws/credentials", "mode": "deny" },
        { "path": "~/.ssh", "mode": "deny" }
      ],
      "envVars": [
        { "name": "GITHUB_TOKEN", "mode": "deny" }
      ]
    }
  }
}

# Team/Enterprise admins: managed settings (users cannot override)
#   "channelsEnabled": true
#   "allowedChannelPlugins": [{ "marketplace": "claude-plugins-official", "plugin": "telegram" }]
#   "permissions": { "disableBypassPermissionsMode": "disable" }

8. Troubleshooting Common Issues

The bot does not respond

The official answer: "make sure Claude Code is running with --channels … The bot can only reply while the channel is active." A closed SSH session, a crash, a reboot or sleep silently takes the bot offline. Since 2.1.281 the installed plugin's name must also match the --channels entry exactly:

# Is the session still there?
tmux attach -t claude
# Was it started WITH the flag, and with the exact plugin name?
claude --channels plugin:telegram@claude-plugins-official
# Read the startup "Channels" notice: it says why a channel did not register

# Telegram: the Bot API offers no history or search, so Claude cannot fetch older messages;
# Telegram holds undelivered updates for at most 24 hours.
# Discord can catch up: ask Claude to use fetch_messages (max 100).

"Marketplace claude-plugins-official not found" or no /telegram:configure command

Add the marketplace first, choose the user scope on install, and run /reload-plugins if the install summary asks for it (or simply restart):

/plugin marketplace add anthropics/claude-plugins-official
/plugin install telegram@claude-plugins-official     # choose the USER scope
/reload-plugins
/telegram:configure <token>

# Bun missing? every channel plugin requires it
bun --version

Channel connects but no messages arrive (Team, Enterprise or Console org)

channelsEnabled is a managed setting users cannot override. On claude.ai Team/Enterprise it is blocked by default until an Owner enables it; Console orgs that deploy managed settings must set it too. The MCP server still connects and its tools work, only inbound messages are missing, with a startup warning. Check the startup notice and ask your Owner:

# Owner: claude.ai > Admin settings > Claude Code > Channels, or in managed settings:
#   "channelsEnabled": true
# Pro/Max accounts without an organization skip this check entirely.

# Also check that the plugin is on the allowlist (or the org's allowedChannelPlugins)
# and that nothing forces MCP_PROTOCOL_NEGOTIATION=auto in the environment

iMessage server exits with "authorization denied"

Full Disk Access was not granted to the app that launched Bun, or Claude Code was started from a different launcher (sshd, a tmux server started elsewhere, a LaunchAgent) than the one you approved. Grant it over VNC and relaunch from the same place:

# Over VNC: System Settings > Privacy & Security > Full Disk Access > add the terminal app
# that launches your tmux/claude session, then restart the session from that same app.

# The reply path needs the Automation grant as well: the first outbound reply shows
# "Terminal wants to control Messages": click OK in the VNC session.

# SMS/RCS senders are ignored by design unless IMESSAGE_ALLOW_SMS=true (not recommended)

Session stops: "Login expired · Please run /login"

A subscription login expires and an unattended session stops making progress. Reattach to tmux and renew, or switch the always-on box to a one-year OAuth token or an API key:

tmux attach -t claude
/login                   # renew the subscription login
/status                  # check the "Login" row

# Or make the box independent of the browser login:
claude setup-token       # one-year CLAUDE_CODE_OAUTH_TOKEN (Pro/Max/Team/Enterprise)
# or export ANTHROPIC_API_KEY (Console, per-token billing)
# Over SSH the Keychain may be locked: credentials then live in ~/.claude/.credentials.json (0600)

9. Cost Analysis vs. Cloud VPS

Claude Code Channels adds no cost of its own, but Claude Code itself requires a paid plan, the same on any host. What differs is the machine. A general-purpose Linux VPS is cheaper per month than a Mac mini, but it cannot run the iMessage channel, has no Xcode, and shares its hardware. Here is what a typical setup costs in USD per month:

Use Case Claude Access Linux VPS Host Mac mini Host (MyRemoteMac) What the Mac mini Adds
Solo developer, Telegram or Discord Pro, $20/mo ~$20–40/mo (assumption) $85/mo (M4, 16 GB / 256 GB) Dedicated 1:1 hardware, VNC, macOS toolchain
Solo developer, iMessage Pro, $20/mo Not possible (macOS only) $85/mo (M4) The only host type that can run it
Heavy use, several sessions, Xcode builds Max, from $100/mo ~$40–80/mo (assumption) $149/mo (M6) Xcode, Simulator, fast Apple Silicon builds
Team bot (Owner enables channels) Team, $25/seat/mo ~$40–80/mo (assumption) $149/mo (M6) One dedicated box per team, managed settings apply

Assumptions: VPS figures are our rough ranges for entry (4–8 GB) and mid-range (16 GB) general-purpose Linux instances, not quotes from a specific provider. Claude plan prices are from claude.com/pricing on September 28, 2026 (Pro $20/mo or $17/mo billed annually; Max from $100/mo; Team $25/seat/mo standard or $20 annual, $125 premium). Console API-key billing is per token instead, first-party list prices at the time of writing: Sonnet 5 $2/$10, Opus 5 $5/$25, Haiku 4.5 $1/$5 per million input/output tokens. Subscription plans are metered: an always-on bot shares the same allowance as your interactive coding. Anthropic publishes no RAM or CPU footprint for a channel session, so we size qualitatively: a Mac mini M4 with 16 GB is ample for one Claude Code + Bun plugin session; pick the M6 (available since September 22, 2026) if the same machine also runs heavy builds, several sessions or a local model.

Bottom Line: If you only need Telegram or Discord and never touch macOS, a Linux VPS is the cheaper host. The Mac mini earns its price when the agent should have your Xcode project open, when you want iMessage, or when you want dedicated, non-virtualized hardware with VNC for the one-time macOS prompts, from $85/month on top of the Claude plan you already pay for.

10. Claude Code Channels vs. OpenClaw

They solve different problems. Claude Code Channels is a feature of a proprietary CLI, not a standalone assistant: it bridges Telegram, Discord or iMessage into an already-running Claude Code session, so the value is "talk to the coding agent that has your repo open", with Anthropic support, Claude Code's permission model, relayed yes/no approvals with sanitized prompts, sender allowlists, the Bash sandbox and managed org settings. It is Claude-only through Anthropic authentication, has no daemon of its own, and custom channels are only loadable behind a development flag during the preview. OpenClaw (github.com/openclaw/openclaw, MIT, community-maintained, roughly 391k GitHub stars versus 148k for anthropics/claude-code on September 28, 2026) is an open-source, self-hosted gateway that runs 24/7 as its own supervised launchd service, supports many more chat platforms (WhatsApp, Telegram, Discord, iMessage, Slack, Signal, Teams, Google Chat and more) and lets you choose the model provider, including local models. Several secondary articles have framed Channels as an OpenClaw alternative; the official documentation makes no such comparison.

Pick Channels if you already pay for Claude Pro, Max or Team and want your real project files reachable from your phone with official support and relayed permissions. Pick OpenClaw for WhatsApp, Slack or Signal, provider choice, local models or true daemon operation, see our OpenClaw on Mac mini guide (and its Python cousin, Hermes Agent). Both iMessage bridges need macOS with Messages signed in and the same TCC grants, which is exactly why a dedicated 1:1 Mac mini suits either.

11. FAQ

Is Claude Code Channels free or open source?

No on both counts for Claude Code itself: the CLI is proprietary ("© Anthropic PBC. All rights reserved. Use is subject to Anthropic's Commercial Terms of Service.") and requires a Pro, Max, Team, Enterprise or Console account, the free claude.ai plan does not include Claude Code. Only the channel plugins in the claude-plugins-official repository are open source (Apache-2.0). Channels adds no extra charge beyond your plan or API usage.

Do I have to keep a terminal open for the bot to work?

Yes, the session must stay open. Per the official docs, events only arrive while the Claude Code session is running with --channels, so for an always-on setup you run it in a background process or persistent terminal. Anthropic does not prescribe a mechanism; our recommendation on a Mac mini is a named tmux session you can reattach to over SSH, optionally supervised by a user LaunchAgent (see Step 4 for the caveats).

Can I use a local model, Ollama, Bedrock or Vertex with Channels?

No. Channels require Anthropic authentication through claude.ai or a Console API key and are not available on Amazon Bedrock, Google Cloud's Agent Platform or Microsoft Foundry. Routing to a non-Claude endpoint is not a supported configuration. You can still run a local LLM on the same Mac mini as a separate workload, see our local LLM guide, but not as the brain of a channel session.

Which Mac mini configuration should I pick?

Anthropic's stated requirements are modest (macOS 13+, 4 GB+ RAM) and no per-session footprint is published, so we size qualitatively: the Mac mini M4 with 16 GB / 256 GB at $85/month is ample for one Claude Code session plus a Bun channel plugin. Choose the Mac mini M6 from $149/month if the same machine will also run heavy Xcode builds, several channel sessions or a local model alongside.

Does the iMessage channel work on a headless Mac mini?

Yes, with two one-time GUI steps done over VNC: granting Full Disk Access to the app that launched Bun, and clicking OK on the Automation prompt ("Terminal wants to control Messages") on the first reply. The plugin reads the logged-in user's ~/Library/Messages/chat.db and drives Messages.app through AppleScript, so, our inference from that mechanism, not a docs sentence, keep the user logged in with Messages signed in to the Apple ID, and enable Automatic login so it survives reboots. Use a dedicated Apple ID with 2FA.

What about WhatsApp, Slack, Signal or Teams?

They are not official channels. The research preview ships Telegram, Discord and iMessage plugins plus the fakechat demo; any other channel is a custom MCP server that, during the preview, only loads behind --dangerously-load-development-channels or an organization's allowedChannelPlugins setting. Claude in Slack is a different feature that spawns cloud sessions. If breadth of platforms is the priority, OpenClaw is the better fit.

12. Sources and Further Reading

Every command, flag and requirement in this guide was checked on September 28, 2026 against the official Claude Code documentation, the CHANGELOG (Claude Code 2.1.283, published to npm on September 25, 2026) and the claude-plugins-official repository (telegram 0.0.7, discord 0.0.4, imessage 0.1.0, fakechat 0.0.1). Channels is a research preview whose flags may change, consult these pages for the current state:

Related Guides

Ready to Message Your Coding Agent 24/7?

Deploy a dedicated Apple Silicon Mac mini as your Claude Code Channels host. M4 from $85/month, M6 from $149/month, 1 Gbps included, SSH and VNC.

Looking for more detail?

Browse the full documentation for step-by-step setup, configuration references, and troubleshooting.

Open the documentation →