Skip to main content

Local-first security scanner, MCP protocol inspector, dynamic fuzzer, sandbox runner, and report generator for Model Context Protocol servers.

Project description

mcp-fence

CI Python License

Local-first security scanner, MCP protocol inspector, dynamic fuzzer, Docker sandbox, and report generator for Model Context Protocol servers.

mcp-fence architecture

mcp-fence is a developer tool. Point it at your mcp.json (or any running MCP server you wrote) and it will:

  1. Statically scan the config and source for tool poisoning, dangerous startup commands, plaintext secrets, schema gaps, and unauthenticated HTTP transports.
  2. Inspect the server live over stdio — runs initialize, tools/list, gathers schemas/annotations.
  3. Fuzz every tool with schema-aware payloads (path traversal, command injection, SSRF, prompt injection, oversize input, type confusion). Safe by default; opt in to runtime payloads via --toy-mode or --allow-unsafe.
  4. Sandbox any stdio server in Docker with sensible profiles (strict, filesystem-readonly, network-deny, dev).
  5. Report findings as a plain-text table, JSON, SARIF 2.1.0 (for GitHub code scanning), or a fully offline HTML page.

It is non-destructive, local-first, and uses no cloud LLM by default. An optional local-LLM judge can talk to a local Ollama or OpenAI-compatible endpoint.

Install

git clone https://github.com/DaoyuanLi2816/mcp-fence
cd mcp-fence
python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
python -m pip install -e ".[dev]"

Requires Python 3.11+.

30-second quickstart

# 1. Bring up the bundled examples in your working directory.
mcp-fence init-example ./mcp-fence-examples

# 2. Static scan the intentionally poisoned metadata server.
mcp-fence scan examples/vulnerable_metadata_server/mcp.json

# 3. Live-inspect the safe baseline.
mcp-fence inspect examples/safe_server/mcp.json

# 4. Fuzz the arbitrary-file-read server.
mcp-fence fuzz examples/vulnerable_filesystem_server/mcp.json

# 5. Generate a `docker run` command that sandboxes any of the above.
mcp-fence sandbox examples/vulnerable_filesystem_server/mcp.json \
    --profile strict --dry-run

# 6. Turn a saved JSON result into an offline HTML report.
mcp-fence scan examples/vulnerable_metadata_server/mcp.json \
    --format json --output /tmp/scan.json
mcp-fence report /tmp/scan.json --format html --output /tmp/scan.html

Example output

mcp-fence 0.1.0 :: scan :: target=examples/vulnerable_metadata_server/mcp.json
  summary: total=1 score=7/100 verdict=FAIL
  by_severity: high=1
  by_category: secrets=1

# Findings
  SEV   RULE     TITLE                    CATEGORY  WHERE                    DETAIL
  HIGH  MCPG006  Plaintext secret in env  secrets   param=OPENAI_API_KEY     Environment variable OPENAI_API_KEY appears to be a plaintext secret.

Supported transports

Transport scan inspect fuzz sandbox Notes
stdio First-class.
streamable-http Static (config) only; live HTTP inspector v0.2.
sse / websocket Same.

Supported risk classes

Full catalog in docs/rule_catalog.md. Highlights:

  • Tool poisoning — prompt-injection phrases in tool descriptions, hidden HTML comments, zero-width characters, confusable tool names (Unicode + ASCII visual confusables like Iist_files vs list_files).
  • Dangerous startup commandsshell=True, curl | sh, sudo, /var/run/docker.sock, --privileged, references to ~/.ssh, ~/.aws.
  • Transport binding0.0.0.0 + no auth, HTTP without bearer.
  • Schema risks — unbounded strings, missing additionalProperties, high-risk param names (command, path, url, webhook, …) without pattern/enum/maxLength.
  • Dynamic — path traversal hitting a planted fake secret, command injection marker echoed back, SSRF accepting metadata IPs, malformed input passing schema validation, sensitive patterns in tool output.
  • Protocol — server hangs, schema mismatches, non-JSON output on stdio.

Why MCP servers need their own scanner

MCP server output flows directly into an LLM's context. Anything in a tool's description, name, or response can be interpreted by the assistant as instructions:

  • Tool metadata is attacker-controllable once you install someone else's server.
  • Tool inputs are LLM-controllable and untrusted by default.
  • Tool outputs end up in the LLM's prompt and can carry injection payloads from external content.

General-purpose SAST / npm-audit / pip-audit don't model any of this. mcp-fence has rules and fuzzers built specifically for it.

Safety boundaries

  • Non-destructive payloads. The command-injection marker is echo MCPG_FUZZ_MARKER_8f2a. No rm, mv, chmod, or destructive primitives are ever emitted.
  • Local-first. No code, configuration, or scan result is uploaded anywhere.
  • No cloud LLM by default. Optional --llm-judge talks to a local endpoint only.
  • No public-network scanning. SSRF payloads test the tool's validation behaviour; we don't initiate outbound requests for you.
  • Safe path probing. Path-traversal payloads target a planted fake_secret.txt inside the bundled examples or any explicit --traversal-target. They never aim at /etc/shadow or ~/.ssh/.

--allow-unsafe is an explicit safety hatch for use inside the mcp-fence sandbox Docker profile. See SECURITY.md and docs/sandboxing.md.

Optional local-LLM judge (Ollama / vLLM)

For semantic suspiciousness scoring on tool descriptions, enable the optional judge:

ollama pull qwen3:8b
mcp-fence scan examples/vulnerable_metadata_server/mcp.json \
    --inspect --llm-judge ollama --llm-model qwen3:8b

Sized for a 16 GB GPU (e.g. RTX 4080). Failures are silent: the core scan completes either way. See docs/local_llm.md.

GitHub Action

Drop .github/workflows/mcp-fence.yml into any repo with an mcp.json. It scans every config and uploads SARIF to GitHub's code scanning dashboard.

- name: install mcp-fence
  run: pip install mcp-fence
- name: scan
  run: mcp-fence scan path/to/mcp.json --format sarif --output mcp-fence.sarif
- uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: mcp-fence.sarif
    category: mcp-fence

Five most useful commands

mcp-fence scan examples/vulnerable_metadata_server/mcp.json
mcp-fence inspect examples/safe_server/mcp.json
mcp-fence fuzz examples/vulnerable_filesystem_server/mcp.json
mcp-fence sandbox examples/vulnerable_shell_server/mcp.json --profile strict --dry-run
mcp-fence report /tmp/scan.json --format html --output /tmp/scan.html

Roadmap

See docs/roadmap.md. v0.2 adds AST-based source scanning, HTTP/SSE live inspector, a local SSRF capture server, and a pre-trained tool-poisoning classifier.

License

Apache-2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_fence-0.1.0.tar.gz (65.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_fence-0.1.0-py3-none-any.whl (66.5 kB view details)

Uploaded Python 3

File details

Details for the file mcp_fence-0.1.0.tar.gz.

File metadata

  • Download URL: mcp_fence-0.1.0.tar.gz
  • Upload date:
  • Size: 65.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for mcp_fence-0.1.0.tar.gz
Algorithm Hash digest
SHA256 32014e47b89355ef5e6b917dc8ffaff0458ee9bf123d8466bd647e172b0ef4b0
MD5 c8945f9447b4becb15fb463bd194d1b0
BLAKE2b-256 bfdd5e626ebff336d2ed8ae674f9992375d095aa1a646a4c7df5e12f5bc03436

See more details on using hashes here.

File details

Details for the file mcp_fence-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: mcp_fence-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 66.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for mcp_fence-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8739b11e80919f72955f544ce2534e394a3a07b37739bd6cc3c42ae505d17245
MD5 3e926e864f4390936cd24f5e220eba06
BLAKE2b-256 7d69f75be68102c46ef8620b8051e432a8d08a16a8a57295d1a98fa4f3f1e55a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page