Personal AI bot connecting Plane.so to Telegram via AI + MCP
2.5K
A self-hosted Docker service that connects Plane.so to Telegram via AI. Ask questions about your projects, issues, cycles, and more — right from Telegram.
Supports two deployment modes:
/login with their own Plane credentials; ideal for shared team bots or public deploymentsTelegram → Bot (python-telegram-bot) → AI (Claude/GPT) + Plane Tools → Plane.so
The AI uses Plane tools to query and interact with your workspace. It decides which tools to call based on your natural language questions. Tools are built on the official plane-sdk with lean schemas to minimise token usage, backed by an SQLite cache for workspace data.
/newbot and follow the prompts:
TELEGRAM_BOT_TOKENNote: No need to set bot commands in BotFather. The bot registers all commands with Telegram automatically on startup.
Optional extras via BotFather:
/setdescription — Description shown in the chat header/setabouttext — Text shown in the bot's profile/setuserpic — Profile pictureRun the pre-built Docker image:
docker run -d \
--name plane-telegram \
-v $(pwd)/data:/app/data \
-e PLANE_PAT=your_plane_api_key \
-e PLANE_WORKSPACE_SLUG=your-workspace-slug \
-e TELEGRAM_BOT_TOKEN=your_telegram_bot_token \
-e AI_PROVIDER=anthropic \
-e AI_API_KEY=your_ai_api_key \
--restart unless-stopped \
mguptahub/plane-telegram:latest
That's it! Replace the values with your credentials, find your bot on Telegram, and send /start.
Add MULTI_USER=true and omit PLANE_PAT / PLANE_WORKSPACE_SLUG:
docker run -d \
--name plane-telegram \
-v $(pwd)/data:/app/data \
-e MULTI_USER=true \
-e TELEGRAM_BOT_TOKEN=your_telegram_bot_token \
-e AI_PROVIDER=anthropic \
-e AI_API_KEY=your_ai_api_key \
--restart unless-stopped \
mguptahub/plane-telegram:latest
Each user (or group chat) runs /login to connect their own Plane account. See Multi-User Mode for details.
docker run -d \
--name plane-telegram \
-v $(pwd)/data:/app/data \
-e PLANE_PAT=your_plane_api_key \
-e PLANE_WORKSPACE_SLUG=your-workspace-slug \
-e TELEGRAM_BOT_TOKEN=your_telegram_bot_token \
-e AI_PROVIDER=openai \
-e AI_API_KEY=your_ai_api_key \
-e AI_MODEL=gpt-4o \
-e AI_BASE_URL=https://api.openai.com/v1 \
-e MAX_HISTORY_MESSAGES=15 \
-e SESSION_TIMEOUT_MINUTES=60 \
-e DEBUG_LOGGING=false \
--restart unless-stopped \
mguptahub/plane-telegram:latest
| Variable | Required | Default | Description |
|---|---|---|---|
MULTI_USER | No | false | Enable multi-user mode — each Telegram chat registers its own Plane account |
PLANE_PAT | Yes* | — | Plane API key / Personal Access Token (*not required when MULTI_USER=true) |
PLANE_WORKSPACE_SLUG | Yes* | — | Default workspace slug (*not required when MULTI_USER=true) |
PLANE_BASE_URL | If self-hosted | https://app.plane.so | Your self-hosted Plane URL |
TELEGRAM_BOT_TOKEN | Yes | — | Telegram bot token from BotFather |
AI_PROVIDER | Yes | — | anthropic or openai (any OpenAI-compatible) |
AI_API_KEY | Yes | — | API key for your AI provider |
AI_MODEL | No | Auto | Model name (defaults to claude-sonnet-4-20250514 or gpt-4o) |
AI_BASE_URL | No | Provider default | Optional base URL override |
AI_APP_REFERER | No | — | HTTP-Referer header (used by OpenRouter for attribution) |
AI_APP_TITLE | No | Plane Telegram AI | X-Title header (used by OpenRouter for attribution) |
MAX_HISTORY_MESSAGES | No | 15 | Number of messages to include as context |
SESSION_TIMEOUT_MINUTES | No | 60 | Auto-expire old messages from context |
LOG_LEVEL | No | INFO | Logging level |
DEBUG_LOGGING | No | false | Write per-request debug logs to data/debug_logs/ |
| Provider | AI_PROVIDER | AI_BASE_URL |
|---|---|---|
| Anthropic (default) | anthropic | — |
| OpenAI (default) | openai | — |
| Groq | openai | https://api.groq.com/openai/v1 |
| OpenRouter | openai | https://openrouter.ai/api/v1 |
| Together AI | openai | https://api.together.xyz/v1 |
| LiteLLM proxy | openai | http://localhost:4000/v1 |
| Azure OpenAI | openai | https://your-resource.openai.azure.com/ |
| Tool | Description |
|---|---|
get_me | Get current user info |
get_workspace_members | List all workspace members |
list_projects | List all projects |
get_project | Get a project by UUID |
get_project_members | List members of a project |
list_states | List workflow states for a project |
list_labels | List labels for a project |
list_work_items | List work items (filterable by state, priority, assignee, label) |
get_work_item | Get a work item by UUID or identifier (e.g. PROJ-42) |
create_work_item | Create a new work item |
update_work_item | Update an existing work item |
list_initiatives | List workspace initiatives |
The bot registers all commands with Telegram automatically — they appear in the / menu.
| Command | Description |
|---|---|
/login | Connect your Plane account (PAT + workspace slug) |
/logout | Remove your credentials and clear all chat data |
/status | Show connection status, cache state, and active project |
| Command | Description |
|---|---|
/start | Show welcome message |
/help | Show help and command reference |
/reset | Clear conversation history and start fresh |
/tools | List all available Plane tools |
/status | Show connection status and active context |
| Command | Description |
|---|---|
/workspace | Show the currently active workspace and project |
/workspace show | Same as above |
/workspace <slug> | Switch workspace, rebuild cache, and clear active project |
Examples:
/workspace
/workspace my-company
/workspace show
Each chat session has its own active workspace. The default is set by PLANE_WORKSPACE_SLUG. Switching workspace rebuilds the cache and resets the active project (projects are workspace-scoped).
Set an active project once so you don't need to type the identifier on every /workitems call.
| Command | Description |
|---|---|
/project | Show the currently active project |
/project show | Same as above |
/project <IDENTIFIER> | Set the active project (validated against cache) |
Examples:
/project
/project BACK
/project INVESTOS
The active project is cleared automatically when you switch workspace.
Explicit mode — project identifier always required, ignores active project context. Useful for one-off lookups across projects.
| Command | Description |
|---|---|
/list projects | List all projects in the active workspace |
/list workitems <PROJ> [query] | List work items for a project |
/list states <PROJ> | List workflow states for a project |
/list labels <PROJ> | List labels for a project |
/list members <PROJ> | List members of a project |
Context mode — uses the active project set by /project. Set it once, then query freely.
| Command | Description |
|---|---|
/workitems [query] | List work items using the active project context |
/states | List workflow states for the active project |
/labels | List labels for the active project |
/members | List members of the active project |
<PROJ> is the project identifier (e.g. BACK, INVESTOS). The optional [query] for work items is plain English — the AI resolves it into filters (state, priority, assignee, label). Only one filter value is supported per field.
Examples:
/list projects
# Explicit — project always required
/list workitems BACK
/list workitems BACK todo
/list workitems BACK high priority
/list workitems BACK assigned to me
/list workitems BACK labeled as James
/list states BACK
/list labels BACK
/list members BACK
# Context — /project BACK must be set first
/workitems
/workitems todo
/workitems in progress
/workitems urgent
/workitems assigned to me
/workitems labeled as James
/states
/labels
/members
The bot caches workspace data (user info, projects, states, labels, members) in SQLite to reduce API calls and speed up responses.
| Command | Description |
|---|---|
/cache | Show all cache entries (same as show) |
/cache show | List cache entries with size and age |
/cache update | Refresh all cached data (top-level + existing project data) |
/cache clean | Delete project-level caches, refresh top-level only |
Project states, labels, and members are lazily cached on first use and reused for subsequent calls. Use /cache clean after making structural changes in Plane (new states, members, etc.).
These are natural language queries you can send directly to the bot (no commands needed):
Who am I?
What workspace am I in?
List all my projects
How many projects do I have?
Tell me about the Backend project
What are the open issues in project Backend?
Show me all urgent items in INVESTOS
What issues are assigned to me in BACK?
Get me issue BACK-42
What's the status of PROJ-7?
Create an issue titled "Fix auth bug" with high priority in project Backend
Create a new todo in INVESTOS: "Update pricing page"
Update BACK-42 to Done
Change the priority of PROJ-7 to urgent
Assign BACK-15 to John
Who are the members of the BACK project?
List all workspace members
What states does the INVESTOS project have?
What labels are available in BACK?
Set MULTI_USER=true to allow any Telegram user (or group chat) to connect their own Plane account. The bot stores credentials per-chat and isolates all data (cache, history, active workspace) between chats.
User: /login
Bot: Step 1 — reply with your Plane API token
User: plane_pat_abc123... ← bot deletes this message for security
Bot: ✅ Verified as John ([email protected])
Step 2 — reply with your workspace slug
User: my-company
Bot: ✅ Registered! Found 5 projects in workspace my-company.
| Command | Description |
|---|---|
/login | Connect a Plane account (PAT + workspace slug) |
/logout | Remove credentials and clear all chat data |
PLANE_PAT and PLANE_WORKSPACE_SLUG environment variables are optional when MULTI_USER=true/login flow uses Telegram's ForceReply so the bot receives replies even with privacy mode enabled/logout removes the registration, all conversation history, and all cache entries for that chatIn multi-user mode, each chat also has its own active workspace. The registered workspace is the default — users can switch with /workspace <slug> at any time. Each chat tracks its own:
/project <IDENTIFIER>/login and /cache clean./data/chat_history.db (volume-mapped)Pull the latest image and restart:
docker pull mguptahub/plane-telegram:latest
docker stop plane-telegram
docker rm plane-telegram
# Then run the docker run command from Quick Start
Your chat history and cache persist in the ./data volume.
Bot not responding?
docker logs -f plane-telegramPlane connection fails?
PLANE_PAT is valid and has the right permissionsPLANE_WORKSPACE_SLUG is correct (the slug, not the full URL)PLANE_BASE_URL is reachable from inside the containerdocker logs -f plane-telegramAI errors?
AI_API_KEY is valid and has creditsAI_MODEL is correct for your providerWork item filters not working?
/cache clean to ensure states and members are freshly cached/cache show to inspect what's cachedCommands not showing in Telegram?
/help to force re-registration of commandsgit clone https://github.com/mguptahub/plane-telegram-ai
cd plane-telegram-ai
cp .env.example .env
# Edit .env with your credentials
docker compose up -d --build
Check logs:
docker compose logs -f
Set DEBUG_LOGGING=true to write per-request JSON logs to data/debug_logs/. Each file captures the full AI exchange including tool calls, token usage, and cache hits.
MIT
Content type
Image
Digest
sha256:01fe1635d…
Size
53.5 MB
Last updated
7 months ago
docker pull mguptahub/plane-telegram