Help us shape the future of Go! Take the 2026 Go Developer Survey

mcp-visor

module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 22, 2026 License: MIT

README

MCP Visor

Runtime Policy Enforcement & Audit Control Plane for MCP Tool Execution

Go Version License CI


Problem

AI agents are connected to enterprise tools through MCP. They can read files, query databases, send Slack messages, execute shell commands, and modify cloud infrastructure. But AI agents are probabilistic systems vulnerable to prompt injection. Current MCP architecture has no enforcement point — if an agent calls a tool, it executes.

MCP Visor sits between the agent and the tools, enforcing deterministic policy before execution. It does not use an LLM to make decisions. Prompt injection cannot bypass it.

How It Works

AI Agent → mcp-visor proxy → policy decision → allow/deny/approve/redact → MCP server

Every tools/call is intercepted and evaluated:

  1. Redact — Strip secrets (API keys, tokens, passwords) from arguments
  2. Block — Deny access to sensitive files (.env, credentials, .ssh)
  3. Check — Validate against allowlists, denylists, and argument rules
  4. Detect — Identify dangerous tool chains (read → send)
  5. Approve — Hold high-risk calls for human confirmation
  6. Log — Record every decision in a redacted, structured audit trail

Quick Start

git clone https://github.com/themayursinha/mcp-visor
cd mcp-visor

# Start the proxy with a built-in demo server
go run ./examples/demo-runner/

# Or proxy a real MCP server with a policy file:
go run ./cmd/mcp-visor serve \
  -server ./my-mcp-server \
  -policy examples/policies/developer-medium.yaml

# With audit logging:
go run ./cmd/mcp-visor serve \
  -server ./my-mcp-server \
  -policy examples/policies/developer-medium.yaml \
  -audit-log audit.jsonl

Architecture

┌──────────────┐     ┌────────────────────────────────────────────────┐     ┌──────────────┐
│  AI Agent    │────▶│                  mcp-visor                      │────▶│  MCP Server  │
│  (MCP Client)│     │                                                  │     │  (Tools)     │
└──────────────┘     │  ┌─────────┐  ┌──────────┐  ┌──────────────┐   │     └──────────────┘
                      │  │Redaction│  │  Policy  │  │    Chain     │   │
                      │  │ Engine  │  │  Engine  │  │  Detector    │   │
                      │  └─────────┘  └──────────┘  └──────────────┘   │
                      │                                                  │
                      │  ┌─────────┐  ┌──────────┐  ┌──────────────┐   │
                      │  │Approval │  │  Audit   │  │    Trace     │   │
                      │  │ Engine  │  │  Logger  │  │   Logger     │   │
                      │  └─────────┘  └──────────┘  └──────────────┘   │
                      │                                                  │
                      │  ┌─────────┐  ┌──────────┐  ┌──────────────┐   │
                      │  │Vault    │  │ Webhook  │  │    SIEM      │   │
                      │  │ Signer  │  │ Emitter  │  │  Exporter    │   │
                      │  └─────────┘  └──────────┘  └──────────────┘   │
                      │                                                  │
                      │  Transport: stdio (local) or HTTP+SSE (remote)   │
                      └────────────────────────────────────────────────┘

Policy Model

Policies are YAML files that define exactly which tools are allowed, under what conditions.

version: "1.0"
default_action: deny   # deny everything by default

servers:
  - name: "filesystem"
    allowed: true
    tools:
      - name: "file_read"
        allowed: true
        risk: medium
        rules:
          - type: deny_path
            patterns:
              - "/etc/passwd"
              - "**/.env"
              - "**/*.pem"
          - type: allow_path
            patterns:
              - "/home/**"
              - "/tmp/**"

      - name: "shell_exec"
        allowed: true
        risk: critical
        approval_required: true
        rules:
          - type: deny_command_pattern
            patterns:
              - "bash\\s+-i\\s+>&"
              - "rm\\s+-rf\\s+/"

  - name: "slack"
    allowed: true
    tools:
      - name: "slack_send_message"
        allowed: true
        risk: high
        approval_required: true

# Block read → send chains
tool_chains:
  - name: "prevent_exfiltration"
    sources:
      - server: "*"
        tool_pattern: "file_read"
    sinks:
      - server: "*"
        tool_pattern: "(http_post|slack_send_message)"
    action: deny
    within_calls: 3

See examples/policies/ for more examples.

Features

Policy Enforcement
  • Tool allowlist/denylist with default-deny
  • 16 argument rule types: deny_path, allow_path, deny_command_pattern, allow_command_pattern, deny_command_keyword, deny_command_pattern_composite, deny_query_pattern, allow_query_pattern, allowed_repos, deny_recipient_domain, allow_recipient_domain, max_file_size, max_result_rows, max_export_rows, require_approval_always
  • Risk classification (critical/high/medium/low)
  • Identity-based access control per agent
  • Time-based access restrictions (business hours, denied days)
  • Policy hot-reload with fsnotify watcher
Policy Linting
  • mcp-visor lint CLI for static validation of policy YAML
  • Detects invalid regex patterns, unknown rule types, missing required fields
  • Severity-classified output (error/warning/info)
  • --json, --strict, --no-info, --no-warnings output options
  • Composite command pattern validation
Chain Detection
  • Detects dangerous tool sequences: read → send, query → post
  • Configurable sliding window
  • Deny or require approval for matched chains
  • Session-level tracking
Redaction
  • Strips API keys (sk-...), tokens (ghp_...), JWTs, connection strings, private keys, internal IPs
  • Redacts arguments before forwarding to server
  • Redacts outputs before returning to client
  • Blocks access to sensitive files (.env, .ssh, credentials, .pem, .key)
Approval Workflow
  • File-based: write req-<id>.json, approver creates req-<id>.ok to approve
  • CLI-based: interactive yes/no prompt on terminal
  • Configurable timeout with fail-closed default
  • Full audit trail for approval decisions
Durable Approval (v2)
  • Signed Decision Receipts with ed25519 signatures
  • Execution IDs with nonce and expiry for replay protection
  • Durable retry: persist pending approvals, agent retries with signed receipt
  • Pluggable signer interface (built-in ed25519, Vault Transit/KMS ready)
Webhook Event Emitter (v2)
  • Async HTTP delivery of audit and approval events
  • HMAC-SHA256 signatures for payload authenticity
  • Configurable retry with exponential backoff
Audit Logging
  • JSONL format with redacted data
  • 8 event types: tool_call_allowed, tool_call_denied, tool_call_chain_detected, tool_call_approval_required, session_started, session_ended, policy_loaded, policy_reloaded
  • Hash-chained entries (SHA-256) for tamper evidence
  • O_SYNC writes for durability
SIEM Export (v2)
  • RFC 5424 syslog format
  • JSON envelope format for Splunk/Elastic
  • CEF (Common Event Format)
  • Pluggable writers: file, TCP, UDP
HTTP/SSE Transport (v2)
  • Connect to remote MCP servers over HTTP
  • Server-Sent Events (SSE) for server-to-client streaming
  • Configurable mTLS support
  • Mock transport for testing
n8n Control Plane Blueprint (v2)
  • Ready-to-import n8n workflow for Slack/Teams approval
  • SIEM forwarding integration
  • Audit database storage (PostgreSQL)
Trace Logging (v1.1)
  • MCP message-level tracing for debugging and forensics
  • Three output formats: text (directional C->S/S->C), JSONL (machine-readable), summary (counters)
  • Configurable via --trace and --trace-format CLI flags
  • Granular control: handshake, decisions, redactions, chain detections
Vault Transit Integration (v1.1)
  • Cryptographic signing backed by HashiCorp Vault Transit secrets engine
  • TransitSigner and TransitVerifier implementing pluggable signer interfaces
  • Configurable via --vault-addr, --vault-token, --vault-key-name CLI flags
  • TLS/mTLS support with CA cert and skip-verify options
  • Namespace support for Vault Enterprise
Performance Benchmarks (v1.1)
  • 26 benchmarks across 5 hot-path packages
  • Policy evaluation: 587 ns, chain detection: 2.9 us, redaction: 1.8 us
  • JSON-RPC decode: 1 us, encode: 180 ns
  • Ed25519 signing: 12.9 us, verification: 28.4 us
  • make bench target for one-command benchmark run

Comparison with mcp-llm-security-evaluator

mcp-llm-security-evaluator mcp-visor
Purpose Evaluates LLM security Enforces tool execution
When CI/CD, on-demand scans Every tool call at runtime
Output Reports, scores, findings Allow/deny/approve, audit logs
LLM Tests LLM responses No LLM interaction
MCP Simulated mock calls Real MCP protocol proxy

Evaluator tells you what can go wrong. Visor stops it at runtime.

See mcp-llm-security-evaluator

CLI Reference

mcp-visor serve [flags]
mcp-visor lint [flags] <policy-file>
mcp-visor version

Serve flags:
  -server string          MCP server command to proxy (local stdio)
  -server-name string     Logical server name for policy matching
  -server-arg value       Argument for the MCP server command (repeatable)
  -server-url string      Remote MCP server URL (enables HTTP+SSE transport)
  -sse-path string        SSE endpoint path (default: /sse)
  -insecure-tls           Skip TLS certificate verification for remote servers
  -remote-cert string     Client certificate file for remote MCP mTLS
  -remote-key string      Client private key file for remote MCP mTLS
  -remote-ca string       CA certificate file for remote MCP TLS verification
  -remote-server-name string
                           Expected TLS server name for remote MCP server
  -policy string          Path to policy YAML file (default: built-in deny-all)
  -audit-log string       Path to JSONL audit log file (default: stderr)
  -webhook-url value      Webhook endpoint for audit/approval events (repeatable)
  -webhook-hmac-secret string
                           HMAC secret used to sign webhook payloads
  -siem-target value      SIEM export target: file path, tcp:host:port, or udp:host:port (repeatable)
  -siem-format string     SIEM export format: json, syslog-rfc5424, cef (default: json)
  -approval-dir string    Directory for file-based approval workflow
  -approval-cli           Use interactive CLI prompt for approval
  -approval-signing-key string
                           Ed25519 private key PEM file for signing approval receipts (default: ephemeral key)
  -session-id string      Session identifier
  -client-id string       Client identifier
  -demo                   Start with built-in mock server and permissive policy
  -trace                  Enable MCP message tracing
  -trace-format string    Trace output format: text, jsonl, summary (default: text)
  -log-level string       Log level: debug, info, warn, error (default: info)
  -vault-addr string      Vault server address for Transit signing
  -vault-token string     Vault authentication token
  -vault-key-name string  Vault Transit key name (default: mcp-visor-approval)
  -vault-namespace string Vault namespace (Enterprise)
  -vault-ca-cert string   Vault CA certificate file
  -vault-skip-verify      Skip Vault TLS verification

Lint flags:
  -json                   Output in JSON format
  -strict                 Treat warnings as errors
  -no-info                Hide info-level findings
  -no-warnings            Hide warning-level findings

Development

# Build
go build ./cmd/mcp-visor/

# Test
go test ./...

# Benchmark
make bench

# Vet
go vet ./...

# Run demo
go run ./examples/demo-runner/

# Lint a policy
go run ./cmd/mcp-visor lint examples/policies/developer-medium.yaml

Roadmap

  • v1.0: MCP proxy, policy engine, audit logging, chain detection, redaction, approval
  • v1.1: Identity-based policies, time-based restrictions, CLI approval, policy hot-reload
  • v2.0: Signed decision receipts, webhook approvals, hash-chained audit logs, mTLS, SIEM export, HTTP/SSE transport, durable retry approval, n8n control-plane blueprint
  • v3.0: Sandboxed tool execution (WASI), eBPF syscall telemetry, Vault/KMS-backed approval signing
  • v4.0: Deeper host-level enforcement, formal policy verification

Security Model

  • Deterministic — No LLM in the decision path
  • Fail-closed — Unknown tools denied by default
  • Layered — Redaction → Policy → Chain → Approval
  • Observable — Every decision logged with hash-chained integrity
  • Minimal TCB — Single Go binary, minimal dependencies
  • Tamper-evident — Signed approval receipts, bound evidence hashes, chained audit hashes

Limitations

  • Relies on host filesystem security for policy file integrity
  • Approval webhooks use HMAC; full mTLS between visor and control plane is optional
  • Session state is ephemeral (lost on restart); signed approval receipts bind approved calls to request, policy, argument, and chain-context hashes
  • Single-agent, single-server deployment model
  • No web-based approval dashboard (n8n blueprint provides Slack/Teams path)

Contributing

Contributions welcome. See CONTRIBUTING.md for guidelines. Areas needing work: web-based approval dashboard, Vault/KMS live integration, additional MCP server integrations, WASI sandboxing.

License

MIT — see LICENSE

Directories

Path Synopsis
cmd
mcp-visor command
policy-lint command
examples
demo-mcp-server command
demo-runner command
internal
mcp

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL