Distributed inter-agent message bus using Telegram
Project description
AI-Intercom
A distributed inter-agent communication system that enables AI coding agents (Claude Code, Codex, Gemini, etc.) running on different machines across a Tailscale network to communicate with each other through a Telegram-based message bus, with human-in-the-loop oversight via approval policies and forum-topic conversations.
Architecture
Machine A (Hub) Machine B (Daemon)
+--------------------------+ +--------------------------+
| Telegram Supergroup | | |
| (forum topics/mission) | | AI Agent (Claude, etc.) |
| ^ | | ^ |
| | | | | stdin/stdout |
| +------+--------+ | | +----+----------+ |
| | Telegram Bot | | | | Agent Launcher | |
| +------+--------+ | | +----+----------+ |
| | | | | |
| +------+--------+ | HTTP/HMAC | +----+----------+ |
| | Hub Router +-------+---7700------+--+ Daemon API | |
| +------+--------+ | | +----+----------+ |
| | Approval | | | | |
| | Engine | | | +----+----------+ |
| +------+--------+ | | | MCP Server | |
| | Registry | | | | (13 tools) | |
| | (SQLite) | | | +----+----------+ |
| +------+--------+ | | | |
| | Attention | | | +----+----------+ |
| | Store + API |<------+-- events ---+--+ Attention | |
| +------+--------+ | | | Monitor | |
| | | | +----+----------+ |
| WebSocket | | ^ |
| v | | /tmp/cc-sessions/*.json |
| +------+--------+ | | (heartbeat files) |
| | PWA Dashboard| | | |
| | /attention | | +--------------------------+
| +---------------+ |
+--------------------------+
Machine C (Daemon) Human
+--------------------------+ +--------------------+
| AI Agent | | Telegram App |
| MCP Server | | - Approve/deny |
| Daemon API | | - Read transcripts |
| Hub Client --------+--->| - /start_agent |
+--------------------------+ | - /attention alerts |
+--------------------+
+--------------------+
| PWA Dashboard |
| /attention |
| - Session status |
| - Terminal viewer |
| - Respond to |
| prompts |
+--------------------+
Hub runs on one machine: Telegram bot, message router, approval engine, and SQLite registry. Daemons run on every other machine: lightweight HTTP API, agent launcher, and MCP server exposing tools to AI agents.
Features
- Multi-agent communication -- AI agents on different machines send messages and delegate tasks to each other
- Human-in-the-loop -- Every inter-agent message can require Telegram approval (once, per-mission, per-session, or always allow)
- Telegram forum topics -- Each mission gets its own forum topic for clean conversation threading
- HMAC-SHA256 authentication -- Per-machine tokens with timestamp anti-replay protection
- Tailscale auto-discovery -- Install script scans the Tailscale network to find the hub automatically
- Interactive agent-to-agent chat -- Asynchronous bidirectional messaging between active Claude Code sessions across machines via inbox queues and PostToolUse hooks
- MCP integration -- Thirteen tools exposed via Model Context Protocol so any MCP-compatible agent can use the intercom
- Agent launcher -- Start AI agents on remote machines with mission context and path restrictions
- Real-time mission feedback -- Live streaming of agent activity (tools used, files read, commands run) via Telegram progress messages
- Policy engine -- Glob/regex-based approval rules with runtime grants (mission-level, session-level)
- SQLite registry -- Persistent machine and project tracking with heartbeat monitoring
- Intelligent dispatcher -- Send natural language messages in Telegram and Claude interprets and executes via MCP intercom tools
- Version tracking -- Daemons report their version in heartbeats; visible in agent listings for fleet management
- Self-upgrade --
ai-intercom self-upgradeperforms git pull, pip install, and daemon restart across the network - Attention Hub -- Full pipeline for detecting when AI agents need human attention:
- Claude Code hooks (
cc-heartbeat.sh) write session heartbeat files to/tmp/cc-sessions/ - Daemon
AttentionMonitorreads heartbeats, detects state transitions (working/thinking/waiting), captures terminal output via PTY (pyte) or tmux - State-change events are pushed to the Hub, which stores them and broadcasts via WebSocket
- PWA dashboard at
/attentionshows real-time session status, terminal viewer, and prompt response UI - Telegram notifications alert when a session transitions to WAITING state
- Claude Code hooks (
- TTS Narrator -- Agents narrate their progress via
intercom_announce(). The PWA synthesizes speech via XTTS and plays it automatically with per-category toggles, volume control, and verbosity settings - Voice conversations -- Send voice messages in Telegram; the hub transcribes via Whisper STT (with 25s chunking for long messages), dispatches to an agent, and returns both text and voice responses via XTTS TTS (with sentence-level chunking)
- Hallucination filter -- Detects and rejects Whisper STT artifacts (known training phrases, repeated phrases/words) without false-flagging natural speech
- Active conversations -- Follow-up messages within 10 minutes are injected into the running agent session instead of spawning a new mission
- Dispatcher preferences -- PWA control panel for conversation mode, agent exchange visibility, voice response, and POS printing toggles (persisted + WebSocket-synced)
- Docker support -- Separate Compose files for hub and daemon deployment
Quick Start
Prerequisites
- Python 3.12+
- A Telegram bot token (from @BotFather)
- A Telegram supergroup with forum topics enabled
- Tailscale installed on all machines (for auto-discovery)
1. Hub Setup (first machine)
git clone <repo-url> && cd AI-intercom
pip install -e .
# Interactive setup: creates ~/.config/ai-intercom/config.yml
./install.sh --init-hub
# Start the hub
ai-intercom standalone
The installer will prompt for your Telegram bot token, supergroup ID, and your Telegram user ID.
2. Daemon Setup (additional machines)
pip install -e .
# Auto-discovers hub on Tailscale, requests approval via Telegram
./install.sh
# After approval, start the daemon
ai-intercom daemon
Or specify the hub URL explicitly:
./install.sh --hub-url http://<hub-tailscale-ip>:7700
3. MCP Server (for AI agents)
Add to your agent's MCP configuration (e.g., .mcp.json):
{
"mcpServers": {
"ai-intercom": {
"command": "ai-intercom",
"args": ["mcp-server", "--config", "~/.config/ai-intercom/config.yml"]
}
}
}
MCP Tools Reference
| Tool | Description |
|---|---|
intercom_list_agents |
List available agents on the network. Filter by "all", "online", or "machine:<id>". |
intercom_send |
Send a fire-and-forget message to another agent. |
intercom_ask |
Send a message and wait for a response (synchronous request/reply). |
intercom_start_agent |
Start an AI agent on a remote machine with a mission prompt. |
intercom_status |
Get the current status of a running mission. |
intercom_history |
Retrieve the full conversation history of a mission. |
intercom_register |
Update this agent's registry entry (description, capabilities, tags). |
intercom_report_feedback |
Report bugs, suggestions, or questions to the human operator. |
intercom_chat |
Send a message to an agent's active session. Creates a conversation thread. |
intercom_reply |
Reply to a message in an existing conversation thread. |
intercom_check_inbox |
Manually check for pending messages from other agents. |
intercom_announce |
Push a TTS voice announcement to the Attention Hub PWA (milestone, difficulty, didactic). |
intercom_upgrade |
Trigger network-wide daemon upgrades ("all", "outdated", or specific machine). |
Configuration Reference
Configuration is loaded from ~/.config/ai-intercom/config.yml with environment variable overrides.
config.yml
mode: standalone # hub, daemon, or standalone (hub+daemon)
machine:
id: "my-machine" # Unique machine identifier
display_name: "My Machine"
description: "Description of this machine"
telegram: # Hub/standalone only
bot_token: "" # or TELEGRAM_BOT_TOKEN env var
supergroup_id: 0 # or TELEGRAM_SUPERGROUP_ID env var
security:
allowed_users: [] # or TELEGRAM_OWNER_ID env var
restrict_to_supergroup: true
ignore_private_messages: true
hub:
url: "" # Daemon: URL of the hub (or HUB_URL env var)
listen: "0.0.0.0:7700" # Hub: listen address
auth:
token: "" # Per-machine token (or INTERCOM_TOKEN env var)
discovery: # Auto-detect projects on this machine
enabled: true
scan_paths: []
detect_by:
- file: "CLAUDE.md"
- file: ".git"
- file: "AGENTS.md"
exclude: ["node_modules", ".venv", "backup", "__pycache__"]
agent_launcher:
default_command: "claude"
default_args: ["-p", "--output-format", "json"] # Automatically switched to stream-json for background missions
allowed_paths: [] # Empty = allow all
max_mission_duration: 1800
voice: # Voice services (STT/TTS)
enabled: true
stt_url: "" # Whisper STT endpoint
tts_url: "" # XTTS TTS endpoint
tts_language: "fr"
tts_speed: 1.0
response_voice: true # Send voice reply alongside text
voice_styles: # Per-agent TTS voice instructions
default: "Warm French female voice"
dispatcher: "Warm French female voice"
agent_project: "Calm French male voice"
dispatcher: # Hub/standalone only
enabled: false
target: "serverlab/serverlab" # machine/project to dispatch to
system_prompt: | # Prepended to every dispatched message
Tu es le dispatcher Telegram AI-Intercom.
Environment Variable Overrides
| Variable | Config Path | Description |
|---|---|---|
TELEGRAM_BOT_TOKEN |
telegram.bot_token |
Telegram bot token |
TELEGRAM_SUPERGROUP_ID |
telegram.supergroup_id |
Telegram supergroup chat ID |
TELEGRAM_OWNER_ID |
telegram.security.allowed_users |
Authorized Telegram user ID |
HUB_URL |
hub.url |
Hub URL for daemon connections |
INTERCOM_TOKEN |
auth.token |
HMAC authentication token |
Approval Policies
Policies are defined in ~/.config/ai-intercom/policies.yml:
defaults:
require_approval: once # never, always_allow, once, mission, session
rules:
- from: "*"
to: "*"
type: ask
message_pattern: "check|status|list|verify"
approval: never
label: "Read-only queries"
Approval levels:
never-- Messages are delivered without any approvalalways_allow-- Auto-approved for this agent pair (session-persistent)once-- Requires Telegram approval for each messagemission-- Approve once, then auto-approved for the rest of that missionsession-- Approve once, then auto-approved for this agent pair until restart
Intelligent Dispatcher
The dispatcher transforms the Telegram bot from a command-based router into a natural language interface. Instead of memorizing slash commands and machine/project names, you write plain messages and Claude handles the rest.
How it works:
- You send a natural language message in the Telegram supergroup (outside any topic)
- The bot shows a "Reflexion en cours..." indicator with typing animation
- The message is dispatched to the configured target agent via
claude -p - The thinking message is replaced with the response
Example:
"List all online agents" → Claude calls
intercom_list_agents()and returns the result
Configuration (config.yml):
dispatcher:
enabled: true
target: "serverlab/serverlab" # Agent that receives dispatched messages
system_prompt: |
Tu es le dispatcher Telegram AI-Intercom. Tu reponds de maniere concise.
Utilise les outils MCP intercom pour communiquer avec les agents.
The dispatcher bypasses the router (no forum topic creation, no approval) and calls the target daemon directly. Add a policy rule for auto-approval of human messages:
rules:
- from: "human"
to: "*"
approval: never
label: "Human dispatch - no approval needed"
Security Model
-
Per-machine HMAC tokens -- Each machine receives a unique token (
ict_<machine>_<hex>) during the join/approve flow. All daemon-to-hub and hub-to-daemon HTTP requests are signed with HMAC-SHA256. -
Timestamp anti-replay -- Signed requests include a Unix timestamp. Requests older than 60 seconds are rejected.
-
Telegram authorization -- Only Telegram users in the
allowed_userslist can interact with the bot (approve messages, start agents, view status). -
Join approval -- New machines must be approved via Telegram before receiving a token. The hub operator sees a notification and explicitly approves or denies.
-
Path restrictions -- The agent launcher can be configured with
allowed_pathsto restrict which directories agents can operate in.
Docker Deployment
Hub
cp config/config.example.yml config/config.yml
# Edit config/config.yml with your settings
docker compose -f docker-compose.hub.yml up -d
Environment variables can be set in a .env file:
TELEGRAM_BOT_TOKEN=your-bot-token
TELEGRAM_SUPERGROUP_ID=-1001234567890
TELEGRAM_OWNER_ID=123456789
INTERCOM_TOKEN=your-shared-token
Daemon
docker compose -f docker-compose.daemon.yml up -d
HUB_URL=http://<hub-ip>:7700
INTERCOM_TOKEN=your-machine-token
Important: The daemon container needs access to Claude CLI credentials and the host filesystem for agent launching. Add to
docker-compose.daemon.yml:environment: - HOME=/home/youruser volumes: - /home/youruser:/home/youruser
Both containers expose port 7700 and use the same Dockerfile.
Development
Setup
git clone <repo-url> && cd AI-intercom
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
Running Tests
pytest --tb=short -q
Project Structure
src/
shared/
models.py # Message, AgentId, AgentInfo, AttentionSession, etc. (Pydantic)
config.py # YAML config loader with env var overrides
auth.py # HMAC-SHA256 sign/verify with anti-replay
hub/
main.py # Hub entry point (Telegram bot + HTTP API + attention)
hub_api.py # FastAPI: register, heartbeat, join, discover, attention events
registry.py # SQLite-backed machine/project registry
router.py # Message routing with approval checks
approval.py # Policy engine (glob/regex rules, runtime grants)
telegram_bot.py # Telegram bot (forum topics, commands, keyboards, /attention alerts)
telegram_helpers.py # Markdown sanitization and message splitting for Telegram
voice_services.py # STT (Whisper, 25s chunking) and TTS (XTTS, sentence chunking)
hallucination_filter.py # Detects Whisper artifacts (known phrases, phrase/word repetition)
active_conversations.py # Tracks active dispatcher conversations for follow-up injection
conversation_store.py # SQLite-backed conversation memory for dispatcher context
attention_store.py # In-memory session store with WebSocket broadcasting
attention_api.py # REST + WebSocket endpoints for the PWA dashboard
daemon/
main.py # Daemon entry point (HTTP API + hub registration + attention monitor)
api.py # FastAPI: health, status, message receive
hub_client.py # HTTP client for hub communication (incl. push_attention_event)
agent_launcher.py # Subprocess agent launcher with path validation and stream-json feedback
mcp_server.py # FastMCP server exposing 13 intercom tools
upgrade.py # Self-upgrade mechanism (detect, pull, install, restart)
attention_monitor.py # Reads heartbeat files, detects state changes, pushes events to hub
prompt_parser.py # Parses terminal output (PTY/tmux) to detect Claude Code prompts
cli.py # CLI entry point (hub/daemon/standalone/mcp-server)
main.py # Module entry point
pwa/ # Attention Hub Progressive Web App
index.html # Dashboard shell
app.js # WebSocket client, session rendering, TTS integration
styles.css # Dashboard styles
terminal.js # Terminal viewer component
tts.js # TTS narrator module (queue, dedup, PCM playback)
manifest.json # PWA manifest
sw.js # Service worker
scripts/
cc-heartbeat.sh # Claude Code hook script: writes heartbeat files to /tmp/cc-sessions/
tests/
test_shared/ # Config, models, auth tests
test_hub/ # Registry, approval, router, telegram, hub_api tests
test_daemon/ # Daemon API, hub client, agent launcher, MCP tests
test_integration/ # End-to-end message flow tests
config/
config.example.yml # Example configuration
policies.example.yml # Example approval policies
License
MIT License. See LICENSE.
Author: Gilles Pinault
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ai_intercom-0.7.1.tar.gz.
File metadata
- Download URL: ai_intercom-0.7.1.tar.gz
- Upload date:
- Size: 328.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8730b76a4839ddee3c7d4d0f9c4efc9ebc0fac00acb37e0b8a0f6e9f1d60ce67
|
|
| MD5 |
99547cc622e317fd4bc249b141672fb4
|
|
| BLAKE2b-256 |
e026575d90813b207ad07915c2129f1c5cd02e910d8a1a8ae249792c81900c51
|
File details
Details for the file ai_intercom-0.7.1-py3-none-any.whl.
File metadata
- Download URL: ai_intercom-0.7.1-py3-none-any.whl
- Upload date:
- Size: 92.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7b12302454f6cf1f3716639ef09d3500ef397c9f03bea4f32714f92f9abb201
|
|
| MD5 |
12128a614703c4c346645b067d7c924a
|
|
| BLAKE2b-256 |
a3400185bbe79591ab6e7a391ffd44a429890c17e7b190d64d45d309584148bf
|