You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rewrote the page to lead with screenshots, cut design-doc tone,
and speak directly to platform/k8s engineers. Added image references
for real Telegram conversation screenshots.
Signed-off-by: Sebastian Maniak <sebastian@maniak.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
description: "Learn how to build a Telegram bot that interacts with kagent via A2A"
4
+
description: "Build a Telegram bot that talks to your Kubernetes cluster through kagent and A2A"
5
5
---
6
6
7
7
exportconst metadata = {
8
-
title: "Building a Telegram Bot for Kubernetes with kagent and A2A",
9
-
description: "Learn how to build a Telegram bot that interacts with kagent via A2A",
8
+
title: "Build a Telegram Bot for Kubernetes with kagent and A2A",
9
+
description: "Build a Telegram bot that talks to your Kubernetes cluster through kagent and A2A",
10
10
author: "kagent.dev",
11
11
};
12
12
13
-
# Building a Telegram Bot for Your Kubernetes Cluster with kagent and A2A
13
+
# Talk to Your Kubernetes Cluster from Telegram
14
14
15
-
Kagent enables you to create AI agents that run inside your Kubernetes cluster. They can access a variety of [built-in tools](/docs/kagent/concepts/tools) and use other [external tools via MCP](/docs/kagent/examples/documentation).
15
+
This is what you'll have by the end of this guide:
16
16
17
-
This guide shows how to build a Telegram bot that connects to a kagent agent using the A2A (Agent-to-Agent) protocol. The bot uses polling (no webhooks or public endpoints required) and forwards messages to your agent, which handles LLM orchestration, tool invocation, and response generation.
17
+

18
18
19
-
We'll walk through:
19
+
Your phone. Your cluster. No VPN, no laptop, no `kubectl`. Just a Telegram message.
20
20
21
-
1. Setting up a Telegram bot with BotFather.
22
-
2. Deploying a kagent agent with A2A enabled.
23
-
3. Writing the bot code.
24
-
4. Deploying and testing the integration.
21
+
It handles real operations too — ask it to create a namespace and it confirms before doing anything destructive:
25
22
26
-
---
27
-
28
-
## Architecture Overview
23
+

29
24
30
-
```
31
-
┌──────────────────┐
32
-
│ Telegram Cloud │
33
-
│ (Bot API) │
34
-
└────────┬─────────┘
35
-
│ Long Polling
36
-
▼
37
-
┌──────────────────────────────────────────────┐
38
-
│ Kubernetes Cluster │
39
-
│ │
40
-
│ ┌──────────────────┐ │
41
-
│ │ telegram-bot │ │
42
-
│ │ (Pod) │ │
43
-
│ └────────┬─────────┘ │
44
-
│ │ HTTP POST (A2A JSON-RPC) │
45
-
│ ▼ │
46
-
│ ┌──────────────────┐ ┌────────────────┐ │
47
-
│ │ kagent-controller│───▶│ Agent Pod │ │
48
-
│ │ :8083/api/a2a/ │ │ + LLM + Tools │ │
49
-
│ └──────────────────┘ └────────────────┘ │
50
-
└──────────────────────────────────────────────┘
51
-
```
25
+

52
26
53
-
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.
27
+
The bot itself is ~120 lines of Python. It doesn't know anything about Kubernetes or LLMs — it's a dumb pipe between Telegram and kagent's [A2A](https://google.github.io/A2A/) endpoint. All the intelligence lives in the agent.
54
28
55
29
---
56
30
57
-
## Creating a Telegram Bot
31
+
## Create Your Telegram Bot
58
32
59
-
1. Open Telegram and search for **@BotFather**.
60
-
2. Send `/newbot` and follow the prompts to choose a name and username.
61
-
3. BotFather will give you a **bot token** — save it, you'll need it later.
33
+
1. Open Telegram, search for **@BotFather**.
34
+
2. Send `/newbot`, pick a name and username.
35
+
3. Copy the **bot token** it gives you.
36
+
37
+
Done. 30 seconds.
62
38
63
39
---
64
40
65
-
## Deploying an Agent
41
+
## Deploy a kagent Agent
66
42
67
-
Before deploying an agent, make sure you have installed kagent in your cluster. If you haven't, you can install it by following the instructions [here](https://kagent.dev/docs/kagent/getting-started/quickstart). Make sure that you also install the `kmcp` CRDs as shown in that guide so that you can create an MCPServer.
43
+
> **Prerequisite:** kagent running in your cluster with `kmcp` CRDs installed. If not, hit the [quickstart](https://kagent.dev/docs/kagent/getting-started/quickstart) first.
68
44
69
-
Deploy a Kubernetes agent with A2A enabled:
45
+
This agent has Kubernetes tools, Helm tools, and Prometheus — and it's exposed over A2A so any client (our Telegram bot, or anything else) can talk to it:
70
46
71
47
```shell
72
48
kubectl apply -f - <<EOF
@@ -122,80 +98,22 @@ spec:
122
98
EOF
123
99
```
124
100
125
-
The `a2aConfig.skills` section tells A2A clients what this agent can do. The `requireApproval` list ensures destructive operations go through [Human-in-the-Loop](/docs/kagent/examples/human-in-the-loop) approval in the kagent UI before executing.
101
+
Notice `requireApproval` — anything destructive (deleting resources, applying manifests, Helm upgrades) goes through [Human-in-the-Loop](/docs/kagent/examples/human-in-the-loop) approval in the kagent UI first. Nobody's accidentally nuking prod from a Telegram chat.
126
102
127
-
To access the agent through A2A locally, port-forward the kagent controller:
You should see a JSON response with the agent's name, description, and skills.
140
-
141
-
---
142
-
143
-
## The A2A Protocol
144
-
145
-
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.
146
-
147
-
The protocol uses JSON-RPC 2.0 over HTTP. A message exchange looks like:
148
-
149
-
**Request:**
150
-
```json
151
-
{
152
-
"jsonrpc": "2.0",
153
-
"id": "unique-task-id",
154
-
"method": "message/send",
155
-
"params": {
156
-
"id": "unique-task-id",
157
-
"message": {
158
-
"role": "user",
159
-
"parts": [{"kind": "text", "text": "list my pods"}]
160
-
}
161
-
}
162
-
}
163
-
```
164
-
165
-
**Response:**
166
-
```json
167
-
{
168
-
"result": {
169
-
"artifacts": [{
170
-
"parts": [{
171
-
"kind": "text",
172
-
"text": "Here are your pods: ..."
173
-
}]
174
-
}]
175
-
}
176
-
}
177
-
```
178
-
179
-
> **Important notes about kagent's A2A implementation:**
180
-
> - The method is `message/send` (not `tasks/send` as in the older A2A draft spec)
181
-
> - Parts use `"kind": "text"` (not `"type": "text"`)
182
-
> - The URL pattern is `/api/a2a/{namespace}/{agent-name}/` — **trailing slash required**
183
-
> - Responses come back in `result.artifacts[].parts[]`
110
+
You should get back JSON with the agent's name and skills.
184
111
185
112
---
186
113
187
-
## Writing the Bot Code
188
-
189
-
The bot is ~120 lines of Python using `python-telegram-bot` (polling mode) and `httpx` for A2A calls.
114
+
## Write the Bot
190
115
191
-
### Project Structure
192
-
193
-
```
194
-
telegram-bot/
195
-
├── main.py
196
-
├── requirements.txt
197
-
└── Dockerfile
198
-
```
116
+
Three files. That's the whole thing.
199
117
200
118
### requirements.txt
201
119
@@ -311,12 +229,7 @@ if __name__ == "__main__":
311
229
main()
312
230
```
313
231
314
-
Key design decisions:
315
-
316
-
-**Polling, not webhooks**: No ingress, no public endpoint, no TLS termination. The bot makes outbound connections to Telegram's API from inside the cluster.
317
-
-**Session per user**: Each Telegram user gets their own A2A session ID, so conversations have context continuity.
318
-
-**Chunked responses**: Telegram has a 4096-character message limit. Long agent responses are split automatically.
319
-
-**Health file**: A simple `/tmp/bot-healthy` file is created on startup for Kubernetes liveness/readiness probes.
232
+
It uses polling — no ingress, no webhooks, no TLS to set up. Each Telegram user gets their own session so conversations keep context. Long responses get chunked automatically (Telegram's 4096-char limit). The `/tmp/bot-healthy` file is there for Kubernetes liveness probes.
> **Important:** The `Recreate` strategy is required — Telegram's polling API doesn't support multiple consumers. With `RollingUpdate`, you'd briefly have two pods pulling the same messages, causing duplicates or missed messages.
452
-
453
-
Apply the deployment:
353
+
The strategy is `Recreate` on purpose — Telegram polling doesn't support multiple consumers. Two pods polling the same bot token means duplicate or missed messages.
454
354
455
355
```shell
456
356
kubectl apply -f deployment.yaml
457
357
```
458
358
459
359
---
460
360
461
-
## Gotchas and Tips
462
-
463
-
### The trailing slash matters
464
-
465
-
The kagent A2A endpoint at `/api/a2a/kagent/telegram-k8s-agent` returns a 307 redirect to `/api/a2a/kagent/telegram-k8s-agent/`. Most HTTP clients won't follow redirects on POST requests by default. Always include the trailing slash.
466
-
467
-
### kagent uses `message/send`, not `tasks/send`
468
-
469
-
If you're reading the A2A spec or looking at other implementations, be aware that kagent uses `message/send` as the method name. The older `tasks/send` method returns a "Method not found" error.
470
-
471
-
### Parts use `kind`, not `type`
472
-
473
-
The A2A spec uses `"kind": "text"` for message parts. Some implementations use `"type": "text"`. kagent expects `kind`.
474
-
475
-
### Telegram message limits
476
-
477
-
Telegram enforces a 4096-character limit per message. The bot code handles this automatically by chunking responses.
478
-
479
-
---
480
-
481
-
## Testing It
482
-
483
-
Once deployed, open Telegram and find your bot:
484
-
485
-
1. `/start` — Shows available commands
486
-
2. `/new` — Resets your conversation session
487
-
3. Send any message — It goes to the agent and comes back with a real answer
361
+
## Things That Will Bite You
488
362
489
-
Example interactions:
363
+
**Always include the trailing slash** in the A2A URL: `/api/a2a/kagent/telegram-k8s-agent/`. Without it you get a 307 redirect. Most HTTP clients don't follow redirects on POST. You will lose time to this.
490
364
491
-
```
492
-
You: What pods are running in kagent namespace?
493
-
494
-
Bot: Here are the running pods in the kagent namespace:
**The method is `message/send`**, not `tasks/send`. If you're copying from other A2A examples, they might use the older spec. kagent uses `message/send` — `tasks/send` gives you "Method not found."
499
366
500
-
```
501
-
You: What helm releases are installed?
502
-
503
-
Bot: Here are the Helm releases across all namespaces:
504
-
• kagent (kagent) v0.8.0-beta6
505
-
• vault (vault) v0.29.1
506
-
• istio-base (istio-system) v1.25.2
507
-
```
367
+
**Parts use `kind`, not `type`.** The payload needs `"kind": "text"`, not `"type": "text"`. Easy to miss if you're referencing other implementations.
508
368
509
369
---
510
370
511
-
## What's Next
512
-
513
-
From here you could:
371
+
## Take It Further
514
372
515
-
- **Add more agents**: Create separate agents for security, Istio, or monitoring and route to them from the bot.
516
-
- **Route by command**: Use different Telegram commands (`/k8s`, `/istio`, `/security`) to route to different kagent agents.
517
-
- **Add image support**: kagent supports multi-modal parts — you could send screenshots of dashboards and ask "what's wrong here?"
518
-
- **Connect via AgentGateway**: Route the A2A traffic through [AgentGateway](https://agentgateway.dev) for rate limiting, authentication, and observability.
373
+
The interesting part isn't the Telegram bot — it's the pattern. The bot is just a transport layer. A2A is the interface. That means:
519
374
520
-
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.
375
+
- **Multiple agents, one bot.** Add Telegram commands like `/k8s`, `/istio`, `/security` that route to different kagent agents.
376
+
- **Any chat platform.** Swap `python-telegram-bot` for `discord.py` or `slack-bolt`. Everything else stays the same.
377
+
- **Multi-modal.** kagent supports image parts — screenshot a Grafana dashboard and ask "what's wrong here?"
378
+
- **AgentGateway.** Put [AgentGateway](https://agentgateway.dev) in front of the A2A endpoint for rate limiting, auth, and observability.
521
379
522
-
For questions or support, join our [Discord community](https://discord.gg/Fu3k65f2k3).
380
+
Questions? Come find us on [Discord](https://discord.gg/Fu3k65f2k3).
0 commit comments