English | 中文
Approve Claude Code permission requests remotely — keep your agent running when you're away from the computer.
cc-remote-approval is a Claude Code plugin. When Claude needs your approval (permissions, forms, questions), if you don't respond locally within a few seconds, the request is forwarded to your messaging channel so you can respond remotely.
Claude Code needs permission → Native dialog shows locally (as usual)
→ Hook starts counting down
↓ 20 seconds with no response (configurable)
→ Notification with buttons on your channel
↓
You tap Allow / Deny / Always
↓
Claude Code continues
Race mode: Both the local dialog and your remote channel are active simultaneously. Whichever you respond to first wins, and the other side auto-syncs.
| Scenario | Hook | Description |
|---|---|---|
| Bash / Edit / Write approval | PermissionRequest | Allow / Always / Deny buttons |
| AskUserQuestion | PermissionRequest | Option buttons + text input |
| MCP forms (Elicitation) | Elicitation | Remote form (string/enum/boolean/integer/number fields), 60s timeout falls back to local |
| Agent idle | Notification | 💤 idle notification |
| Remote task continuation (optional) | Stop | Continue/Dismiss buttons, reply with next instruction; opt-in via stop_hook_enabled |
📖 Full context button: every interactive hook above also includes a "Full context" button that expands the last N transcript turns (config: context_turns) as reply-threaded messages under the original. Useful when the truncated preview isn't enough to decide.
In Claude Code, run:
/plugin marketplace add Manta-Network/cc-remote-approval
/plugin install cc-remote-approval@manta
/reload-plugins
Then start a new session (or /clear) so the SessionStart hook can inject the AskUserQuestion preference hint into the conversation context.
For local development, point the marketplace at your clone instead:
/plugin marketplace add /path/to/cc-remote-approval
/plugin install cc-remote-approval@manta
/reload-plugins
The hook commands invoke python3. On a stock Windows install, python3 resolves to the Microsoft Store alias stub (exits immediately) — Python's official Windows installer only provides python.exe. Pick one:
- Shim (recommended): in PowerShell as admin,
New-Item -ItemType SymbolicLink -Path "$(Split-Path (Get-Command python).Source)\python3.exe" -Target (Get-Command python).Source. Survives reinstalls of the plugin. - Or: disable the Store aliases (Settings → Apps → Advanced app settings → App execution aliases → turn off both
python.exeandpython3.exe) so Windows stops shadowing your real Python.
In Claude Code, run /cc-remote-approval:setup to configure interactively, or manually create ~/.cc-remote-approval/config.json. After setup, run /cc-remote-approval:status any time to verify the channel is working (bot token valid, chat reachable, recent hook activity).
Manual config:
{
"channel_type": "telegram",
"bot_token": "123456:ABC-DEF...",
"chat_id": "your-chat-id",
"escalation_seconds": 20,
"elicitation_timeout": 60,
"stop_hook_enabled": false,
"stop_wait_seconds": 180,
"session_hint_enabled": true
}- Open Telegram, search for @BotFather →
/newbot→ copy the token - Send any message to your new bot
- Get your chat_id:
curl -s "https://api.telegram.org/bot<TOKEN>/getUpdates" | \
python3 -c "import json,sys; u=json.load(sys.stdin)['result']; \
print(u[-1]['message']['chat']['id']) if u else print('Send a message to your bot first')"| Field | Default | Description |
|---|---|---|
channel_type |
"telegram" |
Messaging channel (telegram, more coming) |
bot_token |
required | Telegram bot token from @BotFather |
chat_id |
required | Your Telegram chat ID |
escalation_seconds |
20 | Seconds before escalating to channel |
elicitation_timeout |
60 | Seconds before falling back to local form for MCP elicitations |
context_turns |
3 | Conversation turns shown in message context |
context_max_chars |
200 | Max chars per context turn |
stop_hook_enabled |
false |
Enable Stop hook for remote task continuation (opt-in — blocks Claude Code for stop_wait_seconds between turns). |
stop_wait_seconds |
180 | Seconds to wait for remote instruction before allowing idle (local input in Claude Code releases immediately) |
session_hint_enabled |
true |
Inject SessionStart hint that steers Claude to prefer AskUserQuestion tool for option-picking (renders as buttons on channel). Set false to let Claude use its natural behavior. |
All values are configurable. You can also override any config field via environment variable with the CC_REMOTE_APPROVAL_ prefix (e.g., CC_REMOTE_APPROVAL_SESSION_HINT_ENABLED=false).
- Local-first — Everything runs on your machine; only channel API calls go external
- Non-invasive — Claude Code's native dialogs still show; hooks run in parallel
- Zero dependencies — Python stdlib only, no pip install needed
- Channel-agnostic — Hook logic separated from channel implementation; adding Slack = add one file
- Concurrency-safe — Shared polling queue prevents message loss with multiple agents
For project structure, known limitations, and developer guide, see CLAUDE.md.
MIT