Claude Code mcp_tool hook skipped on SessionStart: Sume balance check
Claude Code's mcp_tool hooks are skipped on SessionStart and Setup because no MCP client exists yet. Run a Sume balance check at PreToolUse instead.

Version 2.1.283 of Claude Code added an mcp_tool hook entry, per the Claude Code changelog, read 2026-10-03. It lets a hook call an MCP tool directly. It has a timing limit that catches people who want a check at the start of a session. The hooks reference says SessionStart and Setup events fire before MCP is available, so mcp_tool hooks are skipped there, and the debug log says "mcp_tool hooks are not available for the 'SessionStart' hook event (no MCP client context)".
The hook's fields
According to the hooks page, an mcp_tool hook takes server, tool and input, with ${path} substitution from the hook input. A tool result with isError: true produces a non-blocking error. On PreToolUse and Stop the hook waits for a connecting server, for at most MCP_TIMEOUT and within the hook's own timeout. The matcher form is mcp__<server>__<tool>, and .* is required to match a whole server. An exit code of 2 blocks.
| Event | mcp_tool hook | Use for Sume |
|---|---|---|
| SessionStart | Skipped (no MCP client yet) | Use a command hook, or move the check |
| Setup | Skipped | Same |
| PreToolUse | Runs, waits for a connecting server | Check balance or preview cost before a create |
| Stop | Runs, waits for a connecting server | Record usage after the session |
A balance check that actually runs
Sume's tools and gates page lists balance_get and usage_get among its tools, and dry_run and generation_admission_preview for previewing cost. Attach the check to PreToolUse with a matcher for your create tools, for example mcp__sume__generate_video, so it runs just before the spend instead of at session start where it would be skipped.
Because isError: true is non-blocking, a failed balance check will not stop the create by itself. If you want a hard stop, use a script that exits with code 2. Put max_spend_usd on the create as well, because it is enforced only when provided.
What to remember
- A skipped hook produces a debug-log line, not a user-facing error; check the log if a SessionStart check seems silent.
- Waiting for a server is bounded by
MCP_TIMEOUT, so a slow connect can still skip your check by timing out. - The hook sees the tool input, so you can compare a requested cost with a limit before the call.
idempotency_keyis still required on paid and write tools; a hook does not supply it.
Sources
Related posts
More in Agents
- Claude Code plugin agents honor disallowedTools: block Sume paid tools
Since 2.1.288 plugin-defined agents run with their own prompt, tools, disallowedTools and effort. A reviewer agent that can read Sume jobs but never create one.
- Claude Code RETRY_WATCHDOG gives up after 3 timeouts: Sume jobs
Unattended Claude Code sessions using CLAUDE_CODE_RETRY_WATCHDOG now stop after three timeouts. Persist Sume job ids so a restart resumes, not resubmits.
- Claude Code routine API text is untrusted: pass Sume input as data
A routine's fire text arrives wrapped as untrusted data, and the saved prompt must opt in to use it. Sume's run input follows the same rule: data only.
- Claude Code routine connectors: leave Sume's Write off first
A new Claude Code routine includes every connector and can call write tools without asking. Grant Sume read-only first, then widen it on purpose.
Written by Sume