Control Claude Code, Codex CLI and Gemini CLI from Telegram. Live streaming, persistent memory, cron jobs, webhooks, Docker sandboxing.
# Add to your Claude Code skills
git clone https://github.com/PleasePrompto/ductorIf you want to control Claude Code, Google's Gemini CLI, or OpenAI's Codex CLI via Telegram or Matrix, build automations, or manage multiple agents easily — ductor is the right tool for you. The messaging layer is modular: Telegram and Matrix ship today, and new transports plug into the same transport-agnostic core.
ductor runs on your machine and sends simple console commands as if you were typing them yourself, so you can use your active subscriptions (Claude Max, etc.) directly. No API proxying, no SDK patching, no spoofed headers. Just the official CLIs, executed as subprocesses, with all state kept in plain JSON and Markdown under ~/.ductor/.
pipx install ductor # or: uv tool install ductor
ductor
The onboarding wizard handles CLI checks, transport setup (Telegram or Matrix), timezone, optional Docker, and optional background service install.
Requirements: Python 3.11+, at least one CLI installed (claude, codex, or gemini), and either:
For Matrix support: ductor install matrix — see Matrix setup guide.
Detailed setup: docs/installation.md
ductor gives you multiple ways to interact with your coding agents. Each level builds on the previous one.
This is where everyone starts. You get a private 1:1 chat with your bot (Telegram or Matrix). Every message goes to the CLI you have active (claude, codex, or gemini), responses stream back in real time.
You: "Explain the auth flow in this codebase"
Bot: [streams response from Claude Code]
You: /model
Bot: [interactive model/provider picker]
You: "Now refactor the parser"
Bot: [streams response, same session context]
This single chat is all you need. Everything else below is optional.
Telegram: Create a group, enable topics (forum mode), and add your bot. Matrix: Invite the bot to multiple rooms — each room is its own context.
Every topic (Telegram) or room (Matrix) becomes an isolated chat with its own CLI context.
Group: "My Projects"
├── General ← own context (isolated from your single chat)
├── Topic: Auth ← own context
├── Topic: Frontend ← own context
├── Topic: Database ← own context
└── Topic: Refactor ← own context
That's 5 independent conversations from a single group. Your private single chat stays separate too — 6 total contexts, all running in parallel.
Each topic can use a different model. Run /model inside a topic to change just that topic's provider.
All chats share the same ~/.ductor/ workspace — same tools, same memory, same files. The only thing isolated is the conversation context.
Telegram note: The Bot API has no method to list existing forum topics. ductor learns topic names from
forum_topic_createdandforum_topic_editedevents — pre-existing topics show as "Topic #N" until renamed. This is a Telegram limitation, not a ductor limitation.
Need to work on something unrelated without losing your current context? Start a named session. It runs inside the same chat but has its own CLI conversation.
You: "Let's work on authentication" ← main context builds up
Bot: [responds about auth]
/session Fix the broken CSV export ← starts session "firmowl"
Bot: [works on CSV in separate context]
You: "Back to auth — add rate limiting" ← main context is still clean
Bot: [remembers exactly where you left off]
@firmowl Also add error handling ← follow-up to the session
Sessions work everywhere — in your single chat, in group topics, in sub-agent chats. Think of them as opening a second terminal window next to your current one.
Any chat can delegate long-running work to a background task. You keep chatting while the task runs autonomously. When it finishes, the result flows back into your conversation.
You: "Research the top 5 competitors and write a summary"
Bot: → delegates to background task, you keep chatting
Bot: → task finishes, result appears in your chat
You: "Delegate this: generate reports for all Q4 metrics"
Bot: → explicitly delegated, runs in background
Bot: → task has a question? It asks the agent → agent asks you → you answer → task continues
Each task gets its own memory file (TASKMEMORY.md) and can be resumed with follow-ups.
Sub-agents are completely separate bots — own chat, own workspace, own memory, own CLI auth, own config settings (heartbeat, timeouts, model defaults, etc.). Each sub-agent can use a different transport (e.g. main on Telegram, sub-agent on Matrix).
ductor agents add codex-agent # creates a new bot (needs its own BotFather token)
Your main chat (Claude): "Explain the auth flow"
codex-agent chat (Codex): "Refactor the parser module"
Sub-agents live under ~/.ductor/agents/<name>/ with their own workspace, tools, and memory — fully isolated from the main agent.
You can delegate tasks between agents:
Main chat: "Ask codex-agent to write tests for the API"
→ Claude sends the task to Codex
→ Codex works in its own workspace
→ Result flows back to your main chat
| | Single chat | Group topics | Named sessions | Background tasks | Sub-agents |
|---|---|---|---|---|---|
| What it is | Your main 1:1 chat | One topic = one chat | Extra context in any chat | "Do this while I keep working" | Separate bot, own everything |
| Context | One per provider | One per topic per provider | Own context per session | Own context, result flows back | Fully isolated |
| Workspace | ~/.ductor/ | Shared with main | Shared with parent chat | Shared with parent agent | Own under ~/.ductor/agents/ |
| Config | Main config | Shared with main | Shared with parent chat | Shared with parent agent | Own config (heartbeat, timeouts, model, ...) |
| Setup | Automatic | Create group + enable topics | /session <prompt> | Automatic or "delegate this" | Telegram: ductor agents add; Matrix: agents.json / tool scripts |
~/.ductor/ ← shared workspace (tools, memory, files)
│
├── Single chat ← main agent, private 1:1
│ ├── main context
│ └── named sessions
│
├── Group: "My Projects" ← same agent, same workspace
│ ├── General (own context)
│ ├── Topic: Auth (own context, own model)
│ ├── Topic: Frontend (own context)
│ └── each topic can have named sessions too
│
└── agents/codex-agent/ ← sub-agent, fully isolated workspace
├── own single chat
├── own group support
├── own named sessions
└── own background tasks
/model to change provider/model (never blocks, even during active processes)wake (inject into active chat) and cron_task (isolated task run) modesNo comments yet. Be the first to share your thoughts!