Currently Available: Need a skilled Software Developer for your next project?
Categories
Coding Agents

How to Get Notified When Claude Code Finishes a Task or Needs Input With Hooks

When Claude Code runs in a terminal, you may want an alert when it finishes a response or pauses for your approval. A hook is a command you configure to run when a specific Claude Code event occurs. Use the Stop hook for a finished response and the Notification hook for selected prompts, such as permission requests.

The alerts report different events: Stop means Claude Code finished a response, while a Notification alert means it is waiting for input. The distinction matters because a finished response does not necessarily mean a larger, multi-step task is complete.

Use Stop for finished responses and Notification for prompts

Claude Code runs a Stop hook when its main agent finishes responding. That gives you a direct alert at the end of a response. The hook does not run when you interrupt Claude, and API errors have a separate StopFailure event, as described in the hooks reference.

A Notification hook runs when Claude Code emits a notification. Use a matcher, a label that selects which notification type triggers the hook, to choose the events you care about. For example, permission_prompt signals that Claude is waiting for approval to use a tool. The elicitation_dialog and elicitation_url_dialog matchers cover input requests from an MCP server. MCP, or Model Context Protocol, is a standard that lets Claude Code connect to external tools and services.

Avoid an empty Notification matcher if you only want input alerts. An empty matcher catches every notification type, including events unrelated to a permission or input request. The hooks guide describes the available notification matchers and their behavior.

Add macOS notifications to your settings

Add the following entries inside the hooks object in ~/.claude/settings.json. This user-level settings file applies to your Claude Code sessions on the local machine. If the file already contains hooks, merge these entries into its existing hooks object rather than replacing it.

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude finished responding\" with title \"Claude Code\"'"
          }
        ]
      }
    ],
    "Notification": [
      {
        "matcher": "permission_prompt",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude is waiting for permission\" with title \"Claude Code\"'"
          }
        ]
      },
      {
        "matcher": "elicitation_dialog",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"An MCP server needs your input\" with title \"Claude Code\"'"
          }
        ]
      },
      {
        "matcher": "elicitation_url_dialog",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"An MCP server needs you to open a URL\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

The settings file must contain valid JSON, which means no comments or trailing commas. You can also store shared project settings in .claude/settings.json; the settings documentation explains the available scopes.

On another operating system, replace the osascript command with a notification command that works in your environment. Anthropic’s guide shows notify-send for Linux, which requires a working desktop notification service. Linux notifications generally do not appear on servers without a desktop (headless servers), in SSH sessions, or in most containers. Anthropic’s Windows example opens a PowerShell dialog rather than a toast, and that dialog may appear behind the terminal. Test the operating-system command directly before troubleshooting the hook.

Check the hooks and test the alert

After saving the settings, run /hooks at the Claude Code prompt and confirm that the entries appear under Stop and Notification. Then run each notification command directly in your terminal. If the command does not display an alert by itself, fix that before testing the hook.

Next, trigger a permission request or an MCP input request. On macOS, a notification can fail silently if Script Editor does not have permission to show notifications, so check macOS notification settings if the command runs without a visible alert. Claude Code hooks run even when Claude Code’s own desktop notifications are turned off; that setting affects Claude Code’s alert channel, not whether the hook runs.

Account for delays and duplicate alerts

A permission notification generally appears after about six seconds without typing in a terminal session. In sessions hosted through the Agent SDK, including Claude Desktop and the VS Code extension, the notification is expected after about six seconds whether or not you type. MCP input notifications also wait until you have been inactive for that long.

Claude Code’s idle_prompt notification arrives about 60 seconds after a response if you have not typed and no background agent is still running. Because Stop already alerts when a response ends, adding idle_prompt can produce a second alert for the same response.

A Stop alert signals that Claude finished responding. The requested work may still be incomplete. Claude Code’s TaskCompleted event applies to tasks marked complete using its task features, and its scope excludes some ordinary user requests. Whether a permission alert fires also depends on where Claude Code runs and which version you use: the current hooks reference notes that permission_prompt did not fire in Agent SDK-hosted sessions before Claude Code v2.1.233.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *