Install the published MCP package for Claude Code, Codex, Cursor, and MCP-capable workspaces.
View 10 MCP tools ↓UploadCheck docs
UploadCheck is deterministic pre-upload QC for AI agents. Agents call UploadCheck, receive timestamped PASS, WATCH, or BLOCK evidence, repair only flagged spans, then rerun the gate before upload.
Install
npx -y @drantoniou/uploadcheck-mcp
Create jobs, poll status, fetch reports, manage uploads, and provision workspace API keys.
View 12 endpoints ↓MCP server
Install command for public agent workspaces:
npx -y @drantoniou/uploadcheck-mcp
Set UPLOADCHECK_API_BASE_URL=https://api.uploadcheck.app and UPLOADCHECK_API_KEY=<workspace_api_key>.
Estimate checked minutes and effective gates before an agent uploads or runs media.
Inputsminutes, duration_seconds, profile, checks, plan_id, ai_review_seconds, cost_guardrail
Outputsmargin_safe, effective_checks, removed_checks, cost_estimate, action
Start a full-timeline UploadCheck run from Claude, Codex, or another agent workspace.
Inputsyoutube_url, upload_id, signed_url, profile, video_base64, audio_base64, data_url, manifest_url, transcript_url, watchlist_url, expected_script_url, chunk_sidecars_url, callback_url
Outputsjob_id, verdict, status_url, report_url, minutes_metered, media_ingress, sidecar_ingress, cost_estimate
Read a local media file from an agent workspace and send it through Render inline or signed upload.
Inputsfile_path, profile, checks, manifest_path, transcript_path, watchlist_path, expected_script_path, sidecar_dir, plan_id, cost_guardrail
Outputsjob_id, verdict, status_url, report_url, minutes_metered, media_ingress, cost_estimate
Poll status, stage, progress, current verdict, and minutes for an active job.
Inputsjob_id
Outputsstatus, stage, progress_pct, verdict, minutes_metered, media_ingress
Retrieve a finished UploadCheck report with evidence-grounded timestamp flags.
Inputsjob_id
Outputsverdict, flags, timestamps, transcript_evidence, share_url
Get a signed, tamper-evident PASS/BLOCK receipt for a completed job — bound to the file's sha256 and named profile — so a CI step or agent can gate its publish on the verdict and prove it later.
Inputsjob_id
Outputsverdict, sha256, profile, gates, blocked, signature, summary
Retrieve lifecycle events so an agent can cite exactly which QC stages ran.
Inputsjob_id
Outputsevents, event_type, created_at
List report artifacts and editor handoff files for a QC run.
Inputsjob_id
Outputsartifacts, artifact_type, url
Download the CSV marker export for an editor handoff.
Inputsjob_id
Outputscsv
Create a signed upload URL so agents can send local files without handling QC storage directly.
Inputsfilename, content_type, size_bytes
Outputsupload_id, signed_put_url, expires_at, put_then_run_qc_with_upload_id
REST API
Base URL: https://api.uploadcheck.app
Fetch standard NTO/NPO production pipeline recipes.
Fetch public NPO podcast and audio pipeline runbook details.
Estimate checked minutes and effective QC gates before uploading media.
Create a QC job from a YouTube URL, upload id, or signed asset URL.
Poll job status, verdict, gate progress, and minute usage.
Fetch shareable JSON/PDF-ready defects, timestamps, and evidence.
Inspect lifecycle events for agent explanations and progress audit.
List generated reports, marker exports, clips, and related QC artifacts.
Download editor marker CSV for a completed QC run.
Create a signed upload target for agents and self-serve users.
Send local media bytes to the signed upload URL before creating an upload_id QC job.
Check upload processing and metadata probe status.
Signed PASS/BLOCK receipts
A receipt turns a QC verdict into a required check a CI step or agent gates its publish on — the leap from "here is a report a human reads" to "this blocks the deploy," the way a signed CI status check gates a merge. Fetch it after a job completes; gate your publish on verdict === "PASS".
What a receipt guarantees
- Bound to the exact file. The receipt carries the media's
sha256. Swap the file, and the signature no longer matches — a receipt can never be reused for different content. - Bound to a named target.
profilerecords which delivery spec the file was checked against, so a green receipt reads "PASS foryoutube_shorts", not an abstract gate list. - Tamper-evident. The whole payload is HMAC-SHA256 signed. Any change to the verdict, hash, profile, or gate list is caught on verify.
- Verifiable by anyone, offline of your account. A third party (a CI system, an auditor, a client) confirms authenticity with a single no-auth call — no login, no access to your workspace.
Get a receipt
GET /v1/qc/jobs/{job_id}/receipt (or the qc_get_receipt MCP tool) once the job is completed. A BLOCK receipt lists the failed gates in blocked.
{
"schema": "uploadcheck-receipt/1",
"verdict": "PASS",
"sha256": "<the checked file's hash>",
"profile": "youtube_shorts",
"gates": ["av_sync", "canvas_fill", "loudness", "shorts_format"],
"blocked": [],
"jobId": "job_...",
"issuedAt": "2026-07-20T00:00:00.000Z",
"issuer": "uploadcheck.app",
"signature": "sha256=..."
}
Verify a receipt
POST /v1/public/receipts/verify — no auth. POST the receipt JSON; the response confirms whether the signature is authentic and unaltered. Always confirm the receipt's sha256 matches your file before trusting the verdict.
Gate a CI job on the receipt
The CLI and GitHub Action already exit non-zero on BLOCK. Add --receipt <path> (CLI) or receipt-path: (Action) to also write the signed receipt as a build artifact:
uploadcheck check final.mp4 --profile youtube_shorts --fail-on block --receipt uploadcheck-receipt.json
Named delivery profiles
Check against a recognizable target so the receipt names a spec your pipeline trusts:
| Profile | Delivery target |
|---|---|
youtube_shorts | YouTube Shorts (9:16, hook, caption-safe, loudness) |
youtube_longform | YouTube long-form upload (pacing, levels, end screen) |
meta_reels_ad | Meta Reels / Instagram ad (9:16, safe-area, ad-review basics) |
tiktok_post | TikTok post (9:16, hook, caption-safe) |
broadcast_r128 | Broadcast delivery (EBU R128 loudness + legal levels + fields) |
podcast_delivery | Podcast delivery (loudness, LRA, hum, dropouts, balance) |
ai_render_gate | AI-render publish gate (temporal artifacts + technical readiness) |
Public QC gate reference
These are public, callable publish-readiness gates. The table describes customer-facing behavior and required inputs; exact algorithms, thresholds, prompts, fixtures, and internal evaluation workflows stay private.
Visual
| Gate | Catches | Input needed |
|---|---|---|
| canvas_fill | Pillarbox, letterbox, black gutters, or wrong canvas fit. | video/image |
| loop_freeze | Frozen, looped, or held visual spans that should move. | video |
| black_frames | Sustained black video spans at head, tail, or mid-timeline. | video |
| format_spec | Resolution, codec, or frame-rate that misses the target delivery spec. | video |
| shorts_format | 9:16 export shape, full-bleed framing, duration, and Shorts structure risk. | video |
Audio
| Gate | Catches | Input needed |
|---|---|---|
| voiceover_music_balance | Background music too loud or not ducked enough under voiceover. | manifest mix metadata |
| dead_air | Unwanted silence or audio dropout spans. | audio/video |
| loudness | Integrated loudness (LUFS) off the platform target, or true peak over ceiling. | audio/video |
| clipping | Audio clipping / distortion — peaks at or over full scale. | audio/video |
| av_sync | Audio/video sync offset — lip-sync drift. | video with audio |
| channel_balance | Dead stereo channel, L/R level imbalance, or out-of-phase mono-collapse. | audio/video |
Text & captions
| Gate | Catches | Input needed |
|---|---|---|
| text_crop_jitter | Text cards cropped, jittering, overlapping, or too close to unsafe edges. | manifest |
| text_overlap | Overlay text colliding with other overlay text on a frame or image. | video/image or manifest |
| thumbnail_text_readability | Thumbnail text that is low contrast or unsafe for preview crops. | image |
| hallucinated_plate_text | Unapproved readable text, watermarks, garbled signs, or title-card remnants. | manifest |
| text_contrast | Low contrast readable text risk. | video/image |
| text_safe_area | Text hidden by platform UI, cropped near edges, or unsafe for Shorts chrome. | video/image |
Structure & pacing
| Gate | Catches | Input needed |
|---|---|---|
| repeat_fatigue | Repeated visual patterns, source-family overuse, or cheap repeated beats. | manifest |
| speaker_visual_binding | Manifest says a voice is paired with the wrong visible speaker. | manifest |
| static_head_dominance | Long stretches dominated by static talking-head or portrait shots. | manifest |
| literal_subject_match | Narration names a specific subject while visuals stay generic. | manifest |
| visual_narration_match | Manifest says visuals do not support narration. | manifest |
| first_three_seconds | Weak opening hook, missing hook card, or opening-frame mismatch. | manifest |
| end_screen_tease | Missing CTA, next-video tease, footer card, or episode handoff. | manifest |
| rehook_cadence | Long stretches without a pattern interrupt or visual reset. | manifest |
| contact_sheet_evidence | Missing before/after proof for repaired visual spans. | manifest |
| opening_footer_text_presence | Shorts missing required hook or footer text-card structure. | manifest |
| clean_segment_source_scrub | Source clips with wrong-region inserts, bad footage families, or incompatible source material. | manifest |
| asset_triage_reuse_manifest | Reusable assets, one-off candidates, and cleanup candidates missing triage. | manifest |
| chunk_sidecar_failures | Failed render/audio chunks left from previous repair loops. | sidecar directory |
Transcript
| Gate | Catches | Input needed |
|---|---|---|
| spoken_leaks | Spoken production notes, URLs, vendor names, markdown, or stage directions. | transcript |
| pronunciation_watchlist | Project-specific names or terms that must be pronounced correctly. | transcript + watchlist |
| script_faithfulness | Narration drift from a locked script. | transcript + expected script |
| sentence_boundary | Clips ending mid-word, mid-sentence, or before the punchline resolves. | transcript |
| dialogue_in_music_short | Music-only Shorts that still contain unintended spoken dialogue. | transcript |