Serverless DNA Logo
Loading...
Run Any MCP Server Securely Without Changing Its Config hero image

Run Any MCP Server Securely Without Changing Its Config

We all just copy MCP configs from READMEs and hope for the best. run-mcp lets you keep that simplicity while running servers in complete isolation. One word change, full container security.

MCP servers are powerful - they give Claude Desktop or other AI assistants access to your filesystem, databases, APIs, and more. But that power comes with risk. Every MCP server runs with your full user permissions. A bug or malicious MCP package could read your SSH keys, AWS credentials, or browser cookies.

When you add an MCP server to Claude Desktop, you're running arbitrary code on your machine. That filesystem server? It can see everything your user can see. That database tool? It has access to your entire home directory. Most of us just... trust it. We copy the config from the README and hope for the best, because we want immediate results.

The Traditional Container Approach

Some security-conscious users already run MCP servers in containers using Docker, or other container runtimes. Here's what that looks like:

{ "mcpServers": { "sqlite": { "command": "docker", "args": [ "run", "-i", "--rm", "-v", "/home/michael/data:/data", "-v", "/home/michael/.cache/uv:/home/mcp/.cache/uv", "-e", "HOME=/home/mcp", "--user", "1000:1000", "ghcr.io/serverlessdna/mcp-python:latest", "uvx", "mcp-server-sqlite", "--db-path", "/data/mydb.sqlite" ] } } }

That's 12 lines of Docker arguments you need to get right and it looks nothing like the example configuration the MCP server provider gives you. Volume mounts, user permissions, environment variables, image tags. Miss one flag and it fails silently or breaks in subtle ways.

Most people look at that and think "I'll just run it natively".

What if you could run MCP servers in complete isolation, with access only to what you explicitly allow - and configure them exactly as their READMEs document?

Most MCP server documentation shows something like this:

{ "mcpServers": { "sqlite": { "command": "uvx", "args": ["mcp-server-sqlite", "--db-path", "~/data/mydb.sqlite"] } } }

With run-mcp, your config is almost the same:

{ "mcpServers": { "sqlite": { "command": "run-mcp", "args": ["uvx", "mcp-server-sqlite", "--db-path", "/data/mydb.sqlite"], "env": { "MCP_MOUNT": "~/data:/data" } } } }

One word changes. Replace uvx or npx with run-mcp, add the original command as the first argument, and declare what the server can access. That's it.

Three approaches, compared:

ApproachLines of ConfigContainer IsolationComplexity
Native (uvx/npx)4❌ NoneLow
Raw Docker12+✅ FullHigh
run-mcp5✅ FullLow

The server runs in a container with zero access to your host - unless you explicitly grant it through a registered mount using the MCP_MOUNT environment variable as shown in the example.

What Changes

Without run-mcpWith run-mcp
Server sees entire home directoryServer sees only what you mount
Server can read ~/.aws, ~/.sshNo access unless you add it
Malicious package = full compromiseMalicious package = contained
Servers share your environmentEach server gets isolated storage

The security model flips from "access everything by default" to "access nothing by default."

How It Works

  1. Replace the command - uvx becomes run-mcp uvx, npx becomes run-mcp npx
  2. Mount what you need - MCP_MOUNT=~/data:/data grants explicit access.
  3. Credentials are opt-in - Add ~/.aws:/home/mcp/.aws:ro only when the server needs AWS access and provides read-only access.

No Docker knowledge required. No Dockerfile. No docker-compose. Just a single binary that handles everything across all platforms (Windows, macOS, Linux).

Real Examples

Filesystem Server (Read-Only Access)

{ "mcpServers": { "filesystem": { "command": "run-mcp", "args": ["npx", "@modelcontextprotocol/server-filesystem", "/docs"], "env": { "MCP_MOUNT": "~/Documents:/docs:ro" } } } }

The server can only read your Documents folder. Nothing else.

AWS Server (With Credentials)

{ "mcpServers": { "aws-api": { "command": "run-mcp", "args": ["uvx", "awslabs.aws-api-mcp-server"], "env": { "MCP_MOUNT": "~/.aws:/home/mcp/.aws:ro", "AWS_REGION": "us-east-1" } } } }

The server gets read-only access to your AWS credentials. Nothing else on your system is visible.

Memory Server (No Host Access)

{ "mcpServers": { "memory": { "command": "run-mcp", "args": ["npx", "@modelcontextprotocol/server-memory"] } } }

No MCP_MOUNT means no host filesystem access at all. The server gets an isolated home directory that persists between runs - but it's completely sandboxed using standard volume features of container runtimes.

No Runtime Dependencies

Don't have Node.js 22 installed? Python 3.12? Doesn't matter.

run-mcp auto-detects your container runtime - Docker, Podman - and runs the appropriate container. Your machine stays clean. No version conflicts. No global package pollution.

Getting Started

Install the binary:

# Linux (amd64) curl -fsSL https://github.com/serverless-dna/run-mcp/releases/latest/download/run-mcp-linux-amd64 \ -o ~/.local/bin/run-mcp && chmod +x ~/.local/bin/run-mcp # macOS (Apple Silicon) curl -fsSL https://github.com/serverless-dna/run-mcp/releases/latest/download/run-mcp-darwin-arm64 \ -o ~/.local/bin/run-mcp && chmod +x ~/.local/bin/run-mcp # macOS (Intel) curl -fsSL https://github.com/serverless-dna/run-mcp/releases/latest/download/run-mcp-darwin-amd64 \ -o ~/.local/bin/run-mcp && chmod +x ~/.local/bin/run-mcp
# Windows (PowerShell) New-Item -ItemType Directory -Force -Path ~\.local\bin | Out-Null Invoke-WebRequest -Uri https://github.com/serverless-dna/run-mcp/releases/latest/download/run-mcp-windows-amd64.exe -OutFile ~\.local\bin\run-mcp.exe

Note: Ensure ~/.local/bin is in your PATH, or use the full path to run-mcp in your Claude Desktop config.

Update your Claude Desktop config and you are done.

The Security Boundary That Should Have Been There

Every MCP server you run is code executing on your machine with your permissions. The MCP protocol is powerful, but it shipped without a security model for the host system.

run-mcp adds that missing layer. Same simple configs. Same MCP servers. Now with isolation by default.


Links:

Questions or feedback? Open an issue or find me on LinkedIn.