AI Agent Notifications
Your AI agents work in the background. syncfu gives them a voice.
The problem with silent agents
Claude Code rewrites a module, runs tests, and finishes — while you are reading Hacker News in another tab. Cursor spawns an agent that refactors three files — you miss it and accept a stale PR diff. A CrewAI workflow hits a decision point that needs human judgement — and hangs indefinitely because there is no way to surface it.
AI coding agents are productive precisely because they run autonomously, but that same autonomy makes them invisible. You end up in a loop: Alt-Tab, check terminal, nothing yet — Alt-Tab, check terminal, it finished five minutes ago. Worse, for destructive actions like git push --force or dropping a database table, there is no safe way to require approval without watching the terminal the entire time.
How syncfu solves it
syncfu adds a thin notification layer between your agent and your attention. Three patterns cover most workflows:
- Task completion alerts. When an agent finishes a task, one syncfu call pops a persistent overlay on your screen — on any monitor, above all other windows — so you know immediately without polling.
- Decision gates with
--wait. The agent needs your approval before continuing. syncfu sends a notification with Approve / Reject buttons and blocks until you click one. The chosen action flows back to the script as an exit code and stdout value. - Live progress bars. For long multi-step workflows, the agent updates a single persistent notification with a progress percentage so you can see where it is at a glance.
Claude Code integration
Claude Code supports lifecycle hooks in .claude/settings.json. A PostToolUse hook fires after every tool call; Stop fires when the session ends. Add both to get desktop notifications for every significant event:
// .claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "syncfu send -t 'Claude finished a task' -p normal 'Bash tool call complete'"
}
]
},
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "syncfu send -t 'File edited' -p low 'Claude wrote or edited a file'"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "syncfu send -t 'Claude Code session complete' -p high --action 'open:Open project:primary' 'Agent has finished working'"
}
]
}
]
}
}For a HITL gate — for example, before Claude runs a destructive command — use a PreToolUse hook with --wait:
# In a wrapper script called by PreToolUse syncfu send \ -t "Claude wants to run a shell command" \ -p critical \ --wait \ --action "allow:Allow:success" \ --action "deny:Deny:danger" \ "$TOOL_INPUT" # Exit code 0 = Allow, exit code 1 = Deny # Claude Code interprets a non-zero hook exit as "block this tool call"
Cursor integration
Cursor does not expose native lifecycle hooks, but you can wrap agent invocations in a shell script. Add a .cursor/run-agent.sh that calls syncfu before and after the agent:
#!/usr/bin/env bash # .cursor/run-agent.sh # Notify: agent starting syncfu send -t "Cursor agent started" -p low "Running: $*" # Run the actual agent command "$@" EXIT=$? # Notify: agent done with status if [ $EXIT -eq 0 ]; then syncfu send -t "Cursor agent complete" -p normal --action "view:View changes:primary" "Finished successfully" else syncfu send -t "Cursor agent failed" -p high "Exit code $EXIT" fi exit $EXIT
Multi-agent workflows with decision gates
In orchestrated agent systems (CrewAI, LangGraph, custom pipelines), syncfu acts as the human-in-the-loop layer between autonomous steps. The --wait flag turns any notification into a blocking checkpoint:
#!/usr/bin/env bash # Multi-agent pipeline with syncfu HITL gates # Step 1: Research agent runs autonomously run_research_agent syncfu send -t "Research complete" -p normal "Agent collected 12 sources" # Step 2: Gate — should we proceed to the write step? syncfu send \ -t "Proceed to draft?" \ -p high \ --wait \ --action "yes:Write draft:primary" \ --action "no:Stop here:secondary" \ "Research phase finished. Ready to generate the first draft." if [ $? -ne 0 ]; then echo "User chose to stop. Exiting." exit 0 fi # Step 3: Writing agent — show progress NOTIF_ID=$(syncfu send -t "Writing draft…" -p normal --progress 0 "Starting draft generation" --json | jq -r .id) run_writing_agent --on-progress "syncfu update $NOTIF_ID --progress" # Step 4: Final approval before publishing syncfu send \ -t "Draft ready — publish?" \ -p critical \ --wait \ --action "publish:Publish:success" \ --action "review:Review first:warning" \ --action "discard:Discard:danger" \ "The draft is complete. Choose an action." case $? in 0) publish_content ;; 1) open_editor_for_review ;; 2) echo "Draft discarded." ;; esac
The same pattern works from Python using the HTTP API at http://localhost:9868:
import requests
# Send a blocking decision gate from Python
resp = requests.post("http://localhost:9868/notify", json={
"title": "Deploy to production?",
"body": f"Build {build_id} passed all tests.",
"priority": "critical",
"actions": [
{"id": "deploy", "label": "Deploy", "style": "success"},
{"id": "cancel", "label": "Cancel", "style": "danger"},
],
})
notif_id = resp.json()["id"]
# Block until the user clicks
result = requests.get(f"http://localhost:9868/notify/{notif_id}/wait").json()
if result["actionId"] == "deploy":
trigger_deploy(build_id)
else:
print("Deploy cancelled by user.")Why not just use system notifications?
macOS and Windows system notifications disappear after a few seconds and carry no interactive buttons beyond “dismiss”. They cannot block a calling process, they cannot update in place with a progress value, and they offer no way to return a decision to the script that sent them. syncfu is built specifically to fill these gaps for developer and agent workflows.
Decision gates
Block an agent mid-task and ask for approval before proceeding. The --wait flag pauses execution; the clicked action returns to the script as an exit code and stdout value.
Task completion
Fire a PostToolUse or Stop hook in Claude Code, Cursor, or any agent runner. A persistent desktop overlay tells you exactly what finished — no terminal polling needed.
Error alerts
Catch agent failures the moment they happen. Send a high-priority notification with the error message and an “Open logs” action button so you can jump straight to the problem.
Progress tracking
For multi-step pipelines, update a single notification with a progress value from 0–100. The overlay shows an animated bar so you always know how far along the agent is.
Frequently asked questions
How do I get notifications from Claude Code?
Add a PostToolUse hook to your Claude Code settings.json that calls syncfu send. Every time Claude finishes a tool call, the hook fires and a desktop overlay appears. You can also use a Stop hook to alert you when the entire session completes.
Does syncfu work with any AI agent?
Yes. syncfu exposes a CLI (syncfu send) and a local HTTP API on port 9868. Any agent, script, or automation that can run a shell command or make an HTTP request — Claude Code, Cursor, Copilot, CrewAI, LangGraph, AutoGPT, custom Python scripts — can send notifications.
What is human-in-the-loop with syncfu?
Human-in-the-loop (HITL) means an AI agent pauses and asks you to make a decision before continuing. With syncfu, the --wait flag blocks the calling process until you click an action button on the overlay. The chosen action ID is printed to stdout and the exit code reflects your choice, so the agent script can branch accordingly.
Can an agent actually wait for my response before continuing?
Yes. Pass --wait to syncfu send and the CLI will block until you click an action button or dismiss the overlay. The exit code is 0 for the first action, 1 for the second, 2 for the third, and the action ID is printed to stdout. You can also poll GET /notify/{id}/wait on the HTTP API from any language.
Can I track progress of a long agent task?
Yes. Send an initial notification, then POST to /notify/{id}/update with a progress value between 0 and 100. The overlay updates in real time with an animated progress bar. This works well for multi-step agent workflows where you want a visual indicator of how far along the task is.
Related
- Claude Code integration guide — step-by-step hook setup
- API reference — full payload schema, CLI flags, and exit codes
- Replace SaaS with AI agents — tools your agent no longer needs
Give your agents a voice
Open source, no account needed. Install in 30 seconds and wire syncfu into your first AI agent workflow today.
Get started →