Skip to main content

HomeTube's next chapter

Turn URLs, files and text into media, knowledge and documents.

Content is a self-hosted engine. It analyzes a source, tells you what it can produce, plans and runs the job, and delivers named files into your library. HomeTube is one of its clients. So is your AI agent.

  • Latest v0.8.0
  • Docker amd64 · arm64
  • AGPL-3.0
  • No cloud dependency

One source, many artifacts

Describe the results. The engine resolves the rest.

No yt-dlp flags, ffmpeg pipelines, transcription glue or LLM orchestration in the client. Each request says what you want; Content works out what is possible for that source and records where every file came from.

                       ┌─ My Conference.mp4
                       ├─ My Conference - audio.opus
YouTube URL ──→ Content ──┼─ My Conference - subtitles - en.srt
                       ├─ My Conference - transcript.txt
                       ├─ My Conference - summary.md
                       └─ My Conference - summary.pdf

Web page / .md ──→ Content ──┬─ Article.txt
                       ├─ Article - summary.md
                       ├─ Article - translation.md
                       └─ Article.pdf
  • Video

    Stream selection, remux, fast or frame-accurate cutting, SponsorBlock handling.

  • Audio

    Source audio, Opus, MP3 or M4A from media URLs; local files keep their native track.

  • Subtitles

    Manual or automatic tracks, selected by language.

  • Transcript

    From existing subtitles, or from audio with the optional Whisper runner.

  • Summary

    Transcript or readable text through a local Ollama model or an opt-in cloud key.

  • Translation

    Subtitles or transcripts through an LLM; subtitle timings stay aligned.

  • Chapters

    Declared by the source, or derived from a transcript.

  • Thumbnails

    Published artwork or keyframes extracted from the video.

  • Markdown & PDF

    Readable web pages, text files, PDFs' text layer, and PDF output for summaries and transcripts.

Media acquisition works with YouTube and the 1700+ sites supported by yt-dlp. Summaries, translations and derived chapters need a local Ollama or an opt-in cloud key; unavailable runners are reported up front, never discovered halfway through a job.

The clients

One engine, one contract, eight front doors

Every client speaks the same request, sees the same resolved capabilities and produces the same artifacts. They differ in ergonomics, not in what they can ask for. Pick one or several.

  • HomeTube

    The simplest YouTube video or playlist → library experience.

    In Docker Compose at :8501

    Read more
  • Content Studio

    Capability-driven requests from URLs, uploads, server files and inline text.

    In Docker Compose at :8502

    Read more
  • Browser extension

    Send the Chrome, Brave, Edge or Vivaldi tab you are on to your engine.

    Load unpacked from the release zip

    Read more
  • MCP server

    Give Claude, an IDE or any MCP agent real artifacts instead of talk.

    uvx content-mcp

    Read more
  • CLI

    Terminals, scripts and cron, with an exit code that carries the outcome.

    uv tool install content-cli

    Read more
  • Python SDK

    Typed sync and async client; the one every other client is built on.

    pip install content-sdk

    Read more
  • REST API

    Any language that speaks HTTP. Stable error codes, honest capabilities.

    /api/v1, Swagger at :8010/docs

    Read more
  • Content Console

    Observe and pilot the engine: jobs, runners, storage, configuration.

    In Docker Compose at :8503

    Read more

Screenshots

Content Studio: the general-purpose request builder listing sources, resolved capabilities and outputs
Content Studio renders what the engine answers for your source: a capability the engine gains appears without a UI release, and what cannot be produced is shown with the server's reason.
The Content browser extension popup on a YouTube page, offering outputs and a destination folder
Browser extension: the page you are watching, sent to your engine, with only the outputs that source can produce.
Content Console showing jobs, runners, storage and configuration
Content Console: jobs with their steps, events and logs; runners and their availability; every variable with its effective value. Secrets are never shown.

Quick start

Docker Compose is the only prerequisite

Published images, nothing to clone or build.

terminal
mkdir content && cd content
curl -fsSLO https://raw.githubusercontent.com/LatentNoise/content/main/deploy/docker-compose.yml
curl -fsSL -o .env https://raw.githubusercontent.com/LatentNoise/content/main/.env.example
docker compose up -d
  • Content Studio localhost:8502

    General requests: URL, file, upload, inline text

  • HomeTube localhost:8501

    Focused YouTube video and playlist workflow

  • Content Console localhost:8503

    Health, configuration, storage, jobs, logs

  • Content API localhost:8010/docs

    REST API, OpenAPI and embedded worker

Everything stays in the installation folder. Point CONTENT_DELIVERY_DIR_HOST at your NAS or media library and its sub-folders become the destination choices in every client. The API has no built-in authentication: keep it on a trusted network or behind an authenticating reverse proxy. Deployment guide

For agents, terminals and code

Real artifacts, not just talk

Ask Claude to save a lecture's audio into Talks, produce a transcript and a structured summary, and report where every file landed. The agent never needs shell access or yt-dlp syntax.

MCP server

terminal
# Claude Code
claude mcp add content \
  --env CONTENT_API_URL=http://localhost:8010 \
  -- uvx content-mcp

CLI

terminal
uv tool install content-cli
export CONTENT_API_URL=http://nas.local:8010

content analyze "https://www.youtube.com/watch?v=…"
content video "https://…" --height 1080 --subs en,fr --watch
content audio "https://…" --format opus --playlist --watch

Python SDK

python
from content_sdk import ContentClient, outputs

with ContentClient("http://localhost:8010") as client:
    analysis = client.analyze(outputs.url_source("https://www.youtube.com/watch?v=…"))
    job = client.generate(analysis.id, [outputs.audio_output(), outputs.summary_output()])
    job.wait()
    for artifact in job.artifacts:
        print(artifact.display_filename, artifact.delivered_path)

Why build on Content

Principles that hold

  • Declare intent, not tooling

    Requests describe outputs. yt-dlp, ffmpeg, Whisper, LLMs and PDF renderers stay replaceable implementation details.

  • Self-hosted, local-first

    Workstation, NAS or homelab. No account, no telemetry, no mandatory cloud service.

  • One public contract

    Every client converges on the same engine instead of drifting into parallel feature sets.

  • Human files, not pipeline debris

    Every artifact gets a readable name and can land directly in the library you already use.

  • Observable work

    Jobs expose states, ordered events, progress, logs, provenance, cancellation and retry.

  • Honest capabilities

    'Valid but unsupported', 'unavailable on this source' and 'broken' are different answers, given up front.

Coming from standalone HomeTube?

Nothing breaks. There is no deadline.

The standalone HomeTube container has passed 300,000+ package downloads and keeps running and being maintained. The HomeTube app inside Content is a new UI on the Content engine carrying the same workflow forward. Move when you are ready, not because you are forced to.

What comes across

Paste a URL; choose quality, codec, container, audio languages and subtitles; SponsorBlock; clips; server-side cookies; embedded chapters, thumbnails and metadata; readable names delivered into a Plex, Jellyfin or Emby library. Playlists too, each entry planned and named on its own.

What is new

The same source can also produce a transcript, a summary, a translation, thumbnails, metadata, Markdown or PDF. And the engine is reachable from Studio, the browser extension, an MCP agent, the CLI, the SDK and plain HTTP.

Not there yet

Playlist synchronization (the plan/apply diff with rename detection and archiving) is roadmapped, not shipped. If sync is your main use, keep standalone HomeTube for that job. Both apps default to port 8501: change one to run them side by side.

Free, open source, yours to run.

AGPL-3.0. Bug reports, ideas and design feedback are welcome through issues.