Metadata-Version: 2.4
Name: watchlight-mcp
Version: 0.4.3
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security
License-File: LICENSE
Summary: Watchlight MCP Runtime PEP — deny denied MCP tool calls before they reach the server. In-process Watchlight engine, zero infrastructure.
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Documentation, https://docs.watchlight.ai
Project-URL: Homepage, https://watchlight.ai

# Watchlight MCP Runtime PEP

A **Policy Enforcement Point** for the [Model Context Protocol](https://modelcontextprotocol.io).
It sits in front of an upstream MCP server and makes one guarantee:

> **No governed MCP action reaches the target system until Watchlight has made a
> deterministic runtime authorization decision — and only an explicit PERMIT
> forwards it.**

Every `tools/call` is authorized **in-process** by the real Watchlight engine
before it can reach the upstream server. A denied call is blocked *before it
executes* — not detected after. Zero infrastructure: no database, no network
hop, no sidecar.

## Install

```bash
pip install watchlight-mcp
```

## Run

```python
import watchlight_mcp

watchlight_mcp.serve(
    listen_addr="127.0.0.1:9700",
    upstream_url="http://localhost:3000/mcp",   # the MCP server you are governing
    upstream_server="github",                    # a stable name for it (used in policy + audit)
    policy_files=["policies/allow-read.json"],   # Cedar policies, wl-apdp shape
    audit_path="audit/mcp-pep.jsonl",            # value-free JSONL audit (omit → logs)
)
```

Point your MCP client at `http://127.0.0.1:9700/mcp` instead of the server
directly. Governed `tools/call`s are authorized; everything else is forwarded
transparently.

## What it enforces

- **MCP `2026-07-28`** Streamable HTTP: the JSON-RPC body is authoritative, and
  the `Mcp-Method` / `Mcp-Name` / `MCP-Protocol-Version` routing headers are
  validated against it — a spoofed header cannot route a governed call around
  enforcement.
- **Fail-closed**: a deny, a runtime error, a malformed body, a header/body
  mismatch, or an unsupported protocol version all block the action. The upstream
  is contacted *only* on an explicit permit.
- **Value-free audit**: the audit record has no field for tool arguments,
  tokens, or credentials — only the decision and safe correlation ids.

## Identity

The PEP reads client-asserted `Watchlight-*` headers (`Watchlight-Agent-Id`,
`Watchlight-Execution-Id`, …) to build the authorization principal and execution
context — the Developer-Edition trust model. Without an attributed agent, the
action is denied by default.

---

© Watchlight AI. The embedded runtime is proprietary; see LICENSE.

