Para receber notificações push do Claude Code com ntfy, instale o app do ntfy no celular, assine um tópico com um nome difícil de adivinhar e adicione um hook do Claude Code que execute curl -d "message" https://ntfy.sh/your-topic. Um hook Notification avisa quando o Claude precisa de uma permissão ou está esperando por você, e um hook Stop avisa assim que um turno termina. É gratuito, leva uns dez minutos e funciona no Mac, Windows e Linux.
01Passo 1: escolha um tópico e assine
O ntfy não exige cadastro. Um tópico é criado na primeira vez que alguém publica ou se inscreve nele, e qualquer pessoa que saiba o nome pode lê-lo. A própria documentação do ntfy diz que o tópico funciona basicamente como uma senha, então use um nome longo e aleatório, por exemplo claude-7f3k9q2xw4mz. Nomes de tópico podem ter letras, números, underscores e hífens, com até 64 caracteres.
Instale o app do ntfy (App Store, Google Play ou F-Droid), toque em + e assine seu tópico em ntfy.sh.
Teste pelo terminal:
curl -H "Title: Test" -d "Hello from my computer" https://ntfy.sh/claude-7f3k9q2xw4mz
O celular deve vibrar em um ou dois segundos. No Windows, o curl.exe já vem com o Windows 10 e 11 e aceita o mesmo comando.
02Passo 2: um script de hook (Mac e Linux)
O Claude Code passa a cada hook um objeto JSON pela entrada padrão. Os dois eventos compartilham campos como cwd e hook_event_name. O Notification adiciona message e notification_type, e o Stop adiciona last_assistant_message, o texto da resposta final do Claude. Este script transforma qualquer um deles em um push legível. Ele precisa do jq (brew install jq, ou apt install jq no Debian e Ubuntu).
Salve como ~/.claude/ntfy-notify.sh e execute chmod +x ~/.claude/ntfy-notify.sh:
#!/bin/sh
TOPIC_URL="https://ntfy.sh/claude-7f3k9q2xw4mz"
input=$(cat)
event=$(printf '%s' "$input" | jq -r '.hook_event_name')
project=$(basename "$(printf '%s' "$input" | jq -r '.cwd')")
if [ "$event" = "Stop" ]; then
title="Claude finished: $project"
body=$(printf '%s' "$input" | jq -r '(.last_assistant_message // "Done") | .[0:300]')
priority=3
else
title="Claude needs you: $project"
body=$(printf '%s' "$input" | jq -r '.message // "Needs your attention"')
priority=4
fi
curl -s -H "Title: $title" -H "Priority: $priority" -H "Tags: robot" \
-d "$body" "$TOPIC_URL" > /dev/null
exit 0
A prioridade vai de 1 (mínima) a 5 (urgente). Tags adiciona um emoji à notificação; robot mostra uma carinha de robô.
03Passo 3: configure no settings.json
Adicione os hooks em ~/.claude/settings.json. Se o arquivo já tiver um objeto hooks, coloque estes eventos dentro dele em vez de substituí-lo.
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{ "type": "command", "command": "~/.claude/ntfy-notify.sh" }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "~/.claude/ntfy-notify.sh", "async": true }
]
}
]
}
}
"async": true faz o hook Stop enviar em segundo plano, então uma rede lenta nunca atrasa o Claude. Inicie uma nova sessão do Claude Code, porque os hooks são carregados quando a sessão começa.
Stop ou idle_prompt?
O Stop dispara assim que o Claude termina, mesmo que você esteja no teclado. Se isso for demais, remova o bloco Stop e use o matcher permission_prompt|idle_prompt. A documentação da Anthropic diz que o idle_prompt dispara cerca de 60 segundos depois que o Claude termina, só se você não tiver digitado nada desde então, e o permission_prompt dispara quando um pedido de permissão fica uns seis segundos sem nenhuma tecla pressionada. Isso já te dá, de graça, um filtro aproximado de "só quando eu não estiver aqui". O guia do Notification hook e o guia do Stop hook explicam todos os campos e tempos.
04Windows (PowerShell)
No Windows, salve isto como %USERPROFILE%\.claude\ntfy-notify.ps1. Não precisa instalar nada extra:
$in = [Console]::In.ReadToEnd() | ConvertFrom-Json
$project = Split-Path $in.cwd -Leaf
if ($in.hook_event_name -eq 'Stop') {
$title = "Claude finished: $project"
$body = [string]$in.last_assistant_message
if ($body.Length -gt 300) { $body = $body.Substring(0, 300) }
$priority = '3'
} else {
$title = "Claude needs you: $project"
$body = [string]$in.message
$priority = '4'
}
Invoke-RestMethod -Method Post -Uri 'https://ntfy.sh/claude-7f3k9q2xw4mz' `
-Headers @{ Title = $title; Priority = $priority } `
-Body ([Text.Encoding]::UTF8.GetBytes($body)) | Out-Null
Depois use esta entrada de hook no lugar das linhas command acima:
{
"type": "command",
"shell": "powershell",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"$HOME\\.claude\\ntfy-notify.ps1\""
}
Se você roda o Claude Code dentro do WSL, use o script de Mac e Linux; para o hook, o WSL é Linux.
05Mantendo a privacidade
Tudo no push passa pelo servidor do ntfy, e no ntfy.sh qualquer pessoa com o nome do tópico pode lê-lo. A mensagem do Stop acima inclui o início da resposta do Claude, que pode conter código ou nomes de arquivos. Três formas de reforçar isso:
- Envie menos. Troque o corpo do
Stoppor um texto fixo como"Done"e deixe só o nome do projeto no título. - Use um token de acesso. O ntfy aceita
-H "Authorization: Bearer tk_..."em qualquer publicação. No seu próprio servidor, definaauth-default-access: "deny-all", crie um usuário comntfy user adde um token comntfy token add. - Hospede seu próprio servidor. O ntfy pode ser auto-hospedado. Para entrega instantânea no app do iPhone, a documentação do ntfy recomenda definir
upstream-base-url: "https://ntfy.sh", que encaminha só um ID de mensagem e um hash do tópico para o ntfy.sh para acordar o celular; o app então busca a mensagem no seu servidor.
Se o Claude Code roda em um servidor remoto, o mesmo hook funciona lá sem mudanças, o que faz do ntfy uma boa opção para notificações via SSH.
06Onde o Claude Code Notifier se encaixa
Para alertas de mão única, a configuração acima resolve tudo e não vamos tentar te convencer do contrário. Ela só avisa, porém. Quando o push diz que o Claude precisa de uma permissão, a sessão continua esperando até você voltar ao teclado.
O ntfy suporta botões de ação que fazem uma requisição HTTP, então dá para montar um caminho de resposta você mesmo: um hook PermissionRequest que publica o pedido, espera uma resposta em um segundo tópico e retorna uma decisão. Alguns projetos open source fazem exatamente isso (veja a comparação).
O Claude Code Notifier já entrega esse caminho pronto. Com um celular pareado, você pode permitir uma vez, permitir para a sessão ou negar uma permissão, escolher uma resposta quando o Claude faz uma pergunta e enviar a próxima instrução depois que o Claude termina, tudo pelo celular. Ele também detecta sua presença: se você digitou nos últimos 30 segundos, o terminal pergunta normalmente e nada fica esperando no celular. Se você estiver ausente, o terminal espera sua resposta até um limite que você define e para de esperar assim que você toca no teclado. O ccn roda no Mac, Windows e Linux; veja a página do ccn e os preços dos apps de celular.
07Perguntas frequentes
O ntfy é gratuito para notificações do Claude Code?
Publicar e assinar no ntfy.sh não exige conta, e o servidor é aberto a qualquer um. O ntfy também tem um plano pago e pode ser auto-hospedado. Consulte o site do ntfy para ver os limites atuais.
Por que meu hook do ntfy não dispara?
Inicie uma nova sessão do Claude Code depois de editar o settings.json, já que os hooks são carregados na inicialização. Depois rode a linha de teste do curl manualmente e passe um JSON de exemplo para o script, por exemplo echo '{"hook_event_name":"Stop","cwd":"/tmp/x"}' | ~/.claude/ntfy-notify.sh. O checklist de solução de problemas cobre o resto.
Posso responder ao Claude Code por uma notificação do ntfy?
Não com uma publicação simples. Os botões de ação HTTP do ntfy conseguem enviar uma requisição, mas você precisa de um hook que espere a resposta e a transforme em uma decisão que o Claude Code entenda.
Recebo um push para todo tipo de notificação?
Só para os matchers que você listar. Omita o matcher na entrada Notification para receber todos os tipos, incluindo diálogos de autenticação e de MCP.