tzMCP is a GUI and CLI tool that uses mitmproxy to intercept and selectively save media from web traffic β including images, videos, HTML, CSS, JavaScript, and other downloadable files.
It is secure-by-default, lightweight, and designed to be cross-platform and user-friendly.
- β GUI with Tabbed Interface
- π΅οΈββοΈ Runs a MITM Proxy (mitmdump)
- π Media filtering by:
- MIME group (e.g.,
image,video,html) - File size range
- Pixel dimensions
- Domain whitelists / blacklists
- MIME group (e.g.,
- π§ Smart MIME detection using byte scanning (not just Content-Type)
- π§Ή Automatic cleanup of expired logs and browser profiles
- π Security-first:
- Directory traversal protection
- Executable file type warnings
- SHA256-based deduplication
- π¬ Real-time log stream to GUI (via internal log server)
- π§ͺ Optional persistent deduplication (SQLite-backed)
- π Portable browser launcher with proxy preconfiguration
The GUI opens on Capture Session, a single guided workflow:
- Start the local capture proxy.
- Choose a dedicated portable browser.
- Confirm the browser is not your everyday installed browser, then launch it.
Capture Rules contains media filters, save location, and logging settings; Activity shows capture/proxy messages.
Important: mitmproxy decrypts traffic from the browser it launches. Do not use accounts, passwords, payment details, or other sensitive credentials in a capture session. Use a dedicated portable browser only. Launching an installed everyday browser can interfere with, lock, or change its usual profile.
git clone https://github.com/taggedzi/tzMCP
cd tzmcppip install -r requirements.txtOr, if installing via PyPI (coming soon):
pip install tzmcp
python -m tzMCP.guiConfiguration is stored in tzMCP's per-user application-data directory, not in
the installation directory. By default this is %LOCALAPPDATA%\\tzMCP on
Windows, ~/Library/Application Support/tzMCP on macOS, and
~/.local/share/tzMCP on Linux (or $XDG_DATA_HOME/tzMCP). Set
TZMCP_DATA_DIR to use a different directory, such as a portable drive.
media_proxy_config.yaml and browser_paths.yaml are created in its config
subdirectory. You can modify them via the GUI or manually. Browser paths start
empty because executable locations are specific to each machine.
# Optional. If omitted, captures are saved to the application's data directory.
# save_dir: /path/to/tzMCP-captures
# Local listener used by tzMCP and its browser launcher.
proxy_port: 8888
allowed_mime_groups:
- image
- video
filter_pixel_dimensions:
enabled: true
min_width: 300
min_height: 300
max_width: 12000
max_height: 12000
filter_file_size:
enabled: true
min_bytes: 10240 # 10KB
max_bytes: 157286400 # 150MB
whitelist: []
blacklist:
- ads\..*
- .*\.doubleclick\.net
log_to_file: true
log_level: INFO
auto_reload_config: true
enable_persistent_dedup: falseCLI is supported. Here are the parameters for the CLI.
usage: tzMCP-cli [-h] [--config CONFIG] [--proxy-port PROXY_PORT] [--save-dir SAVE_DIR] [--mime-groups [MIME_GROUPS ...]]
[--whitelist [WHITELIST ...]] [--blacklist [BLACKLIST ...]] [--min-bytes MIN_BYTES]
[--max-bytes MAX_BYTES] [--min-width MIN_WIDTH] [--max-width MAX_WIDTH] [--min-height MIN_HEIGHT]
[--max-height MAX_HEIGHT] [--log-to-file] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--dedup]
[--no-auto-reload]
tzMCP CLI Media Capture Proxy
options:
-h, --help show this help message and exit
--config CONFIG Path to YAML config file
--proxy-port PROXY_PORT
TCP port for the local proxy listener
--save-dir SAVE_DIR Directory to save media files
--mime-groups [MIME_GROUPS ...]
List of allowed MIME groups
--whitelist [WHITELIST ...]
Domain whitelist (domain or regex)
--blacklist [BLACKLIST ...]
Domain blacklist (domain or regex)
--min-bytes MIN_BYTES
Minimum file size in bytes
--max-bytes MAX_BYTES
Maximum file size in bytes
--min-width MIN_WIDTH
Minimum image width
--max-width MAX_WIDTH
Maximum image width
--min-height MIN_HEIGHT
Minimum image height
--max-height MAX_HEIGHT
Maximum image height
--log-to-file Enable file logging
--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
Set log level
--dedup Enable persistent deduplication
--no-auto-reload Disable config auto-reload- MIME detection uses both extension and byte-scanning (via
filetype) - File extensions are never guessed
- Executables are blocked unless explicitly allowed
- File names are sanitized to prevent directory traversal or reserved name collisions
- SHA256 deduplication prevents accidental overwrites or re-saves
When published on PyPI:
pip install tzmcp
tzmcp # launch GUI (entry point)-
Python version: 3.12+
-
Platform: Windows, Linux, macOS (via tkinter + mitmproxy)
-
License: MIT
-
Dependencies:
- mitmproxy
- Pillow
- filetype
- psutil
- pyyaml
- watchdog
- requests
This is the repository layout. Runtime configuration, captures, logs, and browser profiles are instead created under the per-user application-data directory described above.
βββ .github\
βββ .gitignore
βββ .pylintrc
βββ .treeignore
βββ cache\
βββ config\
β βββ browser_paths.yaml
β βββ media_proxy_config.yaml
βββ docs\
βββ LICENSE
βββ pyproject.toml
βββ README.md
βββ requirements.txt
βββ scripts\
β βββ clean_unused_packages.py
β βββ tree_maker.py
βββ src\
β βββ config\
β β βββ browser_paths.yaml
β βββ tzMCP\
β βββ __init__.py
β βββ browser_plugins\
β β βββ __init__.py
β β βββ brave.py
β β βββ chrome.py
β β βββ firefox.py
β β βββ iron.py
β β βββ kmeleon.py
β β βββ librewolf.py
β β βββ opera.py
β β βββ seamonkey.py
β β βββ vivaldi.py
β βββ cli.py
β βββ common_utils\
β β βββ __init__.py
β β βββ cleanup_logs.py
β β βββ cleanup_profiles.py
β β βββ log_config.py
β βββ gui.py
β βββ gui_bits\
β β βββ __init__.py
β β βββ app_constants.py
β β βββ browser_launcher.py
β β βββ browser_tab.py
β β βββ config_manager.py
β β βββ config_tab.py
β β βββ log_server.py
β β βββ proxy_control.py
β β βββ proxy_tab.py
β β βββ status_bar.py
β βββ save_media.py
β βββ save_media_utils\
β βββ __init__.py
β βββ config_provider.py
β βββ gen_whitelist_regex.py
β βββ hash_tracker.py
β βββ mime_categories.py
β βββ mime_data_minimal.py
β βββ save_media_utils.py
βββ tasks.py
βββ tests\
Run the suite with pytest (no install required β pyproject.toml sets
pythonpath = ["src"]):
pytest # or: invoke test
pytest --cov=tzMCP # or: invoke coverageThe suite covers the media filters and sanitizers, config validation and
load/save, hash-based deduplication, the CLI config merge, and the
MediaSaver.response() capture pipeline (driven by mocked mitmproxy flows).
It is fully isolated and never touches your real config/, logs/, or
cache/ directories.
Domain whitelist/blacklist entries that are bare hostnames (for example,
example.com) match that domain and its subdomains, but not lookalikes such
as notexample.com. Entries containing regex syntax are matched as regular
expressions, so patterns such as .*\.doubleclick\.net work as written.
MIT License. See LICENSE file for full text.
- Built on top of mitmproxy
- Inspired by the need for a safe, auditable web media capture tool
Please understand and read the terms of this software before using it. They are located here: CYA_NOTICE.md.