
Content
io.github.LatentNoise由 GitHub 帳號 LatentNoise 發布v0.8.5更新於 Oct 24, 2026
Turn URLs, files and text into media, transcripts, summaries, translations and PDF.
概覽
讓助理透過自架的 Content 引擎,把網址、本機檔案和文字轉成媒體、逐字稿、摘要、翻譯和 PDF。
- 可以做什麼
- content-mcp 伺服器提供的是意圖層級的工具,而不是每個端點一個工具:分析來源以了解可產出什麼,要求一個或多個輸出並選擇媒體庫目的位置,監控或取消工作,並找到已交付的產物。小型文字產物可以內嵌讀取,大型媒體則不會進入模型上下文。一般工具流程為 get_config、analyze_source、generate、get_job、get_artifact。
- 適用情境
- 當助理需要從 YouTube 網址、播放清單、網頁、PDF 或本機檔案產出真實檔案,而不只是描述它們,並交付到既有的媒體庫時,適合使用。它適用於引擎執行在工作站、NAS 或家庭實驗室的自架環境。
- 執行需求
- 需要一個可透過 CONTENT_API_URL 存取的執行中 Content 引擎(預設 Docker Compose 啟動。伺服器透過 uvx 或已安裝的 content-mcp 套件以 stdio 在本機執行。摘要、翻譯和衍生章節需要本機 Ollama 或雲端金鑰;逐字稿需要字幕或選用的 Whisper 執行器。下載範圍由 CONTENT_MCP_DOWNLOAD_DIR 限定。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Content,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
Content
Turn URLs, files, and text into media, knowledge, and documents.
One self-hosted engine. HomeTube client for YouTube — Content Studio for everything else — HomeTube browser extension — MCP server — CLI — Typed SDK — REST API underneath them all
[Latest release] [CI] [Docker] [License]
Quick start · HomeTube · Coming from HomeTube? · All the clients · Connect an agent · Read the docs
Content is a self-hosted engine that turns supported sources into media, transcripts, summaries, translations, images, metadata, Markdown, PDF, and more. The backend analyzes each source, determines what it can actually produce, plans and runs the job, records its history, and delivers the results.
[Sources — URLs, files, or texts, several of them in a single job — feed one self-hosted Content engine that analyzes, plans, runs and delivers. HomeTube, Studio, Console, the browser extension, the MCP server, the CLI, the Python SDK and the REST API all sit above the engine and reach it through the same public contract. Out come video, audio, subtitles, transcript, summary, translation, chapters and PDF.]Everything else is a client of one public contract: HomeTube for the
focused YouTube experience, Content Studio for general workflows, a
Chromium extension for the tab you are already on, the content-mcp
server for agents, a CLI for terminals and cron, a typed Python SDK for
applications, the REST API for every other language, and Content
Console to watch the engine work. Pick one or several — none of them is a
layer the others have to pass through, and none of them holds business logic of
its own.
HomeTube is the quickest way to see what that means: paste a YouTube URL, pick what you want out of it, and watch the files land in your library.
HomeTube in Content — paste a YouTube URL, choose what you want, follow the job into your library. More about HomeTube ↓
[!NOTE] A proven workflow, now growing into a platform. The standalone HomeTube container has passed 300,000 package downloads on GitHub Container Registry. It keeps running and stays maintained — nothing breaks, and there is no deadline. Content is where that work continues, and where its users are invited to move at their own pace.
The two are separate projects: standalone HomeTube has not been retrofitted to run on Content. The HomeTube app in this repository is a new UI on the Content engine, carrying the same workflow forward. Coming from standalone HomeTube? ↓
Quick start
Docker Compose is the only runtime prerequisite. Install from the published images — nothing to clone or build:
The default .env starts the complete local stack:
Open Content Studio for the general workflow, or HomeTube if your source is YouTube. You can also skip both web apps entirely and drive the same engine from the MCP server, CLI, SDK, extension, or REST API.
Everything stays in the installation folder: ./data holds the database, jobs,
and artifacts; finished files are delivered to ./playground/output. Set
CONTENT_DELIVERY_DIR_HOST in .env to point at your own NAS or media library
instead — its sub-folders then become the destination choices offered in the
clients.
Update later with:
The first line is not optional, and it is the one that is easy to skip.
docker compose pull refreshes the images; the stack definition is the
local copy you downloaded on day one, and new settings arrive in it — a
container receives only what its environment: block names. A compose file
left at its original version therefore keeps silently dropping every setting
added since, however correctly you write it in .env. Your .env is yours and
is never touched; compare it against the current
.env.example when you want the new knobs.
Build from source instead — for development or to include the optional speech-to-text runner
The repository's docker-compose.yml adds local build: definitions beside
the same images. deploy/docker-compose.yml is
the build-free deployment file used above; a test keeps the two aligned.
One source, many artifacts
The same engine serves media and document workflows:
Each branch starts with a declarative request. You describe the results; Content resolves what is possible, plans the work, runs the available tools, and records where every artifact came from. No yt-dlp flags, ffmpeg pipelines, transcription glue, or LLM orchestration in the client.
The clients
One engine, one contract, several independent front doors. Every client below
speaks the same GenerationRequest, sees the same resolved capabilities, and
produces the same artifacts — they differ in ergonomics, not in what they can
ask for. HomeTube is entirely optional; so is every other row.
HomeTube — YouTube, focused
http://localhost:8501 · README
Paste a URL, choose the media and related artifacts, and follow the job into your library — the workflow demonstrated at the top of this page.
With HomeTube in Content, you can:
- download a video or playlist as video or audio, with quality, codec, container, audio-language, and subtitle choices;
- remove or mark sponsored segments with SponsorBlock, cut clips, use server-side cookie credentials, and embed subtitles, chapters, thumbnails, and metadata;
- give every artifact a readable name and deliver it into a filesystem library watched by Plex, Jellyfin, or Emby;
- ask the same source for a transcript, summary, thumbnail, or metadata — not just the downloaded media — when the required runners are available.
HomeTube is deliberately focused: it does not accept file, upload, or inline-text sources, and it does not expose the broader document workflow or PDF output. For those, use Content Studio, the API, CLI, or SDK. HomeTube is a Content client, not a layer every Content user must pass through.
It has no settings of its own. It reads the engine's configuration, so what
changes HomeTube lives in the .env beside your docker-compose.yml: the
delivery library whose sub-folders become the destination choices
(CONTENT_DELIVERY_DIR_HOST), the languages pre-selected for audio and
subtitles (CONTENT_LANGUAGE_PRIMARY, CONTENT_LANGUAGES_SECONDARIES,
CONTENT_VO_FIRST, CONTENT_LANGUAGE_PRIMARY_INCLUDED_IN_SUBTITLES), and the
server-side cookie file that unlocks age-restricted or members-only videos
(CONTENT_CREDENTIALS — HomeTube only ever shows its id; the file never leaves
the server). Nothing is ever pre-selected that the source does not offer, and
no default is final.
HomeTube's README documents each variable and works the language rules through a concrete example — a Japanese talk, a French speaker, and exactly what ends up pre-checked. The full variable table lists everything the engine accepts.
Coming from standalone HomeTube?
HomeTube — the standalone Streamlit app — keeps running and stays maintained. Nothing breaks, and there is no deadline. Content is where the work continues, so this is a move you make when you are ready, not one you are forced into.
What comes across. The workflow you know: paste a URL, choose quality, codec, container, audio languages and subtitles; remove or mark sponsored segments with SponsorBlock; cut clips; unlock restricted videos with a server-side cookie file; embed subtitles, chapters, thumbnails and metadata; and deliver readable file names into a library watched by Plex, Jellyfin, or Emby. Playlists come across too — each entry is analyzed and planned on its own, named per item, and delivered as its own artifact.
What is new. The same source can also produce a transcript, a summary, a translation, generated thumbnails, metadata, Markdown, or PDF. And the engine is no longer reachable only from a web form: Studio, the Chromium extension, an MCP agent, the CLI, the SDK, and plain HTTP all ask for the same things.
What has not made the trip yet. HomeTube's playlist synchronization — the plan/apply diff that keeps a local folder in step with a playlist over time (rename detection, archiving or deleting removed videos, relocation after a naming or location change) — does not exist here. Content downloads a playlist; it does not yet re-sync one. It is roadmapped as part of M2. If playlist sync is your main use, keep standalone HomeTube for that job.
One practical note. Both HomeTube apps default to port 8501. Change one of
them in your .env if you want to run the two side by side.
Content Studio — the whole contract, in a form
http://localhost:8502 · README
The general-purpose web app: several sources in one request, every output type
the engine can resolve, with their options, preferences, and constraints. The
form is capability-driven — it renders what /capabilities answers for
your source, so a capability the engine gains appears without a UI release, and
what cannot be produced is shown with the server's reason instead of silently
disappearing.
Content Studio — build general URL, file, upload and text requests
Studio takes a file two ways, and the distinction matters when the engine runs on another machine:
- From this device — the bytes are sent to the engine and become an
uploadsource (ADR 0020). Several files at once become several sources. Streamlit buffers the upload in the UI container, so the ceiling here is deliberately lower than the API's (200 MB by default, and the picker states the current value rather than letting you discover it by failing). - On the server — a path the engine can already read, under a configured
allowed input root. With this Compose setup that root is
./playground/input.
For genuinely large files, skip the browser: the SDK streams from disk with
client.upload_file(path).
Chromium extension — the tab you are already on
Send the page you are watching to your engine without opening a UI. Manifest V3, Chromium only (Chrome, Brave, Edge, Vivaldi, Opera, Arc…), no build step — what the browser loads is exactly the files in the zip:
- download
content-browser-extension-chromium-v<version>.zipfrom the latest release and unzip it (Chromium loads a folder, not a zip); - open
chrome://extensions, turn on Developer mode, Load unpacked, select the folder; - open a video and click the extension.
It normalizes the tab's URL (youtu.be, Shorts, and embeds become the
canonical watch URL; a list= on a watch URL means that video, not the
playlist), asks the engine what the source can produce and offers only that,
prefills the name with the naming engine's own proposal, offers the library's
existing folders plus new folder…, then follows the job and shows where each
file landed. Every network call happens in the service worker — the engine
sends no CORS headers by default, and that is what lets the extension work
against a stock instance with nothing to configure
(ADR 0016).
Browser extension — send the current tab to Content, from the tab itself
The popup's footer always names the engine it is talking to, so "where is this sending my video?" is answered on screen. Its README also carries an honest path-by-path verification table — what has actually been driven in a browser, and what has not.
MCP server — for agents and IDEs
Content gives an MCP-compatible agent a controlled way to turn URLs into real
artifacts, not just talk about them. The official content-mcp server
exposes intention-level tools — not one per endpoint — to:
- analyze a URL and discover what it can produce;
- request one or several outputs and choose a library destination;
- monitor the job, cancel it, and report actionable failures;
- find the artifacts and their delivered paths;
- read small text artifacts inline while keeping large media out of the model context.
The agent never needs shell access, yt-dlp syntax, or backend internals.
Nothing to install. uvx fetches the server on first use and caches it, so
the client owns the whole lifecycle (updating stays explicit — uvx --refresh,
or pin [email protected]):
For Claude Desktop, Cursor, and other MCP clients using the standard JSON shape:
Prefer a pinned executable on your PATH — for an offline machine, or to control
when the version changes? Install it and name it directly
("command": "content-mcp", or -- content-mcp for Claude Code):
Then ask naturally:
Analyze this lecture, save its audio into
Talks, create a transcript and a structured summary if the available runners allow it, and tell me where every artifact landed.
The normal tool journey is
get_config → analyze_source → generate → get_job → get_artifact. Downloads to
the agent's own machine are bounded by a single variable
(CONTENT_MCP_DOWNLOAD_DIR, ~/Downloads/Content by default): a destination
pointing outside it is refused, not clamped — widening that is the operator's
decision, not something a prompt can talk the server into.
What it can and cannot do, briefly — the MCP guide has the full three tables, and each row there was driven over stdio against a running engine rather than inferred:
CLI — terminals, scripts, and cron
--watch follows the job's event stream rather than re-asking for its
status, and the exit code carries the outcome so a script can chain on it
(ADR 0021):
0 succeeded, 2 partially succeeded, 1 failed or cancelled. 2 is
deliberately distinct — a playlist that yielded five videos of six is not a
failure, but a script that treats it as a success will quietly move on with
missing files.
Python SDK — typed, sync and async
The one official API client: the CLI, the MCP server, and the web apps all
speak through it, so the engine's rules are never duplicated. Python 3.11+,
httpx and pydantic only.
AsyncContentClient mirrors the whole surface. Analyses are addressable, so
every call accepts either an analysis_id or inline sources
(ADR 0014);
client.upload_file(path) streams a local file to the engine and hands back a
ready-to-use source; and every non-2xx becomes a typed exception carrying the
stable error codes (NotFound, Gone, ValidationError).
REST API — every other language
Public contract · Swagger at http://localhost:8010/docs
/api/v1 is the contract every client above is built on, and it is stable
enough to build a ninth client against: requests describe desired outputs
rather than technical operations, error codes are machine identifiers that do
not change (only their human messages do), and "valid but not implemented" is
a different, explicit answer from "invalid". Reserved fields are refused
rather than silently ignored. The V1 API has no built-in authentication —
see deployment and security.
Content Console — observe and pilot the engine
http://localhost:8503 · README
The operations console: strictly observability and control, and deliberately not a way to create downloads (that is Studio and HomeTube).
Content Console — observe and control the engine
- Overview — version, cache, concurrency, analysis TTL, a live jobs pulse, the installed runners with their availability, storage paths.
- Environment — every
CONTENT_*variable with its effective value, whether it was set or fell back to a default, and a one-line description. Secrets are never shown — only their presence and length. - Jobs — a filterable list plus full detail: steps, the submitted
GenerationRequest, artifacts with their provenance, ordered events, per-step logs, cancel and retry, with an opt-in 5-second auto-refresh that polls only while jobs are in flight. - Storage & cache, and a contract & API tab with the schemas, Swagger, ReDoc, and a raw API tester.
What Content can produce
Content resolves availability for each analyzed resource and installed runner. Clients show what can actually be produced instead of presenting a static list and failing halfway through a job.
Media acquisition works with YouTube and the sites supported by yt-dlp. Playlists can produce artifacts for each member in a single traceable job. Finished files can be delivered directly into any mounted filesystem library, including folders watched by Plex, Jellyfin, or Emby.
Local and optional AI runners
Content has no mandatory cloud dependency. AI-backed outputs activate when a compatible runner is available:
- Summaries, translations, and derived chapters: connect a local Ollama instance, or explicitly configure an Anthropic or OpenAI API key. Cloud runners can be excluded per request.
- Transcription from audio: run a speech service next to the engine —
docker compose --profile speech up -dandCONTENT_SPEECH_URL=http://speech:8000, orspeech.enabled: truein the Helm chart. It is speaches, behind the OpenAI audio API, and the same container also does text-to-speech. Audio is only ever sent to a service on a private network. Transcripts from existing subtitles do not need it.
Unavailable optional runners do not make Content unhealthy. The affected capability is reported as unavailable, and an impossible request is refused before the job starts. See deployment and configuration for the full inventory.
Why build on Content?
- Declare intent, not tooling. Requests describe outputs; yt-dlp, ffmpeg, Whisper, LLMs, and PDF renderers remain replaceable implementation details.
- Self-hosted and local-first. Run it on a workstation, NAS, or homelab. There is no account, telemetry, or mandatory cloud service.
- One public contract. Studio, HomeTube, MCP, the CLI, SDK, extension, and REST API converge on the same domain instead of drifting into parallel feature sets.
- Human files, not pipeline debris. The engine names every artifact and can place it directly in the library you already use.
- Observable work. Jobs expose states, ordered events, progress, logs, artifacts, provenance, cancellation, and retry.
- Honest capabilities. “Valid but unsupported,” “unavailable on this source,” and “broken” are different answers, reported before or during the correct stage.
How it works
The public request describes desired outputs. It does not prescribe technical operations:
The engine analyzes source facts, resolves feasible capabilities against the installed implementations, builds a deterministic execution plan, and runs it as an observable job. The database is the source of truth; yt-dlp, ffmpeg, transcription, LLM, and PDF implementations stay behind dedicated boundaries.
The domain keeps user intent (GenerationRequest), resolved strategy
(ExecutionPlan), execution (Job), and concrete results (Artifact)
separate. For the full design, see the
architecture overview,
public contract, domain model, and
architecture decisions.
Deployment and security
Content targets single-host Linux/macOS deployments on amd64 or arm64. Docker Compose runs the API and embedded worker together, with the web apps as separate API clients. SQLite and artifact storage persist locally; no Redis, Celery, Kubernetes, or cloud infrastructure is required.
The commented .env.example covers UI selection, image
versions, ports, storage and delivery, language preferences, server-side
cookie credentials, optional LLM/STT runners, CORS, and notifications. No
release check makes an outbound request unless you configure one.
The V1 API has no built-in authentication: anyone who can reach it can submit jobs, upload files and read every artifact. Keep it on a trusted network, or put an authenticating reverse proxy in front of any externally reachable instance — and do not publish the port. What an attacker who reaches the API can and cannot do is written out in docs/operations/threat-model.md. See deployment for configuration, health checks, data layout, authenticated sources, and production guidance, and ADR 0024 for why that is the V1 answer.
Development
The repository is a monorepo containing the backend, web applications, CLI,
MCP server, Chromium extension, and Python SDK. The root Makefile is the main
entry point:
The main test suite does not require the Internet. Read the repository architecture and validation guide before changing the code. Releases follow the release runbook.
Documentation
docs/README.md is the complete documentation map. Useful starting points:
- Product vision
- Public contract and domain model
- Architecture and invariants
- Storage and artifact delivery
- Deployment and operations
Licence
Content is source-available under the Functional Source License, Version
1.1, ALv2 Future License (FSL-1.1-ALv2).
In plain words: you may read, audit, modify and run Content — at home, for yourself, or inside your organisation. The one thing you may not do is offer it, or something substantially similar built from it, as a competing commercial product or service.
Every version becomes Apache 2.0 two years after it is published. That promise is in the licence itself and cannot be taken back.
Copyright 2026 Yann Orieult. "Content" and "Latent" are names of the project and of its author's work; a fork must not use them for its own product.
Versions up to and including 0.8.4 were released under AGPL-3.0-or-later and remain available under it, permanently. See COMMERCIAL.md for the full summary; no separate commercial offering is currently available.
Governance
Content is developed and maintained by Yann Orieult under a single-maintainer model. Bug reports, ideas, and design feedback are welcome through issues. Code contributions are not accepted—unsolicited pull requests are closed without review; forking is the intended path for independent changes. See CONTRIBUTING.md and GOVERNANCE.md.
Report security issues privately as described in SECURITY.md.
© 2026 Yann Orieult.
來源:README.md,提交 f5569e3
工具
0版本歷史
2- v0.8.5最新Sep 22, 2026
- v0.8.0Sep 16, 2026
評分
已滿足適用檢查項的 40%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分
請在儲存庫或註冊中心條目中宣告授權條款。