Skip to main content

Watchlight MCP Runtime PEP

A Policy Enforcement Point for the Model Context Protocol. 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

pip install watchlight-mcp

Run

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, and have it send Watchlight-Agent-Id: <agent> on every request. Governed tools/calls are authorized (one without that header is refused); 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 and logs: the audit record has no field for tool arguments, tokens, or credentials — only the decision and safe correlation ids. The process log is value-free at every level too: tool name, decision and ids, never an argument value. A resource URI is recorded as its scheme and host plus a SHA-256 prefix of the path (host-less URIs such as data: or mailto: as the scheme plus a hash).

Identity

The PEP reads client-asserted Watchlight-* headers to build the authorization principal and execution context — the Developer-Edition trust model. The principal comes from exactly one header:

  • Watchlight-Agent-Id (default) → Agent::"<id>". A request that also (or instead) carries Watchlight-Principal-Id is refused.
  • Watchlight-Principal-Id, only when you opt in with serve(..., principal_header="Watchlight-Principal-Id") → a Cedar entity ref such as User::"alice". A request carrying Watchlight-Agent-Id is refused.

Watchlight-Execution-Id, Watchlight-Parent-Execution-Id, Watchlight-Session-Id and Watchlight-Task-Id are read as execution context. A request that repeats any of these headers, or sends an empty or malformed one, is refused with JSON-RPC error -32002 (HTTP 400) and never forwarded. So is an identity value that contains ,, is a malformed Type::"id", or names the reserved unattributed principal.

Identity is mandatory. A governed call (tools/call, resources/read, resources/subscribe, prompts/get) without an identity header is refused with -32002; initialize, ping, tools/list and other pass-through methods need none. To decide such calls as the reserved Agent::"unattributed" principal instead (the 0.4.3 behaviour), pass allow_unattributed=True to serve / serve_background. serve_stdio refuses to start without agent_id or principal_id unless allow_unattributed=True.

Anyone who can reach the listener can assert these headers. Bind to loopback, or put a gateway in front that strips or overwrites all of them.

Responses

Outcome JSON-RPC error HTTP status
Permit none (the server's response is relayed) the server's status
Denied by policy, or a fail-closed engine error -32001 not authorized 200
Identity header refused, or no identity on a governed call -32002 400
Mcp-Method / Mcp-Name disagrees with the body -32020 400
Unsupported MCP-Protocol-Version -32022 400
Malformed or ambiguous body, missing tool name -32602 400
Upstream server unreachable -32603 502

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

Metadata

Release files for watchlight-mcp 0.4.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for watchlight-mcp 0.4.4
File
watchlight_mcp-0.4.4-cp39-abi3-manylinux_2_28_aarch64.whl CPython 3.9 abi3 Linux glibc 2.28+ ARM64 Details
watchlight_mcp-0.4.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
watchlight_mcp-0.4.4-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details
watchlight_mcp-0.4.4-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details

Total release size: 22.8 MB

Release files / watchlight_mcp-0.4.4-cp39-abi3-manylinux_2_28_aarch64.whl

Download URL watchlight_mcp-0.4.4-cp39-abi3-manylinux_2_28_aarch64.whl
Size 5.6 MB
Tags CPython 3.9 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
20c9931cbc7ceb5085e0217932d0e9bdc2f00e86d6be1b675e1d661b293cf91b
BLAKE2b-256 checksum
How to use checksums
bad51fc75764d8829c7803b0f42318ea7da1ae74d535407bfac7133a0f58ad2a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / watchlight_mcp-0.4.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL watchlight_mcp-0.4.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 6.0 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
b4ec3abcd7690cb640c276a22c2385216147d6709d1df1988b3aa589fcb646ab
BLAKE2b-256 checksum
How to use checksums
d0a83fd6c61b69f02b8799b91d4e2c624ead165d50b74d32aa61106ff63280f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / watchlight_mcp-0.4.4-cp39-abi3-macosx_11_0_arm64.whl

Download URL watchlight_mcp-0.4.4-cp39-abi3-macosx_11_0_arm64.whl
Size 5.5 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
002914992ebe6277b854703353dfd19a7f43287f4e499da18c2287e725d9d1b5
BLAKE2b-256 checksum
How to use checksums
334ca0b7aeba01d5601335ab26d2c07c059898ba1d28914ac49cdefcb3d5e62e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release files / watchlight_mcp-0.4.4-cp39-abi3-macosx_10_12_x86_64.whl

Download URL watchlight_mcp-0.4.4-cp39-abi3-macosx_10_12_x86_64.whl
Size 5.8 MB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
f23e7b90cd27b73f7ed65cb6fc8dae227634788b63bc2982c4ba55cfd029f8c2
BLAKE2b-256 checksum
How to use checksums
b99b5b28effd7ecd21bb2ffef414d660c0c7e4fe275b1ce4315eadcba929d1c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.4 This release

4 release files

0.4.3

4 release files

0.4.2

4 release files

0.4.1

4 release files

0.4.0

4 release files

0.3.0

4 release files

0.2.1

4 release files

0.2.0

4 release files

0.1.0

4 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page