All pages
Agents
Claude Code
Connect Claude Code to Golem: hooks that block or hold a call before it runs, Golem's own MCP tools, and the shell jail on macOS.
Claude Code is connected when you install Golem: the installer runs golem setup-client, which writes Golem's hooks and MCP entries into your user settings. Restart Claude Code and every tool call it makes, built-in or MCP, is checked against your rules before it runs and signed into the record.
What Golem adds#
| File | What Golem adds |
|---|---|
~/.claude/settings.json | Hooks on PreToolUse, PostToolUse, SessionStart, UserPromptSubmit, UserPromptExpansion and PermissionDenied, each calling the Golem agent on 127.0.0.1 |
~/.claude/settings.json | On macOS, CLAUDE_CODE_SHELL in the env block, pointing at Golem's shell in ~/.golem/bin, so Bash runs in the shell jail |
~/.claude.json | Two MCP servers, golem-witness and golem-context, which give Claude Golem's own tools |
~/.claude/commands | /safely, and /sandbox on a Mac with the sandbox |
~/.claude/skills | The golem-fleet skill, and golem-sandbox on a Mac with the sandbox |
Golem only adds its own entries. Your other hooks, MCP servers and settings stay as they are, and a matcher you narrowed on Golem's hook is kept when golem setup-client repairs it. If you already set CLAUDE_CODE_SHELL to something else, Golem leaves it, and the shell jail is not attached.
The tool hooks are HTTP hooks. The PreToolUse one looks like this:
{
"hooks": {
"PreToolUse": [
{
"matcher": ".*",
"hooks": [
{
"type": "http",
"url": "http://127.0.0.1:39393/api/v1/hooks/tool-use",
"timeout": 45,
"headers": {
"X-Golem-Hold-Seconds": "35",
"X-Golem-Supports-Ask": "1"
}
}
]
}
]
}
}If you manage Claude Code's settings from a repository, copy the URL exactly, with 127.0.0.1 rather than localhost. Claude Code treats two different URLs as two hooks, so every call would be checked and recorded twice.
What a block looks like#
A call a rule blocks is refused before it runs. Claude sees the reason and passes it on to you:
blocked by Golem policy (rule "no-force-push-to-main", decision gd_3f9a1c07b2e4d815). Trying again won't change this; if you need it, ask your security team and quote the decision id.The rule name and decision id are what your security team needs. To ask them to let it through, run:
golem exception gd_3f9a1c07b2e4d815 --reason "release branch cleanup" --days 7The request goes to the console, where an admin decides it. See Block, hold and contain.
What a hold looks like#
A rule set to Ask holds the call until someone decides. Who decides is part of the rule, and it changes what you see in Claude Code:
- The person at the keyboard. Claude Code shows its own permission prompt, with Golem's reason:
held by Golem policy — approve to continue (rule "prod-changes-need-a-person", decision gd_9b04e2d61c7a35f8). Claude Code shows a hook's prompt in every permission mode,autoandbypassPermissionsincluded. In aclaude -prun ordontAskmode nobody can answer, so the call is refused. - Golem's reviewer agent. The hook holds the call for up to 35 seconds while the reviewer decides, then lets it through or refuses it. If no decision has come by then, Claude is told to wait and retry the same call, and the retry gets the answer.
- Your team. A hook cannot wait for someone to answer in the console, so the call is refused with a message saying your security team holds it, and the decision id to quote.
A rule set to Warn lets the call run and tells Claude it was flagged, so it can stop if that is not what you asked for.
Type /safely to lock the session to read-only tools before Claude reads something you don't trust. It only tightens: start a new session to loosen it. See Safely.
What is captured#
| What | From |
|---|---|
| Every tool call before it runs: tool, arguments, working directory, repository | PreToolUse |
| Every tool call's result | PostToolUse |
The session's permission mode on each call, for example bypassPermissions | the tool hooks |
| Claude Code's own refusals in auto mode | PermissionDenied |
| Each commit Claude makes, tied to its session | the Golem agent, from git |
| On macOS, every operation the shell jail refused, with the command that tried it | the shell jail |
MCP calls to your own servers are checked and recorded through the same hooks, as mcp__server__tool. The full content of each call goes to your storage; the record holds its hash and signature. See What Golem captures.
Your prompts and Claude's replies are not captured by the hooks. To add your prompts, turn on Claude Code's OpenTelemetry export and point it at the Golem agent, in the env block of ~/.claude/settings.json:
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_LOGS_PROTOCOL": "http/protobuf",
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT": "http://127.0.0.1:4318/v1/logs",
"OTEL_LOG_USER_PROMPTS": "1",
"OTEL_LOG_TOOL_DETAILS": "1"
}
}Check it is working#
- Quit Claude Code and start a new session. Claude Code reads hooks and MCP servers only at startup.
- Run
/mcpin Claude Code.golem-witnessandgolem-contextshould be connected. - Run
golem doctor. client wiring should be ok, and after Claude has run a tool, inline enforcement (claude-code) should say its tool calls reach the hooks. - Ask Claude to run a harmless command, such as
git status. The session appears in the console under Conversations shortly after.
Limits#
- The hooks fail open. If the Golem agent is not running, or a hook gets no answer within its 45 seconds, Claude Code runs the call. Nothing is checked or recorded until the agent is back.
golem doctorreports any tool that ran unchecked. - A wrong port fails silently. Claude Code shows no error for a hook it cannot reach. If you change the agent's port, run
golem setup-clientand check withgolem doctor. - The shell jail is macOS only, and covers Claude Code's Bash tool. Reads and edits through Claude's own file tools are checked by the hooks, not by the jail.
- Managed settings can switch Golem off. Claude Code's
strictPluginOnlyCustomizationsetting ignores hooks and MCP servers in user settings, which is where Golem's are. See Roll out to a fleet. - Settings files outside your user settings are not edited. A project's
.claude/settings.jsonthat registers its own copy of Golem's hooks is yours to keep correct.
See also Rules and CEL, Block, hold and contain, Coverage and Limits.