rmccorkl840 downloadsCreate comprehensive notes from YouTube transcripts using LLMs.
TubeSage is an Obsidian plugin that converts YouTube videos into structured notes using large language models. It extracts transcripts, generates summaries, and can add timestamped links back to specific moments in the video.
Demo — click the image to watch the walkthrough video:
Community Plugins: Install through Obsidian's Settings → Community plugins browser once TubeSage is listed in the directory.
Manual install from a GitHub release:
main.js, manifest.json, and styles.css.
Do not download "Source code (zip)" or "Source code (tar.gz)" — those are source archives and will not load as a plugin..obsidian/plugins/tubesage/.tubesage/ folder.Accept the MIT license terms in the settings panel before using the plugin. Use the "View License" button to read the full text.
For the most reliable results, use OpenRouter as the LLM provider together with ScrapeCreators for transcript retrieval. Direct YouTube transcript extraction breaks whenever YouTube changes or restricts how captions are served, so a paid transcript service is the dependable path. Gemini's lower-cost tiers are rate-limited and can be throttled or unavailable under load, whereas OpenRouter lets you pick a model with the capacity you need. Other providers still work; this is the combination the maintainer has found most dependable.
Choose a provider in settings. Only that provider's settings are shown — its key, model and address; the other providers' fields are hidden, not cleared, so switching back finds them as you left them.
http://192.168.1.20:11434 (Ollama itself must be listening on the network, e.g. started with OLLAMA_HOST=0.0.0.0)./v1 (for example http://192.168.1.20:1234/v1; plain http:// is accepted), and type the model name exactly as the server lists it. The API key is optional: leave it blank if the server does not check one.Custom base URL for any provider: OpenAI, Anthropic, Google and OpenRouter can each be pointed at another address — a corporate proxy, a gateway such as LiteLLM, or a mirror. Turn on that provider's Custom base URL toggle to show its base URL field; turn it off to go back to the vendor's address while keeping what you typed. Leave the field blank to use the vendor's own address, which it shows as its placeholder. The shape differs by vendor, so copy the placeholder's: OpenAI and OpenRouter include the version (https://api.openai.com/v1), Anthropic and Google do not (https://api.anthropic.com). Chat requests and the model-list refresh both go to the address you set, and that provider's API key is sent to it. Only bearer-style keys are supported, so services that need another auth scheme (Azure OpenAI's api-key header, for example) are not.
Where API keys are stored: cloud-provider keys (OpenAI, Anthropic, Google, OpenRouter), the optional OpenAI-compatible server key and the transcript-service keys (YouTube Data API, ScrapeCreators, Supadata) are saved in Obsidian's native secret storage, not in the plugin's data.json. Type a key into its field and it is written to the secret store automatically — there is no separate setting to enable this, and it is not optional. The Ollama field, the OpenAI-compatible server URL and the custom base URLs hold server addresses rather than secrets, so they remain in plugin data.
When enabled, each section heading includes a link that opens the YouTube video at the corresponding moment.
TubeSage keeps processing while Obsidian is in the foreground. If you switch to another app, the OS may suspend or terminate Obsidian, and there is no supported way for a plugin to keep JavaScript or network requests running through that — the host controls it, and its behavior is not documented for plugins. TubeSage does not promise execution through suspension.
A job lives and dies with the Obsidian instance that started it. Nothing is resumed, and nothing about a run is remembered across a restart: if Obsidian closes or is killed while a job is running, that job is over — an AI summary that was in flight is lost (and may still have been billed), and you submit the video again. Retrieval is one video at a time, so there is no list of jobs to keep track of.
While a job runs, its current stage is shown:
Obsidian's Vault.create rejects a path that already exists rather than versioning it, so processing a URL you have already done does not overwrite the old note or fail. It lands on the next free neighbouring name — Title 1.md, Title 2.md, and so on — which is the convention Obsidian itself uses.
On desktop and mobile alike:
Title 1.md.Playlists and channels run as a series of single-video jobs and end with the app in the same way.
main.ts): coordinator and UI.src/youtube-transcript.ts): multi-method extraction with mobile fallbacks.src/llm/llm-factory.ts): constructs the provider client.src/llm/transcript-summarizer.ts): orchestrates summarization.src/llm/langchain-client.ts): unified interface for cloud providers.src/utils/fetch-shim.ts): cross-platform HTTP via Obsidian's requestUrl.src/utils/timestamp-utils.ts): timestamp link generation.src/utils/error-utils.ts): error categorization and retry logic.Architecture diagrams are in the docs/ directory:
Cloud-provider API keys (OpenAI, Anthropic, Google, OpenRouter), the optional OpenAI-compatible server key and the transcript-service keys (YouTube Data API, ScrapeCreators, Supadata) are stored in Obsidian's native secret storage, never written to the plugin's data.json. Keys saved in data.json by older versions (before 1.3.0 for the cloud-provider keys) are migrated into secret storage automatically the first time you open the plugin after upgrading.
Requests to hosted services use HTTPS; a self-hosted server (Ollama, an OpenAI-compatible server, or a custom base URL you set) is contacted at the address you give it, which may be plain HTTP. TubeSage contacts:
api.scrapecreators.com) and Supadata (api.supadata.ai) — contacted only if you choose to configure an API key for one of them. These are optional paid transcript services used as alternatives or fallbacks to direct YouTube extraction; with no key set, neither is contacted.That is the complete list. LangChain's bundled tiktoken helper, which would otherwise fetch tokenizer data from a third-party CDN, is replaced with a network-free stub at build time, so TubeSage contacts no other hosts.
No user data is stored on servers operated by the plugin author.
The plugin also bundles langsmith as a transitive dependency of @langchain/core. langsmith is LangChain's optional tracing library and contains a background cache-refresh timer. TubeSage never enables LangSmith tracing and never sets a LangSmith API key, so this code stays dormant and performs no background network transmission.
Static analysis of the bundled main.js shows a few atob()/btoa() (base64) calls. These all originate in bundled libraries, not in TubeSage's own code, and are all routine: decoding embedding vectors and image data URLs, reading a JWT header, and encoding Mermaid diagram syntax for rendering. None of them obscure code, API keys, or URLs.
This project is licensed under the MIT License — see the LICENSE file. A YouTube content-usage disclaimer is included in MIT-license-tubesage.md.
GitHub Repository: https://github.com/rmccorkl/TubeSage