[FEATURE] BeforeModel and AfterModel Hooks for LLM Request/Response Interception

Open 💬 8 comments Opened Jan 28, 2026 by coygeek

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:

  1. Inspect what's being sent to the model - No way to see the full message history, system prompts, or configuration being passed to Claude
  2. Modify requests before they're sent - Cannot adjust temperature, inject additional context at the model level, or filter sensitive data from prompts
  3. Filter or transform model responses - Cannot redact sensitive information from responses, log token usage, or implement custom response caching
  4. 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 updatedRequest to 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 filteredResponse to 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

  1. 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.
  1. Current workarounds: Using UserPromptSubmit provides some pre-processing capability, but only for user messages—not the full conversation context or model configuration.
  1. 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

  1. Security team requires all LLM interactions to be logged with full request/response bodies
  2. They configure a BeforeModel hook that logs the complete request to their SIEM
  3. They configure an AfterModel hook that:
  • Logs the complete response
  • Scans for accidental PII disclosure
  • Redacts any detected PII before it's shown to the user
  1. All logging happens transparently without requiring developers to change their workflow

Scenario: Response caching for cost reduction

  1. Developer frequently asks similar questions about the codebase
  2. BeforeModel hook checks a local cache for matching requests
  3. If found, returns cached response (avoiding API call and cost)
  4. AfterModel hook stores new responses in cache

Scenario: Model parameter enforcement

  1. Organization policy requires temperature=0 for all code generation
  2. BeforeModel hook inspects config and modifies temperature if needed
  3. 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_request and llm_response to 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

View original on GitHub ↗

This issue has 8 comments on GitHub. Read the full discussion on GitHub ↗