Notificationsfrom a remoteagent

Get notified when Claude Code needs you on a remote machine

If you connect with Kitty or Ghostty, you may already have it: Claude Code's built-in desktop notification travels back over SSH and shows up in your computer's notification center, as long as tmux isn't swallowing it. For other terminals, or for your phone, add a Claude Code Notification hook on the server that runs a command, for example a curl to ntfy. Zydra does both from one place: notifications from the VM reach your terminal and, once you pair a phone, arrive there as push notifications.

When does Claude Code send a notification?

Claude Code fires a notification event when it finishes a task or stops at a permission prompt and you appear to be away from the terminal. "Away" is measured by typing. A permission prompt notifies after you haven't typed for about six seconds. A finished turn notifies about 60 seconds later if you haven't typed since and no background subagent is still running.

What you then see depends on the terminal on your end, not on the server.

Which terminals show it over SSH?

Anthropic's terminal docs list the defaults:

  • Ghostty and Kitty show a desktop notification, including from a remote session, with no setup.
  • iTerm2 shows it after you turn on Settings, Profiles, Terminal, "Notification Center Alerts", then Filter Alerts and "Send escape sequence-generated alerts".
  • Apple Terminal gets a silent bell, depending on the profile's bell settings.
  • Other terminals get nothing.

If nothing arrives in a terminal that should work, check that the terminal app has notification permission in your OS settings.

How do I make it work inside tmux?

tmux sits between Claude Code and your terminal and drops escape sequences it doesn't know. Let them through by adding this line to ~/.tmux.conf on the server:

set -g allow-passthrough on

Reload with tmux source-file ~/.tmux.conf. Claude Code's docs also suggest set -g focus-events on in the same file.

What if my terminal shows nothing?

Make Claude Code ring the terminal bell instead. In ~/.claude/settings.json on the server:

{
  "preferredNotifChannel": "terminal_bell"
}

Most terminals can turn a bell into a sound, a flashing tab or a dock bounce.

How do I get Claude Code notifications on my phone?

Use a hook. Hooks are shell commands that Claude Code runs on events, configured in ~/.claude/settings.json for all projects, or .claude/settings.json for one. The Notification event passes a JSON object on standard input with message, title and notification_type fields.

ntfy is a free push service with Android and iOS apps. Install the app, subscribe to a topic name nobody can guess, and add this hook on the server:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r .message | curl -s -H 'Title: Claude Code' -d @- ntfy.sh/your-long-random-topic"
          }
        ]
      }
    ]
  }
}

The command needs jq on the server. An empty matcher fires on every notification type. To be told only about permission prompts, set it to permission_prompt. To hear the moment Claude stops, whether or not you are away, use the Stop event instead, which fires every time Claude finishes responding.

Treat the topic like a password. ntfy's docs are blunt that topics on ntfy.sh are public, so anyone who knows the name can read your messages. For anything private, use access tokens or run your own ntfy server.

What about notify-send?

Anthropic's hook guide shows notify-send for Linux. It needs a desktop notification daemon, and the guide notes that headless servers, SSH sessions and most containers don't have one. On a plain VPS the message has nowhere to go, which is why ntfy or the terminal route is the usual answer there.

Other tools that help

  • cmux, a free macOS terminal for coding agents, picks up OSC 9, 99 and 777 notifications and has a cmux notify command for hooks. Panes get a coloured ring when an agent needs you.
  • herdr, a free open-source agent terminal manager, marks every pane as working, blocked or idle, so you can see at a glance which agent waits.
  • Remote Control (claude --remote-control) puts the session in the Claude app, which helps if you already check your phone there.

How Zydra handles notifications

Zydra runs the agent in your own VM, with a Linux desktop drawn in your terminal. The desktop runs a notification server, so notify-send works there, and programs that print notification escape sequences (OSC 9, 99 or 777) work too. Zydra sends each notification to your terminal in the form it understands. A terminal with no notification support gets a bell instead of nothing.

Claude Code comes with Zydra's desktop plugin installed, and its instructions tell the agent to call a notify tool when a long task finishes, fails or needs an answer. If you want Claude Code's own events as well, add the notify-send hook from Anthropic's Linux guide inside Zydra:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          { "type": "command", "command": "notify-send 'Claude Code' 'Claude Code needs your attention'" }
        ]
      }
    ]
  }
}

Pair your phone from the desktop's menu and turn on notifications in the phone view. When the phone view isn't open, Zydra sends the VM's notifications as Web Push messages, encrypted end to end so the push service sees only ciphertext. On an iPhone or iPad, add the page to your Home Screen first; iOS only delivers web push to Home Screen apps.

Every notification also becomes a marker on the timeline, so you can scrub back to the moment the agent asked.

Try it

Run ssh zydra.sh in Kitty or Ghostty. The demo is free for 15 minutes, needs no sign-up, and passes notifications through like the paid plan.

Related: Using Claude Code from your phone and Running Claude Code on a remote server. Or browse all articles.

ArticlesDiscordCreditsOptimizing SSH