mcpcage · free and open source
Every MCP server in its own cage.
mcpcage puts your AI assistant's plugins in a locked box. Each plugin does its job and nothing else, and if it changes behind your back, it is blocked. It works with Claude, Cursor, VS Code and Copilot. Without mcpcage, their plugins can read your files and passwords and send them anywhere. With mcpcage they can do that only if you allow it. Both protections start together, with one command, on the assistants you already use.
These plugins are called MCP servers.
npm install -g mcpcage
You need Docker and Node.js 22 or later. It runs on macOS, Linux and Windows (with Docker Desktop) and is licensed under Apache-2.0.
$ mcpcage protect Claude Desktop ~/Library/Application Support/Claude/claude_desktop_config.json filesystem npx -y @modelcontextprotocol/server-filesystem /Users/you NOT CAGED access: /Users/you: your whole home directory github npx -y @modelcontextprotocol/server-github NOT CAGED secret in clear text: GITHUB_PERSONAL_ACCESS_TOKEN Summary 2 run on your machine with your permissions and no cage. -> mcpcage protect --fix 1 keeps a secret in clear text in a configuration file. 1 can reach your whole home directory, the disk or a directory with credentials.
mcpcage protect finds two servers without a cage, one that can see the whole home directory and one with a token in clear text.The problem
Most MCP servers are npm or PyPI packages that the assistant starts on your computer with npx or uvx. They run with your permissions, so they can read your SSH keys, your cloud credentials and your source code and send them anywhere.
A harmless server can also change in an update. If a tool description hides instructions, the assistant reads them along with everything else and may follow them. This is known as a rug pull or tool poisoning.
What it does
-
Locks the server in a container
Each server starts in a Docker container with no network, a read-only disk and no access to your home directory. It sees only the folders you choose, read-only unless you say otherwise.
mcpcage run -
Pins the tools on first use
The first time, it records the definition of every tool. If an update changes one, the session is locked and no call reaches the server until a person has looked at the change and approved it.
mcpcage diffmcpcage approve -
Points out signs of hidden instructions
Under every change it lists the parts that look like hidden orders, such as tags addressed to the model, paths to secret files, requests to tell the user nothing or invisible characters. The rules are fixed, and nothing is sent off your computer.
mcpcage protect --inspect -
Keeps a chained log
Each log entry holds the fingerprint of the one before it, so
mcpcage audit verifymcpcage audit verifynotices if anyone has changed or deleted entries. For every call it stores the tool name and a fingerprint of the arguments, never their values.
client: MCP error -32001: mcpcage blocked tools/list: tool definitions of "demo-notes" changed
since they were approved (rug-pull protection). 3 high-severity signs of hidden
instructions. Run `mcpcage diff demo-notes`.
$ mcpcage diff demo-notes
~ tool "add_note" changed since it was approved
! HIGH conceal-from-user description: "Do not tell the user" asks the model to hide something from you
! HIGH hidden-tag description: "<IMPORTANT>" a tag that hides instructions for the model
! HIGH sensitive-path description: "~/.ssh/id_rsa" points at a secret file
! MEDIUM before-using description: "Before calling this tool" adds an action to every call of this tool
3 high-severity signs of hidden instructions in "add_note"
mcpcage diff explains why the change looks suspicious.Getting started
-
Install it
npm install -g mcpcageYou need Docker running and Node.js 22 or later.
-
See what runs without a cage
mcpcage protectIt reads the configurations of the clients installed on the computer and tells you which servers run without a cage and what they can reach. It also flags secrets written in clear text. The configurations stay as they are.
-
Cage them
mcpcage protect --fixIt first shows what it is about to do and asks for confirmation, then cages the servers started with npx or uvx. It leaves a backup next to every file it changes, and
mcpcage unwraprestores the original commands.
It reads the configurations of Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Devin and GitHub Copilot CLI. The full instructions are in the project README.
Why you can trust it
Each item has a link where you can check it.
- Traceable releases
- Since version 0.6.3, every release reaches npm from the public build on GitHub, with no stored keys (trusted publishing), together with its provenance and a signed build attestation. Since 0.6.4, each release waits until the maintainer approves it with two-factor authentication.
- CHANGELOG · npm · release.yml
- OpenSSF Scorecard
- The project is rated by the OpenSSF Scorecard, which checks the security practices of the repository.
- Scorecard
- 63 servers tested
- The 24 most downloaded MCP servers started with npx were tested in the cage on macOS, Windows and Linux, and the 39 most downloaded Python servers started with uvx on macOS and Linux. With the default settings 22 of the 24 start and list their tools, while 2 need the network. Of the 39, on Linux, 27 start, 3 need the network, 3 lack the prebuilt packages the cage requires and 6 stop for reasons of their own, for example because they check their credentials as they start.
- compatibility.md
- Tests every week
- Every week the parts that read untrusted data or decide what is safe get 20,000 randomly generated inputs per test (fuzzing), and the code is changed on purpose, one small change at a time, to see whether the tests notice (mutation testing).
- fuzz.yml · mutation.yml
- Public advisories
- The project publishes security advisories on GitHub. There have been five so far: three fixed in version 0.6.2, one in 0.6.4, one in 0.7.0.
- Security advisories
- Reporting
- Anyone who finds a vulnerability reports it privately, as the project's security policy explains.
- SECURITY.md
What it does not do
- It relies on Docker and the kernel. A vulnerability in Docker or in the kernel that runs the containers can open the cage.
- It does not filter the network. The network is either fully closed or fully open. A server that needs it, opened with
--allow-net, can send data anywhere. - It trusts the first list of tools. It accepts that list without asking, unless you use
--strict, which asks for an explicit approval the first time too. - It does not block results. The rules also read what the tools return and note the signs they find in the log, but they do not stop it, so the assistant gets what the server sent.
- It only builds a cage for servers started with npx or uvx. A Python server needs prebuilt packages (wheels): one that installs only from source is refused, because installing it would run its code.
mcpcage protectlists the others, and remote servers, but leaves them as they are; a server that already ships as a Docker image runs with--image.
The project's threat model, THREAT-MODEL.md, describes these limits in full.
For companies
mcpcage is free. If several people in your company work with AI assistants and MCP servers, we can help you install it and decide which folders each server gets to see.