Claude Code Integration
SigmaShake integrates with Claude Code in two complementary ways:
- MCP tools — Claude Code calls
ssg_*tools directly to set up governance, search the Hub, write rules, and diagnose issues - PreToolUse hook — Every tool call Claude Code makes is evaluated against your rules before it executes
Both are configured automatically by a single command.
Quick setup
ssg init --client=claude-code
This writes to .claude/settings.json (macOS/Linux: ~/.claude/settings.json, Windows: %USERPROFILE%\.claude\settings.json):
- Hook — registers
ssg hook evalas aPreToolUsehandler - MCP server — registers
ssg mcp-serverasssg-governance - Permissions — 14 standard tools pre-approved, 18 destructive patterns pre-denied
Restart Claude Code once, then say:
"Set up SigmaShake governance for my project"
MCP Tools (AI-assisted setup)
With the MCP server connected, Claude Code has access to 19 governance tools it can use autonomously:
| Ask Claude | Tool |
|---|---|
| "Set up SigmaShake for my project" | ssg_onboard — one-shot project setup |
| "Check if governance is working" | ssg_doctor — full health diagnostics |
| "Find TypeScript rules on the Hub" | ssg_hub_search |
| "Install rules-docker" | ssg_hub_pull |
| "Block kubectl in production" | ssg_write_rule — AI-authored rule |
See MCP Server for the complete tool reference.
PreToolUse Hook (runtime protection)
Every time Claude Code calls a tool, the PreToolUse hook runs ssg hook eval:
Claude calls: Bash("git push --force origin main")
↓
ssg hook eval evaluates against rules
↓
Decision: block
↓
Claude receives: "Force push is blocked."
Claude does NOT execute the command.
Hook configuration
The PreToolUse entry written to .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "",
"hooks": [{ "type": "command", "command": "ssg hook eval" }]
}
]
}
}
The matcher field is an empty string so the hook fires for every tool call. ssg init repairs a non-empty matcher on re-install.
Circuit breaker
After 5 consecutive DENY decisions, the hook auto-allows to prevent complete agent lockout. This guards against misconfigured rules that block all tool calls.
Reset: rm /tmp/ssg-deny-count (Windows: del %TEMP%\ssg-deny-count)
Permissions
ssg init --client=claude-code pre-configures permissions.allow and permissions.deny so you don't need to whitelist tools manually.
Allowed (14 standard tools):
Bash(*), Read, Write, Edit, MultiEdit, Glob, Grep, Agent,
WebFetch, WebSearch, TodoWrite, TodoRead, AskUserQuestion, ToolSearch
Denied (18 destructive patterns):
Categories covered: recursive deletion, disk-level writes (dd, mkfs variants), shell history wipe, output redirect truncation, force-push variants, hard resets, force-clean, crontab writes, and raw secret-file reads (.env, .env.*, */secrets/*).
The exact entry strings are defined in CLAUDE_CODE_PERMISSIONS.deny in src/engine/adapters/core.ts.
Permissions are merged additively — existing entries are never removed. Running ssg init again is safe.
Scope
By default ssg init --client=claude-code writes the hook to ~/.claude/settings.json (global), so every Claude Code session is governed regardless of which directory the agent is launched from.
To scope the hook to the current project directory only:
ssg init --client=claude-code --project-only
To write hooks and permissions to ~/.claude/settings.json globally (equivalent to the default, but can be re-run standalone to repair global settings):
ssg init --global
Allowed Domains and WebFetch mirroring
When you add a domain to the Allowed Domains list in the SSG dashboard, SSG can mirror that entry into Claude Code's own WebFetch(domain:...) permissions in ~/.claude/settings.json. This means a domain trusted in SSG is also trusted by Claude Code's permission layer without a separate manual step.
The dashboard calls POST /api/allowed-domains/webfetch with {base, wildcard, op: "add"|"remove"}. A wildcard entry maps to both WebFetch(domain:base) (exact host) and WebFetch(domain:*.base) (subdomains). The host is validated server-side; no client-supplied strings are written verbatim.
This mirroring is best-effort and additive — the SSG .rules ALLOW is the source of truth for governance decisions. Removing a domain from Allowed Domains removes the corresponding WebFetch permission entry.
Tool capability mapping
SigmaShake maps Claude Code's tool names to SSG capability categories for rule matching:
| Claude Code Tool | SSG Capability |
|---|---|
Bash | execute |
Read | read |
Write, Edit, MultiEdit | write |
Glob, Grep | search |
Agent | agent |
WebFetch, WebSearch | network |
| Anything else | execute (conservative default) |
Write rules targeting capabilities, not individual tools:
DENY execute → blocks Bash
DENY write → blocks Write, Edit, MultiEdit
DENY network → blocks WebFetch, WebSearch
Human approval flow (ASK rules)
When a rule uses ASK, Claude Code pauses and waits:
- Terminal bell rings
- Claude Code displays: "Waiting for human approval..."
- Dashboard at
http://localhost:5599shows the queued decision - You approve or deny in the dashboard
- Claude Code resumes with the result
Start the dashboard before using ASK rules:
ssg serve
Agent monitoring
Monitor Claude Code's Agent tool (sub-agent spawning):
rule log-explore-agents {
enabled true
LOG agent
IF input.subagent_type EQUALS "Explore"
MESSAGE "Explore agent activity logged."
}
rule block-background-agents {
enabled true
DENY agent
IF input.run_in_background EQUALS "true"
MESSAGE "Background agents require explicit approval."
}
The dashboard audit table shows agent subagent_type as inline badges.
Example rules for Claude Code
Require approval for deployments
rule require-approval-deploy {
enabled true
priority 90
severity error
ASK execute
IF command CONTAINS "deploy"
OR command CONTAINS "kubectl apply"
OR command CONTAINS "terraform apply"
MESSAGE "Deployment detected."
PROMPT "Allow this deployment?"
}
Block npm publish without approval
rule require-approval-npm-publish {
enabled true
priority 90
severity error
ASK execute
IF command CONTAINS "npm publish"
MESSAGE "npm publish detected."
PROMPT "Allow publishing to npm registry?"
}
Log all file writes to src/
rule log-src-writes {
enabled true
LOG write
IF path GLOB "src/**"
MESSAGE "Source file write logged."
}
Troubleshooting
Hook not triggering
Check the hook is registered:
cat .claude/settings.json | grep -A5 "PreToolUse"
Re-run if missing:
ssg init --client=claude-code
All tools being blocked
Check for broad rules:
ssg list # show all active rules
ssg lint # check for syntax issues
Reset circuit breaker:
rm /tmp/ssg-deny-count
MCP tools not visible in Claude Code
- Verify
ssg mcp-serverstarts cleanly:echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | ssg mcp-server - Restart Claude Code (MCP connections initialize at startup)
- Check
~/.claude/mcp_config.jsonor.claude/mcp_config.jsonfor thessg-governanceentry
ASK decisions not appearing in dashboard
ssg status # check daemon is running
ssg serve # start dashboard at localhost:5599
Related
- MCP Server — Complete MCP tool reference
- Rule Syntax — Full rule language reference
- Writing Rules — Best practices and patterns
- Dashboard — Real-time approval and audit UI