Channels
Connect external messaging platforms to your Letta agents
Channels let your Letta Agent receive and respond to messages from external platforms like Telegram, Slack, Discord, WhatsApp, and Signal. Messages from the platform flow into the agent’s conversation, and the agent replies using the MessageChannel tool.
Getting started
Section titled “Getting started”You can set up channels via the Letta Agent app or the CLI. The app provides a visual setup flow in the Channels sidebar tab. For CLI setup, choose a channel-specific guide:
Channel slash commands
Section titled “Channel slash commands”After a chat is connected, you can send these slash commands as normal messages in the Telegram, Slack, Discord, WhatsApp, or Signal chat. They are handled by the channel runtime before the message reaches the agent.
| Command | Description |
|---|---|
/help | Show channel usage guidance |
/status | Show account, listener, route, agent, and conversation state |
/pause | Pause agent replies for the current routed chat |
/resume | Resume agent replies for the current routed chat |
/cancel | Cancel the in-progress agent turn for the current routed chat |
/chat | Show the Letta web chat link for the current route |
/reflection | Start a memory reflection pass for the current routed chat |
/reflect | Alias for /reflection |
For Slack threads, send the command in the routed thread when there may be more than one Letta thread in the same channel. Slack-native slash command payloads currently exist only for /cancel; the other commands are typed as regular chat messages.
Architecture
Section titled “Architecture”flowchart LR
subgraph Platform["Messaging platform"]
TG["Telegram / Slack / Discord / WhatsApp / Signal"]
end
subgraph Local["Your machine (letta server)"]
Adapter["Channel adapter<br/>(long-polling / Socket Mode / gateway)"]
Registry["Channel registry"]
Queue["Message queue"]
Agent["Agent"]
Tool["MessageChannel tool"]
end
TG -->|"Inbound message"| Adapter
Adapter --> Registry
Registry -->|"XML-wrapped message"| Queue
Queue --> Agent
Agent -->|"Tool call"| Tool
Tool -->|"Outbound reply"| TG
- The adapter receives messages from the platform (Telegram uses long-polling, Slack uses Socket Mode, Discord uses the gateway WebSocket, WhatsApp uses a linked-device WebSocket session, and Signal uses a local
signal-clibridge) - The registry checks DM policy (pairing/allowlist/open), looks up the route, and formats the message as XML
- The message enters the agent’s queue as a
channelsource item - The agent processes it and calls the MessageChannel tool to reply
- The tool converts markdown to platform-safe formatting and sends through the adapter
DM policies
Section titled “DM policies”Each channel has a DM policy that controls who can message the bot:
| Policy | Behavior |
|---|---|
pairing (default for Telegram, Discord, WhatsApp, and Signal) | Unknown users receive a one-time pairing code. An operator must approve the code to bind the chat to an agent. |
allowlist | Only pre-configured user IDs can message. Others are rejected. |
open (default for Slack) | Anyone can message. For Telegram, requires a route to exist. For Slack, Discord, WhatsApp, and Signal, routes are auto-created when the channel/account routing mode allows it. |
Routing
Section titled “Routing”Routes bind a platform chat ID to an agent + conversation pair. They’re stored in ~/.letta/channels/<channel>/routing.yaml.
Routes are created automatically when pairing completes, or manually via the CLI:
# Add a route manuallyletta channels route add \ --channel telegram \ --chat-id 123456789 \ --agent agent-abc123 \ --conversation default
# List all routesletta channels route list
# List routes for a specific channelletta channels route list --channel telegram
# Remove a routeletta channels route remove --channel telegram --chat-id 123456789CLI reference
Section titled “CLI reference”| Command | Description |
|---|---|
letta channels install <channel> | Install channel runtime dependencies (optional — configure does this automatically) |
letta channels configure <channel> | Interactive setup wizard (installs runtime deps if needed) |
letta channels status | Show config, routing, and pairing state (JSON) |
letta channels route list [--channel <ch>] | Show routing table |
letta channels route add [options] | Add a route binding a chat to an agent |
letta channels route remove [options] | Remove a route |
letta channels bind [options] | Bind a Slack or Discord channel account to an agent |
letta channels pair [options] | Complete a pairing code and bind to agent (Telegram, WhatsApp, or Signal) |
Common flags
Section titled “Common flags”| Flag | Commands | Description |
|---|---|---|
--channel <name> | route, pair, bind | Channel name (telegram, slack, discord, whatsapp, signal) |
--account-id <id> | route add/remove, pair | Account ID (required when multiple accounts exist for a channel, auto-resolved when only one exists) |
--chat-id <id> | route add/remove | Platform chat/conversation ID |
--agent <id> | route add, pair, bind | Agent ID (defaults to LETTA_AGENT_ID) |
--conversation <id> | route add, pair | Conversation ID (defaults to LETTA_CONVERSATION_ID or "default") |
--code <code> | pair | Pairing code from the bot |
Headless deployment
Section titled “Headless deployment”For server/Docker deployments without interactive setup:
- Pre-write the config files to
~/.letta/channels/<channel>/ - Start with the
--install-channel-runtimesflag to auto-install dependencies:
letta server --channels telegram --install-channel-runtimesOr install runtimes separately:
letta channels install telegramEnvironment variables
Section titled “Environment variables”| Variable | Description |
|---|---|
LETTA_AGENT_ID | Default agent ID for pair and route add commands |
LETTA_CONVERSATION_ID | Default conversation ID (fallback: "default") |
LETTA_API_KEY | API key for letta server authentication |
State files
Section titled “State files”| File | Description |
|---|---|
~/.letta/channels/<ch>/accounts.json | Channel account configuration (tokens, DM policy, account metadata) |
~/.letta/channels/<ch>/routing.yaml | Route table (chat ID to agent/conversation binding) |
~/.letta/channels/<ch>/pairing.yaml | Pending and approved pairings |
Connection lifecycle
Section titled “Connection lifecycle”Channels integrate with the letta server WebSocket connection:
- On connect: channel adapters register their message handler and flush any buffered messages
- On disconnect: adapters pause delivery but keep polling/listening. Messages buffer until reconnection.
- On shutdown: adapters stop cleanly
This means if letta server briefly loses its WebSocket connection, no Telegram, Slack, Discord, WhatsApp, or Signal messages are dropped — they buffer and deliver when the connection restores.
You can also configure channels on remote devices — simply swap the selected device in the Connections menu of the Letta Agent app.
Skip to content