13 Mar 2026

Building a Telegram Bot for Your Kubernetes Cluster with kagent and A2A

Building a Telegram Bot for Your Kubernetes Cluster with kagent and A2A

By Sebastian Maniak

What if you could manage your Kubernetes cluster from Telegram? Not through a half-baked webhook that runs kubectl β€” but through a real AI agent that understands context, uses tools, and responds intelligently?

In this article, I’ll walk you through how I built exactly that: a Telegram bot that connects to a kagent AI agent running on my home lab Kubernetes cluster (Talos Linux on Proxmox), giving me full cluster operations from my phone. The entire thing is deployed via GitOps with ArgoCD, secrets come from HashiCorp Vault, and the bot uses the A2A (Agent-to-Agent) protocol to communicate with kagent.

No webhooks. No public endpoints. Just polling from inside the cluster.


Architecture Overview

Here’s what we’re building:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Telegram Cloud                               β”‚
β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                              β”‚
β”‚                    β”‚  Telegram Bot API β”‚                             β”‚
β”‚                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                              β”‚
β”‚                             β”‚ Long Polling                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Kubernetes Cluster         β”‚                                       β”‚
β”‚  (maniak-iceman)            β–Ό                                       β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                            β”‚
β”‚              β”‚   telegram-bot (Pod)     β”‚                            β”‚
β”‚              β”‚   python-telegram-bot    β”‚                            β”‚
β”‚              β”‚   + httpx               β”‚                            β”‚
β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                            β”‚
β”‚                           β”‚ HTTP POST (A2A JSON-RPC)                β”‚
β”‚                           β”‚ message/send                            β”‚
β”‚                           β–Ό                                         β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                            β”‚
β”‚              β”‚  kagent-controller       β”‚                            β”‚
β”‚              β”‚  :8083/api/a2a/kagent/   β”‚                            β”‚
β”‚              β”‚  telegram-k8s-agent/     β”‚                            β”‚
β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                            β”‚
β”‚                           β”‚ Routes to Agent                         β”‚
β”‚                           β–Ό                                         β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚              β”‚ telegram-k8s-agent (Pod) │─────▢│ kagent-tool-     β”‚ β”‚
β”‚              β”‚  LLM: gpt-5.4           β”‚ MCP  β”‚ server (Pod)     β”‚ β”‚
β”‚              β”‚  Agent CRD              │◀─────│ :8084/mcp        β”‚ β”‚
β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                                                     β”‚               β”‚
β”‚                                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚                                          β”‚  Tools:             β”‚   β”‚
β”‚                                          β”‚  β€’ k8s_get_resourcesβ”‚   β”‚
β”‚                                          β”‚  β€’ k8s_get_pod_logs β”‚   β”‚
β”‚                                          β”‚  β€’ helm_list        β”‚   β”‚
β”‚                                          β”‚  β€’ istio_*          β”‚   β”‚
β”‚                                          β”‚  β€’ prometheus_*     β”‚   β”‚
β”‚                                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                          β”‚
β”‚  β”‚  Vault        │───▢│ ExternalSecret   │──▢ telegram-bot-token   β”‚
β”‚  β”‚  secret/      β”‚    β”‚ Operator         β”‚                          β”‚
β”‚  β”‚  telegram     β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The key insight: the Telegram bot doesn’t talk to the LLM directly. It sends messages to the kagent controller’s A2A endpoint, which routes them to the correct agent. The agent handles LLM orchestration, tool invocation, and response generation. The bot is just a thin transport layer.


The A2A Protocol

A2A (Agent-to-Agent) is a Google-backed open protocol for agent interoperability. kagent implements A2A on its controller, meaning any A2A-compatible client can talk to any kagent agent.

The protocol uses JSON-RPC 2.0 over HTTP. Here’s what a message exchange looks like:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Telegram β”‚                    β”‚ kagent-controller  β”‚                β”‚ Agent Pod   β”‚
β”‚ Bot Pod  β”‚                    β”‚ (A2A endpoint)     β”‚                β”‚ + LLM + MCP β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
     β”‚                                    β”‚                                  β”‚
     β”‚  POST /api/a2a/kagent/             β”‚                                  β”‚
     β”‚       telegram-k8s-agent/          β”‚                                  β”‚
     β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚                                  β”‚
     β”‚  β”‚ {                       β”‚       β”‚                                  β”‚
     β”‚  β”‚   "jsonrpc": "2.0",     β”‚       β”‚                                  β”‚
     β”‚  β”‚   "method":             β”‚       β”‚                                  β”‚
     β”‚  β”‚     "message/send",     β”‚       β”‚                                  β”‚
     β”‚  β”‚   "params": {           β”‚       β”‚                                  β”‚
     β”‚  β”‚     "message": {        β”‚       β”‚                                  β”‚
     β”‚  β”‚       "role": "user",   β”‚       β”‚                                  β”‚
     β”‚  β”‚       "parts": [{       β”‚       β”‚                                  β”‚
     β”‚  β”‚         "kind": "text", β”‚       β”‚                                  β”‚
     β”‚  β”‚         "text": "list   β”‚       β”‚                                  β”‚
     β”‚  β”‚           my pods"      β”‚       β”‚                                  β”‚
     β”‚  β”‚       }]                β”‚       β”‚                                  β”‚
     β”‚  β”‚     }                   β”‚       β”‚                                  β”‚
     β”‚  β”‚   }                     β”‚       β”‚                                  β”‚
     β”‚  β”‚ }                       β”‚       β”‚                                  β”‚
     β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚                                  β”‚
     β”‚ ──────────────────────────────────▢│                                  β”‚
     β”‚                                    β”‚  Forward to agent                β”‚
     β”‚                                    │─────────────────────────────────▢│
     β”‚                                    β”‚                                  β”‚
     β”‚                                    β”‚              LLM + Tool calls    β”‚
     β”‚                                    β”‚              (k8s_get_resources) β”‚
     β”‚                                    β”‚                                  β”‚
     β”‚                                    │◀─────────────────────────────────│
     β”‚ ◀──────────────────────────────────│  Response with artifacts         β”‚
     β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚                                  β”‚
     β”‚  β”‚ {                       β”‚       β”‚                                  β”‚
     β”‚  β”‚   "result": {           β”‚       β”‚                                  β”‚
     β”‚  β”‚     "artifacts": [{     β”‚       β”‚                                  β”‚
     β”‚  β”‚       "parts": [{       β”‚       β”‚                                  β”‚
     β”‚  β”‚         "kind": "text", β”‚       β”‚                                  β”‚
     β”‚  β”‚         "text": "Here   β”‚       β”‚                                  β”‚
     β”‚  β”‚           are your      β”‚       β”‚                                  β”‚
     β”‚  β”‚           pods: ..."    β”‚       β”‚                                  β”‚
     β”‚  β”‚       }]                β”‚       β”‚                                  β”‚
     β”‚  β”‚     }]                  β”‚       β”‚                                  β”‚
     β”‚  β”‚   }                     β”‚       β”‚                                  β”‚
     β”‚  β”‚ }                       β”‚       β”‚                                  β”‚
     β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚                                  β”‚
     β”‚                                    β”‚                                  β”‚

A few things to note about kagent’s A2A implementation:

  • The method is message/send (not tasks/send as in the older A2A draft spec)
  • Parts use "kind": "text" (not "type": "text")
  • The URL pattern is /api/a2a/{namespace}/{agent-name}/ β€” trailing slash required
  • Responses come back in result.artifacts[].parts[]

The Components

1. ExternalSecret β€” Pulling the Bot Token from Vault

The Telegram bot token lives in HashiCorp Vault at secret/telegram with key api_key. The External Secrets Operator syncs it into a Kubernetes secret:

apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: telegram-bot-token
  namespace: kagent
spec:
  refreshInterval: "1h"
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: telegram-bot-token
    creationPolicy: Owner
  data:
    - secretKey: TELEGRAM_BOT_TOKEN
      remoteRef:
        key: telegram
        property: api_key

This follows the same pattern as the existing kagent-openai and kagent-anthropic secrets in the cluster. No hardcoded tokens in Git.

2. The Agent CRD

The telegram-k8s-agent is a standard kagent Declarative agent. It references the kagent-tool-server RemoteMCPServer for Kubernetes, Helm, Istio, and Prometheus tools:

apiVersion: kagent.dev/v1alpha2
kind: Agent
metadata:
  name: telegram-k8s-agent
  namespace: kagent
spec:
  description: "Kubernetes operations agent accessible via Telegram bot"
  type: Declarative
  declarative:
    modelConfig: default-model-config
    a2aConfig:
      skills:
        - id: k8s-operations
          name: Kubernetes Operations
          description: "Query, manage, and troubleshoot Kubernetes resources"
          examples:
            - "What pods are running in the default namespace?"
            - "Show me the logs for pod X"
            - "What Helm releases are installed?"
          tags: [kubernetes, operations]
        - id: cluster-monitoring
          name: Cluster Monitoring
          description: "Query Prometheus metrics and monitor cluster health"
          examples:
            - "What is the CPU usage across nodes?"
          tags: [monitoring, prometheus]
    systemMessage: |
      You are a Kubernetes operations agent accessible via Telegram.
      Keep responses concise and well-formatted for chat readability.      
    tools:
      - type: McpServer
        mcpServer:
          apiGroup: kagent.dev
          kind: RemoteMCPServer
          name: kagent-tool-server
          toolNames:
            - k8s_get_resources
            - k8s_describe_resource
            - k8s_get_pod_logs
            - k8s_get_events
            - helm_list_releases
            - helm_get_release
            - istio_proxy_status
            - istio_version
            - prometheus_query_tool
            - datetime_get_current_time
          requireApproval:
            - k8s_delete_resource
            - k8s_apply_manifest
            - helm_upgrade
            - helm_uninstall

The a2aConfig.skills section tells other A2A clients what this agent can do. The requireApproval list ensures destructive operations go through Human-in-the-Loop approval in the kagent UI before executing.

3. The Bot Code

The bot is ~120 lines of Python using python-telegram-bot (polling mode) and httpx for A2A calls:

"""Telegram bot that forwards messages to a kagent A2A agent."""

import logging, os, uuid
from pathlib import Path
import httpx
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters

TELEGRAM_BOT_TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
KAGENT_A2A_URL = os.environ["KAGENT_A2A_URL"]

async def send_a2a_task(message_text: str, session_id: str) -> str:
    """Send a message to the kagent A2A endpoint and return the response."""
    task_id = str(uuid.uuid4())
    payload = {
        "jsonrpc": "2.0",
        "id": task_id,
        "method": "message/send",
        "params": {
            "id": task_id,
            "message": {
                "role": "user",
                "parts": [{"kind": "text", "text": message_text}],
            },
        },
    }

    async with httpx.AsyncClient(timeout=120.0) as client:
        resp = await client.post(KAGENT_A2A_URL, json=payload,
                                 headers={"Content-Type": "application/json"})
        resp.raise_for_status()
        data = resp.json()

    result = data.get("result", {})
    artifacts = result.get("artifacts", [])
    if artifacts:
        parts = artifacts[-1].get("parts", [])
        texts = [p.get("text", "") for p in parts if p.get("kind") == "text"]
        if texts:
            return "\n".join(texts)

    return "Agent returned no text response."

# Per-user session tracking
user_sessions: dict[int, str] = {}

def get_session(user_id: int) -> str:
    if user_id not in user_sessions:
        user_sessions[user_id] = str(uuid.uuid4())
    return user_sessions[user_id]

async def handle_message(update: Update, _) -> None:
    user_id = update.effective_user.id
    session_id = get_session(user_id)
    thinking_msg = await update.message.reply_text("Thinking...")

    try:
        response = await send_a2a_task(update.message.text, session_id)
        for i in range(0, len(response), 4000):  # Telegram 4096 char limit
            chunk = response[i : i + 4000]
            if i == 0:
                await thinking_msg.edit_text(chunk)
            else:
                await update.message.reply_text(chunk)
    except Exception as e:
        await thinking_msg.edit_text(f"Error contacting agent: {e}")

def main() -> None:
    app = Application.builder().token(TELEGRAM_BOT_TOKEN).build()
    app.add_handler(CommandHandler("start", start_command))
    app.add_handler(CommandHandler("new", new_command))
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))

    Path("/tmp/bot-healthy").touch()  # For k8s probes
    app.run_polling(drop_pending_updates=True)

Key design decisions:

  • Polling, not webhooks: No ingress, no public endpoint, no TLS termination. The bot makes outbound connections to Telegram’s API from inside the cluster.
  • Session per user: Each Telegram user gets their own A2A session ID, so conversations have context continuity.
  • Chunked responses: Telegram has a 4096-character message limit. Long agent responses are split automatically.
  • Health file: A simple /tmp/bot-healthy file is created on startup for Kubernetes liveness/readiness probes.

4. The Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: telegram-bot
  namespace: kagent
spec:
  replicas: 1
  strategy:
    type: Recreate    # Only one poller at a time
  template:
    spec:
      containers:
        - name: bot
          image: docker.io/sebbycorp/telegram-kagent-bot:latest
          env:
            - name: TELEGRAM_BOT_TOKEN
              valueFrom:
                secretKeyRef:
                  name: telegram-bot-token
                  key: TELEGRAM_BOT_TOKEN
            - name: KAGENT_A2A_URL
              value: "http://kagent-controller.kagent.svc.cluster.local:8083/api/a2a/kagent/telegram-k8s-agent/"

The Recreate strategy is important β€” Telegram’s polling API doesn’t support multiple consumers. If you use RollingUpdate, you’d briefly have two pods pulling the same messages.


GitOps Flow

The entire deployment is managed through ArgoCD. Here’s how changes flow:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     git push      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Developer   β”‚ ─────────────────▢│ GitHub            β”‚
β”‚ (You)       β”‚                   β”‚ ProfessorSeb/     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚ k8s-iceman        β”‚
                                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                           β”‚
                              ArgoCD polls β”‚ (3 min)
                                           β–Ό
                                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                  β”‚ ArgoCD            β”‚
                                  β”‚ kagent-examples   β”‚
                                  β”‚ Application       β”‚
                                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                           β”‚
                              kubectl applyβ”‚
                                           β–Ό
                                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                  β”‚ Kubernetes        β”‚
                                  β”‚ β”œβ”€ ExternalSecret β”‚
                                  β”‚ β”œβ”€ Agent CRD      β”‚
                                  β”‚ └─ Deployment     β”‚
                                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The repo structure:

k8s-iceman/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ kagent-examples.yaml          # ArgoCD Application (recurse: true)
β”‚   └── telegram-bot-src/             # Bot source code
β”‚       β”œβ”€β”€ Dockerfile
β”‚       β”œβ”€β”€ main.py
β”‚       └── requirements.txt
β”œβ”€β”€ manifests/
β”‚   └── kagent-examples/
β”‚       └── telegram-bot/             # Picked up by ArgoCD automatically
β”‚           β”œβ”€β”€ 01-external-secret.yaml
β”‚           β”œβ”€β”€ 02-agent.yaml
β”‚           └── 03-deployment.yaml
└── helm-values/
    └── kagent/
        └── values.yaml               # Model config (gpt-5.4)

Because the kagent-examples ArgoCD Application has directory.recurse: true, any new directory under manifests/kagent-examples/ is automatically synced. No new ArgoCD Application needed.


Gotchas and Lessons Learned

1. The trailing slash matters

The kagent A2A endpoint at /api/a2a/kagent/telegram-k8s-agent returns a 307 redirect to /api/a2a/kagent/telegram-k8s-agent/. The httpx library (and most HTTP clients) won’t follow redirects on POST requests by default β€” for good security reasons. Always include the trailing slash.

2. kagent uses message/send, not tasks/send

If you’re reading the A2A spec or looking at other A2A implementations, be aware that kagent uses message/send as the method name. The older tasks/send method returns a Method not found error.

3. Parts use kind, not type

The A2A spec uses "kind": "text" for message parts. Some implementations and docs use "type": "text". kagent expects kind.

4. Telegram message limits

Telegram enforces a 4096-character limit per message. If your agent returns a large response (like a full pod listing or verbose logs), you need to chunk it. The bot handles this automatically.

5. Recreate strategy, not RollingUpdate

Telegram’s long-polling API delivers each update to exactly one consumer. With two pods running during a rolling update, you’d get duplicate responses or missed messages. Recreate ensures a clean handoff.


Testing It

Once deployed, open Telegram and find your bot (the one you created with @BotFather):

  1. /start β€” Shows available commands
  2. /status β€” Checks connectivity to the kagent controller
  3. /new β€” Resets your conversation session
  4. Send any message β€” It goes to the agent and comes back with a real answer

Example interactions:

You: What pods are running in kagent namespace?

Bot: Here are the running pods in the kagent namespace:

  • kagent-controller-57864fdf69-xfgmr (1/1 Running)
  • telegram-bot-5469669bf-v8h7p (1/1 Running)
  • telegram-k8s-agent-5f696bf4b9-pl7cl (1/1 Running)
  • k8s-agent-6dccd8ddd8-gxt6x (1/1 Running)
  • … (28 more pods)

You: What helm releases are installed?

Bot: Here are the Helm releases across all namespaces:

  • kagent (kagent) v0.8.0-beta6
  • vault (vault) v0.29.1
  • istio-base (istio-system) v1.25.2

What’s Next

This is a foundation. From here you could:

  • Add more agents: Create a telegram-security-agent with Kubescape tools, or a telegram-istio-agent with mesh-specific tools
  • Route by command: Use different Telegram commands (/k8s, /istio, /security) to route to different kagent agents
  • Add image support: kagent supports multi-modal parts β€” you could send screenshots of dashboards and ask “what’s wrong here?”
  • Connect via AgentGateway: Route the A2A traffic through AgentGateway for rate limiting, authentication, and observability

The pattern works for any chat platform. Swap python-telegram-bot for discord.py or slack-bolt and the rest stays the same β€” the A2A protocol is the universal adapter.


The full source code and Kubernetes manifests are in the k8s-iceman repo under apps/telegram-bot-src/ and manifests/kagent-examples/telegram-bot/.