Claude Code, Codex and Cursor: Get a Telegram Message When Your AI Agent Finishes
push.tgYou hand an AI coding agent a 20-minute task and walk away. Then it sits for an hour waiting on a permission prompt you never saw. A hook that pings your phone fixes that. This guide covers Claude Code, OpenAI Codex CLI and Cursor. Every snippet below was checked against the official hook docs (October 2026) and tested with sample events.
Step 1: get your endpoint (30 seconds)
Open @trafficRobot in Telegram and press Start. You get an address like k3x9q@push.tg. Your endpoint is the part before the @: https://push.tg/k3x9q. Every example below uses k3x9q, so swap in your own key.
There's no bot to create, no chat_id to look up and no token to keep safe. Add @trafficRobot to a group and the group gets its own address, so the whole team sees the alerts.
You also need jq and curl on the machine (brew install jq or apt install jq).
Claude Code
Claude Code runs hooks from ~/.claude/settings.json (all projects) or .claude/settings.json (one project). Each hook gets the event as JSON on stdin. Stop fires when Claude finishes answering and includes last_assistant_message. Notification fires when Claude needs you: permission_prompt or idle_prompt. Merge this into your settings:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "jq -r '\"✅ Claude Code finished: \" + (.cwd | split(\"/\") | last) + \"\\n\\n\" + ((.last_assistant_message // \"\")[:300])' | curl -s -m 10 --data-binary @- https://push.tg/k3x9q >/dev/null",
"async": true
}
]
}
],
"Notification": [
{
"matcher": "permission_prompt|idle_prompt",
"hooks": [
{
"type": "command",
"command": "jq -r '\"⏳ Claude Code: \" + (.message // \"needs your attention\") + \" (\" + (.cwd | split(\"/\") | last) + \")\"' | curl -s -m 10 --data-binary @- https://push.tg/k3x9q >/dev/null",
"async": true
}
]
}
]
}
}"async": true runs the hook in the background, so Claude never waits on the network. >/dev/null keeps push.tg's reply out of Claude Code's hook output parser. For a deeper walkthrough, see the Claude Code page in the list below.
OpenAI Codex CLI
Codex works differently. Its notify setting runs a program and passes the event as one JSON argument (not stdin), with kebab-case fields: type (agent-turn-complete), cwd, last-assistant-message, thread-id, turn-id. Put this line in ~/.codex/config.toml, at the top of the file, above any [section]:
notify = ["sh", "-c", "printf '%s' \"$1\" | jq -r '\"✅ Codex finished: \" + (.cwd | split(\"/\") | last) + \"\\n\\n\" + ((.\"last-assistant-message\" // \"turn complete\")[:300])' | curl -s -m 10 --data-binary @- https://push.tg/k3x9q >/dev/null", "pushtg"]
The trailing "pushtg" becomes $0, so the JSON lands in $1. notify only fires on turn completion. Codex's [tui] notifications = ["agent-turn-complete", "approval-requested"] covers approval prompts, but those are desktop/terminal notifications, not Telegram. notify is read from your user-level config only.
Cursor
Cursor hooks live in ~/.cursor/hooks.json. User hooks run from ~/.cursor/, get JSON on stdin, and the stop event includes status (completed, aborted or error):
{
"version": 1,
"hooks": {
"stop": [
{
"command": "./hooks/pushtg-stop.sh"
}
]
}
}#!/bin/bash
# ~/.cursor/hooks/pushtg-stop.sh
status=$(jq -r '.status // "done"')
project=$(basename "${CURSOR_PROJECT_DIR:-$PWD}")
printf 'Cursor agent %s: %s' "$status" "$project" \
| curl -s -m 10 --data-binary @- https://push.tg/k3x9q >/dev/null
echo '{}'Run chmod +x ~/.cursor/hooks/pushtg-stop.sh. Cursor reloads hooks.json on save. The Hooks output channel shows errors. Cursor can also load Claude Code hooks, so if you set up both you may get two messages. Keep one.
Tips
- Use one address per machine or project, so you can see at a glance which agent finished.
- Add @trafficRobot to a team group and point everyone's hooks at the group address.
- The examples cut the agent's reply to 300 characters. Raise or drop the
[:300]to taste.
Check that the message really arrived. push.tg answers HTTP 200 even when the key is wrong. The body says {"error":"no such user"} instead of {"ok":...}. So a green "test sent" in your tool doesn't prove delivery. Look at Telegram.
More copy-paste guides
- Claude Code Telegram Notification Hook
- Uptime Kuma Telegram Alerts Without a Bot Token
- Healthchecks.io Alerts to Telegram
- Proxmox Notifications to Telegram with a Webhook Target
- Home Assistant Telegram Notification Without a Bot
- n8n Error Workflow: Telegram Alert When a Workflow Fails
- Grafana Alerts to Telegram with a Custom Webhook Payload
- Cron Job Failure Alert to Telegram (cron and systemd)
- GitHub Actions and GitLab CI Telegram Notification in One Line
- Synology NAS Email Alerts to Telegram
- Nagios Alerts to Telegram with curl
- Python: Get a Telegram Notification When Training Finishes
- How to Receive Email in Telegram Without Giving Out Your Real Address
- Send Server Alerts to Telegram with One curl Command
Get your endpoint: t.me/trafficRobot?start=tg-ai-agents. It takes 30 seconds, it has no ads, and it has been running since 2016.