Building Incident Response Automation in Practice with Claude Code Hooks + MCP
From Jira Ticket Creation and Datadog Queries to Audit Logs — Including CVE Response and Security Configuration
A PagerDuty alert fires. For the next 20 minutes, you can't look at a single line of code. You open the Datadog dashboard, dig through logs, manually create a ticket in Jira, and relay the situation to the on-call engineer over Slack — an endless cycle of context switching. The incident drags on while your hands are busy switching tabs.
This article covers a practical setup for automating that repetitive work at the AI agent layer. It provides a step-by-step guide on how to combine Claude Code Hooks with MCP (Model Context Protocol) servers to programmatically build automatic Jira ticket creation, Datadog incident queries, and an enterprise-wide audit log pipeline. The core idea is to handle the entire incident response workflow from within the IDE — no switching to Jira or Datadog dashboards. Audit logs and production guards are layers that stack on top.
To follow along with this guide, it helps to have the Claude Code CLI installed, Node.js (with npx available), and Atlassian and Datadog accounts ready. If you're new to MCP concepts, it's recommended to first skim the official MCP server connection documentation.
Core Concepts
What Happens When These Two Technologies Combine
Let's start with the big picture. The key to this setup is a separation of responsibilities: Hooks handle governance inside Claude Code, while MCP servers handle communication with external systems.
[Incident occurs]
↓
Code change detected (PostToolUse Hook)
↓
Datadog MCP: Query anomaly detection (list_incidents, search_logs)
↓
Jira MCP: Auto-create ticket (create_issue)
↓
Slack MCP: Send RCA summary to on-call channel
↓
Audit log recorded (PostToolUse Hook → JSONL)Configuration files are organized by purpose:
~/.claude/settings.json # Global (user) settings
<project>/.claude/settings.json # Project settings (recommended to Git commit)
<project>/.claude/settings.local.json # Local overrides (exclude from Git)Claude Code Hooks: A Deterministic Layer Outside AI Judgment
Claude Code Hooks are user-defined shell commands that run automatically at specific points in the Claude Code lifecycle. The key point is that "the AI doesn't make the decision."
What does Deterministic mean? It means the same input always produces the same output. Unlike the probabilistic judgment of an AI model, a hook will always execute its defined action when a condition is met. This is why hooks are well-suited for "policies that must be enforced."
The hook events listed in the official documentation are as follows:
| Event | Trigger Point | Primary Use |
|---|---|---|
PreToolUse |
Immediately before a tool call | Pre-emptively blocking dangerous operations, approvals |
PostToolUse |
After a tool succeeds | Quality checks, notifications, audit logs |
Notification |
While waiting for input | Sending Slack/Discord notifications |
Stop |
On normal session termination | Cleanup tasks, final reporting |
SubagentStop |
On subagent termination | Subtask completion handling |
PreCompact |
Before context compression | Preserving important information |
Additional events such as
StopFailureandPermissionRequestare experimental features included in the March 2026 update. It is recommended to check the official documentation for their current status before use.
MCP: Standardizing Fragmented AI Integrations
MCP is an open-source standard protocol led by Anthropic, now governed by the independent Model Context Protocol Foundation. It allows AI agents to communicate with external systems through a single JSON-RPC 2.0-based interface. Major SaaS vendors like Atlassian, Datadog, and Salesforce have released official servers, establishing MCP as an enterprise standard.
MCP tools are exposed using the mcp__<server-name>__<tool-name> pattern, which can be matched identically in a hook's matcher field.
There are two connection methods:
| Method | Configuration | Use Case |
|---|---|---|
| stdio | Specify command + args + env |
Locally installed servers (e.g., Atlassian MCP) |
| remote | Specify type: "remote" + url + headers |
Cloud-hosted servers (e.g., Datadog MCP) |
Example 1 (Jira) uses the stdio method; Example 2 (Datadog) uses the remote method. Understanding the difference between these two methods makes applying other MCP servers much easier.
Practical Application
The following five examples are arranged in order along the incident response workflow. Reading them in the sequence of Detection (Example 2) → Ticket Creation (Example 1) → Prevention (Example 3) → Quality Gate (Example 4) → Recording (Example 5) provides continuous context for the full pipeline.
Example 1: Automatic Jira Ticket Creation + Audit Log
This configuration connects the official Atlassian Remote MCP Server and automatically records an audit log after a ticket is created.
{
"mcpServers": {
"jira": {
"command": "npx",
"args": ["-y", "@atlassian/mcp-server"],
"env": {
"ATLASSIAN_API_TOKEN": "${ATLASSIAN_API_TOKEN}",
"ATLASSIAN_BASE_URL": "https://your-org.atlassian.net"
}
}
},
"hooks": {
"PostToolUse": [
{
"matcher": "mcp__jira__create_issue",
"hooks": [
{
"type": "command",
"command": "echo '[AUDIT] Jira ticket created: '$(echo \"$CLAUDE_TOOL_RESPONSE\" | jq -r .key) >> /var/log/claude-audit.log"
}
]
}
]
}
}| Configuration Item | Role |
|---|---|
mcpServers.jira |
Defines the Atlassian MCP server connection via stdio |
ATLASSIAN_API_TOKEN |
Injects credentials via environment variable — never hardcode directly |
matcher: "mcp__jira__create_issue" |
Runs the hook only at the moment a Jira ticket is created |
CLAUDE_TOOL_RESPONSE |
Environment variable containing the tool response JSON, parseable with jq |
Example 2: Datadog Incident Query and RCA Automation
When an incident is detected, the Datadog Remote MCP Server allows you to query logs, metrics, and traces directly from Claude Code. This is an especially useful scenario for SRE and DevOps environments.
{
"mcpServers": {
"datadog": {
"type": "remote",
"url": "https://mcp.datadoghq.com",
"headers": {
"DD-API-KEY": "${DD_API_KEY}",
"DD-APPLICATION-KEY": "${DD_APP_KEY}"
}
}
}
}The key tools available after connecting are as follows:
| Tool Name | Function |
|---|---|
list_incidents |
Query the list of active incidents |
query_metrics |
Query time-series metrics |
search_logs |
Search logs with advanced filtering |
create_monitor |
Create threshold-based monitors |
create_downtime |
Suppress notifications during maintenance windows |
Actual response workflow: PagerDuty alert triggers → Claude Code investigates logs and traces via list_incidents and search_logs → Analyzes recent codebase changes → Sends RCA summary to on-call channel via Slack MCP → Auto-creates ticket via Jira MCP from Example 1.
Example 3: Protecting the Production Environment with a PreToolUse Hook
This guard script blocks commands that directly access the production environment before they execute.
#!/bin/bash
# hooks/guard-production.sh
TOOL_INPUT=$(cat)
TARGET=$(echo "$TOOL_INPUT" | jq -r '.command // .path // ""')
if echo "$TARGET" | grep -qE "(production|prod-db|main-cluster)"; then
# The block decision is passed via JSON on stdout. exit 0 signifies normal termination of the hook script itself.
echo '{"decision": "block", "reason": "Direct access to the production environment must go through an approval workflow."}'
exit 0
fi{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash hooks/guard-production.sh"
}
]
}
]
}
}Important: The
PostToolUsehook triggers after a tool has executed. It is important to usePreToolUsefor pre-emptively blocking dangerous operations. Attempting to block withPostToolUseresults in the hook reacting to a command that has already run.In the script above, the block decision is passed via JSON on stdout (
{"decision": "block", ...}).exit 0signifies normal termination of the hook script itself; the exit code does not determine whether the action is blocked.
Example 4: Quality Gate with PostToolUse Hook + Automatic Jira Bug Ticket Integration
If you've modified code during incident response, this pipeline automatically runs a linter after the edit completes and auto-creates a Jira bug ticket on failure.
#!/bin/bash
# hooks/quality-gate.sh
RESULT=$(npm run lint --silent 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
# The following is a conceptual example. Verify actual Claude Code CLI flags in the official documentation.
claude -p "Create a Jira bug ticket with summary 'Lint failure detected' \
and description: $(echo "$RESULT" | head -c 500)" \
--mcp-server jira
fi{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "bash hooks/quality-gate.sh"
}
]
}
]
}
}Example 5: Enterprise-Wide Audit Log Pipeline
This enterprise audit log configuration records the entire response process in JSONL format. It can be used by organizations with compliance requirements.
{
"hooks": {
"PostToolUse": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "jq -n --argjson input \"$(printenv CLAUDE_TOOL_INPUT)\" --argjson response \"$(printenv CLAUDE_TOOL_RESPONSE)\" '{timestamp: now | todate, tool: env.CLAUDE_TOOL_NAME, user: env.USER, input: $input, response: $response}' >> /var/log/claude-enterprise-audit.jsonl"
}
]
}
]
}
}The
.*matcher: This regular expression matches all tools. It is useful when you need to track all tool calls, as with an audit log, but it is recommended to apply it selectively as unnecessary hook executions can impact performance.Direct interpolation in the form
--argjson input $VARcan cause jq parsing errors if the value contains spaces or special characters. Wrapping it as"$(printenv VAR)"is safer.
Pros and Cons Analysis
Advantages
| Item | Description |
|---|---|
| Deterministic control | Rules are enforced without AI judgment, ensuring governance consistency |
| Single protocol | Connects Jira, Datadog, Slack, GitHub, and more via the same interface with MCP |
| Git-committable | .claude/settings.json lives in the project root, allowing the whole team to share the same hooks |
| Unified local & remote | PreToolUse/PostToolUse handles local tools and MCP tools identically |
| Eliminates context switching | Handles the entire workflow within the IDE without switching to Jira or Datadog dashboards |
| Scalability | Hundreds of major SaaS vendors and community servers support MCP, with rapid adoption |
Disadvantages and Caveats
| Item | Description | Mitigation |
|---|---|---|
| CVE-2025-59536 (CVSS 8.7) | Cloning a repository containing a malicious .claude/settings.json can execute arbitrary code before the trust dialog appears |
Review the contents of settings.json directly after cloning a Git repository |
| CVE-2026-21852 (CVSS 5.3) | API key theft via ANTHROPIC_BASE_URL override |
Manage an environment variable whitelist and control injection paths |
| Files API abuse (unpatched) | API key injection can allow uploading victim files to an attacker's account | Configure sandbox settings and a deny list |
| OAuth re-authentication burden | SSE-based MCP servers require re-authentication every 1–4 hours | Recommended to switch to API token method (officially supported by Atlassian) |
| Multiple MCP server conflicts | Risk of context pollution and tool name collisions when connecting many servers simultaneously | Minimize the number of servers and clarify namespace rules |
| Hook script injection | Since hooks execute shell commands, there is an injection risk when processing external input | Apply input sanitization and the principle of least privilege |
Secret Management: It is best practice not to enter credentials such as
ATLASSIAN_API_TOKENandDD_API_KEYdirectly intosettings.json. It is recommended to reference environment variables using the${ENV_VAR}format and inject them through a CI/CD secret manager (Vault, AWS Secrets Manager, etc.). It is a baseline principle to exclude.claude/settings.local.jsonfrom Git.
The Most Common Mistakes in Practice
- Attempting to block production with
PostToolUse: Since the event occurs after the tool has already executed, it has no blocking effect. It is recommended to apply all policies requiring pre-emptive blocking toPreToolUse. - Using a third-party repository's
settings.jsonwithout reviewing it: As demonstrated by CVE-2025-59536, a malicious configuration file can lead to code execution. It is recommended to directly review the contents of.claude/settings.jsonafter cloning an external repository. - Passing external input to hook scripts without validation: Directly interpolating environment variables like
$CLAUDE_TOOL_INPUTinto shell commands can lead to command injection. It is recommended to safely wrap them as"$(printenv VAR)"or parse them with jq.
Closing Thoughts
With this setup in place, the 20–30 minutes previously spent on context switching during incident response can be handled without ever leaving the IDE. Since powerful automation must be accompanied by equally robust security design, it is recommended to complete your configuration with reference to the CVE entries and the secret management guide.
Three steps you can start with right now:
- [~5 minutes] Verify Datadog MCP connection: Create
.claude/settings.jsonin your project root and add the Datadog Remote MCP configuration from Example 2. Set theDD_API_KEYandDD_APP_KEYenvironment variables, and you can immediately call thelist_incidentstool from Claude Code. - [~15 minutes] Deploy your first production guard: Write the
hooks/guard-production.shscript and connect it to thePreToolUseevent. You can verify that commands accidentally accessing the production environment are safely blocked before they execute. - [Full team rollout] Complete the audit log pipeline: Combine the
matcher: ".*"pattern with the JSONL logging hook and commit the configuration file to Git to gain visibility into the AI agent activity of your entire team.
Next article: An enterprise MCP governance architecture design guide covering centralized management of RBAC, audit trails, and token vaults in a multi-agent environment using MCP gateways (ScopeBlind, Webrix).
References
- Hooks Reference Official Documentation | Claude Code Docs
- Automating Workflows with Hooks (Korean) | Claude Code Docs
- Connecting MCP Servers | Claude Code Docs
- Atlassian Remote MCP Server Official Announcement | Atlassian Blog
- Atlassian MCP Server GitHub | atlassian/atlassian-mcp-server
- Datadog MCP Server Official Documentation | Datadog
- Datadog MCP Server Blog — Observability for AI Agents | Datadog
- 4 Use Cases from the Datadog MCP Engineering Team | Datadog
- Jira MCP Integration Guide | Workato
- Jira MCP + Claude Code Connection Guide | Composio
- CVE-2025-59536: RCE via Claude Code Project Files | Check Point Research
- Claude Code MCP Governance and Enterprise Security | Obot.ai
- MCP as Enterprise Infrastructure: MCP Dev Summit 2026 Review | AAIF
- ScopeBlind Gateway — MCP Policy Gateway | GitHub
- Official MCP Server Registry | GitHub
- 2026 MCP Roadmap | Model Context Protocol Official Blog