# Claude Code hooks nasıl kullanılır: örneklerle rehber

Adres: https://agentvera.dev/blog/claude-code-hooks-rehberi/ · Yayın: 2026-10-23

Claude Code hooks nasıl kullanılır? Olaylar, settings.json, matcher, çıkış kodları ve JSON çıktısı; dosya biçimleyen, riskli komutu engelleyen ve haber veren örnekler.

**Kısaca:**

- Hook’lar settings.json içindeki hooks anahtarına yazılır ve olay her tetiklendiğinde çalışır, çünkü onları model değil Claude Code çalıştırır.
- Bir araç çağrısını engellemek için PreToolUse hook’u 2 koduyla çıkar ya da permissionDecision değeri deny olan JSON döner; 1 koduyla çıkmak hiçbir şeyi engellemez.
- Deny dönen hook --dangerously-skip-permissions altında bile çağrıyı engeller, ama hook’lar sandbox değildir ve senin kullanıcı yetkilerinle çalışır.

Claude Code hooks, Claude Code’un oturumun belli anlarında kendiliğinden çalıştırdığı komutlardır: bir araç çağrısından önce, dosya düzenlendikten sonra, prompt gönderildiğinde, Claude durduğunda ya da senden yanıt beklediğinde. Hepsini `settings.json` içindeki `hooks` anahtarına yazarsın. Bir hook bağlam ekleyebilir, dosyayı biçimleyebilir ya da 2 koduyla çıkarak veya JSON kararı dönerek bir işlemi engelleyebilir. `CLAUDE.md`’deki talimatlardan farkı şu: hook’u model değil, Claude Code’un kendisi çalıştırır, yani her seferinde çalışır.

Bu rehberde işe yarayan olayları, ayar biçimini, matcher’ları, çıkış kodlarını ve JSON çıktısını, hemen kopyalayabileceğin üç hook’u ve eklemeden önce bilmen gereken güvenlik notlarını bulacaksın. Bilgiler resmi [hooks referansından](https://code.claude.com/docs/en/hooks "Claude Code hooks referansı") ve [hooks rehberinden](https://code.claude.com/docs/en/hooks-guide "Claude Code hooks rehberi") geliyor. Kısa tanım için [sözlükteki Claude Code hooks maddesine](/sozluk/claude-code-hooks/ "Claude Code hooks") bakabilirsin.

## Neden talimat değil de hook?

`CLAUDE.md`’ye “her düzenlemeden sonra Prettier çalıştır” yazabilirsin, Claude da çoğu zaman bunu yapar. Sorun “çoğu zaman” kısmında. Talimat, modelin bağlamdaki her şeyle birlikte tarttığı bir öneridir. Hook ise olay her tetiklendiğinde çalışan koddur.

Bu yüzden hook’lar üç tür kural için doğru araç:

- **Her zaman olması gerekenler:** biçimleme, lint, loglama.
- **Asla olmaması gerekenler:** `.env` dosyasını düzenlemek ya da yanlış klasörde `rm -rf` çalıştırmak.
- **Haberdar olmak istediklerin:** sen başka penceredeyken Claude’un izin yanıtı beklemesi gibi.

Üslup tercihlerini ve proje bilgisini [CLAUDE.md](/blog/claude-md-nasil-yazilir/ "CLAUDE.md nasıl yazılır") dosyasında tut, kesin kuralları hook’a taşı.

## Gerçekten kullanacağın hook olayları

Referansta otuzdan fazla olay var ve her sürümle liste uzuyor. Çoğu kurulumda birkaçı yeter:

| Olay | Ne zaman çalışır | Engelleyebilir mi? |
| --- | --- | --- |
| `PreToolUse` | Araç çağrısı çalışmadan önce | Evet, çağrıyı engeller |
| `PostToolUse` | Araç çağrısı başarıyla bittikten sonra | Hayır, araç zaten çalıştı; stderr Claude’a gider |
| `UserPromptSubmit` | Prompt gönderdiğinde | Evet, prompt Claude’a hiç ulaşmaz |
| `Notification` | Claude Code bildirim gönderdiğinde (izin sorusu, boşta bekleme) | Hayır |
| `Stop` | Claude yanıtını bitirdiğinde | Evet, Claude çalışmaya devam eder |
| `SubagentStart` / `SubagentStop` | Bir alt ajan başladığında veya bittiğinde | Sadece `SubagentStop` |
| `SessionStart` | Açılışta, devam ederken, `/clear` veya sıkıştırma sonrası | Hayır, ama stdout bağlama eklenir |
| `PreCompact` | Bağlam sıkıştırılmadan önce | Evet, sıkıştırmayı engeller |
| `PermissionRequest` | İzin penceresi açılmak üzereyken | Sadece JSON ile, 2 koduyla değil |
| `SessionEnd` | Oturum bittiğinde | Hayır |

İhtiyaçların çoğunu `PreToolUse` ve `PostToolUse` karşılar. “İş bitince ya da takılınca bana haber ver” için `Notification` ve `Stop` var.

## settings.json’da hook ayarı

Hook’lar izinlerle aynı ayar dosyalarında durur:

| Dosya | Kapsam | Git ile paylaşılır mı? |
| --- | --- | --- |
| `~/.claude/settings.json` | Tüm projelerin | Hayır |
| `.claude/settings.json` | Tek proje | Evet |
| `.claude/settings.local.json` | Tek proje, sadece sen | Hayır (gitignore’da) |
| Yönetilen politika ayarları | Tüm kurum | Yöneticiler belirler |

Plugin’ler hook’ları `hooks/hooks.json` içinde getirebilir; skill’ler ve alt ajanlar da frontmatter’larında hook tanımlayabilir.

Yapı üç katmanlı: olay, bir matcher grubu ve handler listesi.

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write",
            "timeout": 30
          }
        ]
      }
    ]
  }
}
```

Handler’ın `type` alanı `command` (kabuk komutu), `http` (bir adrese POST), `mcp_tool` (bağlı bir MCP sunucusundaki araç), `prompt` (bir modelin hızlı evet/hayır kontrolü) veya `agent` (deneysel alt ajan kontrolü) olabilir. Varsayılan zaman aşımı command, HTTP ve MCP aracı için 600 saniye, prompt hook’ları için 30, agent hook’ları için 60 saniye.

Her hook stdin’den JSON alır. Ortak alanlar `session_id`, `transcript_path`, `cwd`, `permission_mode` ve `hook_event_name`. Araç olaylarında `tool_name`, `tool_input` ve `tool_use_id` da gelir. Script’in bu JSON’u genelde `jq` ile okuyup karar verir. `CLAUDE_PROJECT_DIR` ortam değişkeni proje kökünü gösterir, depodaki script’leri çağırırken çok işe yarar.

Claude Code içinde `/hooks` yazarak yüklü hook’ları ve her birinin hangi dosyadan geldiğini görebilirsin. Bu ekran sadece okunur; değiştirmek için JSON’u düzenlersin.

## Matcher: hook hangi çağrıları görür

`matcher`, hangi çağrıların hook’u tetikleyeceğini belirler. Araç olaylarında araç adıyla eşleşir:

| Matcher | Anlamı |
| --- | --- |
| `"*"`, `""` veya hiç yok | Tüm çağrılar |
| `"Bash"` | Sadece Bash aracı |
| `"Edit\|Write"` | Edit veya Write (liste) |
| `"mcp__memory__.*"` | `memory` MCP sunucusunun tüm araçları |
| `"mcp__.*__write.*"` | Adı `write` ile başlayan her MCP aracı |

Kural basit: matcher’da sadece harf, rakam, `_`, `-`, boşluk, virgül veya `|` varsa birebir ad ya da ad listesi sayılır. Başka herhangi bir karakter onu JavaScript düzenli ifadesine çevirir. MCP araçlarının adı `mcp__<sunucu>__<araç>` biçimindedir.

`UserPromptSubmit` ve `Stop` gibi bazı olaylar matcher’ı yok sayar, çünkü eşleşecek bir şey yoktur. Bazıları da araç adı yerine başka bir şeye bakar. `SessionStart` oturumun nasıl başladığıyla (`startup`, `resume`, `clear`, `compact`), `Notification` ise bildirim türüyle (`permission_prompt`, `idle_prompt` gibi) eşleşir.

Araç olayları izin kuralı sözdizimiyle bir `if` alanı da alır; örneğin Bash hook’u sadece `"Bash(git *)"` için çalışabilir. Dokümanlar bunu “elden geldiğince” çalışan bir filtre olarak tanımlıyor, asıl kontrolü script’inde tut.

## Çıkış kodları ve JSON çıktısı

Komut hook’u Claude Code’a iki yolla yanıt verir: çıkış kodu ve isteğe bağlı stdout JSON’u.

| Çıkış kodu | Ne olur |
| --- | --- |
| `0` | Başarılı. stdout tek bir JSON nesnesiyse JSON olarak okunur. `UserPromptSubmit` ve `SessionStart`’ta düz metin Claude’un bağlamına eklenir. |
| `2` | Engelleyen hata. Neden stderr’dir. `PreToolUse`’ta çağrı iptal olur, `UserPromptSubmit`’te prompt reddedilir, `Stop`’ta Claude devam eder. |
| Diğerleri, `1` dahil | Engellemeyen hata. Claude Code not alır ve devam eder. |

Asıl tuzak 1 kodu. Çoğu script hata olunca 1 ile çıkar ve bu hiçbir şeyi **engellemez**. “Dur” demek istiyorsan 2 ile çık.

Daha ince kontrol için 0 ile çık ve JSON bas. `PreToolUse` hook’u izin verebilir, reddedebilir ya da sorabilir:

```json
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Use rg instead of grep for better performance"
  }
}
```

`permissionDecision` alanı `allow`, `deny`, `ask` veya `defer` alır. Hook, `updatedInput` ile çağrıyı değiştirebilir ya da `additionalContext` ile Claude’a ek metin verebilir. Her olayda çalışan alanlar da var: `continue: false` Claude’u tamamen durdurur (`stopReason` ile birlikte), `systemMessage` sana bir uyarı gösterir.

Birden fazla hook eşleşirse paralel çalışırlar ve en kısıtlayıcı yanıt kazanır: deny, defer’i; defer, ask’i; ask da allow’u geçer. Hook’tan gelen `allow`, izinlerindeki bir deny kuralını aşmaz.

## Örnek 1: her düzenlemeden sonra dosyayı biçimle

Çoğu kişinin ilk hook’u budur. Claude’un yazdığı ya da düzenlediği her dosyada Prettier çalıştırır:

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
          }
        ]
      }
    ]
  }
}
```

Başka diller için `ruff format`, `gofmt -w` veya `rustfmt` koyabilirsin. Biçimleyici düzenlemeden sonra çalıştığı için Claude dosyayı bir sonraki okuyuşunda biçimli hâlini görür, sen de incelemede sadece boşluk değişen diff’lerden kurtulursun.

## Örnek 2: tehlikeli komutları ve korumalı dosyaları engelle

Kesin sınırların yeri `PreToolUse`. Resmi rehberden uyarlanan bu script hassas dosyaların düzenlenmesini engeller. `.claude/hooks/protect-files.sh` olarak kaydet:

```bash
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

PROTECTED_PATTERNS=(".env" "package-lock.json" ".git/")

for pattern in "${PROTECTED_PATTERNS[@]}"; do
  if [[ "$FILE_PATH" == *"$pattern"* ]]; then
    echo "Blocked: $FILE_PATH matches protected pattern '$pattern'" >&2
    exit 2
  fi
done

exit 0
```

`chmod +x .claude/hooks/protect-files.sh` ile çalıştırılabilir yap, sonra kaydet:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
          }
        ]
      }
    ]
  }
}
```

Aynı yöntem kabuk komutlarında da işler. `Bash` ile eşleştir, `.tool_input.command` alanını oku ve içinde `rm -rf /`, `git push --force` ya da `DROP TABLE` gibi asla istemediğin bir şey varsa 2 ile çık. Metin kontrolünün kolayca atlatılabileceğini unutma; bunu kilit değil, emniyet kemeri olarak düşün.

## Örnek 3: masaüstü bildirimi al

Uzun işler sandığından sık durup seni bekler. `Notification` hook’u bunu hemen haber verir. macOS’ta:

```json
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}
```

Linux’ta bunun yerine `notify-send 'Claude Code' 'Claude Code needs your attention'` kullan. Sadece izin soruları ilgilendiriyorsa matcher’ı `permission_prompt` yap; Claude işi bitirdiğinde de haber almak istersen aynı komutla bir `Stop` hook’u ekle.

## İşe yarayan başka kalıplar

- **Sıkıştırmadan sonra bağlamı geri yükle.** `compact` matcher’lı bir `SessionStart` hook’u kurallarını kısaca `echo` ile basabilir; stdout yeni bağlama eklenir.
- **Ayar değişikliklerini kaydet.** `ConfigChange` hook’u her ayar değişikliğini bir log dosyasına yazabilir.
- **Stop’ta kalite kapısı.** `Stop` hook’u testleri çalıştırıp hataları stderr’e yazarak 2 ile çıkabilir, Claude da düzeltmeye devam eder. Sonsuz döngüye girmemek için girdideki `stop_hook_active` alanına bak. Claude Code da arka arkaya birkaç engellemeden sonra Stop hook’unu geçersiz kılar.
- **Tek bir güvenli soruyu otomatik onayla.** `PermissionRequest` hook’u belirli bir pencereyi karar nesnesinde `{"behavior": "allow"}` ile yanıtlayabilir. Matcher’ı dar tut.

## Hook eklemeden önce güvenlik notları

Hook’lar senin kullanıcı yetkilerinle, sormadan çalışan kabuk komutlarıdır. Bütün mesele bu, risk de burada.

- **Bir depoya güvenmeden önce hook’larını oku.** Projenin `.claude/settings.json` dosyası hook getirebilir. Bunu bir `postinstall` script’i gibi incele.
- **Değişkenleri tırnakla.** Hook girdisi modelden gelir; model de [prompt enjeksiyonu](/sozluk/prompt-enjeksiyonu/ "Prompt enjeksiyonu") içerebilecek dosya ve web sayfalarını okur. `"$VAR"` kullan, girdiyi asla eval etme, elle ayrıştırmak yerine `jq` tercih et.
- **Mutlak ya da projeye göreli yol kullan.** `$CLAUDE_PROJECT_DIR` ile hook’un o anki klasöre bağlı kalmasını önle.
- **Hook’ları hızlı tut.** Yavaş bir `PreToolUse` hook’u her araç çağrısını yavaşlatır. `timeout` belirle.
- **Hook sandbox değildir.** deny hook’u `--dangerously-skip-permissions` altında bile çağrıyı engeller, bu iyi; ama kararlı ya da kafası karışmış bir ajan aynı sonuca başka yoldan ulaşabilir. Hook’ları deny kurallarıyla ve yalıtımla birlikte kullan. Ayrıntılar [yapay zeka kodlama ajanı güvenliği](/blog/yapay-zeka-kodlama-ajani-guvenligi/ "Yapay zeka kodlama ajanı güvenliği") ve [izinleri güvenle atlamak](/blog/claude-code-izinleri-atlamak/ "Claude Code izinleri atlamak") yazılarında.
- **Kapatma düğmelerini bil.** `"disableAllHooks": true` hook’ları kapatır; yöneticiler yönetilen ayarlarda `allowManagedHooksOnly` ile kullanıcı ve proje hook’larını engelleyebilir.

Bir hook tuhaf davranıyorsa Claude Code’u `claude --debug` ile başlat ya da logu `--debug-file /tmp/claude.log` ile dosyaya yaz; her hook’un matcher’ını, çıkış kodunu ve çıktısını görürsün.

## AgentVera hook’ları nasıl kullanıyor

AgentVera; Claude Code, Codex, Gemini CLI ve diğer kodlama CLI’larını yan yana çalıştıran bir masaüstü uygulaması. Claude Code ile çalışırken hook’lar işin önemli bir parçası.

- **Senin hook’ların sana kalır.** AgentVera kendi hook’larını her Claude Code sürecine `--settings` bayrağıyla verir. Claude Code bunları ayar dosyalarındaki hook’larınla birleştirir, `settings.json` dosyana dokunulmaz.
- **Ajan durumu hook’lardan gelir.** Uygulamada her ajanın gösterdiği durum, terminal metninden tahmin edilmez; CLI’ın kendi hook olaylarından okunur.
- **Akıllı araçlar birer hook.** [Akıllı araçlar](/ozellikler/akilli-araclar/ "Akıllı araçlar") özelliği yerel Claude Code ajanlarına dört hook ekler: aynı dosyanın tekrar tekrar okunmasını engeller, sadece düzenlemenin etkilediği testleri çalıştırır, düzenlemeden hemen sonra hata kontrolü yapar ve sonuçları ajanlar arasında paylaştırır. Varsayılan olarak açıktır; Ayarlar → “Token tasarrufu” altından kapatabilirsin.
- **Bildirim script’ine gerek yok.** [Bildirimler ve onaylar](/ozellikler/bildirimler-ve-onaylar/ "Bildirimler ve onaylar") onay bekleyen tüm ajanları tek kuyrukta toplar, uygulama arka plandayken masaüstü bildirimi gönderir ve Telegram üzerinden telefonuna da haber verebilir.

Qwen Code da AgentVera’nın hook’larını alır, çünkü onun hook sistemi Claude Code’un olaylarını ve JSON biçimini izler.

## Toparlarsak

Bir `PostToolUse` biçimleyici ve bir `PreToolUse` korumasıyla başla, `/hooks` ve `--debug` ile kontrol et, bir kural sürekli çiğneniyorsa yenisini ekle. Engellemek için 2 ile çık, daha fazla kontrol gerekiyorsa JSON bas ve her hook’u senin yetkilerinle çalışan kod olarak gör.

Devamını oku:

- [Claude Code hooks (sözlük)](/sozluk/claude-code-hooks/ "Claude Code hooks")
- [Akıllı araçlar](/ozellikler/akilli-araclar/ "Akıllı araçlar")
- [Bildirimler ve onaylar](/ozellikler/bildirimler-ve-onaylar/ "Bildirimler ve onaylar")
- [Claude Code ajanı](/ajanlar/claude-code/ "AgentVera’da Claude Code")

AgentVera’yı denemek için [ana sayfadan](/ "AgentVera") başlayabilirsin.

## Sık sorulanlar

**Claude Code hooks nedir?** Hook’lar, Claude Code’un oturumun belli anlarında kendiliğinden çalıştırdığı kabuk komutları, HTTP çağrıları, MCP araçları veya prompt’lardır. Örneğin bir araç çağrısından önce, dosya düzenlendikten sonra ya da Claude senden yanıt beklediğinde çalışırlar. settings.json içinde tanımlanırlar.

**Claude Code hook’larını nereye yazarım?** Bir ayar dosyasının hooks anahtarına. Tüm projeler için ~/.claude/settings.json, git ile paylaşılan proje ayarı için .claude/settings.json, sadece senin makinendeki proje ayarı için .claude/settings.local.json. Plugin’ler, skill’ler ve alt ajanlar da hook tanımlayabilir.

**Bir hook araç çağrısını nasıl engeller?** PreToolUse hook’u ya 2 koduyla çıkıp nedeni stderr’e yazar ya da 0 ile çıkıp permissionDecision alanı deny olan bir JSON basar. Claude Code çağrıyı iptal eder ve nedeni Claude’a gösterir. 1 koduyla çıkmak engellemez.

**--dangerously-skip-permissions açıkken hook’lar çalışır mı?** Evet. deny dönen bir hook, bypassPermissions modunda bile araç çağrısını engeller. Bu yüzden PreToolUse hook’u asla istemediğin komutlar için iyi bir son kontroldür, ama bir sandbox yerine geçmez.

**Çalışmayan bir hook’u nasıl ayıklarım?** /hooks ile hangi hook’ların yüklendiğine ve nereden geldiğine bak, matcher’ın araç adıyla birebir eşleştiğini kontrol et, sonra Claude Code’u --debug veya --debug-file ile başlatıp her hook’un çıkış kodunu ve çıktısını gör.

---

**AgentVera hakkında.** AgentVera, Solviera Teknoloji tarafından geliştirilen macOS, Windows ve Linux masaüstü uygulamasıdır. 18 yapay zeka kodlama ajanını (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) proje bazında, gerçek terminallerde ve kullanıcının kendi CLI kurulum ve girişleriyle yan yana çalıştırır. Ücretsiz planda sınırsız ajan vardır. İndir: https://agentvera.dev/indir/ · Fiyatlar: https://agentvera.dev/fiyatlar/
