[FEATURE] BeforeModel and AfterModel Hooks for LLM Request/Response Interception
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
Currently, Claude Code hooks operate at the tool execution level (PreToolUse, PostToolUse) but provide no visibility or control over the actual LLM requests and responses. Users cannot:
- Inspect what's being sent to the model - No way to see the full message history, system prompts, or configuration being passed to Claude
- Modify requests before they're sent - Cannot adjust temperature, inject additional context at the model level, or filter sensitive data from prompts
- Filter or transform model responses - Cannot redact sensitive information from responses, log token usage, or implement custom response caching
- Implement request-level policies - Cannot enforce organization-wide rules about model parameters or message content
This limits advanced use cases like compliance auditing, custom caching layers, response filtering for sensitive environments, and debugging model behavior.
Proposed Solution
Add two new hook events: BeforeModel and AfterModel
BeforeModel Hook
Fires before each LLM API request is sent. Receives:
{
"session_id": "abc123",
"hook_event_name": "BeforeModel",
"llm_request": {
"model": "claude-sonnet-4-20250514",
"messages": [
{"role": "user", "content": "..."},
{"role": "assistant", "content": "..."}
],
"config": {
"temperature": 1.0,
"max_tokens": 8192
},
"tool_config": {
"tools": ["Bash", "Read", "Write", "Edit", "Glob", "Grep"]
}
}
}
Output options:
- Allow: Let request proceed unchanged
- Modify: Return
updatedRequestto change parameters - Block: Prevent the request with a reason
- Mock: Return a synthetic response to skip the actual API call (see related feature request)
AfterModel Hook
Fires after receiving an LLM response. Receives:
{
"session_id": "abc123",
"hook_event_name": "AfterModel",
"llm_request": { ... },
"llm_response": {
"content": "...",
"stop_reason": "end_turn",
"usage": {
"input_tokens": 1500,
"output_tokens": 500
},
"tool_calls": [...]
}
}
Output options:
- Allow: Let response proceed unchanged
- Filter: Return
filteredResponseto redact or modify content - Block: Reject the response and force a retry with reason
Configuration Example
{
"hooks": {
"BeforeModel": [
{
"hooks": [
{
"type": "command",
"command": "/path/to/request-logger.py"
}
]
}
],
"AfterModel": [
{
"hooks": [
{
"type": "command",
"command": "/path/to/response-filter.py"
}
]
}
]
}
}
Alternative Solutions
- Proxy approach: Users could theoretically route Claude Code through a custom proxy, but this requires significant infrastructure, doesn't integrate with the hooks system, and breaks for API-key authenticated requests.
- Current workarounds: Using
UserPromptSubmitprovides some pre-processing capability, but only for user messages—not the full conversation context or model configuration.
- External logging: Organizations can enable API logging at the Anthropic account level, but this doesn't allow for real-time intervention or modification.
Priority
High - Significant impact on productivity
This unlocks entirely new categories of use cases that are currently impossible.
Feature Category
Configuration and settings
Use Case Example
Scenario: Enterprise compliance logging
- Security team requires all LLM interactions to be logged with full request/response bodies
- They configure a
BeforeModelhook that logs the complete request to their SIEM - They configure an
AfterModelhook that:
- Logs the complete response
- Scans for accidental PII disclosure
- Redacts any detected PII before it's shown to the user
- All logging happens transparently without requiring developers to change their workflow
Scenario: Response caching for cost reduction
- Developer frequently asks similar questions about the codebase
BeforeModelhook checks a local cache for matching requests- If found, returns cached response (avoiding API call and cost)
AfterModelhook stores new responses in cache
Scenario: Model parameter enforcement
- Organization policy requires temperature=0 for all code generation
BeforeModelhook inspects config and modifies temperature if needed- Logs any policy violations for audit
Additional Context
Prior Art
Gemini CLI (released January 2026) implements this exact feature:
BeforeModel: "Operates on stable SDK-agnostic format" with ability to "override request, inject synthetic response, block"AfterModel: "Fires per-chunk during streaming" with ability to "redact/filter chunks, block turn"
Their documented LLMRequest schema provides:
{
"model": "string",
"messages": [{"role": "user|model|system", "content": "string"}],
"config": {"temperature": "number"},
"toolConfig": {"mode": "string", "allowedFunctionNames": ["string"]}
}
This demonstrates the feature is implementable and provides clear user value.
Implementation Considerations
- Schema stability: Define a stable, versioned schema for
llm_requestandllm_responseto avoid breaking hooks on internal changes - Performance: Consider making AfterModel optional or rate-limited since it fires frequently
- Streaming: Decide whether AfterModel fires once per response or per-chunk (Gemini does per-chunk)
- Security: Same security considerations as existing hooks apply
This issue has 8 comments on GitHub. Read the full discussion on GitHub ↗