Skip to main content

Claude Code Integration

SigmaShake integrates with Claude Code in two complementary ways:

  1. MCP tools — Claude Code calls ssg_* tools directly to set up governance, search the Hub, write rules, and diagnose issues
  2. 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 eval as a PreToolUse handler
  • MCP server — registers ssg mcp-server as ssg-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 ClaudeTool
"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 ToolSSG Capability
Bashexecute
Readread
Write, Edit, MultiEditwrite
Glob, Grepsearch
Agentagent
WebFetch, WebSearchnetwork
Anything elseexecute (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:

  1. Terminal bell rings
  2. Claude Code displays: "Waiting for human approval..."
  3. Dashboard at http://localhost:5599 shows the queued decision
  4. You approve or deny in the dashboard
  5. 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

  1. Verify ssg mcp-server starts cleanly:
    echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | ssg mcp-server
  2. Restart Claude Code (MCP connections initialize at startup)
  3. Check ~/.claude/mcp_config.json or .claude/mcp_config.json for the ssg-governance entry

ASK decisions not appearing in dashboard

ssg status # check daemon is running
ssg serve # start dashboard at localhost:5599