SSD Nodes Learn Hosting plans →
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-08-29

Claude Code hooks कसे काम करतात?

Claude Code hooks म्हणजे काय आणि ते कसे वापरावे हे जाणून घ्या. मॉडेलच्या संमतीशिवाय हे कमांड्स कसे चालतात, exit code 2 चा अर्थ आणि सुरक्षा धोके यांची सविस्तर माहिती येथे उपलब्ध आहे.

Claude Code hook म्हणजे काय

Claude Code hooks हे असे shell commands आहेत जे Claude Code स्वतःच्या lifecycle मधील ठराविक टप्प्यांवर आपोआप चालवते. hook आणि rules file मधील हाच मुख्य फरक आहे. CLAUDE.md मधील सूचना ही एक सल्ला असते आणि मॉडेल त्या संदर्भातील इतर सर्व गोष्टींशी तुलना करून तिचा विचार करते. याउलट, hook हा code असतो आणि मॉडेलची सहमती असो वा नसो, तो चालवलाच जातो. जर तुमचा एजंट तुम्ही दोनदा सांगितलेला formatter वारंवार टाळत असेल, तर तुम्हाला अधिक कडक सूचनेची गरज नाही. तुम्हाला एका hook ची गरज आहे.

ही यंत्रणा साधी आहे. तुम्ही settings file मध्ये एका event name अंतर्गत एक command register करता. जेव्हा तो event घडतो, तेव्हा Claude Code तुमची command चालवते आणि event चा डेटा standard input (stdin) वर JSON (JavaScript object notation) स्वरूपात पाठवते. तुमची command तो डेटा वाचते, आपले काम करते आणि exit status द्वारे उत्तर देते. PreToolUse hook मधून exit 2 दिल्यास tool call चालण्यापूर्वीच रद्द केला जातो आणि तुमच्या script ने standard error (stderr) वर लिहिलेली माहिती मॉडेलला कारणासह परत दिली जाते.

येथील event names आणि field names हे Claude Code hooks reference मधून घेतले आहेत, जे ऑगस्ट 2026 मध्ये release 2.1.232 नुसार तपासले आहेत. हे स्वरूप वेगाने बदलत असते, त्यामुळे कोणत्याही blog post मधील (या पोस्टसह) JSON कॉपी करण्यापूर्वी तुमच्या स्वतःच्या version साठी reference तपासा. तुमचे स्वतःचे स्वरूप claude --version वापरून print करा.

हुक कॉन्फिगरेशन कोठे असते

हुक म्हणजे सेटिंग्ज फाईलमधील एक JSON ब्लॉक. हे सहा ठिकाणी असू शकते आणि फाईलची व्याप्ती (scope) हीच हुकची व्याप्ती असते.

  • ~/.claude/settings.json: तुमच्या मशीनवरील प्रत्येक प्रोजेक्ट, आणि इतर कोणाचेही नाही.
  • .claude/settings.json: एक प्रोजेक्ट, जो रिपॉझिटरीमध्ये कमिट केला जातो, त्यामुळे तो क्लोन करणाऱ्या प्रत्येकाला तो हुक मिळतो.
  • .claude/settings.local.json: एक प्रोजेक्ट, फक्त तुमच्या मशीनपुरता मर्यादित.
  • मॅनेज्ड पॉलिसी सेटिंग्ज: संपूर्ण संस्थेसाठी, ॲडमिनिस्ट्रेटरद्वारे सेट केलेली.
  • hooks/hooks.json प्लगइनच्या आत, जोपर्यंत ते प्लगइन इनेबल आहे तोपर्यंत सक्रिय.
  • स्किल किंवा सब-एजंट फ्रंटमॅटर, जोपर्यंत तो घटक सक्रिय आहे तोपर्यंत कार्यरत.

या फाईल्समधील हुक एन्ट्रीज एकमेकांना ओव्हरराईड करण्याऐवजी एकत्र (merge) होतात. प्रोजेक्ट सेटिंग्ज फाईल तुमचे हुक युजर सेटिंग्जमधील हुकमध्ये जोडते, त्यांना बदलत नाही. त्यामुळे एका इव्हेंटसाठी विविध फाईल्समधून अनेक हुक असू शकतात. "disableAllHooks": true सेटिंग त्यांना बंद करते, फक्त एक अपवाद वगळता: मॅनेज्ड पॉलिसी सेटिंग्जमधील हुक चालू राहतात, जोपर्यंत ती सेटिंग मॅनेज्ड सेटिंग्जमध्येही लागू केली जात नाही.

सध्या नोंदणीकृत असलेले सर्व हुक पाहण्यासाठी सेशनमध्ये /hooks चालवा. हे हुक इव्हेंटनुसार गटबद्ध केलेले असतात आणि प्रत्येकासाठी सोर्स फाईल व मॅचरची माहिती दिली जाते. हा मेनू फक्त वाचण्यासाठी (read-only) आहे, त्यामुळे हुक बदलण्यासाठी तुम्हाला सेटिंग्ज फाईल एडिट करावी लागेल. फाईल वॉचर सहसा रीस्टार्ट न करताच बदल स्वीकारतो.

Claude Code मध्ये कोणते हुक इव्हेंट्स उपलब्ध आहेत

Release 2.1.232 मध्ये 31 इव्हेंट्सची यादी दिली आहे, जी SessionStart पासून SessionEnd पर्यंत आहे. यामध्ये कॉम्पॅक्शन, सब-एजंट्स, वर्क-ट्रीज आणि कॉन्फिगरेशन फाइल्सचा समावेश होतो. सर्व्हरच्या कामासाठी यातील काही मोजकेच इव्हेंट्स वापरले जातात.

  • PreToolUse: टूल कॉल कार्यान्वित होण्यापूर्वी. हा इव्हेंट प्रक्रियेला थांबवू (block) शकतो.
  • PostToolUse: टूल कॉल यशस्वी झाल्यानंतर. जेव्हा टूल कॉल अयशस्वी होतो तेव्हा PostToolUseFailure ट्रिगर होतो, त्यामुळे ज्या हुकला प्रत्येक निकालाची नोंद हवी असते, त्याला दोन्हीची आवश्यकता असते.
  • PermissionRequest: जेव्हा टूल कॉलला परवानगीच्या निर्णयाची आवश्यकता असते, म्हणजेच ज्या क्षणी मंजुरीसाठी प्रॉम्प्ट (approval prompt) दिसतो.
  • UserPromptSubmit: जेव्हा तुम्ही प्रॉम्प्ट सबमिट करता, Claude त्यावर प्रक्रिया करण्यापूर्वी. हा हुक stdout वर जे काही प्रिंट करतो, ते मॉडेलच्या संदर्भात (context) जोडले जाते.
  • SessionStart आणि SessionEnd: सत्राच्या (session) सुरुवातीला आणि शेवटी. SessionStart हा कॉम्पॅक्शननंतरही ट्रिगर होतो, ज्याचे मॅचर व्हॅल्यू compact असते.
  • Stop: जेव्हा Claude प्रतिसाद देणे पूर्ण करतो. हे प्रत्येक टर्नसाठी एकदा घडते, पूर्ण झालेल्या टास्कसाठी एकदा नाही.

प्रत्येक ग्रुपमध्ये एक matcher असतो जो हुक कोणत्या प्रसंगी कार्यान्वित होईल हे ठरवतो. टूल इव्हेंट्सवर तो टूलच्या नावानुसार फिल्टर करतो, त्यामुळे "Edit|Write" फक्त फाइल एडिट्सवर ट्रिगर होतो आणि इतर कशावरही नाही. मॅचर्स हे केस-सेन्सिटिव्ह असतात. रिकामे मॅचर प्रत्येक प्रसंगी ट्रिगर होतात. MCP (model context protocol) सर्व्हरमधील टूल्सना mcp__<server>__<tool> असे नाव दिले जाते, त्यामुळे "mcp__github__.*" चे मॅचर एका सर्व्हरची टूल्स पकडते आणि इतरांना तसेच राहू देते.

Stop हुक्समध्ये एक अशी अडचण आहे जी लिहिण्यापूर्वी जाणून घेणे आवश्यक आहे. जो Stop हुक प्रक्रियेला थांबवतो (block), तो मॉडेलला पुन्हा कामावर पाठवतो आणि सलग आठ वेळा ब्लॉक केल्यानंतर Claude Code त्या हुकला ओव्हरराइड करतो. हुक इनपुटमधील stop_hook_active फील्ड वाचा आणि ते true असताना exit 0 करा, अन्यथा तुमचा हुक त्या मर्यादेपर्यंत पोहोचेपर्यंत लूपमध्ये राहील.

हुकला stdin वर काय प्राप्त होते

जेव्हा Claude npm test चालवणार असतो, तेव्हा Bash वरील PreToolUse हुक stdin वर खालील माहिती वाचतो:

{
  "session_id": "abc123",
  "cwd": "/home/deploy/myproject",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": {
    "command": "npm test"
  }
}

प्रत्येक इव्हेंटमध्ये session_id, cwd, permission_mode, transcript_path आणि hook_event_name असतात. टूल इव्हेंट्समध्ये tool_name, tool_input आणि tool_use_id जोडले जातात. इतर इव्हेंट्समध्ये त्यांची स्वतःची फील्ड्स असतात: UserPromptSubmit मध्ये prompt मजकूर असतो, आणि SessionStart मध्ये startup, resume, clear, compact किंवा fork चा source असतो.

शेल स्क्रिप्टमध्ये हे वाचण्यासाठी jq हा नेहमीचा मार्ग आहे, परंतु किमान सर्व्हर इमेजमध्ये तो उपलब्ध नसतो. Ubuntu आणि Debian वर तो प्रथम sudo apt install -y jq वापरून इंस्टॉल करा.

एक्झिट स्टेटसचा चालू असलेल्या टूल कॉलवर होणारा परिणाम

याचे तीन संभाव्य परिणाम आहेत.

  • Exit 0 चा अर्थ असा की तुमच्या हुकने (hook) कोणतीही हरकत घेतलेली नाही. PreToolUse वर याचा अर्थ मंजुरी असा होत नाही आणि सामान्य परवानगी प्रक्रिया (permission flow) सुरूच राहते. UserPromptSubmit आणि SessionStart वर, stdout मॉडेलच्या संदर्भात (context) जोडले जाते.
  • Exit 2 अशा इव्हेंट्सवर कृती रोखते ज्यांना रोखणे शक्य आहे, ज्यामध्ये PreToolUse समाविष्ट आहे, आणि stderr हे मॉडेलला दाखवण्याचे कारण बनते. ज्या इव्हेंट्सना रोखता येत नाही, जसे की PostToolUse, तिथे हे ब्लॉकिंग दुर्लक्षित केले जाते, तरीही stderr मॉडेलला फीडबॅक म्हणून पोहोचते.
  • इतर कोणताही एक्झिट कोड हा नॉन-ब्लॉकिंग एरर असतो. कृती पुढे सुरू राहते. ट्रान्सक्रिप्टमध्ये Failed with non-blocking status code: मजकुराच्या नंतर stderr ची पहिली ओळ घेऊन एक हुक एरर नोटीस दिसते.

ब्लॉक करण्यापेक्षा किंवा शांत राहण्यापेक्षा अधिक काही करायचे असल्यास, exit 0 वापरा आणि stdout वर एक JSON ऑब्जेक्ट प्रिंट करा. एक PreToolUse हुक permissionDecision सह निर्णय घेतो:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Database drops go through a migration, not through the agent."
  }
}

"allow" इंटरअॅक्टिव्ह प्रॉम्प्ट वगळते, "deny" कॉल रद्द करते आणि त्याचे कारण मॉडेलला पाठवते, आणि "ask" प्रॉम्प्ट नेहमीप्रमाणे दाखवते. प्रत्येक हुकसाठी एक शैली निवडा. exit 2 आणि stdout वरील JSON निर्णय एकत्र केल्यास असा निकाल मिळतो जो तुम्हाला तपासावा लागेल.

जेव्हा अनेक हुक्स एकाच इव्हेंटशी जुळतात, तेव्हा ते समांतर (parallel) चालतात आणि त्यातील प्रत्येक पूर्ण होईपर्यंत चालतो. एका हुककडून आलेला deny त्याच्या इतर हुक्सना थांबवत नाही, त्यामुळे गार्डरेल हुक एखादा कॉल नाकारत असतानाही लॉगिंग हुक आपली ओळ लिहितो. त्यानंतर Claude Code उत्तरे एकत्रित करते आणि सर्वात प्रतिबंधात्मक (restrictive) पर्याय निवडते, ज्याचा क्रम deny, defer, ask, allow असा असतो.

उदाहरण 1: एखादी विनाशकारी कमांड रन होण्यापूर्वी ती ब्लॉक करणे

हे तुमच्या प्रोजेक्टमध्ये .claude/hooks/block-destructive.sh म्हणून सेव्ह करा:

#!/bin/bash
# Deny a Bash tool call whose command matches a banned pattern.
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

for pattern in 'rm -rf /' 'mkfs' 'dd if=' 'DROP TABLE'; do
  if printf '%s' "$COMMAND" | grep -qiF -- "$pattern"; then
    echo "Blocked by policy: the command matches '$pattern'. A human runs this one." >&2
    exit 2
  fi
done

exit 0

त्याला एक्झिक्युटेबल बनवा आणि त्यानंतर .claude/settings.json मधील PreToolUse वर रजिस्टर करा:

chmod +x .claude/hooks/block-destructive.sh
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-destructive.sh",
            "timeout": 10,
            "statusMessage": "Checking the command against policy"
          }
        ]
      }
    ]
  }
}

स्क्रिप्टवर विश्वास ठेवण्यापूर्वी ती हाताने टेस्ट करा, कारण स्वतःच्याच इनपुटवर क्रॅश होणारा हुक 'fails open' (सुरक्षा निकामी) होतो:

echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /var/lib/postgresql"}}' \
  | .claude/hooks/block-destructive.sh
echo $?

तुम्हाला stderr वर Blocked by policy: ओळ आणि 2 हा एक्झिट कोड दिसला पाहिजे. त्याला ls -la सारखी निरुपद्रवी कमांड देऊन पहा, तेव्हा कोणताही आउटपुट दिसू नये आणि एक्झिट कोड 0 असावा. एका सेशनमध्ये, नाकारलेली कॉल ट्रान्सक्रिप्टमध्ये तुमच्या संदेशासह कारणासकट दिसते आणि मॉडेल तो संदेश वाचून स्वतःला ॲडजस्ट करते.

एका वैशिष्ट्यामुळे हे करणे फायदेशीर ठरते: PreToolUse हुक्स हे परमिशन-मोड तपासणीच्या आधी आणि प्रत्येक परमिशन मोडमध्ये फायर होतात, त्यामुळे bypassPermissions अंतर्गत सुद्धा नकार (deny) कायम राहतो. याच कारणामुळे Claude Code auto mode आणि त्याच्या परमिशन सेटिंग्स सोबत हुक उपयुक्त ठरतो, जिथे प्रॉम्प्ट्स कमी केलेले असले तरी हुक अजूनही फायर होतो.

हे नक्की काय आहे याबद्दल प्रामाणिक राहा. कमांड स्ट्रिंगवर पॅटर्न मॅचिंग करणे हे एजंटच्या निष्काळजीपणाविरुद्ध एक सुरक्षा कवच (guardrail) आहे, परंतु एजंटच्या चलाखीविरुद्ध ही सीमा नाही, कारण तीच कमांड अशा स्वरूपात लिहिली जाऊ शकते जी तुमच्या grep ला कधीच दिसत नाही. कडक नियम हे परमिशन सिस्टममध्ये आणि ज्या अकाउंटखाली प्रोसेस रन होते, तिथेच असावेत.

उदाहरण 2: प्रत्येक एडिटनंतर फॉरमॅट आणि लिंट करणे

PostToolUse आणि Edit|Write मॅचर कोणत्याही फाइल-एडिटिंग टूलनंतर कार्यान्वित होतात. हे .claude/hooks/after-edit.sh म्हणून सेव्ह करा:

#!/bin/bash
# Format the edited file, then report lint failures back to the model.
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
[ -z "$FILE" ] && exit 0

case "$FILE" in
  *.py)
    ruff format "$FILE" >/dev/null 2>&1
    if ! ruff check "$FILE" >&2; then
      exit 2
    fi
    ;;
  *.sh)
    if ! shellcheck "$FILE" >&2; then
      exit 2
    fi
    ;;
esac

exit 0
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/after-edit.sh",
            "timeout": 60
          }
        ]
      }
    ]
  }
}

Claude ला एखाद्या Python फाइलमध्ये चुकीच्या इंडेंटेशनसह फंक्शन जोडण्यास सांगा आणि त्यानंतर ती फाइल उघडा. ती फाइल आपोआप फॉरमॅट झालेली दिसेल. हुक यशस्वीरित्या चालला आहे हे तपासण्याचा हा मार्ग आहे, कारण यशस्वी हुक संभाषणात काहीही दर्शवत नाही.

येथील exit 2 मुळे काहीही अनडू (undo) होत नाही. PostToolUse हे टूल एक्झिक्युट झाल्यानंतर कार्यान्वित होते, त्यामुळे एडिट डिस्कवर आधीच झालेली असते. exit 2 चा फायदा असा की, ruff check चे आउटपुट फीडबॅक म्हणून मॉडेलपर्यंत पोहोचते, ज्यामुळे ते नवीन त्रुटी दुरुस्त करते आणि पुढे जाते. कमिट करताना आढळणारी लिंट फेल्युअर आणि एजंटने त्याच टर्नमध्ये दुरुस्त केलेली त्रुटी यातील हा मुख्य फरक आहे.

येथे दोन मॅचर मर्यादा महत्त्वाच्या आहेत. Edit|Write ला शेल कमांडद्वारे बदललेल्या फाइल्स दिसत नाहीत आणि Claude अनेकदा Bash द्वारे फाइल्स लिहितो, त्यामुळे ही त्रुटी महत्त्वाची ठरते. प्रत्येक कॉलच्या कव्हरेजसाठी, Bash ला देखील मॅच करा आणि स्क्रिप्टद्वारे git status --porcelain वापरून बदललेल्या फाइल्सची यादी मिळवा. प्रत्येक टर्नसाठी एकदाच कव्हरेज हवे असल्यास, स्कॅन Stop हुकमध्ये ठेवा.

उदाहरण 3: ऑडिटसाठी प्रत्येक टूल कॉल लॉग करणे

PostToolUse वरील रिकामे मॅचर प्रत्येक टूलवर कार्यान्वित होते. रेकॉर्ड होम डिरेक्टरीमधील फाईलऐवजी सिस्टम जर्नलमध्ये पाठवल्यामुळे ते एजंटच्या स्वतःच्या शेलच्या आवाक्याबाहेर राहते:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{time: now|todate, session: .session_id, cwd: .cwd, tool: .tool_name, input: .tool_input}' | logger -t claude-code -p local0.info"
          }
        ]
      }
    ]
  }
}

ते journalctl -t claude-code -o cat | tail -n 5 वापरून पुन्हा वाचा. तुम्हाला प्रत्येक टूल कॉलसाठी एक JSON ओळ दिसेल, ज्यामध्ये सर्वात अलीकडील ओळ शेवटी असेल. काहीही दिसत नसल्यास, हुक कार्यान्वित झालेला नाही, ज्यासाठी खालील ट्रबलशूटिंग विभाग पहा.

अपयशी ठरलेले कॉल कॅप्चर करण्यासाठी PostToolUseFailure अंतर्गत तोच ब्लॉक जोडा, कारण PostToolUse फक्त यशस्वी कॉलवरच कार्यान्वित होते आणि अपयशी ठरलेली कमांड सहसा अधिक महत्त्वाची असते. तुमच्या होम डिरेक्टरीमधील फाईलमध्ये डेटा जोडण्याऐवजी logger वापरण्याचे कारण म्हणजे मालकी हक्क (ownership): हुक एजंटच्या शेलप्रमाणेच त्याच युजरच्या अधिकारात चालतो, त्यामुळे ज्या फाईलमध्ये तो युजर माहिती जोडू शकतो, ती फाईल तो युजर डिलीट किंवा ट्रंकेट (truncate) सुद्धा करू शकतो. जर्नल हे systemd-journald द्वारे त्याच्या स्वतःच्या अकाउंटवरून लिहिले जाते.

हुक किती वेळ चालू शकतो

ChartDefault hook timeout in seconds, by hook type and event
The data behind this chart
[
  {
    "label": "command, http or mcp_tool hook",
    "default_timeout_seconds": 600
  },
  {
    "label": "agent hook",
    "default_timeout_seconds": 60
  },
  {
    "label": "prompt hook",
    "default_timeout_seconds": 30
  },
  {
    "label": "command hook on UserPromptSubmit",
    "default_timeout_seconds": 30
  },
  {
    "label": "command hook on MessageDisplay",
    "default_timeout_seconds": 10
  },
  {
    "label": "any hook on SessionEnd",
    "default_timeout_seconds": 1.5
  }
]

कमांड हुकला डीफॉल्टनुसार 600 सेकंद मिळतात, जे दहा मिनिटे आहेत. काही इव्हेंट्स हा वेळ लक्षणीयरीत्या कमी करतात. सर्व SessionEnd हुक मिळून 1.5 सेकंदांच्या बजेटचा वापर करतात, त्यामुळे सेशन संपताना होणारी स्वच्छता (cleanup) जलद असणे आवश्यक आहे. तथापि, हुकवर अधिक कालावधीचा timeout सेट केल्यास हे सामायिक बजेट 60 सेकंदांपर्यंत वाढवता येते.

जो हुक त्याच्या टाइमआउट मर्यादेपर्यंत पोहोचतो, तो रद्द केला जातो आणि कोणताही निर्णय देत नाही. PreToolUse गार्डरेलसाठी याचा अर्थ असा की तो प्रक्रियेला रोखत नाही: टूल कॉल सामान्य परवानगी प्रवाहामध्ये (permission flow) पुढे चालू राहतो. याच कारणामुळे गार्डरेल स्क्रिप्ट्स लहान ठेवा. ज्या संथ कामांसाठी कोणीही वाट पाहत नाही, जसे की लॉग कुठेतरी पाठवणे, त्यासाठी "async": true सेट करा. यामुळे हुक बॅकग्राउंडमध्ये चालतो आणि टूल कॉलला थांबवून ठेवत नाही.

Hooks, rules files, skills आणि MCP servers

चार गोष्टी एकमेकांशी गोंधळल्या जातात कारण त्या सर्व एजंटचे कार्य बदलतात. त्यापैकी फक्त एक गोष्ट सूचनेच्या पलीकडे जाऊन अनिवार्य ठरते.

एक rules file (CLAUDE.md, किंवा .claude/rules/ अंतर्गत असलेली फाईल) म्हणजे मॉडेलच्या कॉन्टेक्स्टमध्ये लोड केलेला मजकूर असतो. हे वर्तनाला आकार देते, परंतु कशाचीही सक्ती करत नाही. प्रदीर्घ संभाषण, मोठा diff आणि नवीन वापरकर्ता विनंती यांच्या तुलनेत, यातील एक ओळ दुर्लक्षित होऊ शकते. एजंटने तुम्ही लिहिलेल्या सूचनांकडे दुर्लक्ष करणे यामागील हेच सामान्य कारण आहे.

Skill म्हणजे सूचना आणि स्क्रिप्ट्सचा एक फोल्डर, जो मॉडेलला जेव्हा एखादी skill संबंधित वाटते तेव्हा ते लोड करते. तो निर्णय घेणे हाच skill चा मुख्य उद्देश आहे आणि तीच त्याची मर्यादा देखील आहे: शेवटी मॉडेलच निर्णय घेते. तुम्ही Ponytail सारख्या skill मध्ये दोन्ही बाजू पाहू शकता, जी एजंटला सर्वात लहान आणि प्रभावी बदलाकडे प्रवृत्त करते. हे एखाद्या कार्याकडे पाहण्याचा दृष्टिकोन अशा प्रकारे आकारते जो कोणत्याही hook ला शक्य नाही, आणि हे फक्त तेव्हाच घडते जेव्हा मॉडेल ती skill लोड करण्याचे निवडते.

MCP (model context protocol) server मॉडेलला कॉल करण्यासाठी नवीन टूल्स उपलब्ध करून देतो. हे एजंटची पोहोच वाढवते. हे एजंटला कशाचाही वापर करण्यास भाग पाडत नाही आणि ही एक स्वतंत्र प्रक्रिया आहे जी तुम्हाला चालवावी लागते, जे स्वतःच एक काम आहे: VPS वर MCP servers चालवणे पहा.

या चार गोष्टींपैकी hook हा एकमेव असा प्रकार आहे जो मॉडेलच्या निवडीशिवाय कार्यान्वित होतो. पसंती दर्शवण्यासाठी rules file चा वापर करा आणि जेव्हा मॉडेलला एखादी प्रक्रिया लागू करायची असेल तेव्हा skill चा वापर करा. ज्या पायऱ्या प्रत्येक वेळी घडणे आवश्यक आहे किंवा ज्या गोष्टी कधीही घडू नयेत, त्यासाठी hook चा वापर करा. skill हे rules file पेक्षा कधी सरस ठरते, यासह सखोल तुलना skills, MCP आणि rules files ची तुलना मध्ये दिली आहे.

Plugin ही पाचवी यंत्रणा नसून ती एक पॅकेजिंग पद्धत आहे. हे hooks आणि skills यांना एकत्र करून एक इन्स्टॉल करण्यायोग्य युनिट बनवते, ज्याद्वारे एखादी टीम प्रत्येक मशीनवर समान सुरक्षा नियम (guardrail) लागू करते: Claude Code plugins कसे काम करतात पहा.

शेअर्ड VPS वरील सुरक्षेचा निर्णय

हूक (hook) म्हणजे असा कोड जो एजंटद्वारे ट्रिगर केला जातो आणि तो Claude Code सुरू करणाऱ्या युजरच्या अधिकारांनुसार चालतो. तो त्या युजरचे वातावरण आणि फाईल परवानग्या वारशाने घेतो. लॅपटॉपवर हा केवळ वर्कफ्लोचा प्रश्न असतो, पण ज्या VPS वर एजंट विना देखरेख चालतो, तिथे हा सुरक्षेचा चार व्यावहारिक भागांचा प्रश्न बनतो.

रिपॉझिटरीमधील हूक हा तुम्ही न लिहिलेला कोड असतो. .claude/settings.json कमिट केलेला असतो, त्यामुळे रिपॉझिटरी क्लोन करून त्यात सेशन सुरू केल्यास रिपॉझिटरीसोबत आलेले हूक रजिस्टर होऊ शकतात. Claude Code अशा प्रोजेक्ट हूकना त्या फोल्डरसाठीच्या 'वर्कस्पेस ट्रस्ट' डायलॉगद्वारे नियंत्रित करते. याचा अर्थ, ट्रस्ट स्वीकारणे म्हणजे तुम्ही ते हूक चालवण्याचा निर्णय घेणे होय. आधी hooks ब्लॉक वाचा.

हूकला सर्व टूल इनपुट दिसते. tool_input लॉग करणारा ऑडिट हूक प्रत्येक कमांडचे सर्व आर्गुमेंट्स फाईलमध्ये लिहितो, ज्यामध्ये कमांड लाईनवर असलेले कोणतेही टोकन समाविष्ट असू शकते. त्यानंतर त्या लॉगलाही सीक्रेटइतकेच संरक्षण देणे आवश्यक असते, जे AI एजंटच्या आवाक्याबाहेर सीक्रेट्स ठेवण्याच्या व्यापक समस्येचा एक भाग आहे.

हूक मॉडेलच्या कॉन्टेक्स्टमध्ये लिहू शकतो. SessionStart किंवा UserPromptSubmit हूक stdout वर जे काही प्रिंट करतो, ते संभाषणात जोडले जाते. बाहेरून, इश्यू ट्रॅकरमधून किंवा लॉग फाईलमधून मजकूर पाइप करणारा हूक, जणू तुम्ही स्वतः टाईप केला आहे अशा प्रकारे मॉडेलला अविश्वसनीय मजकूर देतो. त्याच VPS वरील दुसऱ्या Claude Code सेशनमधून टीप फॉरवर्ड करणारा हूक हेच काम करतो आणि एका एजंटच्या आउटपुटवर इश्यू ट्रॅकरपेक्षा जास्त विश्वास ठेवण्याचे कारण नाही. त्या stdout कडे आउटपुटऐवजी इनपुट म्हणून पहा.

प्रिव्हिलेज (Privilege) हेच खरे नियंत्रण आहे. एजंटला एका समर्पित, कमी अधिकार असलेल्या युजरद्वारे चालवा, ज्याला फक्त आवश्यक sudo नियम असतील. PreToolUse डिनाय (deny) असणे फायदेशीर आहे, परंतु ते डिझाइननुसार 'बेस्ट एफर्ट' असते: रेफरन्समध्ये if फिल्टरबद्दलही असेच म्हटले आहे आणि जेव्हा तुम्हाला कडक निर्बंध हवे असतील तेव्हा परमिशन सिस्टम वापरण्याचा सल्ला दिला आहे. परमिशन नियम आणि ज्या अकाउंटखाली प्रोसेस चालते, तेच घटक दबावाखाली टिकून राहतात.

प्रत्येक कॉन्फिगरेशनमध्ये एक गुणधर्म कायम राहतो. PreToolUse हूक प्रत्येक परमिशन मोडमध्ये परमिशन-मोड चेकच्या आधी फायर होतात, त्यामुळे deny रिटर्न करणारा हूक bypassPermissions अंतर्गतही टूलला ब्लॉक करतो. हूक परमिशन नियमांनी दिलेल्या परवानगीला अधिक मर्यादित करू शकतात. ते तिला शिथिल करू शकत नाहीत.

माझा हुक (hook) का चालत नाहीये?

या पायऱ्या क्रमाने तपासा. प्रत्येक पायरीमध्ये तुम्हाला दिसणारे लक्षण दिले आहे.

  • /hooks चालवा आणि तुम्ही अपेक्षित केलेल्या इव्हेंटच्या अंतर्गत हुक दिसत आहे का ते तपासा. मेनूमध्ये हुक दिसत नसेल, तर याचा अर्थ सेटिंग्ज फाईलमध्ये JSON सिंटॅक्स त्रुटी आहे (कारण ट्रेलिंग कॉमा आणि कमेंट्सना परवानगी नाही), किंवा फाईल वर नमूद केलेल्या सहा ठिकाणांपैकी कोणत्याही ठिकाणी नाही.
  • मॅचरची (matcher) तुलना टूलच्या नावाशी तंतोतंत करा. मॅचर्स केस-सेन्सिटिव्ह असतात, त्यामुळे "bash" हे कधीही Bash टूलशी जुळणार नाही.
  • वरील उदाहरण 1 मध्ये दिल्याप्रमाणे, नमुना इनपुट वापरून स्क्रिप्ट स्वतः चालवून पहा. जर एक्झिट कोड अनपेक्षित असेल, तर ती तुमच्या स्क्रिप्टमधील त्रुटी आहे आणि Claude Code याला निर्णयाऐवजी हुक एरर म्हणून रिपोर्ट करते.
  • jq: command not found अशी नोटीस दिसणे म्हणजे त्या मशीनवर jq उपलब्ध नाही. तुमच्या स्वतःच्या स्क्रिप्टसाठी command not found येणे म्हणजे पाथ (path) सापडत नाहीये, म्हणून ${CLAUDE_PROJECT_DIR} किंवा पूर्ण पाथ (absolute path) वापरा. जर स्क्रिप्ट अजिबात चालत नसेल, तर ती कदाचित एक्झिक्युटेबल (executable) नसेल.
  • हुक वैध JSON प्रिंट करतो पण काहीही घडत नाही. शेल-फॉर्म हुक sh -c द्वारे चालतो आणि जर तुमच्या शेल प्रोफाइलमध्ये काही बॅनर प्रिंट होत असेल, तर तो बॅनर तुमच्या JSON च्या सुरुवातीला जोडला जातो. त्यामुळे Stdout ची सुरुवात { ने होत नाही, परिणामी Claude Code संपूर्ण मजकूर प्लेन टेक्स्ट म्हणून वाचते आणि निर्णयाकडे दुर्लक्ष करते. एक्झिट 0 असताना डीबग लॉगशिवाय कुठेही काहीही रिपोर्ट केले जात नाही. तुमच्या प्रोफाइलमधील कोणताही echo अशा प्रकारे रॅप करा की तो फक्त इंटरअॅक्टिव्ह शेलमध्येच चालेल.
  • तरीही अडकले असल्यास: claude --debug-file /tmp/claude.log सह सेशन सुरू करा आणि दुसऱ्या टर्मिनलमध्ये tail -f /tmp/claude.log चालवा. डीबग लॉगमध्ये कोणते हुक मॅच झाले, प्रत्येकाने कोणता एक्झिट कोड दिला आणि त्यांनी stdout व stderr वर काय लिहिले, याची नोंद असते.

FAQ

Claude Code hook आणि CLAUDE.md instruction यामध्ये काय फरक आहे?

CLAUDE.md instruction हे मॉडेलच्या संदर्भातील (context) मजकूर असते, त्यामुळे ते संवादाशी आणि सध्याच्या विनंतीशी लक्ष वेधून घेण्यासाठी स्पर्धा करते आणि मॉडेल त्याचे महत्त्व ठरवू शकते. याउलट, hook ही एक शेल कमांड आहे जी Claude Code तिच्या लाइफसायकलमधील एका निश्चित टप्प्यावर चालवते. त्यामुळे, मॉडेलने काहीही ठरवले तरी, संबंधित घटना घडताच ती कमांड कार्यान्वित होते. पसंती दर्शवण्यासाठी instruction चा वापर करा. एखादी पायरी जी नेहमीच पूर्ण झाली पाहिजे किंवा एखादी कृती जी कधीही होऊ नये, यासाठी hook चा वापर करा.

Claude Code ला विशिष्ट शेल कमांड चालवण्यापासून मी कसे रोखू शकतो?

एका PreToolUse hook ची नोंदणी करा ज्यामध्ये Bash मॅचर असेल. हे मॅचर .tool_input.command मधून कमांड वाचते, stderr वर कारण लिहिते आणि 2 हा एक्झिट कोड देते. Claude Code ती कॉल रद्द करते आणि तुमचे कारण मॉडेलला दाखवते. ही प्रक्रिया permission-mode तपासणीच्या आधी घडते, त्यामुळे bypassPermissions मोडमध्येही ही बंदी लागू राहते. कमांड स्ट्रिंगवर पॅटर्न मॅचिंग करणे हे एक सुरक्षा कवच (guardrail) आहे, सुरक्षिततेची सीमा (security boundary) नाही; कारण तीच कमांड अशा स्वरूपात लिहिता येते जी पॅटर्नला सापडणार नाही. त्यामुळे, याला परवानगी नियमांची (permission rules) आणि एका अनप्रिव्हिलेज्ड (unprivileged) अकाउंटची जोड द्या.

माझा hook वैध JSON प्रिंट करतो, पण काहीही घडत नाही. याचे कारण काय?

याचे सर्वात सामान्य कारण म्हणजे तुमचे शेल प्रोफाइल. ज्या hook मध्ये args फील्ड नसते, तो sh -c द्वारे चालवला जातो. काही प्रोफाइल प्रत्येक शेल सुरू होताना एक बॅनर प्रिंट करतात, जो तुमच्या JSON च्या आधी stdout वर येतो. आउटपुट आता { ने सुरू होत नसल्यामुळे, Claude Code त्या सर्वांना साधा मजकूर मानते आणि निर्णयाकडे दुर्लक्ष करते. एक्झिट कोड 0 असल्यास ट्रान्सक्रिप्टमध्ये काहीही नोंदवले जात नाही. तुमच्या प्रोफाइलमधील कोणताही echo हा interactive-shell टेस्टने सुरक्षित करा आणि त्यानंतर claude --debug-file /tmp/claude.log मधील डीबग लॉग वाचून दुरुस्तीची खात्री करा.

शेअर केलेल्या सर्व्हरवर Claude Code hooks चालवणे सुरक्षित आहे का?

Hooks हे Claude Code सुरू करणाऱ्या वापरकर्त्याच्या अधिकारांनुसार चालतात, त्यामुळे ते अकाउंट जे काही करू शकते, ते सर्व hook करू शकतो. दोन सवयींमुळे बहुतेक जोखीम कमी होते: एजंटला मर्यादित sudo पॉलिसी असलेल्या एका समर्पित अनप्रिव्हिलेज्ड अकाउंटवरून चालवा आणि कोणत्याही रिपॉझिटरीचा वर्कस्पेस ट्रस्ट डायलॉग स्वीकारण्यापूर्वी त्यातील hooks ब्लॉक वाचा, कारण प्रोजेक्ट hooks हे .claude/settings.json मध्ये असतात. जर तुम्हाला कोणतेही hooks चालवायचे नसतील, तर तुमच्या सेटिंग्ज फाइलमध्ये "disableAllHooks": true सेट करा.