Documentation Index Fetch the complete documentation index at: https://mintlify.com/logicminds/ironclaw/llms.txt
Use this file to discover all available pages before exploring further.
IronClaw supports multiple input channels that can run simultaneously, allowing you to interact with your agent through different interfaces at once. Messages from any channel are unified into a single message stream for the agent to process.
Architecture
The channel system uses a unified message format with channel-specific handling:
┌─────────────────────────────────────────────────────────────────────┐
│ ChannelManager │
│ │
│ ┌──────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ ReplChannel │ │ HttpChannel │ │ WasmChannel │ ... │
│ └──────┬───────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └─────────────────┴─────────────────┘ │
│ │ │
│ select_all (futures) │
│ │ │
│ ▼ │
│ MessageStream │
└─────────────────────────────────────────────────────────────────────┘
Available Channels
REPL Interactive command-line interface with markdown rendering, tab completion, and slash commands
HTTP Webhook RESTful API for programmatic access with rate limiting and authentication
Signal Private messaging via Signal protocol with pairing system and group support
Telegram Integration with Telegram messenger (via WASM channels)
Web Gateway Browser-based UI with real-time updates via SSE and WebSocket
REPL Channel
The REPL (Read-Eval-Print Loop) provides a rich terminal interface with:
Line editing via rustyline (history, tab completion)
Markdown rendering via termimad for formatted responses
Slash commands for control operations
Tool approval cards for interactive confirmation
Slash Commands
/help # Show available commands
/debug # Toggle verbose output
/quit # Exit the REPL
/undo # Undo the last turn
/redo # Redo an undone turn
/clear # Clear conversation
/compact # Compact context window
/new # Start a new thread
/interrupt # Stop current operation
┌ fetch_webpage requires approval ────────────────────────────
│ Fetch content from a URL
│
│ url: "https://api.example.com/data"
│ method: "GET"
│
│ yes (y) / always (a) / no (n)
└─ req_a3f2 ─────────────────────────────────────────────────
Starting the REPL
# Default mode (interactive)
ironclaw
# Single message mode
ironclaw -m "What's the weather today?"
# With debug mode enabled
ironclaw --debug
The REPL uses ~/.ironclaw/history to persist command history across sessions.
HTTP Webhook Channel
Provides a RESTful API for sending messages programmatically:
POST /webhook
Content-Type : application/json
{
"content" : "Deploy the latest version" ,
"secret" : "your-webhook-secret" ,
"wait_for_response" : true ,
"thread_id" : "optional-thread-id"
}
Configuration
export HTTP_ENABLED = true
export HTTP_PORT = 8080
export HTTP_WEBHOOK_SECRET = "your-secret-here"
export HTTP_USER_ID = "http-client"
Rate Limiting
The HTTP channel enforces:
60 requests per minute per client
64KB maximum body size
32KB maximum content length
100 maximum pending wait-for-response requests
{
"message_id" : "550e8400-e29b-41d4-a716-446655440000" ,
"status" : "accepted" ,
"response" : "Deployment initiated successfully"
}
Signal Channel
Connect via Signal Messenger using the signal-cli daemon:
Prerequisites
# Install signal-cli
brew install signal-cli # macOS
apt install signal-cli # Ubuntu
# Link your device
signal-cli -u +1234567890 link
# Start daemon
signal-cli -u +1234567890 daemon --http 127.0.0.1:8888
Configuration
export SIGNAL_ENABLED = true
export SIGNAL_HTTP_URL = "http://127.0.0.1:8888"
export SIGNAL_ACCOUNT = "+1234567890"
export SIGNAL_ALLOW_FROM = "+10987654321" # Allowed sender
Pairing System
The Signal channel supports a pairing flow for first-time users:
# When an unknown sender messages the bot
# They receive:
"To pair with this bot, run: ironclaw pairing approve signal abc123"
# The admin approves:
ironclaw pairing approve signal abc123
# The sender can now interact with the bot
Group Chat Support
Configure group access with fine-grained policies:
# DM policy: open, pairing, or allowlist (default)
export SIGNAL_DM_POLICY = "pairing"
# Group policy: disabled, open, or allowlist (default)
export SIGNAL_GROUP_POLICY = "allowlist"
# Allowed groups
export SIGNAL_ALLOW_FROM_GROUPS = "group-id-1,group-id-2"
# Group sender allowlist (inherits from ALLOW_FROM if empty)
export SIGNAL_GROUP_ALLOW_FROM = "+1234567890"
Group messages are excluded from MEMORY.md injection to prevent leaking private context.
Features
The Signal channel sends typing indicators during thinking phases and tool execution status in debug mode: # Debug mode enabled
/ debug
"Debug mode enabled. Tool execution will be shown in chat."
# Tool execution visible
"○ Running tool: shell_execute"
"● Tool 'shell_execute' completed (success)"
Send and receive file attachments: # Agent can send files from workspace
response.attachments = [
"/home/agent/.ironclaw/workspace/report.pdf"
]
# Path validation ensures files are within sandbox
Conversations automatically maintain thread history: # Uses deterministic UUIDs for consistent threads
# - DM: UUID from phone number or Signal UUID
# - Group: UUID from group ID
Web Gateway Channel
Browser-based UI with real-time updates:
Features
REST API for sending messages
Server-Sent Events (SSE) for real-time status
WebSocket for bidirectional communication
Memory browser for workspace exploration
Job management for sandbox execution monitoring
API Endpoints
# Send message
POST /api/chat/send
Authorization: Bearer < toke n >
{
"content" : "Hello",
"thread_id" : "optional"
}
# Stream events
GET /api/chat/events
Authorization: Bearer < toke n >
# Returns SSE stream with thinking, tool_use, result events
# WebSocket (bidirectional)
GET /api/chat/ws
Upgrade: websocket
Authorization: Bearer < toke n >
Configuration
export GATEWAY_ENABLED = true
export GATEWAY_PORT = 3000
export GATEWAY_AUTH_TOKEN = "your-secure-token"
export GATEWAY_USER_ID = "web-user"
If no auth token is provided, IronClaw generates a random one and prints it on startup.
SSE Event Types
type SseEvent =
| { type : 'thinking' ; message : string }
| { type : 'tool_started' ; name : string }
| { type : 'tool_completed' ; name : string ; success : boolean }
| { type : 'stream_chunk' ; content : string }
| { type : 'response' ; content : string }
| { type : 'job_started' ; job_id : string ; title : string }
| { type : 'approval_needed' ; request_id : string ; tool_name : string }
Channel Implementation
All channels implement the Channel trait:
#[async_trait]
pub trait Channel : Send + Sync {
fn name ( & self ) -> & str ;
async fn start ( & self ) -> Result < MessageStream , ChannelError >;
async fn respond (
& self ,
msg : & IncomingMessage ,
response : OutgoingResponse ,
) -> Result <(), ChannelError >;
async fn send_status (
& self ,
status : StatusUpdate ,
metadata : & serde_json :: Value ,
) -> Result <(), ChannelError >;
async fn health_check ( & self ) -> Result <(), ChannelError >;
async fn shutdown ( & self ) -> Result <(), ChannelError >;
}
Creating a Custom Channel
use ironclaw :: channels :: { Channel , IncomingMessage , MessageStream };
pub struct MyChannel ;
#[async_trait]
impl Channel for MyChannel {
fn name ( & self ) -> & str {
"my_channel"
}
async fn start ( & self ) -> Result < MessageStream , ChannelError > {
let ( tx , rx ) = mpsc :: channel ( 256 );
// Start your message receiver
Ok ( Box :: pin ( ReceiverStream :: new ( rx )))
}
async fn respond (
& self ,
msg : & IncomingMessage ,
response : OutgoingResponse ,
) -> Result <(), ChannelError > {
// Send response back to user
Ok (())
}
// Implement other methods...
}
Next Steps
Tools Learn about the dynamic tool system
Configuration Configure channel settings