Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

MCPWatch for Python

The MCPWatch security guard for MCP servers written in Python. It checks every JSON-RPC message between any MCP client and your server, in both directions. It works with:

  • the official MCP Python SDK (MCPServer, FastMCP, the low-level Server)
  • Django
  • Flask
  • FastAPI and Starlette
  • any ASGI or WSGI app

Clients need no changes.

The checks are the same as for Node servers. They run in the MCPWatch engine, which the package starts as a small child process (mcpwatch engine). The same engine also provides the AI reviewer, the dashboard reporting and the live settings. Node.js 20+ must be installed on the machine running the server.

pip install --pre vedhaai-mcpwatch           # beta: --pre until 0.1.0 is released
npm install -g @vedhaai/mcpwatch@beta     # the engine; without it, the package falls back to npx

Official MCP SDK (stdio, SSE, Streamable HTTP)

from mcp.server.mcpserver import MCPServer      # mcp 1.x: from mcp.server.fastmcp import FastMCP
from mcpwatch import mcpwatch

server = MCPServer("my-tools")
# ... @server.tool() as usual

mcpwatch(server)                                # ← the only line added, before run()
server.run()                                    # or uvicorn.run(server.streamable_http_app())
  • stdio and SSE: every message on the server's streams is checked.
  • Streamable HTTP: server.streamable_http_app() returns the app already wrapped by McpWatchASGI.

A blocked call gets a JSON-RPC error (-32001 blocked, -32002 throttled), and your tool never runs.

Django

Add the middleware first in settings.py, so it sees exactly what the client sent:

MIDDLEWARE = ["mcpwatch.django.McpWatchMiddleware", ...]
MCPWATCH = {"name": "my-tools", "path": "/mcp"}        # optional; project_key, mode, deny_tools, …

To guard at the server boundary instead, wrap the app in wsgi.py or asgi.py:

application = McpWatchWSGI(get_wsgi_application(), name="my-tools")    # or McpWatchASGI(get_asgi_application())

Flask

from mcpwatch.flask import McpWatch

app = Flask(__name__)
McpWatch(app, path="/mcp")                    # or McpWatch().init_app(app)

app.config keys MCPWATCH_PROJECT_KEY, MCPWATCH_SERVER and MCPWATCH_MODE are used when set.

FastAPI, Starlette, any ASGI or WSGI app

from mcpwatch import McpWatchASGI, McpWatchWSGI

app.add_middleware(McpWatchASGI, name="my-tools", path="/mcp")      # FastAPI / Starlette
app = McpWatchWSGI(app, name="my-tools", path="/mcp")               # any WSGI app

Only requests under path (default /mcp) are checked. Pass a list for several endpoints, or None for every path. Both JSON and SSE (text/event-stream) responses are checked.

Options

Every adapter takes the Node middleware's options in snake_case. Options you leave out come from the same MCPWATCH_* environment variables, listed in the main README.

Option Variable Meaning
project_key MCPWATCH_PROJECT_KEY Dashboard project key. Events go there, and the project's mode and client lists apply live
server MCPWATCH_SERVER Dashboard URL (default http://127.0.0.1:9100)
enabled MCPWATCH_ENABLED=0 False leaves the server untouched
mode MCPWATCH_MODE off, observe, protect, enforce (default)
deny_tools, allow_tools Tool names that may never / only be called
allowed_origins, allowed_hosts, require_auth, expected_audience MCPWATCH_ALLOWED_ORIGINS, … HTTP transport checks (MW030–MW036)
ai MCPWATCH_AI=1, … AI reviewer, e.g. {"enabled": True, "model": "qwen2.5:7b"}
fail_open True (default): if the engine can't run, messages pass unchecked and an error is logged. False: requests are refused
command MCPWATCH_ENGINE How to start the engine, e.g. node C:/path/to/MCP-Watch/dist/cli.js. Default: mcpwatch on PATH, else npx -y @vedhaai/mcpwatch@beta

How it works

MCP client ──► your Python server ─────────────────────────────────────────────┐
               adapter (SDK hook / ASGI / WSGI / Django)                        │
                 │ each JSON-RPC message, one JSON line   ▲ forward / reply     │
                 ▼                                        │                     │
               mcpwatch engine (Node child process): rules, AI reviewer, ───────┼──► dashboard
               sessions, pins, reporting                                         │
                 allowed messages ──► your tools ───────────────────────────────┘
  • One engine per guarded server. Every connection to the server shares it. A worker process started by forking (gunicorn, uwsgi) starts its own engine.
  • Order kept. Each connection waits for each message's verdict, so messages are never reordered.
  • If the engine stops, the next message starts it again, at most once every 10 seconds. Session scores start over.

Tests

cd ..; npm install; npm run build; cd python
python -m venv .venv; .venv\Scripts\pip install -e ".[test]"
.venv\Scripts\python -m pytest

The tests run the engine from the checkout's dist/cli.js. They cover:

  • an SDK server over stdio and Streamable HTTP
  • Flask, Django, plain ASGI and WSGI apps
  • options reaching the engine
  • the engine being unavailable (fail open and fail closed)

Metadata

Release files for vedhaai-mcpwatch 0.1.0b0

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

Source distribution (sdist)

Source distribution for vedhaai-mcpwatch 0.1.0b0
File Size Uploaded Provenance Actions
vedhaai_mcpwatch-0.1.0b0.tar.gz 20.2 kB Without provenance Details for vedhaai_mcpwatch-0.1.0b0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for vedhaai-mcpwatch 0.1.0b0
File Interpreter ABI Platform Actions
vedhaai_mcpwatch-0.1.0b0-py3-none-any.whl Python 3 none any Details for vedhaai_mcpwatch-0.1.0b0-py3-none-any.whl

Total release size: 40.3 kB

Release files / vedhaai_mcpwatch-0.1.0b0.tar.gz

Download URL vedhaai_mcpwatch-0.1.0b0.tar.gz
Size 20.2 kB
Tags Source
SHA-256 checksum
How to use checksums
4656fe28d25045bcf6ddde20e9de1cbf5f2b8a57811f3fe69afce3526a27615f
BLAKE2b-256 checksum
How to use checksums
502e1ec7d536c8c357c2206cadee2bf88f6e06c03230ab702831fb533ee9820c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release files / vedhaai_mcpwatch-0.1.0b0-py3-none-any.whl

Download URL vedhaai_mcpwatch-0.1.0b0-py3-none-any.whl
Size 20.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
66f35177b05c27a9243805f658a32b94b588c23288db90ef4a0309c42c175f5c
BLAKE2b-256 checksum
How to use checksums
35d32c79ff93f3c08375bc5e5647eb42076193aa059c3bc921e4727adbd4be9f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Security for vedhaai-mcpwatch 0.1.0b0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
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