Metadata-Version: 2.4
Name: mcp-ztgateway
Version: 0.1.0
Summary: Zero-trust security gateway for MCP (Model Context Protocol) tool servers — static scanning, sandbox behavioural profiling, and runtime policy enforcement.
License: MIT
Project-URL: Homepage, https://github.com/nabrahma/MCP_Zero-Trust_Gateway_BTP
Project-URL: Repository, https://github.com/nabrahma/MCP_Zero-Trust_Gateway_BTP
Project-URL: Issues, https://github.com/nabrahma/MCP_Zero-Trust_Gateway_BTP/issues
Keywords: mcp,security,zero-trust,gateway,llm,agent,sandbox,seccomp
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Framework :: FastAPI
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.115
Requires-Dist: uvicorn>=0.30
Requires-Dist: mcp[cli]>=1.0
Requires-Dist: pydantic>=2.0
Requires-Dist: PyYAML>=6.0
Requires-Dist: click>=8.0
Requires-Dist: httpx>=0.27
Provides-Extra: audit
Requires-Dist: pip-audit>=2.7; extra == "audit"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Dynamic: license-file

# 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

```bash
pip install mcp-ztgateway
```

Optional extras:

```bash
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

```bash
# 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:

```bash
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

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

Published images:

```bash
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

```bash
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](LICENSE).
