Skip to main content

Zero-trust security gateway for MCP (Model Context Protocol) tool servers — static scanning, sandbox behavioural profiling, and runtime policy enforcement.

Project description

MCP Zero-Trust Gateway

A security gateway that sits between an LLM agent and the MCP (Model Context Protocol) tool servers it uses, on the principle that no tool server is trusted by default. Every tool is inspected before it is allowed in, profiled to see what it actually does, constrained by least-privilege policy, and monitored at runtime.

It runs entirely on your machine. The trust store is a local SQLite file and no telemetry is sent anywhere.

The problem

An LLM agent discovers tools by reading each MCP server's self-description (tools/list). It then calls them (tools/call) with its own privileges. The agent treats the server's description as truth. That assumption is the vulnerability: a malicious server can hide instructions in its description (tool poisoning) or perform actions its manifest never declared (e.g. read ~/.ssh/id_rsa while claiming to fetch weather). This gateway removes the default trust.

What it does

  1. Intake scan — static inspection of the manifest at registration, including detection of poisoned descriptions.
  2. Behavioral profiling — runs the server in a hardened sandbox (--network none, --cap-drop ALL, seccomp) under strace and records the syscalls it actually makes.
  3. Declared-vs-observed verification — flags any capability the tool used but did not declare, and detects rug-pulls when a new version quietly gains one.
  4. Policy enforcement — constrains even approved tools to least privilege at runtime.
  5. Runtime proxy — every tool call passes through the gateway, is checked, logged, and its response filtered.
  6. Dashboard — makes verdicts, mismatches, and blocked actions visible.

Install

pip install mcp-ztgateway

Optional extras:

pip install "mcp-ztgateway[audit]"   # adds pip-audit for supply-chain scanning

Docker is required for behavioural profiling (step 2). Everything else — static scanning, policy enforcement, the proxy and the dashboard — runs without it.

Quick start

# 1. Check the environment
mcp-ztgateway doctor

# 2. Statically scan a tool manifest (exits non-zero on findings, so it works in CI)
mcp-ztgateway scan manifest.json

# 3. Profile a tool's real behaviour in a sandbox (needs Docker)
mcp-ztgateway profile my-tool:latest --tool get_weather --args '{"city":"London"}'

# 4. Run the gateway
mcp-ztgateway serve

serve binds to 127.0.0.1:8000 by default, so it is not reachable from other machines.

Where profiles live

A profile is the JSON record of what a tool did when sandboxed. Without one, a tool cannot be verified and is denied (default-deny). Profiles are looked up in this order:

  1. ./profiles — project-local, so a repo can pin its own trusted profiles
  2. $MCP_ZTGATEWAY_PROFILES — explicit override for CI or containers
  3. ~/.mcp-ztgateway/profiles — the per-user default

mcp-ztgateway doctor prints which one is active.

Optional: require an API key

The gateway is local-first and needs no authentication when bound to localhost. If you expose it beyond your machine, set a key and every request must then send a matching X-API-Key header:

export GATEWAY_API_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
mcp-ztgateway serve --host 0.0.0.0

/health and / stay open so load balancers can probe them.

Running with Docker

docker compose up --build
#   gateway   -> http://localhost:8000
#   dashboard -> http://localhost:5173

Published images:

docker pull abhiii1005/mcp_zerotrust_security_gateway:1.0.0
docker pull abhiii1005/zerotrust_dashboard:1.0.0

The gateway image is runtime-only: it enforces policy using pre-committed profiles and does not run Docker inside itself, so no privileged socket mount is needed. Live profiling stays a host-side step.

Development

git clone https://github.com/nabrahma/MCP_Zero-Trust_Gateway_BTP
cd MCP_Zero-Trust_Gateway_BTP
pip install -e ".[dev,audit]"
pytest -q

Documentation

  • MD_files/ARCHITECTURE.md — architecture, requirements, components, data flows
  • MD_files/THREAT_MODEL.md — what is defended, what is out of scope, mapped to the OWASP MCP Top 10
  • MD_files/CONTRACTS.md — the shared data shapes between components (read before writing code)
  • sandbox/enforcement/ — captured proof that the sandbox enforcement actually blocks the attacks it claims to

Status and honest limitations

Final-year B.Tech project: built and empirically evaluated, not a production system.

  • Behavioural profiling is evadable. A tool that stays dormant during profiling, detects the sandbox, or only misbehaves on unseen input will not be caught. This is the inherent limit of dynamic analysis.
  • seccomp is coarse. It filters on syscall numbers and scalar arguments, not path strings, so it can deny "all network" but not "reads of .env specifically". Per-path decisions are made by the policy layer above it.
  • Capabilities are classes, not exact semantics. The gateway reports "this tool reads files and opens sockets", not "this tool exfiltrates SSH keys".

See MD_files/THREAT_MODEL.md for the full scope.

Tech stack

Python · FastAPI · Docker (seccomp/strace) · SQLite · React + Tailwind · pip-audit

Team & roles

  • Static scanning & comparator (Layers 1, 3)
  • Sandbox profiler & enforcement (Layer 2)
  • Gateway: proxy, policy, dashboard (Layers 4–7)

License

MIT — 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_ztgateway-0.1.1.tar.gz (47.8 kB view details)

Uploaded Source

Built Distribution

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

mcp_ztgateway-0.1.1-py3-none-any.whl (42.5 kB view details)

Uploaded Python 3

File details

Details for the file mcp_ztgateway-0.1.1.tar.gz.

File metadata

  • Download URL: mcp_ztgateway-0.1.1.tar.gz
  • Upload date:
  • Size: 47.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.5

File hashes

Hashes for mcp_ztgateway-0.1.1.tar.gz
Algorithm Hash digest
SHA256 f1fa5eadfeb496a705ba72ee1f98e04a1257b1eeb996ffba758456fc48abcf4c
MD5 a754177bf939549de9b34ca800f0bf98
BLAKE2b-256 8e971db671bcece67f6db4b4a0056858cb097ba682ae9481151b6a67d23033ba

See more details on using hashes here.

File details

Details for the file mcp_ztgateway-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: mcp_ztgateway-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 42.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.5

File hashes

Hashes for mcp_ztgateway-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b9d684e30c390a0ed40253951b59beddde053d530fec9bccc99ccf2e9bb2633e
MD5 42aa5ab7727ca694760c50f78f8b417e
BLAKE2b-256 edc31c6c9eeb45d480844897e138fe1ebcaf2d0b63660e42c86cafe1f5d47243

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