MCP Firewall Proxy — policy-based tool access control using NAIL effects
Project description
mcp-fw
MCP servers can read your files, run processes, and access the network — all without asking.
mcp-fw is a firewall proxy that sits between Claude Desktop and MCP servers. It uses NAIL effect labels to control exactly what each server can do.
Claude Desktop ←→ mcp-fw (proxy) ←→ MCP Server
↑
policy.yaml
allow: [FS, IO]
deny: [NET]
Why
MCP servers are powerful — but there's no built-in permission model. A filesystem server could silently make network calls. An "everything" server could spawn processes.
mcp-fw enforces boundaries:
| Effect | What it controls | Example |
|---|---|---|
FS |
File read/write | Read a file, list directory |
IO |
General I/O | stdin/stdout, echo |
NET |
Network access | HTTP requests, DNS |
PROC |
Process execution | Spawn subprocess, exec |
TIME |
Time/clock access | Get current time |
RAND |
Randomness | Generate random numbers |
Quick Start
pip install mcp-fw
1. Write a policy
# policy.yaml
servers:
filesystem:
command: npx
args: ["@modelcontextprotocol/server-filesystem", "/tmp"]
allow: [FS, IO]
deny: [NET]
This lets the filesystem server read/write files (FS, IO) but blocks all network access (NET).
2. Point Claude Desktop to the proxy
In claude_desktop_config.json:
{
"mcpServers": {
"filesystem-fw": {
"command": "mcp-fw",
"args": ["--config", "/path/to/policy.yaml", "--server", "filesystem"]
}
}
}
That's it. Claude Desktop now talks to mcp-fw, which filters tools before forwarding to the real server.
3. See what happened
$ mcp-fw --config policy.yaml --server filesystem --verbose
2025-01-15 10:00:01 [INFO] Filtered 5 → 3 tools (allowed effects: ['FS', 'IO'])
2025-01-15 10:00:05 [WARNING] Blocked tool call: fetch_url
Menubar App (macOS)
For a GUI experience:
pip install "mcp-fw[menubar]"
mcp-fw-menubar --config policy.yaml
A [FW] icon appears in your menubar:
[FW]
├── mcp-fw v0.1.0
├── ────────
├── ● filesystem
│ ├── Status: Running
│ ├── ────────
│ ├── [x] FS
│ ├── [x] IO
│ ├── [ ] NET ← toggle effects live
│ ├── [ ] PROC
│ └── ...
├── ○ everything
├── ────────
├── Edit Policy YAML
├── View Logs...
├── ────────
├── Sync to Claude Desktop
└── Quit
- Toggle effects with checkboxes — changes are written to
policy.yamlinstantly - Sync to Claude Desktop generates
claude_desktop_config.jsonentries automatically - View Logs opens a live log viewer
- Process monitor shows ● running / ○ stopped status per server
How It Works
1. Claude calls list_tools()
→ mcp-fw forwards to the real server
→ NAIL annotates each tool with effect labels
→ mcp-fw filters out tools that violate the policy
→ Claude only sees allowed tools
2. Claude calls a tool
→ mcp-fw checks if it's in the allowed set
→ Allowed: forward to server
→ Blocked: return error
The key insight: tools aren't just allowed or denied by name — they're classified by what they do (filesystem, network, process, etc.) using NAIL's effect system. This means mcp-fw can enforce policies on servers it has never seen before.
Policy Reference
servers:
my-server:
command: npx # server command
args: ["@org/server", "/tmp"] # command arguments
allow: [FS, IO] # permitted effects (empty = all)
deny: [NET] # blocked effects (overrides allow)
tool_overrides: # per-tool effect corrections
safe_fetch: [IO] # override NAIL's auto-detection
Rules:
allow: [](empty) = all effects permitted, thendenysubtractsallow: [FS, IO]= only these effects, thendenysubtractsdenyalways wins overallowtool_overrideslets you correct NAIL's automatic effect detection for specific tools
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_fw-0.2.0.tar.gz.
File metadata
- Download URL: mcp_fw-0.2.0.tar.gz
- Upload date:
- Size: 22.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bf00f0842fc153a96a99691ca28daaad0ccc0042b064b7341402f90b4dc4df7
|
|
| MD5 |
a34ae9d933a9c17d9011a42a4a6484ca
|
|
| BLAKE2b-256 |
fc0db91532b20133d1ccbe86fb11ea8ef4f51acf107c0c6049e8de519aa7b040
|
File details
Details for the file mcp_fw-0.2.0-py3-none-any.whl.
File metadata
- Download URL: mcp_fw-0.2.0-py3-none-any.whl
- Upload date:
- Size: 20.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29f9026d54c40cd190f8902737919e8f382a2878f4d86136c852f691838481b4
|
|
| MD5 |
ce2aebcdb0a7b74a0b54cd5f43071631
|
|
| BLAKE2b-256 |
7e68914f186b8c7fbd6808254d10cf28e856ccd72318684e5743b2941445ee51
|