Skip to content

LLMExpert: cited Q&A over YouTube videos

by llmexpert.io · remote · no sign-in to list tools · v0.2.1 · published by io.llmexpert

Ask cited questions across sets of YouTube videos, and get their transcripts. API key or x402 USDC.

Changes · 6

13 tools: 6 change things and 7 only read.

Scanned Oct 21, 2026

1 check matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.

claude mcp add --transport http transcription https://llmexpert.io/mcp

Findings

Matches of fixed checks, with the text they matched.

1 warn
  • The server marks "query_channel" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

    Matched text

    annotations: {"readOnlyHint":true,"openWorldHint":true}; The name "query_channel" says "query": a word for reading.

    What this check looks for

Tools

Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.

13 tools

Changes things 6Claude Code: ask
  • add_sourceAdd a source to a channel and begin background ingestion.No findings

    Why it is in this group

    • The name "add_source" says "add": a word for a change.
    Description, as the server wrote it
    Add a source to a channel and begin background ingestion. Maps to POST /v1/channels/{channelId}/sources. Only `type: video` is processed today; `document` and `website` are reserved and return a 501 error until released. Requires the key's `write` scope.

    Annotations the server declares

    • title: Add a source to a channel
    • readOnlyHint: false
    • openWorldHint: true
  • add_sourcesCharged like `transcribe`.No findings

    Why it is in this group

    • The name "add_sources" says "add": a word for a change.
    Description, as the server wrote it
    Charged like `transcribe`. Expand the given YouTube URLs, charge for the new work and start an ingest job in an existing collection. Maps to POST /v1/collections/{collectionId}/sources. $0.01/min standard, $0.03/min whisper by default, 1-minute minimum per video. Videos already in the collection are free. Pass a `quote_id` from `quote` to be charged exactly that price. Poll `get_status` every 10–30 s until `status` is completed, partial or failed; `completed` means every accepted video is transcribed and indexed, so the collection is queryable. API key required (the key's `write` scope). Prices are the service defaults; `quote` returns the exact price.

    Annotations the server declares

    • title: Add YouTube sources to a collection
    • readOnlyHint: false
    • openWorldHint: true
  • create_collectionFree.No findings

    Why it is in this group

    • The name "create_collection" says "create": a word for a change.
    Description, as the server wrote it
    Free. Create an empty collection to add sources to later with `add_sources`. Maps to POST /v1/collections. Returns the collection and its `collection_token` (`ct_…`, shown once: store it; absent on an idempotent replay). API key required (the key's `write` scope). Prices are the service defaults; `quote` returns the exact price.

    Annotations the server declares

    • title: Create an empty collection
    • readOnlyHint: false
    • openWorldHint: true
  • query_channelRun a retrieval-augmented query against a channel's indexed knowledge base and return a generated answer with citations.1 finding

    Why it is in this group

    • The name "query_channel" says "query": a word for reading.
    • The description's first verb is "run": a word for a change.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.

    Findings

    • Warn

      The server marks "query_channel" read-only (readOnlyHint: true), and its own name, description or input give the class "write".

      Matched text

      annotations: {"readOnlyHint":true,"openWorldHint":true}; The name "query_channel" says "query": a word for reading.

      What this check looks for
    Description, as the server wrote it
    Run a retrieval-augmented query against a channel's indexed knowledge base and return a generated answer with citations. Maps to POST /v1/query. Requires the key's `query` scope and access to the channel. Charged: $0.02 flat per call by default. Prices are the service defaults; `quote` returns the exact price.

    Annotations the server declares

    • title: Query a channel
    • readOnlyHint: true
    • openWorldHint: true
  • quoteFree.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    • The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
    Description, as the server wrote it
    Free. Expand YouTube URLs exactly as an ingest would and return the price, the per-video lines and the per-source rejections. Maps to POST /v1/quote. $0.01/min standard, $0.03/min whisper by default, 1-minute minimum per video. The `quote_id` is valid for 15 minutes; pass it to `transcribe` or `add_sources` to be charged exactly this price. Pass `collection_id` to price against an existing collection (videos already in it are free). At least one of url, urls, channel_url, channel_urls. Requires the key's `read` scope. Prices are the service defaults; `quote` returns the exact price.

    Annotations the server declares

    • title: Quote an ingest
    • readOnlyHint: true
    • openWorldHint: true
  • transcribeCharged.No findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.
    Description, as the server wrote it
    Charged. Create a collection and start an ingest job for the given YouTube URLs in one call. Maps to POST /v1/transcribe. $0.01/min standard, $0.03/min whisper by default, 1-minute minimum per video. Pass a `quote_id` from `quote` to be charged exactly that price. Returns `job_id`, `collection_id` and `collection_token` (`ct_…`, shown once: store it; it reads this collection without an API key). Poll `get_status` every 10–30 s until `status` is completed, partial or failed; `completed` means every accepted video is transcribed and indexed, so the collection is queryable. With an API key it needs the key's `write` scope. Without an API key this tool is payable in USDC via x402: the first call returns a payment-required result (`isError` with the payment requirements in `structuredContent`); an x402-aware MCP client signs and retries the same call with `_meta['x402/payment']`, and the receipt returns in the result's `_meta['x402/payment-response']`. Never pay again after a 409 (already presented) or 502 (settlement unknown) result. Keyless `transcribe` takes one channel-like source and at most 3 videos. Prices are the service defaults; `quote` returns the exact price.

    Annotations the server declares

    • title: Transcribe into a new collection
    • readOnlyHint: false
    • openWorldHint: true
Only reads 7Claude Code: allow
  • get_sourceFetch a single source and its processing status (type-specific provenance included).No findings

    Why it is in this group

    • The name "get_source" says "get": a word for reading.
    Description, as the server wrote it
    Fetch a single source and its processing status (type-specific provenance included). Maps to GET /v1/sources/{sourceId}. Requires the key's `read` scope.

    Annotations the server declares

    • title: Get a source
    • readOnlyHint: true
    • openWorldHint: true
  • get_statusFree.No findings

    Why it is in this group

    • The name "get_status" says "get": a word for reading.
    Description, as the server wrote it
    Free. Get an ingest job started by `transcribe` or `add_sources`. Maps to GET /v1/jobs/{jobId}. Poll every 10–30 s until `status` is completed, partial or failed (terminal). `completed` means every accepted video is transcribed and indexed, so the collection is queryable; `partial` means some videos failed and were credited back (`credited_usd`); `videos.completed` / `videos.failed` count progress. Works with an API key or the collection's `ct_` token as the bearer. Prices are the service defaults; `quote` returns the exact price.

    Annotations the server declares

    • title: Get an ingest job
    • readOnlyHint: true
    • openWorldHint: true
  • get_transcriptFree.No findings

    Why it is in this group

    • The name "get_transcript" says "get": a word for reading.
    Description, as the server wrote it
    Free. Get the transcript of a video that is completed in one of your collections. Maps to GET /v1/videos/{youtubeId}/transcript. `collection_id` is required with an API key; with the collection's `ct_` token as the bearer it defaults to the token's collection. `format` is json (segments with timestamps, default) or text (one `[H:MM:SS] text` line per segment). 404 when the video is not completed in that collection, or the transcript predates the transcript cache. Prices are the service defaults; `quote` returns the exact price.

    Annotations the server declares

    • title: Get a video's transcript
    • readOnlyHint: true
    • openWorldHint: true
  • get_usageGet usage, quota, and spend for the calling key (queries, tokens, cost, budget remaining).No findings

    Why it is in this group

    • The name "get_usage" says "get": a word for reading.
    Description, as the server wrote it
    Get usage, quota, and spend for the calling key (queries, tokens, cost, budget remaining). Maps to GET /v1/usage. Requires the key's `read` scope.

    Annotations the server declares

    • title: Get usage and spend
    • readOnlyHint: true
    • openWorldHint: true
  • list_channelsList the channels the calling key is scoped to.No findings

    Why it is in this group

    • The name "list_channels" says "list": a word for reading.
    Description, as the server wrote it
    List the channels the calling key is scoped to. Maps to GET /v1/channels. Cursor-paginated. Requires the key's `read` scope.

    Annotations the server declares

    • title: List channels
    • readOnlyHint: true
    • openWorldHint: true
  • list_sourcesList the sources (video/document/website) in a channel, optionally filtered by type or status.No findings

    Why it is in this group

    • The name "list_sources" says "list": a word for reading.
    Description, as the server wrote it
    List the sources (video/document/website) in a channel, optionally filtered by type or status. Maps to GET /v1/channels/{channelId}/sources. Cursor-paginated. Requires the key's `read` scope.

    Annotations the server declares

    • title: List sources in a channel
    • readOnlyHint: true
    • openWorldHint: true
  • query_collectionCharged: $0.02 flat per call by default, no token multiplier.No findings

    Why it is in this group

    • The name "query_collection" says "query": a word for reading.
    Description, as the server wrote it
    Charged: $0.02 flat per call by default, no token multiplier. Ask a question of a collection and get a generated answer with citations. Maps to POST /v1/collections/{collectionId}/query. Query a collection once `get_status` says completed. With an API key it needs the key's `query` scope. Without an API key this tool is payable in USDC via x402: the first call returns a payment-required result (`isError` with the payment requirements in `structuredContent`); an x402-aware MCP client signs and retries the same call with `_meta['x402/payment']`, and the receipt returns in the result's `_meta['x402/payment-response']`. Never pay again after a 409 (already presented) or 502 (settlement unknown) result. Keyless, only the address that paid for the collection may query it. Prices are the service defaults; `quote` returns the exact price.

    Annotations the server declares

    • title: Query a collection
    • readOnlyHint: true
    • openWorldHint: true

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Install

Pinned to version 0.2.1. Values in angle brackets are yours to fill in.

claude mcp add --transport http transcription https://llmexpert.io/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__transcription__list_channels",
      "mcp__transcription__list_sources",
      "mcp__transcription__get_source",
      "mcp__transcription__get_usage",
      "mcp__transcription__get_status",
      "mcp__transcription__get_transcript",
      "mcp__transcription__query_collection"
    ],
    "ask": [
      "mcp__transcription__query_channel",
      "mcp__transcription__add_source",
      "mcp__transcription__quote",
      "mcp__transcription__transcribe",
      "mcp__transcription__create_collection",
      "mcp__transcription__add_sources"
    ],
    "deny": []
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as transcription. Review it before you use it.