English | 한국어
CCTG (Claude Code Tmux Gateway) is a macOS launcher that ties together tmux + Claude Code + a chat gateway (Telegram or Discord), so you can run and manage a per‑project Claude Code chat bot from your phone or any chat client. The command is cctg.
In short, it's a macOS CLI that connects Claude Code to Telegram and Discord bots and uses tmux to launch, isolate, and manage many per‑project bots from one place. You don't have to babysit a terminal — start tasks and check status remotely from your phone or any chat app. (Common searches: run Claude Code from Telegram/Discord, Claude Code Telegram bot, Claude Code Discord bot, tmux bot gateway, macOS Claude Code bot manager.)
Each project bot has its own state directory, token, working directory, and isolated tmux session — and CCTG never touches the global channel bot at ~/.claude/channels/<channel>/.
⚠️ Privacy — read this first. A bot relays the messages it receives to a Claude Code process running in its working directory, and Claude Code sends that content to the Anthropic API for processing. Conversations, code, and file contents you exchange with the bot therefore pass through a third party (Anthropic) and through Telegram/Discord infrastructure. Think twice before attaching a bot to a sensitive repository, and strictly limit who can reach it via theaccess.jsonallowlist (yourself, or trusted users only).ℹ️ Unofficial tool. CCTG is an unofficial, third‑party tool not built or endorsed by Anthropic. "Claude Code" and "Claude" are trademarks of Anthropic; this project is not affiliated with Anthropic.
📜 Your use is subject to upstream terms. Talking to a bot sends content to the Anthropic API, so your use is governed by your own Anthropic plan terms and Usage Policy; running a bot also makes you a Telegram/Discord bot operator (e.g. Discord requires a privacy policy, and you should disclose the bot is an AI if others can reach it). See SECURITY.md → Your responsibilities as a bot operator.
- Who is this for?
- Requirements
- Quick Start
- Everyday commands
- Permissions in one minute
- Supported channels
- Documentation
- Uninstall
- Contributing & license
You want to talk to Claude Code in one of your project directories from Telegram or Discord — for example to kick off a task from your phone, or to keep a long‑running assistant attached to a repo — without leaving a terminal open and babysitting permission prompts. CCTG gives each project its own isolated bot and keeps it alive in a detached tmux session.
macOS only. CCTG relies on
caffeinate(a macOS built‑in) and assumes the macOS shell/tooling layout. Linux and WSL are not supported at this time.
| Dependency | Purpose | Required? |
|---|---|---|
claude |
Claude Code CLI — the assistant each bot runs | ✅ Required |
tmux |
Runs the bot in a detached background session | ✅ Required |
caffeinate |
Prevents the Mac from sleeping while a bot runs | Built into macOS |
jq |
status --json, structured common edits, Discord --group seeding |
Optional |
| channel plugin | The Telegram/Discord integration, installed globally in Claude Code | ✅ Required for the channel you use |
Install details, PATH setup, and update/uninstall are in docs/installation.md.
The fastest path from zero to a working bot. The example uses Telegram; for Discord, swap Step 3 for docs/discord-setup.md.
-
Install Claude Code and tmux (e.g.
brew install tmux). Optionallybrew install jq. -
Install the channel plugin globally inside Claude Code:
/plugin install telegram@claude-plugins-official(For Discord:
/plugin install discord@claude-plugins-official.)
git clone https://github.com/qwertygeon/cctg.git
cd cctg
./install.shinstall.sh checks dependencies, places cctg at ~/.local/bin/cctg, installs a short alias command cg (default; --no-alias to skip, --alias=NAME to rename), installs shell completions, and adds a managed block to your shell rc for PATH + completions. It is safe to re‑run. To install a specific release instead of the latest, use --version X.Y.Z (and switch later with cctg update --version X.Y.Z / --latest / --list). Then open a new terminal (or source ~/.zshrc) and verify:
cctg doctorIf ~/.local/bin is not on your PATH, the installer prints the exact line to add. See docs/installation.md for install modes (release vs. --dev), BINDIR, completions, and more.
For Telegram you need two things — a bot token and your numeric Telegram ID:
- Create a NEW bot with @BotFather: send
/newbot, pick a name and a username. BotFather gives you a token like123456789:ABCdef.... It must be a brand‑new bot (not one already running elsewhere). - Get your numeric ID: DM @userinfobot; it replies with your numeric user ID.
Now register the bot. <name> is any label (letters/digits/_/-); <dir> is the project directory the bot will work in:
cctg add myproject ~/work/myprojectadd prompts you for the channel (required — there is no default), the token (masked), your numeric ID, and a permission mode. It scaffolds the state directory, stores the token with 600 permissions, and seeds the access.json allowlist with your ID — so no separate pairing step is needed for Telegram.
$ cctg add myproject ~/work/myproject
Channel — pick a number (required):
1) telegram
2) discord
Number [1-2] or channel name: 1
Bot token (issued by @BotFather, must be a NEW bot): ********
Your Telegram numeric ID: 123456789
Permission mode — pick a number:
...
Registered: myproject → cwd=/Users/you/work/myproject, state=/Users/you/.claude/channels/myproject
seeded 123456789 into the allowlist (no pairing needed)Full walkthroughs, including non‑interactive registration for CI: docs/telegram-setup.md · docs/discord-setup.md.
cctg up myprojectThis launches the bot in a detached tmux session (cctg-myproject) under caffeinate -is, so your Mac won't sleep while it runs.
$ cctg up myproject
UP myproject (cwd=/Users/you/work/myproject, state=/Users/you/.claude/channels/myproject, tmux=cctg-myproject)Open Telegram and DM your new bot — it responds right away, with Claude Code running in your project directory. Check on it any time:
cctg status # is it running? for how long? which mode/channel?
cctg logs myproject # recent output (works even after the bot is stopped)
cctg attach myproject # watch the live session (detach with Ctrl-b d)That's it. Stop with cctg down myproject, restart with cctg restart myproject.
💬 Bots are told to reply through the channel. So that a bot always answers in chat (instead of "thinking" only in its terminal), CCTG injects a short reply-reminder into every bot via
claude --append-system-prompt. It's on by default, seeded at~/.claude/channels/cctg-reply-reminder.txt. Edit that file to customize the wording, or empty it to turn the reminder off.cctg doctorshows whether it's on. Details: docs/configuration.md → Channel reply reminder.
cctg <command> [args]
add <name> <cwd> --channel telegram|discord [--id <num>]
[--token-env <VAR>|--token-stdin] [--mode <m>] [--group ...]
rm <name> [--purge] rename <old> <new> [--keep-dir]
up <name...|all> down <name...|all> restart <name...|all>
status [--json] [-a] logs <name> [N] attach <name>
config <name> [...] common [...] lang [show|en|ko|clear]
doctor update version help
| Command | What it does |
|---|---|
add / rm / rename |
Register, unregister, or rename a bot |
up / down / restart |
Start / stop / restart one or more bots (names, telegram/discord, or all) |
status / logs / attach |
See state and uptime / read logs / attach to the live session |
config / common |
Per‑bot options / shared permission policy |
lang |
Switch CLI output language (English/Korean) |
doctor / update / version |
Diagnose the environment / update CCTG / print version |
The full reference for every command and flag is in docs/commands.md.
A bot is a Claude Code TUI running headless in tmux — nobody is there to answer a permission prompt, so a prompt would stall it. CCTG's answer is "auto‑approve what's harmless, block what's dangerous with deny rules."
- A shared policy (
cctg common) applies to all bots: it defaults tobypassPermissionsplus a deny safety net (sudo,rm -rf /, force‑push, reading~/.ssh, …). Deny rules and PreToolUse hooks still apply even underbypassPermissions. - A per‑bot mode (
cctg config <name> mode ...) overrides the shared default for one bot.
The full model — every mode, the default deny list, and how to tighten it — is in docs/permissions.md.
CCTG follows Claude Code's channels layout (~/.claude/channels/): each channel plugin keeps its global bot under ~/.claude/channels/<channel>/, overridable per process via that plugin's <CHANNEL>_STATE_DIR.
| Channel | Claude Code plugin | CCTG support |
|---|---|---|
| Telegram | telegram@claude-plugins-official |
✅ Supported — see docs/telegram-setup.md |
| Discord | discord@claude-plugins-official |
✅ Supported — DM via pairing by default, server channels via --group; see docs/discord-setup.md |
| iMessage | imessage@claude-plugins-official |
⛔ Planned — name reserved |
| fakechat | fakechat@claude-plugins-official |
⛔ Not applicable — name reserved |
| Slack | slack@claude-plugins-official |
➖ Out of scope — not a tmux‑hosted message bridge |
CCTG reserves the names
telegram,discord,imessage, andfakechatso a project bot can never overwrite a global channel bot's token or allowlist. It also refuses to reuse a state directory that already holds a non‑CCTG channel bot's state. How channels are wired (thechannel_specdescriptor) is covered in docs/configuration.md.
| Document | Contents |
|---|---|
| Installation | Detailed install, modes, PATH, completions, updating, uninstall |
| Telegram setup | Create a bot with BotFather, get your ID, connect step by step |
| Discord setup | Discord application/bot, token, pairing, server‑channel --group |
| Command reference | Every command and flag, with examples |
| Permissions & policy | Shared policy + per‑bot modes, deny/allow, the default deny list |
| Configuration & internals | CLI language, env vars/paths, how it works, log snapshots |
Project meta: Security policy · Changelog
./uninstall.shThis removes the cctg launcher, completions, the shell rc managed block, and CCTG's own config — but never touches the registry or state directories under ~/.claude/channels/, so your bot registrations and tokens survive a reinstall. Details in docs/installation.md.
The version is sourced from the VERSION file at the repository root (the single source of truth); check it with cctg version, and cctg update shows the before/after versions. Licensed under MIT.