A lightweight, secure, cloud-native ACP harness that bridges Discord and any Agent Client Protocol-compatible coding CLI (Kiro CLI, Claude Code, Codex, Gemini, Copilot CLI, etc.) over stdio JSON-RPC — delivering the next-generation development experience.
🪼 Join our community! Come say hi on Discord — we'd love to have you: 🪼 OpenAB — Official 🎉
┌──────────────┐ Gateway WS ┌──────────────┐ ACP stdio ┌──────────────┐
│ Discord │◄─────────────►│ openab │──────────────►│ coding CLI │
│ User │ │ (Rust) │◄── JSON-RPC ──│ (acp mode) │
└──────────────┘ └──────────────┘ └──────────────┘
- Pluggable agent backend — swap between Kiro CLI, Claude Code, Codex, Gemini, Copilot CLI via config
- @mention trigger — mention the bot in an allowed channel to start a conversation
- Thread-based multi-turn — auto-creates threads; no @mention needed for follow-ups
- Edit-streaming — live-updates the Discord message every 1.5s as tokens arrive
- Emoji status reactions — 👀→🤔→🔥/👨💻/⚡→👍+random mood face
- Session pool — one CLI process per thread, auto-managed lifecycle
- ACP protocol — JSON-RPC over stdio with tool call, thinking, and permission auto-reply support
- Kubernetes-ready — Dockerfile + k8s manifests with PVC for auth persistence
- Voice message STT — auto-transcribes Discord voice messages via Groq, OpenAI, or local Whisper server (docs/stt.md)
See docs/discord-bot-howto.md for a detailed step-by-step guide.
helm repo add openab https://openabdev.github.io/openab
helm repo update
helm install openab openab/openab \
--set agents.kiro.discord.botToken="$DISCORD_BOT_TOKEN" \
--set-string 'agents.kiro.discord.allowedChannels[0]=YOUR_CHANNEL_ID'kubectl exec -it deployment/openab-kiro -- kiro-cli login --use-device-flow
kubectl rollout restart deployment/openab-kiroIn your Discord channel:
@YourBot explain this code
The bot creates a thread. After that, just type in the thread — no @mention needed.
| Agent | CLI | ACP Adapter | Guide |
|---|---|---|---|
| Kiro (default) | kiro-cli acp |
Native | docs/kiro.md |
| Claude Code | claude-agent-acp |
@agentclientprotocol/claude-agent-acp | docs/claude-code.md |
| Codex | codex-acp |
@zed-industries/codex-acp | docs/codex.md |
| Gemini | gemini --acp |
Native | docs/gemini.md |
| Copilot CLI |
copilot --acp --stdio |
Native | docs/copilot.md |
🔧 Running multiple agents? See docs/multi-agent.md
cp config.toml.example config.toml
# Edit config.toml with your bot token and channel ID
export DISCORD_BOT_TOKEN="your-token"
cargo run[discord]
bot_token = "${DISCORD_BOT_TOKEN}" # supports env var expansion
allowed_channels = ["123456789"] # channel ID allowlist
# allowed_users = ["987654321"] # user ID allowlist (empty = all users)
[agent]
command = "kiro-cli" # CLI command
args = ["acp", "--trust-all-tools"] # ACP mode args
working_dir = "/tmp" # agent working directory
env = {} # extra env vars passed to the agent
[pool]
max_sessions = 10 # max concurrent sessions
session_ttl_hours = 24 # idle session TTL
[reactions]
enabled = true # enable emoji status reactions
remove_after_reply = false # remove reactions after replyFull reactions config
[reactions.emojis]
queued = "👀"
thinking = "🤔"
tool = "🔥"
coding = "👨💻"
web = "⚡"
done = "🆗"
error = "😱"
[reactions.timing]
debounce_ms = 700
stall_soft_ms = 10000
stall_hard_ms = 30000
done_hold_ms = 1500
error_hold_ms = 2500The Docker image bundles both openab and kiro-cli in a single container.
┌─ Kubernetes Pod ──────────────────────────────────────┐
│ openab (PID 1) │
│ └─ kiro-cli acp --trust-all-tools (child process) │
│ ├─ stdin ◄── JSON-RPC requests │
│ └─ stdout ──► JSON-RPC responses │
│ │
│ PVC (/data) │
│ ├─ ~/.kiro/ (settings, sessions) │
│ └─ ~/.local/share/kiro-cli/ (OAuth tokens) │
└───────────────────────────────────────────────────────┘
docker build -t openab:latest .
docker tag openab:latest <your-registry>/openab:latest
docker push <your-registry>/openab:latestkubectl create secret generic openab-secret \
--from-literal=discord-bot-token="your-token"
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/pvc.yaml
kubectl apply -f k8s/deployment.yaml| Manifest | Purpose |
|---|---|
k8s/deployment.yaml |
Single-container pod with config + data volume mounts |
k8s/configmap.yaml |
config.toml mounted at /etc/openab/ |
k8s/secret.yaml |
DISCORD_BOT_TOKEN injected as env var |
k8s/pvc.yaml |
Persistent storage for auth + settings |
├── Dockerfile # multi-stage: rust build + debian-slim runtime with kiro-cli
├── config.toml.example # example config with all agent backends
├── k8s/ # Kubernetes manifests
└── src/
├── main.rs # entrypoint: tokio + serenity + cleanup + shutdown
├── config.rs # TOML config + ${ENV_VAR} expansion
├── discord.rs # Discord bot: mention, threads, edit-streaming
├── format.rs # message splitting (2000 char limit)
├── reactions.rs # status reaction controller (debounce, stall detection)
└── acp/
├── protocol.rs # JSON-RPC types + ACP event classification
├── connection.rs # spawn CLI, stdio JSON-RPC communication
└── pool.rs # thread_id → AcpConnection map
- sample-acp-bridge — ACP protocol + process pool architecture
- OpenClaw — StatusReactionController emoji pattern
MIT
