Wrap Your First Agent
In this tutorial, you'll wrap Claude Code with ThoughtGate to govern its MCP tool calls. You'll start with a passthrough config, add deny rules, and try development mode — all without modifying Claude Code's source.
What You'll Learn
- How
thoughtgate wrapdiscovers and rewrites agent configs - How governance rules control tool calls
- How
--dry-runpreviews changes safely - How profiles let you observe before enforcing
Prerequisites
- Rust 1.87+ installed (
rustup updateif needed) - Claude Code installed and working (
claude --version) - At least one MCP server configured in Claude Code (check
~/.claude.json)
Step 1: Install ThoughtGate
Build and install the CLI binary:
git clone https://github.com/thoughtgate/thoughtgate
cd thoughtgate
cargo install --path thoughtgate
Verify the installation:
thoughtgate --help
You should see the wrap and shim subcommands listed.
Step 2: Create a Minimal Config
Create thoughtgate.yaml in your project directory with a passthrough configuration:
schema: 1
sources:
- id: upstream
kind: mcp
url: http://localhost:3000 # Unused in stdio mode, but required by schema
governance:
defaults:
action: forward # Forward everything — no blocking yet
This config forwards all tool calls without any governance. We'll add rules shortly.
Step 3: Preview with Dry Run
Before making any changes, use --dry-run to see what ThoughtGate would do:
thoughtgate wrap --dry-run -- claude-code
ThoughtGate will:
- Auto-detect Claude Code from the command name
- Find
~/.claude.jsonand read your MCP server configs - Print the config diff showing how each server's
commandwould be rewritten
Detected agent: ClaudeCode
Config file: /Users/you/.claude.json
Servers found: 2 (filesystem, github)
--- original
+++ rewritten
"filesystem": {
- "command": "npx",
- "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
+ "command": "/Users/you/.cargo/bin/thoughtgate",
+ "args": ["shim", "--server-id", "filesystem", "--governance-endpoint",
+ "http://127.0.0.1:0", "--profile", "production",
+ "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
No files are modified during a dry run.
Step 4: Wrap the Agent
Run Claude Code through ThoughtGate:
thoughtgate wrap -- claude-code
ThoughtGate will:
- Back up
~/.claude.jsonto~/.claude.json.thoughtgate-backup - Start the governance HTTP service on an ephemeral port
- Rewrite your MCP server configs to route through ThoughtGate shims
- Launch Claude Code
- Restore the original config when you exit
Use Claude Code normally. All tool calls pass through because defaults.action: forward.
Step 5: Observe Governance Logs
While Claude Code is running, watch the ThoughtGate logs. Every tool call is logged:
INFO governance: tool=read_file server=filesystem action=forward
INFO governance: tool=list_files server=filesystem action=forward
This confirms ThoughtGate is intercepting and forwarding tool calls.
Step 6: Add a Deny Rule
Exit Claude Code (Ctrl+C or quit normally — ThoughtGate restores your config automatically).
Update thoughtgate.yaml to deny admin tools:
schema: 1
sources:
- id: upstream
kind: mcp
url: http://localhost:3000
governance:
defaults:
action: forward
rules:
- match: "admin_*"
action: deny
- match: "delete_*"
action: deny
Re-wrap and try calling a denied tool:
thoughtgate wrap -- claude-code
If the agent tries to call delete_user or admin_reset, it receives a -32003 PolicyDenied error instead of the tool executing.
Step 7: Try Development Mode
Development mode lets you observe what would be blocked without actually blocking:
thoughtgate wrap --profile development -- claude-code
Now when a denied tool is called, you'll see:
WOULD_BLOCK tool=delete_user rule=delete_* action=deny
But the call still goes through to the server. This is perfect for testing rules before enforcing them.
Step 8: Switch to Production
Once you're satisfied with your rules, switch to production (the default):
thoughtgate wrap -- claude-code
In production mode:
- Deny rules return errors to the agent
- Approve rules would create Slack approval workflows (requires Slack token)
- Governance errors fail closed (deny on error)
What's Next
- Wrap other agents — Cursor, VS Code, Windsurf, Zed, Claude Desktop
- Write governance policies — Complex rules with Cedar
- Use profiles — Deep dive on development vs production
- Architecture — How the 4-gate model works
- CLI Reference — Complete flag documentation