Raw screenshots, PDFs, photos, recordings, and documents are created faster than they can be curated manually.
This repo provides a resilient, local-first pipeline that converts raw media into:
- canonicalized layouts (image/video/document),
- sidecar metadata,
- OCR/keyword enrichment,
- queryable indexes,
- repairable state.
The brand: Media Ark (the "ark" metaphor — a small, intentional, durable collection of heterogeneous things kept safe through disruption). Domain: media-ark.org. GitHub: 4444J99/media-ark. Previously: screen-capture-automation (renamed 2026-06-10).
Media Ark stays useful as a free, local-only repository at 4444J99/media-ark: your captures, OCR, manifests, indexes, and reports live on your machine under .media-ark/, and you decide how to copy or back them up.
For knowledge workers and journalists, the harder problem is not just processing files. It is preserving the material that supports a story, investigation, research brief, client memo, or long-running project when devices fail or work moves across machines. Media Ark Pro adds encrypted cloud sync and backup for $7/mo so source material, derived metadata, and searchable context can be recovered without giving up a local-first workflow.
| Tier | Price | Best for | What is included |
|---|---|---|---|
| Free | $0 | Local-first personal archives, private experiments, and repository-based automation | CLI/API/MCP/dashboard, local processing, local manifests, local indexes, local reports |
| Pro | $7/mo | Knowledge workers and journalists who need durable capture libraries across devices | Everything in Free, plus encrypted cloud sync, encrypted backup, and recovery for the archive state |
See docs/PRICING.md for the full pricing and value-prop notes.
flowchart TD
A[Raw source\ndata/captures/raw] --> B[Ingest scan]
B --> C[Deduplicate + canonical naming]
C --> D[Process and normalize]
D --> E[Generate thumbnails/OCR metadata]
E --> F[Append sidecar + index]
F --> G[State and reports]
G --> H[Query + verify + repair]
python3 src/media_ark/process_captures.py data/captures/raw --out .media-ark --dry-run./tools/media-ark/run_media_ark.sh data/captures/raw .media-ark --copy./tools/media-ark/media_ark_watch.sh data/captures/raw .media-ark --watch --interval 10 --max-runs 0./tools/media-ark/media_ark_pipeline.sh data/captures/raw .media-arkStart the platform in one command:
npm run platform:startThe command creates the default source/output directories, preflights the stdio MCP tool contract, then starts the API and dashboard at http://127.0.0.1:8787/.
Start UI + API directly:
python3 -m src.platform.api_server --host 127.0.0.1 --port 8787- Open
http://127.0.0.1:8787/for the dashboard. - Register or log in with
POST /api/auth/registerorPOST /api/auth/login. - Send
Authorization: Bearer <api_key>on protected/api/*requests. GET /api/status?source=<path>&out=<path>GET /api/manifest?out=<path>GET /api/index?out=<path>&limit=<n>&status=<all|processed|duplicate>&media=<all|image|video|document>POST /api/runwith JSON{"action":"process|check-source|verify|repair|query","source":"...","out":"..."}
Local HTTP users are stored in ~/.media-ark/users.db; each user gets a sandbox
under ~/.media-ark/users/<username> for API source/output paths.
python3 -m src.platform.mcp_serverExposed tools:
capture_statuscapture_checkcapture_runcapture_verifycapture_query
npm run media-ark:run
npm run media-ark:watch
npm run media-ark:pipelineRun verification:
npm run release:verifydata/captures/raw/— incoming media.src/media_ark/— core engine (Python package).src/media_ark/__init__.py—BRAND_*constants (single source of truth for the product name, env-var prefix, default data dir, server identity strings, etc.).src/platform/— API/MCP runtime bridge.tools/media-ark/— operational wrappers..media-ark/— canonical outputs, manifests, indexes, events..config/— examples and tooling presets.docs/— guides and operational references.web/— dashboard UI shell.pyproject.toml— Python project metadata;[project] name = "media-ark".
The product's identity strings — display name, domain, repo URL, env-var prefix, server identity, npm name, default data dir — are data, not strings baked into source. They live in src/media_ark/__init__.py as BRAND_* constants and are imported by every consumer (config, server, tests, scripts).
from media_ark import (
BRAND_NAME, # "media-ark"
BRAND_DISPLAY, # "Media Ark"
BRAND_DOMAIN, # "media-ark.org"
BRAND_REPO_URL, # "https://github.com/4444J99/media-ark"
BRAND_DATA_DIR, # ".media-ark"
BRAND_NPM, # "media-ark"
BRAND_PYTHON_PKG, # "media_ark"
BRAND_ENV_PREFIX, # "MEDIA_ARK"
BRAND_MCP_NAME, # "media-ark"
BRAND_SERVER_VERSION, # "MediaArk/1.0"
env_key, # helper: env_key("SOURCE") -> "MEDIA_ARK_SOURCE"
)Renaming the product is a one-file change in src/media_ark/__init__.py (and an update to the README h1 / docs that hardcode the display name).
# Query indexed OCR text
python3 src/media_ark/process_captures.py data/captures/raw --out .media-ark --query "meeting"
# Source scan summary only
python3 src/media_ark/process_captures.py data/captures/raw --out .media-ark --check-source
# Health check only
python3 src/media_ark/process_captures.py data/captures/raw --out .media-ark --verify
# Repair drift and stale state
python3 src/media_ark/process_captures.py data/captures/raw --out .media-ark --repair --repair-orphan-assets- Add hooks via
--post-hookfor downstream enrichment. - Keep
data/captures/raw/as the only inbound source. - Use
--cleanup-rawcarefully (copy mode recommended). - Use
--event-logand--reportfor run telemetry. - API/MCP actions persist telemetry by default to
.media-ark/platform-events.jsonland.media-ark/reports/. - Use
MEDIA_ARK_ALLOWED_ROOTSto restrict API/MCPsourceandoutpaths in deployed environments.