Bidirectional bridge between the A2A (Agent-to-Agent) protocol and Telegram. Any A2A-compatible agent sends tasks/send via JSON-RPC — your users see a Telegram message and reply in-chat.
A2A is an open protocol by Google that defines a standard JSON-RPC interface
for agent communication. Agents discover each other via agent cards
(/.well-known/agent.json), exchange messages through tasks/send,
and receive async results via push notifications. Any agent that speaks A2A
can call any other A2A endpoint — regardless of framework, language, or vendor.
A2A defines agent-to-agent communication. But many workflows require a human in the loop — approvals, clarifications, monitoring. There's no A2A-native way to route a task to a person in Telegram, WhatsApp, or Slack. This proxy solves it for Telegram: it maps the A2A protocol surface (tasks/send, tasks/get, push notifications, agent cards) onto Telegram bots and chats.
Your A2A agent needs user approval before executing. It sends tasks/send with input-required. The proxy delivers to Telegram, waits for reply, returns it as A2A task history.
Users type in Telegram, the proxy sends tasks/send to any A2A agent. No custom UI needed. Every A2A-compatible agent instantly gets a Telegram interface.
Route A2A push notifications to a Telegram channel. See task completions, failures, and intermediate status updates in real time without building a dashboard.
Map different A2A agents to different Telegram bots. Each chat maintains its own session context. Group chat support with bot mention filtering.
The first version hand-rolled every JSON-RPC call — tasks/send, tasks/get, message/send. Protocol method names drifted between agent implementations, causing silent failures. In v0.5.0 we replaced the custom client with the official @a2a-js/sdk JsonRpcTransport. Method names, request shapes, and response parsing now come from the SDK. The proxy went from "works with our agent" to "works with any A2A-compliant agent."
A2A agents can return results inline (blocking) or asynchronously via push notifications (non-blocking). Getting both modes right took several iterations. Blocking mode needed fetch timeouts for slow agents. Non-blocking mode needed task ID reconciliation — the proxy generates a client ID, but the agent assigns its own UUID. Push notifications arrive with the server UUID. We solved it by mapping both IDs on the first response and matching on either.
Different A2A implementations send push notifications in different shapes.
The SDK sends { kind: "task", id, status }. Legacy agents send
{ params: { id, status } }. Part objects use kind
in one and type in another. The proxy normalizes both formats
into a single internal representation before routing to Telegram. Full
protocol coverage was validated against a Python A2A test server with 7 modes
and 13 end-to-end tests.
When an A2A agent needs more information, it returns a task with
state: "input-required". The proxy detects this, sends the agent's
question to Telegram, and waits for the user's reply. The reply is routed back
as a continuation of the same A2A task with the original task ID. This enables
multi-turn agent conversations through Telegram — the agent thinks it's
talking to another agent, the user thinks they're chatting with a bot.