Feature Request: Session-Scoped State Persistence for MCP-Tool Hooks

Resolved 💬 1 comment Opened Apr 30, 2026 by vikasagarwal101 Closed Jun 1, 2026

Feature Request: Session-Scoped State Persistence for MCP-Tool Hooks

Summary

The type: "mcp_tool" hook option enables hooks to invoke MCP tools in response to events (PostToolUse, PreToolUse, SubagentStop, etc.). However, the current hook execution model is completely stateless — each hook invocation is independent with no ability to maintain or access state across events within a session. This fundamentally limits the utility of MCP-tool hooks for any workflow that requires correlating multiple discrete events with shared session context.

Problem Statement

When using MCP-tool hooks to perform work-logging or audit-trail operations (e.g., "log every file edit to the task the agent is currently working on"), the hook system has no mechanism to determine which task the agent is working on at any given moment. The hook receives only the immediate event (tool name, inputs, outputs, duration) but has no access to:

  1. Session-scoped state — values that persist across hook invocations within the same session
  2. Prior tool results — outputs from earlier tool calls in the session that might establish context (e.g., which task was claimed)
  3. Conversation context — the user's messages or agent's reasoning that would indicate intent

This makes it impossible to implement patterns like:

  • "Log all file modifications to the task ID the agent claimed earlier in this session"
  • "Track work progress against a specific feature or work item"
  • "Correlate a series of tool calls with a single unit of work"

Concrete Example

Consider implementing a hook that logs an agent's work to a task management system:

Hook fires: PostToolUse (Bash, "npm run test")
  ↓
Hook has: toolName="Bash", input="npm run test", duration_ms=2341
  ↓
Hook needs: taskId="T-456" (the task the agent is working on)
  ↓
Hook cannot determine this because:
  - taskId was set by a prior board_claim_task call (result not accessible)
  - taskId was mentioned in a user message 10 turns ago (conversation not accessible)
  - No session-level state store exists for hooks to read/write

Proposed Solutions

Any of the following would address the core issue:

Option A: Hook-Level Session State

Allow hooks to maintain a state object that persists across invocations within a session:

{
  "hooks": [{
    "name": "work-logger",
    "events": ["PostToolUse"],
    "state": {
      "activeTaskId": null,
      "workLog": []
    },
    "if": "${toolName} != 'board_log_work'",
    "postToolUse": {
      "type": "mcp_tool",
      "tool": "log_work_entry",
      "args": {
        "taskId": "${state.activeTaskId}",
        "tool": "${toolName}",
        "duration": "${duration_ms}"
      },
      "setState": {
        "activeTaskId": "${lastResult.taskId}"
      }
    }
  }]
}

Option B: Prior Result References

Allow hook expressions to reference the result of the most recent matching tool call:

{
  "postToolUse": {
    "type": "mcp_tool",
    "tool": "log_work_entry",
    "args": {
      "taskId": "${lastResultOf('board_claim_task').taskId}"
    }
  }
}

Option C: Conversation Context Access

Allow hooks to access recent conversation messages for pattern matching:

{
  "postToolUse": {
    "type": "mcp_tool",
    "tool": "log_work_entry",
    "args": {
      "taskId": "${extractTaskIdFromRecentMessages}"
    }
  }
}

Why This Matters

The MCP-tool hooks feature is a powerful primitive — it allows MCP servers to serve as hook action handlers, bridging Claude Code events to external systems. But without session state, the feature is limited to truly stateless operations (sending notifications, firing webhooks with no context dependency).

Any workflow that requires correlating events with shared context is currently impossible to implement correctly. The work-logging example is one instance, but the pattern is general:

  • Tracking multi-step operations across a session
  • Implementing circuit breakers that count failures across invocations
  • Building session-level feature flags for experimental hook behaviors
  • Correlating agent actions with the user's original intent

Priority Assessment

This is a hard blocker for any stateful MCP-tool hook use case. Without session state, the feature works only for stateless notification-style hooks, which could already be handled by simpler mechanisms (Bash hooks calling curl, existing webhook systems, etc.).

The feature request is to make MCP-tool hooks first-class stateful event processors rather than stateless per-event action dispatchers.

---

Submitted via Claude Code CLI

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗