Skip to main content

aipager

PyPI Python License

Telegram remote-control for Claude Code CLI sessions. Run Claude inside a detached terminal (dtach), drive it from your phone - read responses, send prompts, approve permission requests, switch sessions - without an SSH session staying open.

aipager.run · Docs · Changelog · Issues

Install

Have a coding agent (Claude Code, or any agent with a shell)? Create a bot with @BotFather, press Start in it, and make sure you are logged in to Claude Code on this machine. Save the bot token to a file your agent never has to read (paste the token, press Enter, then Ctrl-D):

mkdir -p ~/.config/aipager
rm -f ~/.config/aipager/bot-token
(umask 077 && cat > ~/.config/aipager/bot-token)
chmod 600 ~/.config/aipager/bot-token

Then give your agent this prompt:

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>.

If you do not know your Telegram user id, say so instead; the agent can find it.

The guide it follows, including how to hand over the token safely, is docs/install-with-an-agent.md. To install it yourself, read on.

Linux or macOS, any architecture. dtach is installed automatically via the dtach-bin dependency - no separate system package needed.

curl -fsSL https://raw.githubusercontent.com/dev-aly3n/aipager/main/install.sh | sh

It uses uv if present, else pipx, else (on macOS only) Homebrew. If none is found, it bootstraps uv (Astral's Python tool manager) and installs through it.

uv tool install aipager     # if uv is already installed

Or, to install uv first:

curl -LsSf https://astral.sh/uv/install.sh | sh
uv tool install aipager

uv bundles its own Python interpreter, so this works on any macOS / Linux version regardless of what system Python is doing - it sidesteps the Homebrew-Python-vs-Xcode breakage described under the Homebrew section below.

pipx

pipx install aipager

Homebrew tap (macOS, Linuxbrew)

Note: uv tool install aipager is the recommended path on macOS. The brew formula works when Homebrew's python@3.12 bottle and your Xcode / Command Line Tools are in sync, but they periodically drift apart - most recently on macOS Tahoe (26.x), where install fails with a pyexpat _XML_SetAllocTrackerActivationThreshold symbol error (upstream issue). Updating Xcode + Command Line Tools usually fixes it, but it's easier to just use uv.

brew install dev-aly3n/tap/aipager

Pulls dtach from Homebrew's standard formula and installs aipager into a Homebrew-managed Python venv.

Docker

Self-contained image with python, node, claude and dtach baked in, good for VPS / NAS / Pi deployments where you don't want a Python or Node toolchain on the host. Multi-arch (amd64, arm64).

# 1. Run the setup wizard once (interactive)
docker run --rm -it \
  -v "$HOME/.claude:/home/aipager/.claude" \
  -v aipager-config:/home/aipager/.config/aipager \
  ghcr.io/dev-aly3n/aipager:latest config

# 2. Start the daemon (background, auto-restart)
docker run -d --restart=unless-stopped --name aipager \
  -v "$HOME/.claude:/home/aipager/.claude" \
  -v aipager-config:/home/aipager/.config/aipager \
  -v "$PWD:/workspace" \
  ghcr.io/dev-aly3n/aipager:latest

Mount the directories you want claude to edit under /workspace. The ~/.claude mount carries over your claude credentials and conversation history - run claude on the host once to authenticate, or docker exec -it aipager claude for an interactive login in the container.

Tags: latest, 1.0, 1.0.1 (semver track + minor track).

Nix flake

nix run github:dev-aly3n/aipager -- --version
nix profile install github:dev-aly3n/aipager

Builds aipager from source against pinned nixpkgs deps. dtach is provided by Nix; claude is not - install it separately (nix profile install nixpkgs#nodejs && npm install -g @anthropic-ai/claude-code, or follow Anthropic's docs).

For declarative NixOS / Home Manager configs, add aipager as a flake input and pick its package up from environment.systemPackages:

{
  inputs.aipager.url = "github:dev-aly3n/aipager";

  outputs = { self, nixpkgs, aipager, ... }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      modules = [({ pkgs, ... }: {
        environment.systemPackages = [
          aipager.packages.${pkgs.system}.default
        ];
      })];
    };
  };
}

aipager service install will then wire up a systemd-user unit.

Group mode (multi-user)

aipager runs by default as a 1:1 DM bot. To use it in a Telegram group with several developers, add the bot to the group (as an admin, so it can pin the group's status bar), re-run aipager config and pick Add a group scope. The wizard offers you (the owner of your own DM) as the group's owner, then adds each member with a role (owner / admin / user / read_only), and reloads the running daemon. In the group the bot acts only on commands, replies to its messages and mentions (@aipagerbot fix the tests, /jim run the tests); each message runs with its sender's role. Adding a user grants them code-execution rights on the host: see docs/groups.md for the full trust model.

Snap

snap install aipager

Strict-confinement snap that bundles python + node + claude + dtach + aipager. Because of snap's sandbox model, workspaces must live under ~/ (e.g. ~/projects/foo). Manifest at packaging/snap/.

Configure

aipager config

Interactive wizard - asks for your Telegram bot token (from @BotFather) and chat ID, validates them, then patches ~/.claude/settings.json to wire the necessary hooks automatically. You never edit any file by hand.

Setting aipager up for someone from a script or a coding agent? aipager setup --token-file FILE --chat-id ID does the same with no prompts (see the setup command and the guide for agents).

Run

aipager start

The daemon stays in the foreground. Launch a Claude session in another terminal:

aipager session dev

This creates (or reattaches to) a dtach session named claude-dev running Claude Code. The aipager daemon discovers it within seconds and Telegram starts mirroring it. Re-run the same command to reattach later; to leave without stopping Claude, close the terminal or tmux pane (the session keeps running).

If the dtach session was killed (machine reboot, etc.) but you want to pick up the Claude conversation from disk, add --continue:

aipager session dev --continue    # the last claude conversation in this folder

You can also pass --resume <session-id> (or any other claude flag) through as trailing args:

aipager session dev -- --resume abc1234

Run as a service (survives logout)

aipager service install

On Linux this writes a systemd-user unit at ~/.config/systemd/user/aipager.service and starts it. On macOS it writes a launchd plist at ~/Library/LaunchAgents/com.aipager.daemon.plist and bootstraps it. Subcommands: start, stop, status, logs, uninstall.

What it does

  • Mirrors Claude Code session state to Telegram: busy/idle, tool calls, context %, cost, line counts
  • Sends your messages to Claude immediately, even mid-turn - send several and Claude queues them itself, exactly like typing in the terminal. 👀 means sent, 👍 means Claude picked it up
  • Holds a message while a permission or question prompt is open, so it can never be swallowed as an answer to that dialog - then delivers it once you respond
  • Surfaces permission prompts and AskUserQuestion dialogs as Telegram inline keyboards; buttons from an already-finished task refuse instead of acting on your current work
  • Creates sessions from chat: /new x1 starts one at once (/new x1 fix the tests also sends its first message), with the mode, model and folder set in /settings, and buttons to change them
  • Notifies on context warnings, compaction, session end, and stalls
  • Supports multiple concurrent sessions with one bot; optional multi-user team mode with roles and per-tool rules (docs/groups.md)
  • Optional read-only observer bots

Mini App

/app opens a dashboard inside Telegram - live session list with stop / kill / restart / rename / permission controls, a diff viewer for Write/Edit changes, and settings. It is served by the daemon itself and is on by default; every request is verified against Telegram's initData signature. If you belong to more than one chat (your DM and a group), a row of chat names at the top switches between them. Manage it with aipager miniapp enable|disable|status, or point it at your own URL instead of the managed tunnel - see docs/security.md.

Note on model buttons (Bedrock / Vertex users)

The persistent keyboard's Model submenu (and the Mini App's model pickers) offers Claude Code's family aliases, sonnet, opus, haiku, fable and opusplan, and pinned models such as claude-opus-5-5 and claude-sonnet-5-5 (the full list is in docs/commands.md). On the Anthropic API an alias resolves to the latest model in its family. On Bedrock and Vertex the same aliases may resolve to older snapshots depending on your provider's available versions. If you target those backends and want a specific model, send /model <full-id> from chat.

Developing locally

git clone https://github.com/dev-aly3n/aipager.git && cd aipager
python3 -m venv .venv && source .venv/bin/activate
pip install -e '.[dev]'
systemd-run --user --scope -q -p MemoryMax=2G -p MemorySwapMax=0 \
  .venv/bin/python -m pytest -q -p no:cacheprovider
ruff check aipager tests

dtach comes with the dtach-bin dependency, so nothing else is needed. Run the tests under a memory cap as above (on macOS, without systemd-run): a runaway test can otherwise take the machine's memory.

Release process is in CONTRIBUTING.md.

License

MIT - see LICENSE.

Metadata

Release files for aipager 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aipager 1.0.1
File Size Uploaded
aipager-1.0.1.tar.gz 3.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for aipager 1.0.1
File Interpreter ABI Platform
aipager-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 4.7 MB

Release files / aipager-1.0.1.tar.gz

Download URL aipager-1.0.1.tar.gz
Size 3.6 MB
Tags Source
SHA-256 checksum
How to use checksums
9017be6d72c22c1e8e6f947727b6a434654c6c650ac15bd2e9afc09bf2b525df
BLAKE2b-256 checksum
How to use checksums
973c506f32641c1041665fa8bcd19987f98913a105cce038805521b29d97b2e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release files / aipager-1.0.1-py3-none-any.whl

Download URL aipager-1.0.1-py3-none-any.whl
Size 1.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
55d2dcde9d2a5c1c22a6f5b411f83b012fa11eb2965e21233a987a4d26211898
BLAKE2b-256 checksum
How to use checksums
bf881e2fe78536c61630d1abba13fe7dc87229e52c3694d00f1873ed1b142abd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release history Release notifications | RSS feed

1.2.0

2 release files

1.1.0

2 release files

This release

1.0.1 This release

2 release files

1.0.0

2 release files

0.7.20

2 release files

0.7.19

2 release files

0.7.18

2 release files

0.7.17

2 release files

0.7.16

2 release files

0.7.15

2 release files

0.7.14

2 release files

0.7.13

2 release files

0.7.12

2 release files

0.7.11

2 release files

0.7.10

2 release files

0.7.9

2 release files

0.7.8

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.25

2 release files

0.4.24

2 release files

0.4.23

2 release files

0.4.22

2 release files

0.4.21

2 release files

0.4.20

2 release files

0.4.19

2 release files

0.4.18

2 release files

0.4.17

2 release files

0.4.16

2 release files

0.4.15

2 release files

0.4.14

2 release files

0.4.13

2 release files

0.4.12

2 release files

0.4.11

2 release files

0.4.10

2 release files

0.4.9

2 release files

0.4.8

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.19

2 release files

0.3.18

2 release files

0.3.17

2 release files

0.3.16

2 release files

0.3.15

2 release files

0.3.14

2 release files

0.3.13

2 release files

0.3.12

2 release files

0.3.11

2 release files

0.3.10

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page