Skip to main content
Glama

uoink-lite: YouTube transcript MCP server that remembers

CI License: MIT

Give your AI assistant a YouTube link and it reads the captions, and every transcript it fetches stays on your computer so you can search across all of them later.

Install

You need uv. Nothing else: uvx downloads and runs the server for you.

Claude Code

claude mcp add uoink-lite -- uvx --from git+https://github.com/ryanbiddy/uoink-lite uoink-lite

Add --scope user after add to make it available in every project, not just the current one.

Once uoink-lite is published to PyPI, the shorter form will work:

claude mcp add uoink-lite -- uvx uoink-lite

Claude Desktop, Cursor, Windsurf and other clients that use mcpServers JSON

Claude Desktop: Settings > Developer > Edit Config (claude_desktop_config.json). Cursor: ~/.cursor/mcp.json, or .cursor/mcp.json in a project.

{
  "mcpServers": {
    "uoink-lite": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/ryanbiddy/uoink-lite", "uoink-lite"]
    }
  }
}

Restart the app after saving. If it says uvx was not found, replace "uvx" with its full path (run which uvx on macOS/Linux or where uvx on Windows).

VS Code (Copilot agent mode)

Put this in .vscode/mcp.json in your workspace, or run MCP: Open User Configuration to use it everywhere:

{
  "servers": {
    "uoink-lite": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "git+https://github.com/ryanbiddy/uoink-lite", "uoink-lite"]
    }
  }
}

Related MCP server: ytmcp

Tools

Tool

What it does

get_transcript(url, lang="en", timestamps=True)

The full transcript with [mm:ss] timestamps, plus the video title. Saves it locally.

search_transcript(url, query)

Lines in one video that match, each with its timestamp and a link that starts playback at that moment.

search_saved(query, limit=10)

Searches every transcript you have fetched before and returns the video, timestamp, line and link for each hit.

list_saved(limit=20)

What is saved, newest first.

url can be a youtube.com/watch link, a youtu.be link, a Shorts or embed link, or just the 11-character video id. If the video has no captions in the language you ask for, you get a language it does have and a note saying so.

Things to ask

  • "Summarize https://youtu.be/jNQXAC9IVRw"

  • "Where in this talk do they explain the pricing change? Give me timestamps."

  • "Pull the three best quotes from this interview, with links to each moment."

  • "Which of the videos I looked at this week mentioned vector databases?"

  • "What did that cooking video say about resting the dough? I don't remember which one it was."

The last two are what the memory is for. Most YouTube transcript servers fetch, answer and forget. uoink-lite keeps what it fetched, so a question in next week's chat can still find it.

How the memory works

Each video you fetch becomes one JSON file in ~/.uoink-lite/transcripts/ (set UOINK_LITE_HOME to put it somewhere else). The file holds the video id, URL, title, caption language, when it was fetched, and every caption line with its start time. Asking for the same video again reads the saved copy instead of going back to YouTube.

Search is plain keyword matching, case-insensitive. A line that contains more of your words ranks higher, and a line with your exact phrase ranks highest. No embeddings, no model downloads, no database. You can open the files, back them up, or delete them whenever you like.

A single reply is capped at about 80,000 characters, which MCP clients accept without complaint. That is a bit over an hour of speech with timestamps. The full transcript is still saved, and search_transcript finds anything past the cut.

When it can't get a transcript

  • No captions. Some videos have none, not even auto-generated ones. uoink-lite says so; it does not transcribe audio.

  • Blocked or rate limited. YouTube sometimes refuses caption requests, more often from cloud servers and VPNs than from home connections. uoink-lite tells you plainly. Waiting a few minutes and retrying usually works. If you need a proxy, set the standard HTTPS_PROXY environment variable in the server's config.

  • Private, removed or age-restricted videos return a short error that says which.

Want podcasts, X, Reddit, caption-less videos and a desktop library? Get Uoink

uoink-lite is the small version of Uoink, a free, MIT-licensed app for Windows and macOS. Uoink saves YouTube videos, podcasts, X posts and Reddit threads to a local library with transcripts, transcribes videos that have no captions using Whisper on your own machine, and gives your assistant the whole library over MCP.

Download it at uoink.app/get.

Privacy

uoink-lite only talks to YouTube: once for the captions, and once to YouTube's public oEmbed endpoint for the title. Transcripts are stored on your computer and nowhere else. There is no account, no telemetry and no API key.

Development

git clone https://github.com/ryanbiddy/uoink-lite
cd uoink-lite
uv run --with pytest --with-editable . pytest

The tests never touch the network; they swap in a fake fetcher. To point a client at your local checkout instead of GitHub:

claude mcp add uoink-lite-dev -- uvx --from /path/to/uoink-lite uoink-lite

Captions come from youtube-transcript-api. The server is built on the official MCP Python SDK.

License

MIT. See LICENSE.

Available Tools

4 tools
get_transcriptA

Get a YouTube video's transcript, with [mm:ss] timestamps by default.

Accepts any YouTube video URL (watch, youtu.be, shorts, embed) or an 11-character video id. lang is a caption language code such as "en" or "es". The transcript is saved locally so search_saved can find it later.

NameRequiredDescriptionDefault
urlYes
langNoen
timestampsNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false and openWorldHint=true, and the description explains the write side-effect clearly: 'The transcript is saved locally so search_saved can find it later.' That reconciles the non-read-only annotation with an otherwise retrieval-sounding tool, which is exactly the context an agent needs. It stops short of failure modes (private videos, missing captions, rate limiting).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, each earning its place: core action first, then accepted inputs, then the persistence side-effect. No filler or repetition of the schema's boolean defaults.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still conveys the return shape (timestamped transcript) and the persistence behavior that affects downstream tools. Missing only what happens when no transcript is available, which matters for an open-world network tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load, and it largely does: it enumerates accepted url formats (watch, youtu.be, shorts, embed) and the 11-character id form, and gives lang examples ('en', 'es'). For timestamps it only implies the off-state, so a slight gap remains.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get a YouTube video's transcript') plus the default output shape ('[mm:ss] timestamps by default'). An agent can tell this apart from search_transcript (search within a transcript) and search_saved without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It supplies usage context for inputs (accepted URL forms, video id, lang codes) and hints that the result becomes searchable via search_saved. But it never states when to prefer a sibling such as search_transcript, nor any exclusions like videos without captions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_savedB
Read-only

List saved transcripts, newest first, with title, id and date.

NameRequiredDescriptionDefault
limitNo

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds that results are newest first and include title, id, and date, but it omits limit or pagination behavior and any result-count details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one front-loaded sentence with no filler, efficiently packing purpose, ordering, and returned fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only listing tool, it conveys purpose, ordering, and returned fields adequately. However, the undocumented limit parameter leaves a meaningful gap for controlling result size.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single optional limit parameter has 0% schema description coverage, and the description never explains what it controls or how it affects the result set. It therefore does not compensate for the schema gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and resource ('saved transcripts'), and states the ordering and returned fields. It implies a distinction from search_saved and get_transcript by being a listing operation, but does not explicitly name or differentiate those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It does not state when to use this tool instead of search_saved or search_transcript, nor does it provide any exclusions or prerequisites. Usage is only implied by the listing verb and the 'saved' scope.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_savedA
Read-only

Search every transcript fetched before, across all saved videos.

Returns the video, timestamp, matching line and a deep link for each hit, best matches first. Use this when the user refers to something they watched or asked about earlier.

NameRequiredDescriptionDefault
limitNo
queryYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety and world scope are covered. The description adds genuine context beyond them: the corpus is limited to transcripts fetched before, and results are ranked best-first with video, timestamp, matching line and deep link. It says nothing about result caps or what happens when nothing matches, which matters for a search tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, zero waste, with the scope constraint front-loaded and the return shape before the usage hint. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter read tool with no output schema, the description covers purpose, corpus scope, return shape and a usage trigger. The remaining hole is parameter behavior, especially the undocumented limit, which the empty schema descriptions leave unfilled.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden for the two parameters and does not meet it. Neither the query semantics (keywords, phrases, natural language?) nor the limit parameter (default 10, maximum, effect on ranking) is addressed anywhere.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Search every transcript fetched before, across all saved videos" gives a specific verb and a precisely scoped corpus, which implicitly separates it from search_transcript (single transcript) and list_saved (no query). It stops short of naming those siblings, so an agent must infer the split rather than being told it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The final sentence gives a concrete trigger: use it when the user refers to something they watched or asked about earlier. That is real when-to-use guidance, but there is no explicit exclusion (e.g. what to use for a transcript never fetched before) and no named alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_transcriptA

Find where a video talks about something.

Returns matching transcript lines with timestamps and a deep link to each moment (https://youtu.be/ID?t=SECONDS). Matching is case-insensitive keyword matching, best matches first.

NameRequiredDescriptionDefault
urlYes
queryYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only supply readOnlyHint=false and openWorldHint=true, so the description carries most of the weight and delivers genuinely useful traits: results are transcript lines with timestamps, each carries a deep link of the form https://youtu.be/ID?t=SECONDS, matching is case-insensitive keyword matching, and results are ranked best-match-first. What it omits is any result-count limit or pagination behavior, which matters for an open-world search.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the purpose before the return format and matching semantics; the inline deep-link example earns its space because it defines the timestamp format. Minor looseness in the colloquial opener ("talks about something") but no padding overall.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description correctly compensates by describing the shape of results (lines, timestamps, deep links) and the ranking order. Against a two-parameter search tool, the only substantive gaps are the accepted url format and any cap on returned matches.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and both parameters are required and undocumented, so the description must compensate. It partially does: "keyword matching" clarifies that query is literal keywords rather than natural-language semantics, and "a video" frames url as a video reference. It never states whether url must be a full YouTube URL or a bare video ID, leaving a real ambiguity in the required parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Find where a video talks about something" gives a specific verb (find/search) and resource (video transcript), and the return description (matching transcript lines with timestamps) makes clear this is a keyword search rather than a full-transcript fetch. It never names the sibling get_transcript, so the distinction is inferred from the word "matching" rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: "find where a video talks about something" suggests a targeted search, which an agent would contrast with get_transcript for full retrieval, but that alternative is never mentioned. There are no exclusion conditions and no note about when keyword search will fail (e.g., paraphrased content), so the agent must infer the routing decision.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedget_transcript
    • First observedlist_saved
    • First observedsearch_saved
    • First observedsearch_transcript

TDQS

A3.8/5.0

Scored across 4 tools

Disambiguation4/5

The four tools have mostly distinct purposes: fetching a transcript, searching within a video transcript, searching across saved transcripts, and listing saved transcripts. The boundary between search_transcript and search_saved is somewhat subtle because both perform transcript searching, though the descriptions clarify one is per-video and the other is cross-video.

Naming Consistency5/5

All names follow a consistent snake_case verb_object pattern: get_transcript, search_transcript, search_saved, list_saved. The convention is predictable and easy to scan.

Tool Count5/5

Four tools is well-scoped for a lightweight YouTube transcript utility. Each tool covers a distinct part of the fetch-search-list workflow without unnecessary surface area.

Completeness4/5

The core lifecycle for fetching, searching, and listing saved transcripts is covered. Minor gaps exist around managing saved data, such as deleting or clearing saved transcripts, and possibly retrieving a full saved transcript without refetching.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers