Monitoring changedmonitoring-usage
Nearest release: v2.1.304, published under an hour before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 19 Oct 2026 19:52 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 19 Oct 2026 20:07 UTC.
Upstream edited
Recorded here
Lines+41added
Lines−4removed
From line
304
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits60to this page, all time
The whole hunk
from line 304, old and new numbered
/
from line 304
304304| Attribute | Description | Gated by |
305305| - | - | - |
306306| `duration_ms` | Time spent waiting for the permission decision | |
307| `decision` | `accept` or `reject` | |
308| `source` | Decision source, matching the [Tool decision event](#tool-decision-event) | |
307| `decision` | `accept`, `reject`, or `cancelled`, where `cancelled` means Claude Code stopped waiting for a permission decision on the tool call and didn't run it | |
308| `source` | For an `accept` or `reject`, where the decision came from, such as `config`, `hook`, or `user_temporary`, with the meanings given under the [Tool decision event](#tool-decision-event). For a `cancelled`, what ended the wait before any decision was made, such as `user_abort` | |
309309
310A `cancelled` decision with `source` `user_abort` means a message needing immediate delivery interrupted the turn while the permission prompt or [auto mode](/docs/en/permission-modes#eliminate-prompts-with-auto-mode) check was pending. For example, during an auto mode check, the user had a message queued and [sent it immediately](/docs/en/interactive-mode#when-claude-code-sends-what-you-queued).
311
310312**`claude_code.tool.execution`**
311313
312314| Attribute | Description | Gated by |
from line 974
972974 * `"mcp"`: MCP servers generally
973975 * `"sdk_host_builtin_mcp"`: an in-process server built into Claude Desktop itself, in a session Claude Desktop owns. Claude Desktop owns a session it started from one of its own entrypoints, `claude-desktop`, `claude-desktop-3p`, or `local-agent`, when that session isn't a nested child; nested sessions, including sessions Claude Code itself spawns, report these servers as `"mcp"`
974976* `source`: Where the decision came from:
975 * `"config"`: Decided automatically without prompting, based on project settings, allow or deny rules in the user's personal settings, enterprise managed policy, `--allowedTools` or `--disallowedTools` flags, the active permission mode, a session-scoped grant from an earlier prompt in the same interactive CLI session, or because the tool is inherently safe. The event doesn't indicate which of these sources matched. Claude Code also reports `"config"` when the permission prompt request itself fails, for example when the Agent SDK's [`canUseTool`](/docs/en/agent-sdk/typescript#canusetool) callback or the [`--permission-prompt-tool`](/docs/en/cli-reference#cli-flags) tool returns an invalid result, or when the input stream closes while the request is pending. Before v2.1.216, Claude Code reported these failures as `"user_reject"`.
977 * `"config"`: Decided automatically without prompting, by one of these sources:
978
979 * Project settings
980 * Allow or deny rules in the user's personal settings
981 * Enterprise managed policy
982 * `--allowedTools` or `--disallowedTools` flags
983 * The active permission mode
984 * The auto mode classifier, whose verdict the same event records in `classifier_verdict`
985 * A grant for the rest of the session, given at an earlier permission prompt in the same interactive CLI session
986 * The tool being inherently safe
987
988 The `source` value doesn't indicate which of these sources matched.
989
990 Claude Code also reports `"config"` when the permission prompt request itself fails. For example, that request fails when the Agent SDK's [`canUseTool`](/docs/en/agent-sdk/typescript#canusetool) callback or the [`--permission-prompt-tool`](/docs/en/cli-reference#cli-flags) tool returns an invalid result, or when the input stream closes while the request is pending. Before v2.1.216, Claude Code reported these failures as `"user_reject"`.
976991 * `"hook"`: A `PreToolUse` or `PermissionRequest` hook returned the decision.
977992 * `"user_permanent"`: Emitted when the user chose "Yes, and don't ask again for ..." at a permission prompt, which saves an allow rule to their personal settings. In the interactive CLI this is emitted only for that choice itself; later calls that match the saved rule emit `"config"` instead. In Agent SDK or non-interactive `-p` sessions, both the initial choice and later rule matches emit `"user_permanent"`. Treated as an accept.
978993 * `"user_temporary"`: Emitted when the user chose "Yes" at a permission prompt for a one-time approval, or chose an option that grants access for the rest of the session on a file edit or read prompt. In the interactive CLI this is emitted only for the choice itself; later calls allowed by that session-scoped grant emit `"config"` instead. In Agent SDK or non-interactive `-p` sessions, both the choice and later matches emit `"user_temporary"`. Treated as an accept.
979994 * `"user_abort"`: Emitted when the user dismissed the permission prompt without answering. In Agent SDK and non-interactive `-p` sessions, this includes interrupting the turn while a `canUseTool` or `--permission-prompt-tool` permission request is pending; before v2.1.216, Claude Code reported that interrupt as `"user_reject"`. Treated as a reject.
980995 * `"user_reject"`: Emitted when the user chose "No" when prompted. In the interactive CLI this is emitted only for that choice itself; calls that match a deny rule in the user's personal settings emit `"config"` instead. In Agent SDK or non-interactive `-p` sessions, calls that match a deny rule in personal settings emit `"user_reject"`. Treated as a reject.
996* `classifier_verdict`: The auto mode [classifier](/docs/en/permission-modes#how-the-classifier-evaluates-actions) verdict for the call, or why Claude Code denied the call when none came. Requires Claude Code v2.1.301 or later
997
998 * `"allow"`: the classifier approved the call
999 * `"block"`: the classifier blocked the call. A classifier check that fails partway through can also end as `"block"`, so a partial classifier outage can appear as more blocks rather than as `"unavailable"`
1000 * `"no_verdict"`: the check ran but gave [no usable verdict](/docs/en/errors#auto-mode-cannot-determine-the-safety-of-an-action), so Claude Code denied the call. The denial doesn't mean the classifier found the call unsafe
1001 * `"unavailable"`: the request to the classifier failed, for example on a rate limit, timeout, or connection error, so Claude Code denied the call. With [server-side classifier review](/docs/en/permission-modes#server-side-classifier-review), it also marks a call denied because [the server returned no safety verdict](/docs/en/errors#the-server-returned-no-safety-verdict)
1002
1003 The attribute also appears on plan mode calls when [the classifier reviews commands in plan mode](/docs/en/permission-modes#analyze-before-you-edit-with-plan-mode). The attribute is absent in these cases:
1004
1005 * An allow or deny [permission rule](/docs/en/permissions#manage-permissions) decided the call
1006 * Claude Code approved the call in auto mode without asking the classifier
1007 * The user answered the prompt Claude Code showed after [repeated blocks](/docs/en/permission-modes#repeated-block-thresholds)
1008 * In a `-p` run without `--permission-prompt-tool`, Claude Code denied the call after repeated blocks because there was nobody to answer a prompt. That event reports `decision` as `"reject"` and `source` as `"config"`
1009* `classifier_category` (when `OTEL_LOG_TOOL_DETAILS=1`): The name of the [built-in rule](/docs/en/auto-mode-config#inspect-the-defaults-and-your-effective-config) the classifier named when it blocked the call, in lowercase with underscores, such as `"data_exfiltration"` for the Data Exfiltration rule. Requires Claude Code v2.1.301 or later. The attribute is present when all of these hold:
1010 * `classifier_verdict` is `"block"`
1011 * Claude Code sent the classifier request itself, rather than using [server-side classifier review](/docs/en/permission-modes#server-side-classifier-review)
1012 * The classifier named exactly one rule, and that rule is a built-in one rather than one you wrote
1013* `permission_mode`: [Permission mode](/docs/en/permission-modes) active when this call's permission check began: `"default"`, `"plan"`, `"acceptEdits"`, `"bypassPermissions"`, `"dontAsk"`, or `"auto"`. Manual mode appears as `"default"`. A [subagent](/docs/en/sub-agents#permission-modes) call reports the subagent's permission mode rather than the session's. Requires Claude Code v2.1.301 or later
9811014* `tool_parameters` (when `OTEL_LOG_TOOL_DETAILS=1`): JSON string containing tool-specific parameters. Same shape as the [Tool result event](#tool-result-event), minus post-execution fields such as `git_commit_id`. Values may differ from `tool_result` for an accepted call if the permission decision rewrites the tool input via `updatedInput`. Use this attribute to see which command was rejected when `decision` is `"reject"`.
9821015 * For `"sdk_host_builtin_mcp"` tools: `mcp_server_name` and `mcp_tool_name` are included even when `OTEL_LOG_TOOL_DETAILS` is off, because the host application defines these names; without them, a rejected call to one of these built-in servers would be unattributable on the default stream. For user-configured MCP servers, the event's `tool_name` is always the literal `"mcp_tool"`, and the server and tool names appear only in `tool_parameters` with the flag on; argument content requires the flag everywhere.
9831016 * For Bash tool: includes `bash_command`, `full_command`, `timeout`, `description`, `dangerouslyDisableSandbox`. The desktop app's workspace bash tool also reports `tool_name` as `Bash`, but includes only `bash_command`, `full_command`, and `timeout`
from line 1022
9891022
9901023Logged when the permission mode changes, for example from `Shift+Tab` cycling, exiting plan mode, or an auto mode gate check.
9911024
1025To group tool calls by the permission mode each was checked in, use `permission_mode` on the [Tool decision event](#tool-decision-event).
1026
9921027**Event Name**: `claude_code.permission_mode_changed`
9931028
9941029**Attributes**:
from line 1545
15101545
15111546| Signal | Event | Key attributes |
15121547| - | - | - |
1513| Tool call allowed or denied, and by what | `tool_decision` | `decision`, `source`, `tool_name`, `tool_parameters` |
1548| Tool call allowed or denied, and where the decision came from, such as a rule, a hook, or the user | [`tool_decision`](#tool-decision-event) | `decision`, `source`, `classifier_verdict`, `permission_mode`, `tool_name`; `tool_parameters` when you set `OTEL_LOG_TOOL_DETAILS=1` |
1549| Auto mode classifier allowed or blocked a tool call, or Claude Code denied the call without a classifier verdict | [`tool_decision`](#tool-decision-event) where `classifier_verdict` is present. For a denial without a verdict, `classifier_verdict` is `"no_verdict"` or `"unavailable"` | `classifier_verdict`, `permission_mode`, `tool_name`; `classifier_category` when you set `OTEL_LOG_TOOL_DETAILS=1` |
15141550| Permission mode escalation | `permission_mode_changed` | `from_mode`, `to_mode`, `trigger` |
1551| Which permission mode each tool call was checked in, including calls subagents make | [`tool_decision`](#tool-decision-event) | `permission_mode`, `session.id` |
15151552| Policy hook blocked an action | `hook_execution_complete` | `hook_event`, `num_blocking` |
15161553| Login, logout, and authentication failure | `auth` | `action`, `success`, `error_category` |
15171554| MCP server connect or failure | `mcp_server_connection` | `status`, `server_name`, `is_plugin`, `error_code` |
No line in this hunk matches that.