@interven/mcp-guard
v0.2.1
Published
Model Context Protocol (MCP) server that scans agent tool calls through Interven before they execute. Drop-in for Claude Desktop, Cursor, Cline, OpenAI Agents SDK, and any MCP-aware client.
Maintainers
Readme
@interven/mcp-guard
Model Context Protocol (MCP) server that scans agent tool calls through Interven before they execute. Drop-in for Claude Desktop, Cursor, Cline, OpenAI Agents SDK, and any other MCP-aware client.
What it does
Exposes two tools to your MCP-aware client:
interven_scan— call before invoking any other tool. Returns a decision (ALLOW/DENY/SANITIZE/REQUIRE_APPROVAL) plus reason codes and a risk score. The LLM uses this to decide whether to proceed.interven_scan_response— call after a successful read (Drive file, API GET) to feed Interven the response body for forensics and read→write exfil correlation.
It also exposes one resource — interven://about — that the LLM should read
at session start to load policy guidance into context.
Install
You don't install it long-term. Your MCP client launches it on demand via
npx:
{
"mcpServers": {
"interven": {
"command": "npx",
"args": ["-y", "@interven/mcp-guard"],
"env": {
"INTERVEN_API_KEY": "iv_live_..."
}
}
}
}Drop that block into your client config:
| Client | Config file |
|--------|-------------|
| Claude Desktop | ~/.config/Claude/claude_desktop_config.json (Linux), ~/Library/Application Support/Claude/claude_desktop_config.json (macOS), %APPDATA%\Claude\claude_desktop_config.json (Windows) |
| Cursor | Settings → MCP → Add Server |
| Cline | Settings → MCP → Add Server |
| OpenAI Agents SDK | mcp_servers=[{...}] in your agent config |
Restart the client. The LLM now has access to interven_scan whenever it
plans to call a tool.
Optional config
| Env var | Default | Purpose |
|---------|---------|---------|
| INTERVEN_API_KEY | required | Sign up at https://app.intervensecurity.com/signup |
| INTERVEN_GATEWAY_URL | https://api.intervensecurity.com | Override only when self-hosting |
| INTERVEN_SCAN_TIMEOUT_MS | 30000 | Per-scan timeout. Bump to 60000 if your gateway is on a slow link |
Recommended system prompt addition
To get the LLM to actually use interven_scan before invoking tools, add
this to your client's system prompt (or to the per-conversation instructions):
Before invoking ANY tool from a non-Interven MCP server that touches external systems (Slack, Drive, GitHub, Salesforce, HubSpot, internal HTTP endpoints, etc.), first call
interven_scanwith the intended tool name, URL, method, and body. If the decision isDENY, refuse. IfSANITIZE, use thesanitized_bodyfrom the response instead of the original args. IfREQUIRE_APPROVAL, tell the user an analyst must approve at the Console URL Interven returns. Only proceed onALLOW.
How decisions map back to your agent
ALLOW → invoke the tool with original args
SANITIZE → invoke with the redacted body in `sanitized_body`
DENY → refuse; tell user why, citing reason_codes
REQUIRE_APPROVAL → pause; user approves at the URL; re-call interven_scan
to auto-ALLOW (recent-approval grant, valid for 10 min)Self-hosting
Point at your own Interven instance:
"env": {
"INTERVEN_API_KEY": "iv_live_...",
"INTERVEN_GATEWAY_URL": "https://interven.your-company.internal"
}Proxy mode (v0.2+)
The standalone mode above relies on the LLM to call interven_scan before
each tool call. That works when your system prompt is well-tuned — but a
sufficiently jailbroken model can simply skip the call. Proxy mode is
the answer: front another MCP server, intercept every tools/call
transparently, and the LLM cannot bypass.
{
"mcpServers": {
"slack-via-interven": {
"command": "npx",
"args": [
"-y", "@interven/mcp-guard", "proxy",
"--", "npx", "-y", "@modelcontextprotocol/server-slack"
],
"env": {
"INTERVEN_API_KEY": "iv_live_...",
"SLACK_BOT_TOKEN": "xoxb-..."
}
}
}
}The proxy spawns the upstream MCP server (@modelcontextprotocol/server-slack
in this example) as a child process and passes JSON-RPC traffic through.
Every tools/call is scanned; ALLOW forwards as-is, SANITIZE forwards a
redacted version, DENY returns an error to the client, and REQUIRE_APPROVAL
blocks until an analyst approves in the Console (timeout configurable via
INTERVEN_APPROVAL_MAX_WAIT_MS, default 4 hours).
Failure mode
If /v1/scan is unreachable, the proxy fails closed by default (returns
an error to the client). Set INTERVEN_FAIL_OPEN=1 to forward calls
through when scanning fails — only do this if availability matters more
than enforcement.
Approval polling
The proxy polls /v1/approvals/<id> every 3 seconds (override:
INTERVEN_APPROVAL_POLL_MS) until the approval is granted, denied, or
times out. The original tool call is held the whole time — from the
client's perspective the call just took longer.
Roadmap
- Resource: recent activity — surface recent decisions as MCP resources so the LLM has context on what's been allowed/blocked recently.
- Auto-policy suggestions — server logs DENY reasons and suggests new policies the user can copy-paste into the Console.
- HTTP transport — for clients that use the streamable-HTTP MCP transport instead of stdio.
License
MIT
