A secure Slack bot that connects your workspace to Kagent's Kubernetes AI agents using the A2A (Agent2Agent) protocol.
Ask questions about your Kubernetes cluster in natural language directly from Slack. Get instant insights, debug issues, and manage resources through conversational AI.
✅ Natural Language Interface - Ask questions like "@kagent what pods are running in production?" ✅ Two Deployment Methods - Single bot per cluster OR one bot for multiple clusters ✅ Multi-Cluster Routing - Detect cluster keywords (test, dev, prod) in messages ✅ Conversational Context - Maintains conversation history within Slack threads ✅ A2A Protocol - Standard Agent2Agent communication with streaming support ✅ Socket Mode - No public URLs needed, works behind firewalls ✅ Production Ready - Security hardened with proper error handling ✅ Kubernetes Native - Full pod security compliance
- Slack workspace with admin access to create apps
- Kagent installed and running in your Kubernetes cluster(s)
- New to Kagent? Follow the Kagent Getting Started Guide
- Python 3.13+ (for local development) OR Kubernetes cluster (for production)
- Docker (optional, for building custom images)
# 1. Clone the repository
git clone https://github.com/your-org/kagent-slack-bot.git
cd kagent-slack-bot
# 2. Port-forward Kagent (for local testing)
kubectl port-forward -n kagent svc/kagent-controller 8083:8083 &
# 3. Configure environment
cp .env.example .env
# Edit .env with your Slack tokens (see Configuration section below)
# 4. Run locally
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
python slack_bot.pySee QUICKSTART.md for detailed 5-minute setup guide.
This bot supports two deployment methods. Choose the one that fits your needs:
Deploy one bot instance in each cluster. The bot runs inside the cluster and connects directly to the Kagent controller.
When to use:
- You want isolated, independent bot instances
- Each cluster has its own dedicated Slack bot
- Simple setup with direct A2A connection
Architecture:
Slack → Bot (in cluster) → Kagent Controller (port 8083) → k8s-agent → Kubernetes API
Deployment file: k8s-deployment-single-cluster.yaml
Documentation: KUBERNETES.md
Quick Deploy:
# Create secret with Slack tokens
kubectl create secret generic slack-credentials \
--from-literal=bot-token='xoxb-your-bot-token' \
--from-literal=app-token='xapp-your-app-token' \
--namespace=kagent
# Deploy
kubectl apply -f k8s-deployment-single-cluster.yamlDeploy ONE bot on a middleman machine that routes to multiple clusters via AgentGateway.
When to use:
- You want a single Slack bot for all clusters
- Users specify cluster keywords (test, dev, prod) in messages
- Central management from one bot instance
Architecture:
Slack → Bot (on laptop/server) → AgentGateway (port 8080) → Kagent Controller → k8s-agent → Kubernetes API
↓
Routes to test, dev, or prod cluster
Deployment file: k8s-deployment-multi-cluster.yaml OR run on laptop/server
Documentation: LAPTOP_SERVER_SETUP.md
Quick Deploy:
# For Kubernetes deployment
kubectl create secret generic slack-credentials \
--from-literal=bot-token='xoxb-your-bot-token' \
--from-literal=app-token='xapp-your-app-token' \
--namespace=default
kubectl apply -f k8s-deployment-multi-cluster.yaml
# For laptop/server deployment
# See LAPTOP_SERVER_SETUP.md for systemd service setupHow it works:
- User:
@kagent list pods in test cluster - Bot detects "test" keyword
- Routes to:
http://192.168.1.200:8080/api/a2a/kagent/k8s-agent - AgentGateway forwards to test cluster's Kagent controller
- Response streams back to Slack
# Slack credentials
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_APP_TOKEN=xapp-your-app-token
# Single cluster mode
ENABLE_MULTI_CLUSTER=false
# Direct A2A connection (port 8083)
KAGENT_BASE_URL=http://kagent-controller.kagent.svc.cluster.local:8083
KAGENT_NAMESPACE=kagent
KAGENT_AGENT_NAME=k8s-agent# Slack credentials
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_APP_TOKEN=xapp-your-app-token
# Multi-cluster mode
ENABLE_MULTI_CLUSTER=true
KAGENT_NAMESPACE=kagent
KAGENT_CLUSTERS=test,dev,prod
KAGENT_DEFAULT_CLUSTER=test
# Agent name (same across all clusters)
KAGENT_AGENT_PATTERN=k8s-agent
# AgentGateway endpoints (port 8080)
KAGENT_TEST_BASE_URL=http://192.168.1.200:8080
KAGENT_DEV_BASE_URL=http://192.168.1.201:8080
KAGENT_PROD_BASE_URL=http://192.168.1.202:8080Required OAuth Scopes:
app_mentions:read- Detect @mentionschat:write- Post messageschannels:history- Read channel history
Required Settings:
- Socket Mode - Enabled with
connections:writescope - Event Subscriptions - Enabled with
app_mentionevent - Request URL - Leave blank (Socket Mode doesn't need it)
Get your tokens:
- Go to https://api.slack.com/apps → Create New App
- OAuth & Permissions → Copy Bot User OAuth Token (xoxb-...)
- Basic Information → App-Level Tokens → Create token with
connections:writescope (xapp-...)
┌─────────────────────┐
│ Slack (Browser) │
│ @kagent what ...? │
└──────────┬──────────┘
│ WebSocket (Socket Mode)
↓
┌─────────────────────────────┐
│ Kagent Slack Bot │
│ (runs in cluster) │
│ - Event Handler │
│ - A2A Client │
└──────────┬──────────────────┘
│ HTTPS POST (port 8083)
↓
┌───────────────────────────────┐
│ Kagent Controller │
│ - Direct A2A endpoint │
└──────────┬────────────────────┘
│
↓
┌───────────────────────────────┐
│ k8s-agent (AI Agent) │
│ - kubectl via MCP tools │
└───────────────────────────────┘
┌─────────────────────┐
│ Slack (Browser) │
│ @kagent test ... │
└──────────┬──────────┘
│ WebSocket (Socket Mode)
↓
┌─────────────────────────────┐
│ Kagent Slack Bot │
│ (laptop/server) │
│ - Detects "test" keyword │
│ - Multi-cluster router │
└──────────┬──────────────────┘
│ HTTPS POST (port 8080)
↓
┌───────────────────────────────┐
│ AgentGateway (Test Cluster) │
│ IP: 192.168.1.200:8080 │
└──────────┬────────────────────┘
│ Forwards to
↓
┌───────────────────────────────┐
│ Kagent Controller │
│ - Processes request │
└──────────┬────────────────────┘
│
↓
┌───────────────────────────────┐
│ k8s-agent (AI Agent) │
│ - kubectl via MCP tools │
└───────────────────────────────┘
# Invite the bot to a channel
/invite @kagent
# Ask questions (Method 1 - single cluster)
@kagent list all namespaces
@kagent what pods are running?
@kagent show me logs for the first pod
# Ask questions (Method 2 - multi-cluster)
@kagent list pods in test cluster
@kagent check dev namespace status
@kagent show prod deployments
Each Slack thread maintains its own conversation context:
Thread 1:
User: @kagent what namespaces exist?
Bot: default, kube-system, kagent
User: @kagent how many pods in the first one? ← Remembers "first one" = default
Bot: 12 pods running in default namespace
This project follows 2025 security best practices:
- ✅ Environment-based configuration (no hardcoded secrets)
- ✅ SSL/TLS verification enabled
- ✅ Timeout protection (5-minute max)
- ✅ Secure message ID generation (SHA-256)
- ✅ Log injection prevention
- ✅ Minimal dependencies with pinned versions
- ✅ Pod Security Standards: restricted
- ✅
allowPrivilegeEscalation: false - ✅
readOnlyRootFilesystem: true - ✅
runAsNonRoot: true - ✅ Capabilities dropped: ALL
- ✅ Seccomp profile: RuntimeDefault
- ✅ Service account auto-mount disabled
- ✅ Resource limits defined
- Verify Event Subscriptions in Slack app settings
- Check
app_mentionis subscribed - Reinstall app to workspace
- Check bot logs:
kubectl logs -n kagent -l app=kagent-slack-bot
Method 1 (Direct A2A):
# Test endpoint
curl http://localhost:8083/api/a2a/kagent/k8s-agent/.well-known/agent.jsonMethod 2 (AgentGateway):
# Test endpoint
curl http://192.168.1.200:8080/api/a2a/kagent/k8s-agent/.well-known/agent.jsonSee TROUBLESHOOTING.md for more help.
- QUICKSTART.md - 5-minute setup guide
- KUBERNETES.md - Method 1: Single bot per cluster deployment
- LAPTOP_SERVER_SETUP.md - Method 2: Multi-cluster middleman deployment
- LOCAL_DEV.md - Local development guide
- TROUBLESHOOTING.md - Common issues and fixes
Contributions are welcome! Areas for contribution:
- Long-term conversation memory (Redis/database)
- Slash commands (
/kagent ask ...) - Interactive buttons and forms
- Metrics and observability (Prometheus/Grafana)
- Unit and integration tests
MIT License - Copyright (c) 2025
See LICENSE file for full details.
- Kagent Getting Started: https://kagent.dev/docs/kagent/getting-started/quickstart
- Kagent Documentation: https://kagent.dev/docs
- A2A Protocol Specification: https://a2a-protocol.org/latest/specification/
- Slack Bolt for Python: https://slack.dev/bolt-python/
- Slack Socket Mode: https://api.slack.com/apis/connections/socket
Made with ❤️ for the Kubernetes community