Skip to content

MCP Proxy

What is MCP?

Model Context Protocol (MCP) is an open standard that lets AI agents talk to external tools — file systems, databases, APIs, cloud providers — through a unified interface. Instead of each agent having bespoke integrations, MCP servers expose "tools" that any MCP-compatible client can call.

The problem: MCP servers often have broad access (your entire filesystem, your GitHub repos, your Slack workspace). When an AI agent calls an MCP tool, there's no built-in way to say "read files, but don't delete them" or "access the GitHub API, but never delete repos."

Rampart's MCP proxy sits between the MCP client (your AI agent) and the MCP server, evaluating every tools/call against your policies. The client and server don't know it's there.

Usage

# Wrap any MCP server
rampart mcp -- npx @modelcontextprotocol/server-filesystem /path

# Monitor mode (log only)
rampart mcp --mode monitor -- npx @modelcontextprotocol/server-filesystem .

Standalone approval limit

rampart mcp evaluates policies locally but has no connected approval resolver. In enforce mode, ask immediately refuses the call; it does not create a request in rampart pending or the dashboard. Starting rampart serve alone does not change this. Use explicit operator-reviewed allow or deny rules for this path.

MCP Client Configuration

In your agent's MCP config (Claude Desktop, Cursor, etc.):

{
  "mcpServers": {
    "filesystem": {
      "command": "rampart",
      "args": ["mcp", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "."]
    }
  }
}

How It Works

MCP Client\n(Claude Desktop, Cursor…)rampart mcpPolicy EngineMCP ServerError ResponseApproval Required(fail closed) tools/callevaluateallowdenyaskno standalone resolverresponseresponse

Rampart speaks the MCP protocol natively. The client and server don't know it's there. Denied tool calls return a standard JSON-RPC error — the MCP server never sees them.

In enforce mode, a policy decision is not forwarded unless its audit record is persisted. Webhook actions also write a second final-decision event with request.mcp_phase set to webhook_result; failure to persist that result blocks the call. Request, webhook-result, and response events share a generated tool_call_id for correlation. Monitor mode logs storage errors but remains non-blocking.

Start with a Static Policy

Create the bundled MCP starter policy, then review and customize it for the server you intend to proxy:

rampart init --profile mcp-server

rampart mcp scan remains as a disabled compatibility command. It does not start the supplied server or create a policy.

MCP Tool Runtime Classification

During intercepted calls, Rampart maps MCP tool names to policy categories. This runtime matching does not discover server tool definitions or write a policy:

Category Keywords Default Action
mcp-destructive delete, destroy, remove, drop deny
mcp-dangerous stop, restart, execute, modify ask (blocked by the standalone proxy)
mcp Any tool name Rampart cannot classify ask (blocked by the standalone proxy)

MCP Proxy vs Shell Hook

Shell Hook (setup claude-code) MCP Proxy (mcp --)
What it intercepts Shell commands, file reads/writes MCP tools/call JSON-RPC messages
Best for Agents with hook support (Claude Code, Cline, Cursor) Claude Desktop, Cursor MCP servers, any MCP client
Setup One-time rampart setup Wrap each MCP server command
Granularity Command-level (rm -rf *) Tool-level (delete_file, create_issue)
Works with Agents that support hooks or $SHELL Any agent that uses MCP servers

Use both together for defense in depth — hooks catch shell commands, MCP proxy catches tool calls.

MCP server examples

The proxy wraps command-launched MCP servers using newline-delimited JSON-RPC over stdio. Compatibility with a particular server, client, or optional protocol feature requires its own verification. Examples of server categories:

Server Package What It Does
Filesystem @modelcontextprotocol/server-filesystem Read, write, delete files
GitHub @modelcontextprotocol/server-github Issues, PRs, repos
Slack @modelcontextprotocol/server-slack Messages, channels
PostgreSQL @modelcontextprotocol/server-postgres SQL queries
Brave Search @modelcontextprotocol/server-brave-search Web searches
Puppeteer @modelcontextprotocol/server-puppeteer Browser automation

Just prefix the server command with rampart mcp --:

rampart mcp -- npx -y @modelcontextprotocol/server-github
rampart mcp -- npx -y @modelcontextprotocol/server-slack
rampart mcp -- npx -y @modelcontextprotocol/server-postgres postgres://localhost/mydb

5-Minute Setup

1. Install Rampart

brew install peg/tap/rampart

2. Create a Policy

Run this from the directory where the proxy will load rampart.yaml:

rampart init --profile mcp-server

Review the resulting static policy before use. The bundled profile is a starting point, not a policy tailored to a server's advertised tools. You can also copy the example template.

3. Update Your MCP Config

In your agent's MCP config (Claude Desktop, Cursor, etc.), wrap each server:

{
  "mcpServers": {
    "filesystem": {
      "command": "rampart",
      "args": ["mcp", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/home/you/projects"]
    }
  }
}

That's it. Restart your agent and every MCP tool call now goes through Rampart.

Example Policy for MCP Tools

Rampart auto-categorizes MCP tools by name, so many tools are protected out of the box. For fine-grained control:

version: "1"
default_action: allow

policies:
  - name: block-destructive-tools
    match:
      tool: ["mcp-destructive"]
    rules:
      - action: deny
        message: "Destructive MCP tool blocked"

  - name: approve-dangerous-tools
    match:
      tool: ["mcp-dangerous"]
    rules:
      - action: ask
        message: "Risky MCP operation requires approval; standalone proxy refuses this call"

  - name: block-file-deletion
    match:
      tool: ["write"]
    rules:
      - action: deny
        when:
          command_matches: ["delete_file*"]
        message: "File deletion blocked"

  - name: approve-unclassified-mcp
    match:
      tool: ["mcp"]
    rules:
      - action: ask
        message: "Unclassified MCP tool requires approval; standalone proxy refuses this call"

See configs/examples/mcp-server.yaml for a ready-to-use template.

The ask rules above retain their approval-required meaning, but the standalone proxy refuses them as described in the approval limit. They do not present an approval button. See the support matrix for integrations that provide an approval flow.

Example: Proxmox MCP Policy

version: "1"
default_action: allow

policies:
  - name: block-vm-destruction
    match:
      tool: ["mcp__proxmox__vm_delete", "mcp__proxmox__snapshot_delete"]
    rules:
      - action: deny
        message: "VM/snapshot deletion blocked by policy"

  - name: log-vm-power
    match:
      tool: ["mcp__proxmox__vm_stop", "mcp__proxmox__vm_shutdown"]
    rules:
      - action: watch
        message: "VM power operation logged"

  - name: block-disk-resize
    match:
      tool: ["mcp__proxmox__vm_resize_disk"]
    rules:
      - action: deny
        message: "Disk resize blocked — irreversible operation"