A firewall and audit log for AI agents.
AgentShield sits between your AI agents and the tools they use. It intercepts every tool call, enforces allow/deny policies, rate-limits dangerous operations, and logs everything — so you know exactly what your agents are doing.
Works with Claude Code, Cursor, Windsurf, and any custom MCP-based agent.
You wouldn't deploy an API without rate limiting. Why are your agents different?
┌─────────────┐ ┌──────────────────────────────────────────┐ ┌─────────────┐
│ AI Agent │ │ AgentShield Proxy │ │ MCP Server │
│ (Claude Code │────▶│ │────▶│ (GitHub, │
│ Cursor, │◀────│ Intercept → Policy Check → Log → Route │◀────│ Jira, │
│ Custom) │ │ │ │ Slack...) │
└─────────────┘ └──────────────────────────────────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
┌────────┐ ┌─────────┐ ┌──────────┐
│ Policy │ │ Audit │ │Dashboard │
│ Engine │ │ Log │ │ API │
└────────┘ └─────────┘ └──────────┘
Three interception layers:
- MCP tool calls — intercept any MCP server (GitHub, Jira, Slack, filesystem, etc.)
- CLI commands — intercept shell commands agents run (
rm -rf,git push --force, etc.) - HTTP requests — intercept outbound HTTP (block exfil domains, scan for secret leaks)
npm install -g agent-shieldCreate agent-shield.yaml in your project root:
version: "1"
settings:
log_level: "info"
log_file: "./agent-shield-audit.log"
redact_secrets: true
servers:
- name: "github"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: "${GITHUB_TOKEN}"
rules:
# Block dangerous operations
- name: "block-destructive-git"
action: deny
servers: ["github"]
tools: ["push_files", "delete_branch", "delete_repository"]
message: "Destructive git operations are blocked"
# Rate limit writes to 20/min
- name: "rate-limit-writes"
action: allow
tools: ["write_file"]
rate_limit:
max_calls: 20
window_seconds: 60
# Allow reads freely
- name: "allow-reads"
action: allow
tools: ["read_file", "search_files", "list_directory"]
# Log anything else for review
- name: "warn-unknown"
action: warn
message: "Unrecognized tool — logged for review"
# Block everything not matched above
- name: "default-deny"
action: deny
message: "Not explicitly permitted by policy"agent-shield policy validate
# ✓ Policy is valid (5 rules loaded)Claude Code — update ~/.claude/config.json:
{
"mcpServers": {
"github": {
"command": "agent-shield",
"args": ["start", "--server", "github", "--config", "./agent-shield.yaml"]
}
}
}Cursor — update .cursor/mcp.json:
{
"mcpServers": {
"github": {
"command": "agent-shield",
"args": ["start", "--server", "github", "--config", "./agent-shield.yaml"]
}
}
}That's it. Every tool call now goes through AgentShield's policy engine.
rules:
- name: "block-destructive"
action: deny
tools: ["delete_repository", "delete_branch", "push_files"]
message: "Destructive operations are not allowed"
- name: "allow-read-ops"
action: allow
tools: ["get_issue", "search_issues", "list_repos", "read_file"]
- name: "default-deny"
action: deny
message: "Not permitted"rules:
- name: "rate-limit-writes"
action: allow
tools: ["write_file", "create_file"]
rate_limit:
max_calls: 10
window_seconds: 60
- name: "allow-reads"
action: allow
tools: ["read_file", "search_files"]
- name: "default-deny"
action: denyservers:
- name: "github"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: "${GITHUB_TOKEN}"
- name: "filesystem"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-filesystem", "./workspace"]
- name: "linear"
url: "https://mcp.linear.app/sse"
headers:
Authorization: "Bearer ${LINEAR_TOKEN}"
rules:
# GitHub: read-only
- name: "github-read-only"
action: deny
servers: ["github"]
tools: ["push_files", "create_branch", "delete_branch"]
message: "GitHub is read-only through AgentShield"
# Filesystem: allow reads, rate-limit writes
- name: "fs-allow-reads"
action: allow
servers: ["filesystem"]
tools: ["read_file", "list_directory", "search_files"]
- name: "fs-limit-writes"
action: allow
servers: ["filesystem"]
tools: ["write_file"]
rate_limit:
max_calls: 30
window_seconds: 60
# Linear: allow everything (trusted)
- name: "linear-allow-all"
action: allow
servers: ["linear"]
# Default deny
- name: "default-deny"
action: deny
message: "Not explicitly permitted"rules:
# Block writes to production paths
- name: "block-prod-writes"
action: deny
tools: ["write_file"]
args_match:
path: "/prod/|/production/"
message: "Cannot write to production paths"
# Allow writes elsewhere
- name: "allow-writes"
action: allow
tools: ["write_file"]Agents don't just call MCP tools — they run shell commands too. AgentShield can intercept those as well.
agent-shield exec --dry-run "rm -rf /"
# ✗ DENY: "rm -rf /" — Destructive file operations blocked (rule: block-destructive)
agent-shield exec --dry-run "git status"
# ✓ ALLOW: "git status" (rule: allow-safe-commands)
agent-shield exec --dry-run "docker run ubuntu"
# ⚠ WARN: "docker run ubuntu" — Docker command detected (rule: warn-docker)agent-shield exec "git status" # runs if allowed
agent-shield exec "rm -rf /" # blocked — exits with code 1AgentShield can generate a Claude Code PreToolUse hook that automatically intercepts every Bash tool call:
# See the hook config
agent-shield hook show
# Test what the hook would do
agent-shield hook test "kubectl delete pod --all"Add the output of agent-shield hook show to your .claude/settings.json and every shell command Claude Code runs will go through policy.
Default command rules block:
rm -rf, destructive filesystem opsgit push --force,git reset --hard- System commands (
shutdown,dd,mkfs) - Data exfiltration via
curl/wget
AgentShield can also act as an HTTP forward proxy — intercepting outbound requests, blocking dangerous domains, and scanning request bodies for leaked secrets.
agent-shield http-check https://pastebin.com/raw/abc
# ✗ DENY — Request to known data exfiltration domain blocked
agent-shield http-check https://api.github.com/repos
# ✓ ALLOW (rule: allow-dev-domains)
agent-shield http-check https://random-site.xyz
# ⚠ WARN — HTTP request to unrecognized domain
agent-shield http-check -m POST -b '{"key":"AKIAIOSFODNN7EXAMPLE"}' https://api.example.com
# ✗ DENY — Request body contains potential secretsagent-shield http-proxy --port 8080Then route agent traffic through it:
HTTP_PROXY=http://localhost:8080 HTTPS_PROXY=http://localhost:8080 your-agentDefault HTTP rules block:
- Exfiltration domains (pastebin, ngrok, webhook.site, requestbin, etc.)
- File uploads (
multipart/form-data) to external services - Secret leaks in request bodies (AWS keys, GitHub PATs, private keys, Stripe/OpenAI keys)
Allows:
- Dev domains (GitHub, npm, PyPI, localhost)
- AI/cloud APIs (OpenAI, Anthropic, Google, AWS, Azure)
agent-shield dashboard
# ✓ Dashboard running at http://localhost:4040Provides:
- Live Feed — Real-time stream of every tool call with policy decisions
- Analytics — Total calls, allow/deny/warn breakdown, top tools, latency
- Anomaly Alerts — Volume spikes, new tool access, off-hours activity, high deny rates
- Policy Reference — Quick view of your current rules
The dashboard reads from SQLite, so it works even when the proxy isn't running. (Requires optional better-sqlite3 — see Optional Dependencies).
Every intercepted call is logged as structured JSON:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2024-01-15T10:30:00.000Z",
"server_name": "github",
"agent_id": "claude-code",
"method": "tools/call",
"tool_name": "create_issue",
"arguments": { "project": "PROD", "title": "Fix bug" },
"result_preview": "Created issue PROD-123",
"policy_decision": "allow",
"policy_rule": "allow-reads",
"latency_ms": 142,
"error": null
}- Secrets are automatically redacted before logging (AWS keys, GitHub tokens, Slack tokens, API keys, passwords, emails)
- Log file is structured JSON (one entry per line) — pipe to
jq, Datadog, or any log aggregator - Policy file changes are hot-reloaded — no restart needed
agent-shield logs # Show recent entries
agent-shield logs --filter write_file # Filter by tool name
agent-shield logs --action deny # Show only blocked calls
agent-shield logs --server github --json # JSON output for piping| Command | Description |
|---|---|
agent-shield start --server <name> |
Start the MCP proxy (called by agent config) |
agent-shield logs |
View audit log entries |
agent-shield policy validate |
Validate your policy file |
agent-shield dashboard |
Launch web dashboard |
agent-shield exec <command> |
Run a shell command through policy |
agent-shield exec --dry-run <command> |
Check if a command would be allowed |
agent-shield hook show |
Show Claude Code hook config |
agent-shield hook test <command> |
Test hook policy for a command |
agent-shield http-proxy --port <port> |
Start HTTP forward proxy |
agent-shield http-check <url> |
Check a URL against HTTP policy |
Rules are evaluated top-to-bottom. First match wins (like iptables/nginx).
| Field | Type | Description |
|---|---|---|
name |
string | Human-readable rule name |
action |
allow | deny | warn |
What to do when matched |
servers |
string[] | Match specific servers (omit = all) |
tools |
string[] | Match specific tools (omit = all) |
args_match |
object | Regex matching on tool arguments |
rate_limit |
{ max_calls, window_seconds } |
Rate limiting (only with allow) |
time_window |
{ start, end, timezone } |
Time-of-day restrictions (HH:MM) |
message |
string | Shown on deny, logged on warn |
allow— permit the call and log itdeny— block the call, return an error to the agent, and log itwarn— permit the call but flag it for review in logs/dashboard
- Policy enforcement — Allow/deny/warn rules with first-match-wins evaluation
- Rate limiting — Per-tool call limits with configurable time windows
- Audit logging — Structured JSON logs, queryable via CLI
- SQLite storage — Queryable audit data for dashboard and analytics (optional)
- Secret redaction — Auto-redacts API keys, tokens, passwords, emails before logging
- Hot-reload — Edit your policy file and changes apply instantly, no restart needed
- Web dashboard — Real-time feed, analytics, top tools, anomaly alerts
- Anomaly detection — Volume spikes, new tools, off-hours activity, high deny rates
- CLI command interception — Intercept shell commands agents run, not just MCP
- HTTP request interception — Forward proxy with domain blocking and secret leak scanning
- Claude Code hooks — Drop-in PreToolUse hook for Bash tool interception
- SSE transport — Proxy remote MCP servers over HTTP (not just local stdio)
- Works with any agent — Claude Code, Cursor, Windsurf, or custom agents
AgentShield works out of the box with zero native dependencies. Some features require optional packages:
| Feature | Package | Install |
|---|---|---|
| Dashboard + SQLite storage | better-sqlite3 |
npm install better-sqlite3 |
If better-sqlite3 is not installed, AgentShield still works — it just uses JSON file logging instead of SQLite, and the dashboard won't be available.
git clone https://github.com/inprod/agent-shield.git
cd agent-shield
npm install
npm test # 146 tests
npm run build # compile TypeScriptMIT