Claude Code Hooks: Automate Your Agent Workflow
Use Claude Code hooks as a deterministic control layer around agent and MCP actions, not as a substitute for the tools themselves.

The short answer
Claude Code hooks are event-driven automations that run before or after agent actions, at session boundaries, and at other lifecycle events. Today they can inspect or block MCP tool calls, invoke an already connected MCP tool, run commands, or call HTTP endpoints—but they do not replace an MCP server or make one portable across clients.
Table of contents
This guide covers the mechanism, a verified setup, client differences, failure modes, and the first MCP connections worth making.
- How Claude Code hooks work today
- Step-by-step setup
- Claude Code vs other MCP clients
- The catch most guides skip
- What to connect first
- Our verdict
How Claude Code hooks work today
Hooks are deterministic rules around Claude Code’s agent loop: an event fires, a matcher selects relevant events, and a handler runs. MCP connects Claude Code to outside systems; hooks decide what happens around those connections.
The official hooks reference documents events including PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, SessionStart, and Stop. A handler can be a command, HTTP request, prompt, agent, or mcp_tool. Command hooks receive JSON on standard input with common and event-specific fields.
MCP tools appear in tool events under the documented pattern mcp__<server>__<tool>. A regular-expression matcher such as mcp__.*__write.* can target write-named tools across connected servers. Conversely, an mcp_tool handler triggers a specific tool on a connected server, so it requires the real server key, tool name, and input schema.
This separation is the design’s best feature. MCP gives the model optional capabilities; hooks provide repeatable checks, logs, notifications, or blocks. For general installation, start with our guide to adding an MCP server, then add hooks only where an event needs policy or automation.
Step-by-step setup
Start with an observable PostToolUse hook, prove that matching works, and only then add a blocking PreToolUse policy. This keeps a typo from stopping legitimate work.
-
Choose the correct scope. Put a personal experiment in
.claude/settings.local.json, a team rule in.claude/settings.json, or a cross-project rule in~/.claude/settings.json. There is no standalone.claude/hooks.json; Anthropic’s configuration troubleshooting guide calls that out as a common failure. -
Create the hook script. Save this as
.claude/hooks/log-mcp.sh. It records only the event and tool name, avoiding full tool inputs in the log.
#!/bin/sh
mkdir -p .claude/logs
jq -c '{event: .hook_event_name, tool: .tool_name}' \
>> .claude/logs/mcp-tools.jsonl
On macOS or Linux, run chmod +x .claude/hooks/log-mcp.sh. The official examples also use jq; install it first or use an approved parser.
- Register the hook. Add this documented structure to the chosen settings file. Merge the
hooksproperty if the file already contains settings.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"hooks": {
"PostToolUse": [
{
"matcher": "mcp__.*",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/log-mcp.sh",
"args": [],
"timeout": 10
}
]
}
]
}
}
${CLAUDE_PROJECT_DIR} is an official path placeholder, and exec-form args avoids shell-splitting paths with spaces. See Anthropic’s path-handling guidance.
-
Connect and verify an MCP server separately. Use the vendor’s exact instructions or browse MCP Directory’s best MCP servers.
claude mcp listreports health,/mcphandles status and OAuth, and project-shared servers live in.mcp.json, according to the Claude Code MCP guide. -
Test with a harmless read. Open
/hooksand confirm the source, event, matcher, and command. Perform a read-only MCP action, then inspect.claude/logs/mcp-tools.jsonl. If no line appears, check the actual tool name before changing the matcher. -
Promote enforcement carefully. A
PreToolUsecommand can inspecttool_inputand return a documented denial or exit with code 2. Keep the test narrow and return a useful reason.

Claude Code vs other MCP clients
Claude Code’s documented hook event system is the strongest choice when lifecycle control matters, but it is not the only client with hooks. The trade-off is terminal-centric configuration in exchange for finer event coverage and MCP-aware matching.
| Client | Lifecycle hooks | MCP setup | Practical trade-off |
|---|---|---|---|
| Claude Code | Broad event system; can match MCP calls and invoke MCP tools | CLI plus .mcp.json and user/local scopes | Best policy control; more scripting and debugging |
| Claude Desktop | No equivalent general coding-agent hook layer in Chat | Connectors and desktop extensions through Settings | Easiest installation; less lifecycle control |
| Cursor | Custom script hooks are available, introduced as beta | .cursor/mcp.json for projects or global configuration | Good editor workflow; hook schema is not Claude-compatible |
| Windsurf | Its MCP guide does not document an equivalent hook system | Marketplace or ~/.codeium/windsurf/mcp_config.json | Convenient discovery; another configuration dialect |
Cursor’s hooks announcement says scripts can observe or control Agent behavior. Do not copy Claude settings into Cursor: event names, paths, and decisions are client features, not part of MCP. Windsurf’s MCP documentation accepts serverUrl or url and uses its own interpolation syntax.
For a GUI-first workflow, Claude Desktop is easier. Anthropic directs users to Settings → Connectors for remote services and Settings → Extensions for local packages, a different model from repository-owned hooks.
The catch most guides skip
A hook is local code running with your user’s access, and valid configuration does not make it safe, portable, or cheap. Treat it as part of the execution boundary, not a vague prompt.
What actually breaks:
- Exit code 1 is non-blocking for most events. To stop a call, use the documented JSON decision or exit code 2.
- An asynchronous command hook cannot block; the protected action may finish before it reports back.
Stopand several other events ignore matchers, creating false confidence in copied configurations.- Command hooks have no interactive terminal, so scripts waiting for input can hang or fail.
- MCP-aware hooks fail when a server is disconnected, unauthenticated, renamed, or exposes a changed schema.
- There is no per-hook off switch; removal or tighter scoping is often cleaner than
disableAllHooks.
I use command hooks for fast deterministic checks, HTTP hooks for a service I operate, and model-backed hooks only when judgment is required. Model checks add latency and may add usage cost; synchronous hooks extend the critical path. The MCP security guidance warns that local servers can execute with the client’s privileges, so narrow filesystem, network, and token access instead of assuming a sandbox.
What to connect first
Connect one read-heavy service tied to a real workflow, then add a hook around its riskiest action. Avoid installing a dozen overlapping servers on day one; more tools mean more permissions and harder audits.
-
GitHub MCP Server. Start here for issues, pull requests, Actions failures, and repository operations. GitHub maintains the official server and offers read-only and lockdown modes; begin read-only and enable mutations only after the workflow earns trust.
-
Sentry MCP. Connect it when diagnosis requires switching between code and production traces. The Sentry-maintained server targets human-in-the-loop coding agents, making it a better observability choice than a broad generic API bridge.
-
Notion MCP. Use it when specifications and decisions live in Notion. Notion’s official setup guide uses hosted OAuth and notes that human authorization is unsuitable for fully headless automation—a limit worth accepting rather than bypassing with an abandoned package.
I would not connect a filesystem MCP server first because Claude Code already has native file tools. The duplicate capability widens the permission surface without adding much value.
Our verdict
Use Claude Code hooks as a small, reviewed policy layer around a few trusted MCP servers. MCP Directory’s preferred pattern is observe first, enforce second, and keep each hook narrow enough that a teammate can explain when it fires, what it receives, and how it fails.
That costs some convenience: you must maintain scripts and client-specific configuration. In return, agent automation becomes auditable and predictable, which matters once a workflow can modify repositories, incidents, or company knowledge.