video-evidence-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@video-evidence-mcpSearch for 'climate change' and analyze the top video"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
video-evidence-mcp
video-evidence-mcp is a self-hosted, read-only MCP service and a video-evidence ChatGPT/Codex plugin. It searches anonymous public YouTube and Bilibili content and produces a compact evidence package: verified metadata, timestamped captions or local ASR, whole-video distributed frames, scene-change frames, Chinese/English OCR, contact sheets, and bounded window reinspection.
The default deployment listens only on 127.0.0.1:8787. Long analyses are queued in Redis and executed by a separate worker; an MCP request only enqueues or polls work. No server-side LLM is required. The calling ChatGPT reads the transcript and ImageContent contact sheet and writes the final explanation.
Code and state are deliberately separate: the checkout contains only code/configuration, while all persistent service state is bind-mounted below the dedicated host directory /data/video-evidence-mcp (app, redis, models, optional Caddy state, and tunnel profile).
Architecture and data flow
ChatGPT/Codex plugin
|
| Secure MCP Tunnel (outbound HTTPS only)
v
127.0.0.1:8787/mcp -> MCP service -> SQLite/WAL job + evidence metadata
|
v
Redis durable queue
|
v
one worker
|
URL/DNS guard -> yt-dlp metadata -> Playwright popup handling
|
captions -> faster-whisper fallback
|
FFmpeg distributed + scene frames -> timestamp overlay
|
RapidOCR -> evidence selection -> WebP sheets
|
retain metadata/transcript/OCR/thumbnails; delete raw mediaThe four MCP tools are search_videos, start_video_analysis, get_video_analysis, and get_video_window. Every input/output model forbids extra fields. Responses include a trace ID, machine-readable status, warnings, and an error code on failure. get_video_analysis and get_video_window add a compressed WebP ImageContent block when requested.
Security boundaries:
Input URLs are HTTPS-only canonical YouTube/Bilibili video URLs; playlists, userinfo, non-default ports, and unknown hosts are rejected.
DNS answers are checked for loopback/private/link-local/reserved addresses. Browser requests are limited to the selected platform and required CDN/API suffixes.
TRUSTED_DNS_PROXY_CIDRis empty by default. A host whose verified transparent proxy maps public names into RFC 2544 benchmarking space may opt into a subnet of198.18.0.0/15; arbitrary private CIDRs are rejected by configuration validation, and the platform/redirect host allowlists still apply.The adapters only dismiss known close/cancel/continue-without-login/cookie/app prompts. They never enter credentials or bypass CAPTCHA, age, payment, private, or forced-auth controls.
The private Compose mapping is exactly
127.0.0.1:8787:8787; Redis has no host port.AUTH_MODE=nonerefuses a non-loopback listener unlessTRUSTED_LOOPBACK_PROXY=true, which the private Compose deployment uses only behind that loopback mapping.The public profile requires an external OIDC/OAuth issuer, validates issuer/audience/scopes/signatures, publishes protected-resource metadata, returns
WWW-Authenticate, rate-limits requests, bounds concurrency, and redacts sensitive headers/query values. Caddy caps public request bodies at 4 MB.
This implementation follows the current OpenAI MCP server guide, plugin packaging guide, authentication guide, ChatGPT connection guide, and Secure MCP Tunnel guide. The server uses the current stable v2 line of the official MCP Python SDK.
Resource guidance
The detected server (Intel N100, 4 cores, 7.5 GiB RAM, no GPU) should keep ANALYSIS_CONCURRENCY=1, ASR_MODEL=small, ASR_COMPUTE_TYPE=int8, standard analysis at 24 frames, and deep analysis at 48 frames. Expect ASR on long videos to be CPU-bound. About 10–15 GiB free disk is a comfortable minimum for images, browser binaries, ASR model cache, and temporary media; this checkout defaults to a 10 GiB evidence limit and a 4 GiB per-job temporary-media limit.
For a supported NVIDIA host, verify nvidia-smi and NVIDIA Container Toolkit first, stop the CPU worker, then build/start worker-gpu:
sudo docker compose stop worker
sudo docker compose --profile gpu up -d --build worker-gpuThe GPU image targets CUDA 12/cuDNN 9. This host has no detected GPU, so only the CPU profile is locally validated.
Local start
cp .env.example .env
sudo ./scripts/prepare_data_dir.sh /data/video-evidence-mcp
sudo docker compose build mcp
sudo docker compose up -d --wait redis mcp worker
curl --fail http://127.0.0.1:8787/healthz
curl --fail http://127.0.0.1:8787/readyzNo inbound home-network port is opened. Do not change the Compose port mapping to 0.0.0.0:8787 while AUTH_MODE=none.
If both getent ahosts www.youtube.com and getent ahosts www.bilibili.com return synthetic 198.18.x.x addresses because this host uses a trusted transparent DNS proxy, set TRUSTED_DNS_PROXY_CIDR=198.18.0.0/15 in the local ignored .env. Leave it empty on ordinary DNS.
For development and tests inside the locked image:
sudo docker compose run --rm --no-deps mcp ruff check .
sudo docker compose run --rm --no-deps mcp mypy src
sudo docker compose run --rm --no-deps mcp pytestMCP Inspector
The official Inspector CLI can initialize the live Streamable HTTP server and enumerate tools:
npx -y @modelcontextprotocol/inspector@latest --cli \
http://127.0.0.1:8787/mcp --transport http --method tools/listFor the browser UI, run npx -y @modelcontextprotocol/inspector@latest, select Streamable HTTP, and enter http://127.0.0.1:8787/mcp. The automated in-memory equivalent is python scripts/mcp_smoke.py.
Secure MCP Tunnel activation
Secure MCP Tunnel is the preferred private route: the server stays loopback-only and tunnel-client makes outbound HTTPS requests to OpenAI. A Tunnel ID and a control-plane API key cannot be fabricated locally.
In OpenAI Platform tunnel settings, create or select a tunnel, associate the intended Platform organization and ChatGPT workspace, and grant the operator Tunnels Read + Use (Manage is needed to create/edit).
Download the latest
tunnel-clientfrom the Platform page or the latest publicopenai/tunnel-clientrelease; save it asdeploy/tunnel/tunnel-client, make it executable, and keep it out of Git.Create
/etc/video-evidence-mcp/tunnel.envas root with mode0600:TUNNEL_ID=tunnel_... CONTROL_PLANE_API_KEY=sk-...Initialize the profile as the dedicated service user from
/data/video-evidence-mcp/tunnel:cd /data/video-evidence-mcp/tunnel set -a . /etc/video-evidence-mcp/tunnel.env set +a /opt/video-evidence-mcp/deploy/tunnel/init-profile.sh tunnel-client doctor --profile video-evidence --explainInstall
deploy/systemd/video-evidence-compose.serviceanddeploy/systemd/video-evidence-tunnel.serviceunder/etc/systemd/system, then enable them. These are templates; review absolute paths and create the unprivilegedvideo-evidenceuser before installation.
The unit runs doctor before run and restarts on failure. The tunnel-client local admin UI, /healthz, /readyz, and /metrics should remain loopback-only. Secrets never belong in .env, Compose YAML, an image, command-line logs, or this repository.
Add the connection in ChatGPT
Per the current OpenAI flow:
Open ChatGPT Settings → Security and login → enable Developer mode (subject to account/workspace policy).
Open ChatGPT Plugins, select
+, enter a name/description, choose Tunnel, and select or paste thetunnel_id.Review the discovered four tools and create the connection. Refresh metadata after server tool changes.
Install/enable the
video-evidenceplugin in the same target account/workspace and test the behavior cases underevals/plugin-behavior.json.
The repository marketplace (marketplace.json) and local .mcp.json are development fixtures. They make the plugin visible to a local Codex/desktop development installation; they do not publish or synchronize it to ChatGPT web, desktop, and mobile. Same-account/workspace cross-device use requires creating/installing the corresponding plugin connection in that account/workspace. Public availability requires OpenAI plugin submission/review and a stable public HTTPS endpoint.
To install this repository marketplace in Codex development:
codex plugin marketplace add /absolute/path/to/video-evidence-mcpAfter changes, run the cachebuster helper from the installed plugin-creator skill and reinstall the plugin; start a new thread so refreshed skill instructions are loaded.
Optional public HTTPS/OAuth profile
Do not write a password system for this service. Configure a mature external OAuth 2.1/OIDC provider that supports Authorization Code, PKCE S256, the MCP resource parameter/audience, required scopes, and either preferred CIMD (none or private_key_jwt) or DCR. The provider—not this repository—owns login, consent, CIMD/DCR, token issuance, and account security.
Set DOMAIN, OIDC_ISSUER, OIDC_AUDIENCE, OIDC_REQUIRED_SCOPES, and optionally OIDC_JWKS_URL, point public DNS at the server, and explicitly start only the public services:
sudo docker compose --profile public up -d --build redis mcp-public worker-public caddyCaddy obtains HTTPS automatically. The MCP endpoint is https://<domain>/mcp; metadata is at https://<domain>/.well-known/oauth-protected-resource/mcp. Validate the issuer discovery document advertises Authorization Code, PKCE S256, CIMD or DCR as selected, and correct token authentication methods. Validate tokens include the configured audience and scopes. Never expose the private mcp service or use AUTH_MODE=none on a public listener.
Maintenance and operations
Upgrade deliberately and regenerate the lock; never update one runtime in place:
# All Python dependencies, including yt-dlp/faster-whisper/RapidOCR
sudo docker run --rm -e UV_CACHE_DIR=/app/.uv-cache -v "$PWD:/app" -w /app \
ghcr.io/astral-sh/uv:python3.12-bookworm-slim lock --upgrade
# Prefer Playwright's matching Chromium when its CDN is reachable
sudo docker compose run --rm --user root mcp playwright install chromium
# Rebuild (the image has a distro Chromium fallback for restricted CDNs)
sudo docker compose build --pull --no-cache mcp
sudo docker compose up -d --wait redis mcp worker
# Choose a different ASR model only after sizing CPU/RAM/disk
sed -i 's/^ASR_MODEL=.*/ASR_MODEL=medium/' .env
sudo docker compose up -d workerBack up /data/video-evidence-mcp while services are stopped, or use SQLite's online backup API. Evidence metadata is in /data/video-evidence-mcp/app/video-evidence.sqlite3, cache files are under /data/video-evidence-mcp/app/cache, Redis AOF/RDB files are under /data/video-evidence-mcp/redis, and ASR downloads are under /data/video-evidence-mcp/models. Restore the matching directory tree and ownership before starting the same application version.
sudo docker compose logs --since 1h mcp worker
sudo docker compose exec mcp video-evidence-cache disk-check
sudo docker compose exec mcp video-evidence-cache cleanup --dry-run
sudo docker compose exec mcp video-evidence-cache cleanupCleanup removes only expired/over-limit evidence entries. It never deletes configuration, secrets, the database, Redis state, or ASR models. To uninstall, stop the units/Compose stack first; docker compose down leaves /data/video-evidence-mcp untouched. Archive that directory before explicitly removing it. Remove /etc/video-evidence-mcp/tunnel.env separately and securely.
Known limitations and troubleshooting
Platform markup, captions, and anonymous-access policy change. When popup fixtures still pass but live access fails, capture only redacted status/selector diagnostics, update the platform adapter's stable roles/attributes/text, and rerun fixture plus live smoke tests.
The 2026-08-17 build environment reset every Playwright CDN TLS download, so the verified image explicitly launches Debian Chromium. When CDN access returns, install Playwright's matching browser and remove the executable override during a planned rebuild.
This host's transparent proxy resolves both platforms into
198.18.0.0/15; its ignored local.envexplicitly trusts only that benchmarking CIDR. On another server, remove this setting unless the same mapping is independently verified.Region restrictions, bot challenges, forced authentication, age gates, private/paid videos, and live streams are reported as limitations; they are not bypassed.
yt-dlp extraction may break after site changes. Reproduce with
yt-dlp --verbose --skip-download '<canonical-url>'in the worker image, redact request data, then upgrade/lock/rebuild.Automatic captions, Whisper, and OCR can be wrong, especially for proper names, numbers, overlapping speech, stylized text, and low-resolution frames. The Skill requires transcript/visual window cross-checking for important claims.
Scene detection plus fixed samples gives whole-video coverage, not frame-complete observation.
get_video_windowis capped and returns cached thumbnails, never arbitrary original media.The first ASR job downloads the configured model and can take longer. Check worker logs, free disk, and model-volume permissions.
If Inspector returns
421, check the Host allowlist and connect to exactly127.0.0.1:8787. If readiness is503, check Redis health. If a job was interrupted by restart, it is explicitly marked failed and can be resubmitted.Optional server-side OpenAI visual description is intentionally disabled by default; the core evidence workflow does not require
OPENAI_API_KEY.
Live smoke tests are opt-in because they contact third-party platforms:
RUN_LIVE_TESTS=1 pytest -m live -vv
python scripts/live_smoke.py
python scripts/live_analysis_smoke.pyResults are written under test-results/ with the URL, UTC date, result, and exact error class. A blocked or rate-limited live test is recorded as such, never reported as passed.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Multimodal video analysis MCP — transcription, vision, and OCR for any video URL.
Any social-video URL → transcript, metadata, frames, OCR, summary, search, Q&A. MCP server + x402.
Remote MCP for C2PA intake verifier MCP, structured receipts, audit logs, and reviewer-ready evidenc
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Sandro-Z/Video-Evidence-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server