[FEATURE] Add `additionalContext` support to PreToolUse hooks
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
PreToolUse hooks can control permissions and modify tool inputs, but cannot inject context into Claude's conversation. This limits their usefulness for providing contextual guidance at the moment it's needed.
Use case: I have an inject-test-methodology hook that triggers when Claude is about to write test files. I want to inject testing best practices (AAA pattern, naming conventions, edge case requirements) at the exact moment Claude needs them—not loaded globally for every conversation.
Currently, I must choose between:
| Approach | Problem |
|----------|---------|
| Global CLAUDE.md | Always loaded, wastes context on non-test work |
| UserPromptSubmit hook | Fires on every prompt, requires complex filtering |
| PostToolUse hook | Fires AFTER the tool runs, too late to guide behavior |
None of these are ideal. PreToolUse fires at exactly the right moment but can't inject context.
Proposed Solution
Add additionalContext field to PreToolUse's hookSpecificOutput, matching the existing pattern used by:
UserPromptSubmitSessionStartPostToolUse
Schema change:
| {
hookEventName: 'PreToolUse';
permissionDecision?: 'allow' | 'deny' | 'ask';
permissionDecisionReason?: string;
updatedInput?: Record<string, unknown>;
additionalContext?: string; // ← NEW FIELD
}
Behavior: When a PreToolUse hook returns additionalContext, include it in Claude's context for the current tool call decision and subsequent processing.
Alternative Solutions
| Approach | Why Not Ideal |
|----------|---------------|
| Global CLAUDE.md | Loads methodology for every project, even non-test work |
| UserPromptSubmit | Fires on every prompt; complex filtering needed |
| PostToolUse | Too late—tool already executed |
| Project CLAUDE.md | Per-project maintenance burden |
Priority
Critical - Blocking my work
Feature Category
CLI commands and flags
Use Case Example
Scenario: Developer asks Claude to write tests for a new feature.
Current flow:
- Claude decides to use Write tool for
test_feature.py - PreToolUse hook fires, detects test file pattern
- Hook can only: allow/deny/modify inputs
- Hook CANNOT tell Claude "follow AAA pattern, use descriptive names, test edge cases"
- Claude writes tests without methodology guidance (unless globally loaded)
Desired flow:
- Claude decides to use Write tool for
test_feature.py - PreToolUse hook fires, detects test file pattern
- Hook returns
additionalContextwith testing methodology - Claude receives methodology at exactly the moment it's needed
- Claude writes high-quality tests following the injected guidance
Additional Context
Current TypeScript Schema (from official docs)
The limitation is visible in the type definitions but not explicitly documented:
hookSpecificOutput?:
| {
hookEventName: 'PreToolUse';
permissionDecision?: 'allow' | 'deny' | 'ask';
permissionDecisionReason?: string;
updatedInput?: Record<string, unknown>;
// NO additionalContext - this is the gap
}
| {
hookEventName: 'UserPromptSubmit';
additionalContext?: string; // HAS IT
}
| {
hookEventName: 'SessionStart';
additionalContext?: string; // HAS IT
}
| {
hookEventName: 'PostToolUse';
additionalContext?: string; // HAS IT
};
Documentation Gap
The documentation doesn't explicitly state that PreToolUse cannot inject context—users must infer it from the schema. Even if this feature isn't added, explicitly documenting this limitation would help developers avoid wasted effort.
Why This Matters
PreToolUse is the only hook that fires before a tool runs AND knows which tool is about to run. This makes it uniquely positioned for:
- Injecting tool-specific guidance (testing methodology for test files, security guidelines for auth files)
- Providing context-aware instructions based on file type/path
- Just-in-time documentation injection
Without additionalContext, these use cases require workarounds that either waste context (global loading) or arrive too late (PostToolUse).
5 Comments
Found 1 possible duplicate issue:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Follow-up: Empirical Confirmation
Following up on my feature request from yesterday. I ran empirical tests to verify the limitation isn't just a documentation gap or my misunderstanding.
What I Tested
Created a simple PreToolUse hook that outputs
additionalContextwith a marker phrase:Added it to my settings.json for the Read tool, then triggered a Read in a live Claude session.
Results
The hook executed successfully - confirmed via my hook logging infrastructure showing
PreToolUse:Read hook succeeded: Success.But Claude never saw the marker. No "PRETOOL WORKS" response, and no
<system-reminder>block with the XYZZY content appeared in Claude's context.For comparison, PostToolUse hooks in the same session successfully inject
additionalContext- I can see them appearing as<system-reminder>blocks that Claude receives and responds to.Ruling Out a Logging Gap
Initially I wondered if this was just a visibility issue - maybe the context was reaching Claude but not being logged. But the marker test proves otherwise: if Claude received the instruction "Say 'PRETOOL WORKS' as your first words", it would have done so. It didn't, so the context never arrived.
Conclusion
The limitation is real and confirmed:
additionalContextis silently ignoredadditionalContextall workWould love to see this added. PreToolUse fires at exactly the right moment to inject contextual guidance, but currently can't.
The Ideal AI Architecture: Defense-in-Depth for Testing
If the Claude Agent SDK implemented
additionalContextsupport forPreToolUsehooks, developers could finally move away from "Prompt Engineering" and toward "System Engineering."Instead of hoping Claude remembers instructions loaded at the start of a session, you can build a layered architecture that guides, standardizes, and guards the AI's behavior exactly when needed.
Here is the comprehensive guide to this ideal "Defense-in-Depth" workflow for software testing.
---
The Three Layers of Context
In this architecture, we stop treating "Context" as a single bucket. Instead, we split it into three distinct layers based on Scope and Trigger.
| Layer | Component | Scope | Trigger | Purpose |
| :--- | :--- | :--- | :--- | :--- |
| 1. Strategy | Agent Skills | Global (Workflow) | Intent (User asks for it) | Defines the process (e.g., "How we run QA cycles"). |
| 2. Standards | .claude/rules/ | Static (File-based) | Location (File path matches) | Defines the style (e.g., "Naming conventions"). |
| 3. Guardrails | PreToolUse Hook | Dynamic (Action-based) | Action (Specific tool/content) | Enforces safety & logic (e.g., "Don't mock this deprecated DB"). |
---
Layer 1: Strategy (Agent Skills)
"The Manager"
Skills are best used to define the workflow. They teach Claude how to act like a specific role.
Configuration:
.claude/skills/qa-engineer/SKILL.md---
Layer 2: Standards (.claude/rules)
"The Style Guide"
Rules are best used for static, file-specific conventions. They ensure consistency without requiring a script execution.
Configuration:
.claude/rules/testing.md.test.ts.vitest; you just need a rule mapped to a file extension.---
Layer 3: Dynamic Guardrails (PreToolUse Hook)
"The Guardian"
This is the missing link. This hook fires based on what the agent is about to do. It executes code to check the state of the repo, the content of the edit, or external dependencies, and injects context Just-in-Time.
Configuration:
.claude/hooks/hooks.jsonThe Logic (
check_test_integrity.py):Unlike the static Rules layer, this script can perform dynamic validation.
PaymentGatewayclass? Yes.PaymentGatewaywas deprecated yesterday.``
jsonPaymentGateway{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"additionalContext": "CRITICAL: You are attempting to mock
. This class was deprecated yesterday and removed from the build pipeline. You MUST mockUniversalPaymentClientinstead, or the tests will fail in CI."
``}
}
.claude/rules) cannot know that an API was deprecated yesterday. Only a script that queries a registry or checks a changelog can know that.---
The Complete Workflow in Action
Here is how these three layers combine to create a perfect development loop.
User Prompt: "I updated the user schema. Update the payment tests to match."
Editonsrc/payments/payment.test.ts..test.tsextension..claude/rules/testing.md.vitestandArrange-Act-Assertformatting.PreToolUsehook fires. The script analyzes the proposed code.PaymentGateway.additionalContextwarning about deprecation.PaymentGateway, but the system tells me it is deprecated. I will update my plan to useUniversalPaymentClientinstead."Edit.Summary of Benefits
If
PreToolUsesupportedadditionalContext, we would move from Correction to Prevention.Feature was implemented in v2.1.9.
-Added support for PreToolUse hooks to return additionalContext to the model
Thanks Anthropic!
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.