Claude is one more chat.
aipager puts your Claude Code sessions in Telegram, between your family, your friends and your team. It runs on your computer.
A Claude Code session resting on your laptop, in Auto mode, where every new session starts.
curl -fsSL aipager.run/install | shLinux & macOS · MIT · about a minute
Three modes. Auto is where you start.
Every session is in one of three, set per session and changed any time with /mode. Ask stops before each action. Auto, where every new session starts, lets Claude Code's own safety check run the safe calls and stop the risky ones for you. Full access runs everything with no checks at all. A mode moves Claude Code's own prompts and nothing else: in a group, a tool a member's role may not use is still refused, whatever the mode says.
- ✅ Allow · this one call
- ❌ Deny · Claude blocks the call
- 🟢 Allow always · adds the rule Claude offers, when it offers one
- ⏹ Stop · interrupt the turn instead of answering
Shows a button for each other mode; /mode ask, /mode auto and /mode full switch straight away. New sessions start in Auto unless the chat chose otherwise under /settings → New sessions.
No restart, even while Claude works: aipager presses Shift+Tab in the session, and the card says it is switching until Claude Code confirms the new mode.
Going to or from Full access restarts the session and keeps the conversation. Only an admin can start or switch one into it (or you, in your own private chat with the bot).
A mode governs permission prompts, not decisions: when Claude asks you something, the buttons land in your chat whatever the mode.
Three chats. Everything else is just your life.
- aipagerbot⏳ api · Working · 3:14 · Read ×2 · Bash ×2Your chat with Claude
One chat for every session. A live card per turn that edits itself, prompts you answer with a tap, and a pinned bar that says what needs you. A plain message goes to the session the bar names; /web sends the next one to another session, and the conversation carries on there.
/status/new/mode/stop/app/<session> <prompt> - BTbackend-teamgroup · team modeSara: @aipagerbot /web run the login e2e against stagingYour team's group
Put the bot in a group and anyone on the allow-list can mention it. Every message runs with its sender's role; a tool the role may not use is refused before it runs, and every decision lands in the audit log with the name of whoever tapped.
owneradminuserread_only - JJimtheir own chat with the bot🔐 web · Permission neededSomeone else, in their own chat
Add a teammate's private chat with the bot and they drive their own sessions, with their own role and their own root folder: their Claude turns start inside it and read nothing in your home folder outside it. Someone who should only watch gets read_only in your group.
members' root folder~/aipager-users/<label>read_only/new
Four roles, and a tool rule per role.
The role that counts is the one you hold in the chat you are acting in, and a tool a role may not use is refused before it runs, not asked about. Nothing in Telegram or the Mini App can change who is in the list: only aipager config, on the computer.
| Can | owner | admin | user | read_only |
|---|---|---|---|---|
| Send prompts to a session | ✓ | ✓ | ✓ | ✕ |
| Allow, Deny, answer Claude's questions | ✓ | ✓ | ✓ | ✕ |
| Bash, and anything else that runs code | ✓ | ✓ | ✕ | ✕ |
| Full access, a group's /settings, /update | ✓ | ✓ | own chat | ✕ |
| Where their sessions may work | anywhere | anywhere | root folder | root folder |
| Read credential files (~/.ssh, …) | ✓ | ✓ | ✕ | ✕ |
Use it like a chat.
Not a console with a chat skin: everything you already do in Telegram works here. Talk into it on the way home, throw it the screenshot, send the next thought before the last one is done.
- 🎙️Say it instead
Send a voice note and it is transcribed on your own computer (never anyone's cloud), echoed back so you can see what it heard, and typed into the session as if you had written it.
0:07🎙️ Heard: fix the flaky login e2e test - 📎A screenshot of the bug
Photos and files land in a folder on your computer and Claude is pointed at the path, with your caption as the prompt, or check this: … when there is none. Send several at once and they go as one prompt.
- 📤It sends files back
Ask in your own words, “send me the screenshot”, and the file comes to that session's chat right after the answer: images as photos, videos and audio as themselves, anything else as a file, several at once as one album. Never aipager's settings, Claude's credentials or your keys: those are refused before anything is sent.
send me the screenshot - 👀Send the next one now
Your message goes to Claude the moment you send it, even mid-turn: 👀 while Claude's own queue holds it, 👍 when Claude takes it. ⚡ Send now hands it over without waiting for the step to end.
- ⏸Never read as the answer
A message you send while a permission prompt is open is held back, not folded into the prompt, and goes to the session the moment you have answered.
- 🤖Agents and shells, counted
Every background agent Claude starts gets its own row on the card with what it is doing, and a command left running in the background keeps its own clock until it ends.
- 🔔It tells you first
A context warning, a compaction, a session that ended or went quiet, a turn that outlived itself: the chat says so without you going to look.
- ⌨️The buttons are already there
A keyboard sits under the message box: one button per live session, then status, stop and new, then Templates for the prompts you keep retyping and Commands for the ones Claude Code handles itself.
- 📋/status, the whole chat at once
Every session as a list you can act on: what each is doing, its model, the context left, what it has cost, what is queued behind it, with Stop, Answer and the rest of the menu on each one.
A dashboard, still inside Telegram.
/app opens every session at once: one tile each, with its context ring, folder, model and what it has spent. The chat is still where you answer, and the app is for the look across all of them, and for the things a chat is clumsy at, like reading a diff or changing a setting.
A tile each, with its context ring, whose it is, the model and what it has spent, with a line over them that says how the chat stands: what is working, what is resting, what the day cost, how many have finished. The + starts another: a name, a folder from the ones you already use, a model.
A session waiting on a permission prompt or a question sits at the top with what it is asking. Answer in chat sends that prompt back to the bottom of the chat, buttons and all, and you answer it there.
The state line, “Working for 3:12” or “Resting, last active 5m ago”, and one tap to Stop or Resume. Under it the last tool calls, the latest reply, the model control, the files the turn changed as a diff, and that session's own settings.
On by default, every request checked against Telegram's own signature, and the page loads nothing from anywhere else: no fonts, no scripts. aipager miniapp disable turns it off.
In your language, down to the digits.
Only aipager's own words change: cards, prompts, buttons, the pinned bar, /status, the Mini App, the docs. Your sessions do not: Claude answers in the language you write to it, and what aipager sends Claude stays as it was. Pick one with /language, or let it follow your Telegram app.
Persian and Arabic read right to left, with Persian (۰-۹) or Arabic-Indic (٠-٩) digits and their own separators, in Telegram and in the Mini App. Session names, paths, commands and code keep their own direction.
Each language was written the way people who use apps in it actually speak, loanwords included, with each language's own plural forms (Arabic has six).
A private chat can follow your Telegram app. A group has one language, set by an admin, and a pop-up after a tap is in the tapper's own language.
The README and every page under docs/ are translated. When a translation and the English page disagree, the English page is right.
pnpm test e2e/login --trace onThe terminal stays the source of truth.
Claude Code runs in a real terminal, inside dtach, so nobody has to keep a window open. Each step fires a hook that sends one datagram to aipager over a local socket, and aipager edits a message in your chat. Your answers travel back the same way: a verdict to the hook holding the call, or keystrokes into the session.
- Claude Codeinside dtach, no window needed
- hookfires at every step
- aipagerone process, your user
- Telegramyour own bot token
- your chatsyour private chat, your team's group
aipager session api attaches to the running session from any shell. Type there, type in the chat: same session. Close the window and it carries on, and the attach even follows the session through a restart.
aipager types into the session and listens to Claude Code's own events. What your chat shows comes from the hooks and the transcript, not from scraping a terminal.
A hook sends one datagram and returns, about 20 ms of Claude Code's time. With aipager not listening the event is simply dropped and Claude carries on; aipager catches up from the session's own files.
Nothing in the middle.
aipager never talks to Anthropic. The only thing that does is Claude Code itself, with your own login, on your own computer. aipager starts it in a terminal and listens to the hooks Claude Code publishes. No endpoint anyone reverse-engineered, no proxy, no account but yours: the session you drive from your phone is the one you would drive from the keyboard.
aipager talks to the Telegram Bot API with your own bot token. There is no aipager account and no aipager service, and no one else's computer between your phone and yours.
aipager answers only in the chats listed in your config. A stranger who finds the bot gets one line saying it is not configured to talk to them; nothing they send reaches a session.
It listens on loopback only. The Mini App goes out through a Cloudflare tunnel where every request must carry Telegram's signature, and aipager miniapp disable turns it off.
The bot token and the chat ids live in ~/.config/aipager/aipager.yaml at mode 600. They are kept out of aipager's log, and redacted wherever they could slip into one.
No sudo, no setuid. Everything it writes is under your home folder, /tmp or its own socket folder, and every process it starts (claude, dtach, the installers) runs as you.
Your settings.json says what needs asking. aipager relays the question; it never decides what may run, and a button left from a finished turn refuses instead of acting on the work running now.
Members and roles change only with aipager config, on the computer. Nothing in Telegram and nothing in the Mini App can add a person or widen a role.
Each Allow, Deny and answer goes to ~/.claude/aipager-audit.jsonl, append-only, with who tapped it in a group.
Four lines. Keep them in Saved Messages.
Tap a line to copy it. Two things first: a bot of your own from @BotFather (press Start in it), and Claude Code logged in on this computer. The wizard in line two asks for the rest.
Put the bot token in a file it never has to read, then give Claude Code this:
Install aipager for me by following https://aipager.run/agent.md. My Telegram bot token is in ~/.config/aipager/bot-token and my Telegram user id is <your id>.
Prefer your package manager? uv, pipx, Homebrew, Docker, Nix, the AUR and Snap. every way to install →
Ask it.
Add Claude to your chats.
Then close the terminal and go live your evening.