---
canonical_url: "https://docs.composio.dev/toolkits/vidiq_mcp"
markdown_url: "https://docs.composio.dev/toolkits/vidiq_mcp.md"
product: "platform"
version: null
last_updated: null
---

# vidIQ MCP

vidIQ MCP lets authorized agents research YouTube and Instagram creators, videos, trends, comments, thumbnails, titles, and connected-channel analytics, with explicitly annotated media and account-management actions.

- **Category:** model context protocol
- **Auth:** DCR_OAUTH, API_KEY
- **Composio-managed OAuth available?** No
- **Tools:** 67
- **Triggers:** 0
- **Slug:** `VIDIQ_MCP`
- **Version:** 20261001_00

## Tools

### Vidiq authorize with youtube

**Slug:** `VIDIQ_MCP_VIDIQ_AUTHORIZE_WITH_YOUTUBE`

Check or establish fresh YouTube authorization for the current vidIQ OAuth connection.

Call this tool when the user asks to authorize with YouTube, before a sensitive workflow that requires fresh YouTube authentication, or after the user completes the authorization handoff. It authorizes using a YouTube channel already connected to vidIQ. If no channel is connected yet, it reports that and vidiq_connect_youtube_channel connects the first one, which also establishes fresh YouTube authorization. When authorization is required, show the authorization widget and wait for the user to use its controls.

Cost: 0 credit(s) per call.

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `kind` | string | Yes |  |
| `status` | string ("verified" | "verification_required") | Yes | Whether this vidIQ connection currently has fresh YouTube identity verification. |
| `message` | string | No |  |

### Vidiq balance

**Slug:** `VIDIQ_MCP_VIDIQ_BALANCE`

Check the user's current vidIQ credits balance.

vidIQ credits live in two buckets:
- A renewable bucket sized by the user's plan (Free/Boost/Max/etc) that refills each billing cycle.
- Zero or more add-on (bonus) credits. Add-on credits drain alongside renewable credits but do NOT refill.

Field semantics are in the output schema. Key invariant: totalCredits = renewableCredits + addOnCredits; maxRenewableCredits is the plan cap only.

Example — Boost user with an open promo grant:
  { type: 'limited', totalCredits: 1800,
    renewableCredits: 1500, maxRenewableCredits: 2000,
    renewableResetsAt: '2026-06-01T00:00:00Z',
    addOnCredits: 300, maxAddOnCredits: 500 }
Read as: 1,800 left = 1,500 of 2,000 renewable + 300 of a 500-credit bonus pool. Renews Jun 1.

Cost: 0 credit(s) per call.

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `type` | string ("limited" | "unlimited") | Yes | 'limited' means the user has a finite renewable credit budget that refills each billing cycle. 'unlimited' means the user is on an unlimited plan (e.g. enterprise) and the renewable bucket does not decrement. |
| `addOnCredits` | number | Yes | Remaining add-on (bonus) credits. Drain alongside renewable credits and do NOT refill on the billing cycle. |
| `totalCredits` | string | Yes | Total remaining credits the user can spend right now — renewableCredits plus addOnCredits. Null when type='unlimited'. This is the headline number to show in chat. |
| `maxAddOnCredits` | number | Yes | Initial total of all currently-active add-on credits — i.e. how much bonus credit the user originally received. Combine with addOnCredits to compute add-on usage. |
| `renewableCredits` | string | Yes | Remaining credits in the renewable plan bucket alone — does NOT include add-on credits. Null when type='unlimited'. |
| `renewableResetsAt` | string | Yes | ISO timestamp when the renewable credit bucket next renews. Add-on credits do NOT renew; only the renewable bucket. Null when type='unlimited' or the backend did not return a renewal time. |
| `maxRenewableCredits` | string | Yes | The user's renewable plan cap (e.g. 150 for Free, 2000 for Boost, 6000 for Max). This is the amount that refills each billing cycle. Does NOT include add-on credits. Null when the plan has no cap. |

### Vidiq bookmarks list

**Slug:** `VIDIQ_MCP_VIDIQ_BOOKMARKS_LIST`

Retrieve the signed-in user's saved bookmarks to review or reuse in research and planning. Use when the user asks "show my saved videos", "show my saved channels", "show my saved keywords", "show my generated videos", "show my uploads", "what did I bookmark?", or wants to reuse saved inspiration or a saved creation. With no arguments, returns the 10 newest bookmarks across all types. Video bookmarks span several types: bookmarkType="saved-video" (videos saved while browsing, any platform), "saved-outlier-video" (YouTube outliers), "saved-generated-video" (the user's own generated videos) and "saved-uploaded-video" (their uploads); channels and creators use "saved-channel" (platform youtube, instagram or tiktok); keywords use "saved-keyword". When the user asks for "saved videos" without saying which, ask whether they mean all of them, outliers only, generated, or uploads — or list all types and group the answer by type. Tags match any supplied tag name. Supports type and tag filters, not keyword or topic search. Returns stored payloads, not live metrics; use the relevant research tool when fresh metrics are requested. Pass nextOffset as offset for the next page; null means no more results.

Cost: 0 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `tags` | array | No | Match any of these tag names. |
| `limit` | integer | No |  |
| `offset` | integer | No |  |
| `bookmarkType` | string | No | Filter by type, e.g. saved-video, saved-channel, saved-outlier-video, saved-generated-video, saved-uploaded-video or saved-keyword; omit for all types. |

### Vidiq bookmarks remove

**Slug:** `VIDIQ_MCP_VIDIQ_BOOKMARKS_REMOVE`

Remove 1–50 bookmarks from the signed-in account in one atomic batch. Only remove items the user explicitly asked to remove; otherwise ask first. Duplicate IDs count once. Any unknown, already removed, or foreign ID rejects the entire batch. If the outcome is uncertain, inspect saved bookmarks before retrying.

Cost: 0 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `ids` | array | Yes | 1–50 bookmark IDs to remove. |

### Vidiq bookmarks save

**Slug:** `VIDIQ_MCP_VIDIQ_BOOKMARKS_SAVE`

Save 1–50 bookmarks of one type to the signed-in account in one atomic batch. Only save items the user explicitly asked to save. Repeated saves create duplicates. Do not automatically retry a failed save; inspect saved bookmarks first if the outcome is uncertain. After success, briefly confirm the saved count and what was saved. The response includes a suggested vidiq_bookmarks_list call for later retrieval; do not call it automatically just to confirm a successful save.

Cost: 0 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `tags` | array | No | Existing tag IDs applied to every item. |
| `payloads` | array | Yes | 1–50 payloads of the selected bookmarkType. Common field mappings, subject to the configured type schema: - saved-video: videoId (YouTube ID, Instagram shortcode, or TikTok video ID), title, platform (youtube, instagram, or tiktok), type (long or short). - saved-channel (a creator profile on any supported platform): platform (youtube, instagram, or tiktok), channelId (a YouTube channel ID when platform=youtube; a profile handle when platform=instagram or tiktok), title (display name). - saved-outlier-video: videoId from the selected YouTube outlier. - saved-keyword: keyword (question in questions mode); when available, competition, overall→overallScore, estimatedMonthlySearch→searchVolume. Omit unavailable metrics; preserve zero. Never use volume or countryVolume as searchVolume; zero estimatedMonthlySearch means below the reporting threshold. - saved-generated-video: projectId, videoUrl, prompt, model, resolution, duration→durationSeconds from the completed generation result. - saved-uploaded-video: uploadId, title (the title provided when uploading), duration→durationSeconds. Omit videoUrl because it expires. Use values from tool inputs and results; do not invent missing fields. |
| `bookmarkType` | string | Yes | Configured type shared by every payload, e.g. saved-video, saved-channel, saved-keyword, saved-outlier-video, saved-generated-video or saved-uploaded-video. |

### Vidiq channel analytics

**Slug:** `VIDIQ_MCP_VIDIQ_CHANNEL_ANALYTICS`

Get YouTube Analytics data for a channel you own — views, watch time, subscribers gained, likes, comments, retention, traffic sources, demographics, and revenue (monetized channels).

Common reports are available as one-word presets via `report`: audience_retention (per-video drop-off curve), traffic_sources, audience_demographics, audience_geography, revenue_report, top_videos, shorts_vs_longform_split. Or build custom queries with flexible date ranges, metric selection, and dimensional breakdowns (by day, country, device type, traffic source, etc.).

Use this tool to:
- Analyze channel performance over a specific time period
- See where viewers drop off in a video (report='audience_retention' + filters='video==VIDEO_ID')
- Break down views by traffic source, country, device type, age/gender
- See which videos actually earn (report='revenue_report', dimensions=['video'])
- Compare Shorts vs long-form performance (report='shorts_vs_longform_split')

Views vs engaged views: since 2026-08-27 YouTube counts views from the first frame, so `views` runs about 1.7–1.9× higher than before on long-form. Use `engagedViews` for any before/after comparison that spans that date and when judging which of the channel's own videos are outliers.

Note: Only available for channels authorized to your account. Revenue metrics additionally require the channel to be monetized.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sort` | string | No | Sort field, prefix with '-' for descending (e.g. '-views') |
| `report` | string ("audience_retention" | "traffic_sources" | "audience_demographics" | "audience_geography" | "revenue_report" | "top_videos" | "shorts_vs_longform_split") | No | Named report preset that fills metrics/dimensions/sort with a known-good YouTube Analytics report shape (explicitly-passed metrics/dimensions/sort/maxResults still win). audience_retention: per-video retention curve — REQUIRES filters='video==VIDEO_ID'. traffic_sources: views by source (search, suggested, browse, external...). audience_demographics: age/gender split (viewerPercentage). audience_geography: views by country. revenue_report: daily earnings (monetized channels only; combine with dimensions=['video'] for per-video earnings — YouTube does not support revenue by traffic source). top_videos: own videos ranked by views (pass sort='-estimatedRevenue' plus revenue metrics to rank by earnings instead). shorts_vs_longform_split: views/watch-time split between Shorts, long-form and live (creatorContentType). |
| `endDate` | string | No | End date (YYYY-MM-DD). Defaults to today |
| `filters` | string | No | Filter expression (e.g. 'video==dQw4w9WgXcQ', 'country==US') |
| `metrics` | array | No | Metrics to retrieve. Default: views, engagedViews, estimatedMinutesWatched, subscribersGained, likes, comments. Since 2026-08-27 YouTube counts views from the first frame, so views runs about 1.7–1.9× higher than before on long-form; engagedViews is not affected by that change. Use engagedViews for any before/after comparison that spans that date and for outlier judgments on the channel's own videos. Some dimensions support only a restricted metric set — an unsupported metric is rejected, and omitted metrics narrow to the supported subset of the default. Each restricted dimension and the metrics it allows: insightTrafficSourceType, insightTrafficSourceDetail, insightPlaybackLocationType, insightPlaybackLocationDetail, deviceType → views, engagedViews, estimatedMinutesWatched, averageViewDuration, averageViewPercentage; subscribedStatus → those plus likes, dislikes, shares, videosAddedToPlaylists, videosRemovedFromPlaylists, annotationClickThroughRate; ageGroup, gender → viewerPercentage; elapsedVideoTimeRatio → audienceWatchRatio, relativeRetentionPerformance, totalSegmentImpressions, startedWatching, stoppedWatching (where viewers start/stop watching per 1% segment; also available as a single-video total with no dimensions and filters='video==VIDEO_ID'). videosAddedToPlaylists and videosRemovedFromPlaylists are not available with creatorContentType, and top-video reports can't be sorted by shares or those playlist metrics (sort by views instead). For subscriber/comment/share metrics use a time/geo dimension (day, country) or video. |
| `channelId` | string | Yes | YouTube channel ID (e.g. 'UCX6OQ3DkcsbYNE6H8uQQuVA') or handle (e.g. '@MrBeast') |
| `startDate` | string | No | Start date (YYYY-MM-DD). Defaults to 28 days ago |
| `dimensions` | array | No | Dimensions to break down by (e.g. day, country, deviceType). month: startDate/endDate are snapped to the first of their month (YouTube requires month-aligned bounds). video, insightTrafficSourceDetail, insightPlaybackLocationDetail are top-N reports (ranked by views; pass sort/maxResults to change); the two *Detail dims also need a parent-type filter (insightTrafficSourceType== / insightPlaybackLocationType==), and those filters are valid only with their matching *Detail dimension. elapsedVideoTimeRatio (audience retention) needs a video== filter. Most dimensions can't be combined (YouTube supports only specific report shapes) — if a combo is rejected, request each dimension separately. |
| `maxResults` | integer | No | Maximum number of rows to return. insightTrafficSourceDetail and insightPlaybackLocationDetail allow at most 25 (default 25); video allows at most 200 (default 25); elapsedVideoTimeRatio requires at least 100 (default 100) because audience retention is a 100-point curve and does not have the video's 200-row ceiling. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `rows` | array | Yes |  |
| `endDate` | string | Yes |  |
| `channelId` | string | Yes |  |
| `startDate` | string | Yes |  |
| `columnHeaders` | array | Yes |  |

### Vidiq channel performance trends

**Slug:** `VIDIQ_MCP_VIDIQ_CHANNEL_PERFORMANCE_TRENDS`

Get a channel's typical video performance curve — how views accumulate over time after publication.

Returns statistical aggregates (min, max, avg, median, percentiles) of view counts at various time intervals since publication, based on the channel's recent videos.

Use this tool to:
- Understand how quickly a channel's videos gain views after publishing
- Compare a channel's view velocity against benchmarks
- Identify whether a channel has strong initial traction or slow-burn growth

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `channelId` | string | Yes | YouTube channel ID, handle (e.g. '@MrBeast'), or channel URL |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `trends` | array | Yes |  |
| `channelId` | string | Yes |  |
| `createdAt` | string | No |  |

### Vidiq channel search

**Slug:** `VIDIQ_MCP_VIDIQ_CHANNEL_SEARCH`

Comprehensive YouTube channel search. Combines semantic + lexical text search with structured filters across identity, audience size, growth, format mix, and content metadata.

Use this tool to:
- Find channels by niche or topic with natural-language queries (semantic match on niche + description embeddings).
- Look up a specific channel by YouTube handle (e.g. '@MrBeast').
- Require specific wording in the channel description with the description filter (consecutive words, typo-tolerant) — for 'channels whose description mentions/says X'.
- Filter by channel size (subscriber/view/video count ranges), growth (7d / 30d / 1y subs and views), recency (last video published), format (long / short / mixed), per-format average duration and video/view counts (7d / 30d / 1y), creation date, country, language, main category, and flags (faceless, breakout).
- Order results with the optional sort param (relevance / subscriberCount / subsGrowth30d / viewsGrowth30d / lastVideoPublished). Topical asks — including 'top/popular/biggest channels about X' — use relevance (default), which already favors notable channels; field sorts are ONLY for explicit metric scans and re-order by the raw metric, ignoring topical fit.
- Combine any subset of inputs — at least one of query / handle / channel title / filters is required.
- Find emerging channels: set breakoutChannel: true for any 'breakout / emerging / up-and-coming channels in X' intent — the flag filters to breakout channels AND switches ranking to favor small fast-rising channels (replaces vidiq_breakout_channels).
- Non-English / local discovery: `languages` means the actual language channels publish in; `country` means where channels are based, not audience location or content language. Never translate the query — 'дай каналы про уроки макияжа' → query: 'уроки макияжа', languages: ['ru']; 'tokyo street food' → query: 'tokyo street food', country: ['JP']; 'news and politics in Ukraine' → country: ['UA'] (news/politics/local-events about a country means that country's channels, not foreign coverage). Results should match the request's language unless the user says otherwise. For geo-local or language-specific discovery request limit 20+ — relevant local channels may rank below globally popular ones.

For finding COMPETITORS of a channel — the user's own ("who are my competitors?") or a named one ("channels similar to Creator Insider") — prefer vidiq_similar_channels (auto-exclusion and competitor-tuned scoring); this tool is still the right first step there, to resolve the reference channel's niche, subNiches, subscriberCount, country, and languages. For viral-video discovery, use vidiq_outliers.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sort` | string ("relevance" | "subscriberCount" | "subsGrowth30d" | "viewsGrowth30d" | "lastVideoPublished") | No | Result ordering: 'relevance' (default for text searches; ranks by semantic + lexical score), 'subscriberCount' (subscribers desc), 'subsGrowth30d' (30-day subscriber growth desc), 'viewsGrowth30d' (30-day view growth desc), or 'lastVideoPublished' (most recently active first). Pure-filter searches default to subscriberCount desc. Use 'relevance' for ALL topical queries including 'popular/famous/top channels in X' — relevance ranking already favors notable channels. Use field sorts only for explicit metric scans ('most subscribed regardless of topic fit', 'fastest growing'); pair growth sorts with subscriberCountMin (e.g. 1000) because growth percentages explode at tiny subscriber bases. |
| `limit` | integer | No | Number of channels to return (max 50). For geo-local or language-specific discovery, request 20+ — relevant local channels may rank below globally popular ones. |
| `query` | string | No | Free-text query describing the niche, topic, or content (e.g. 'vegan cooking tutorials', 'tech reviews', 'minecraft let's plays'). Drives semantic search across niches and description embeddings plus lexical match on niches/description. Write the query in the LANGUAGE THE USER USED — NEVER translate their wording to English. The search is multilingual; translating discards the language signal and returns the wrong locale's channels. Non-English request → keep the original wording here AND set `languages` to the request's language. Optional — you can also run a pure metrics/attribute search by providing only filters. |
| `handle` | string | No | YouTube handle / custom URL (e.g. '@MrBeast' or 'mrbeast'). Leading '@' is optional. Use this when you want a specific channel. |
| `country` | array | No | Filter by channel country (ISO 3166-1 alpha-2 codes, uppercase, e.g. ['US', 'GB']): the country where the channel is BASED — NOT the audience/viewer country, and NOT the channel's language (use `languages` to filter by language). Multiple codes are OR-ed. When the query names a place ('tokyo street food', 'nyc daily vlogs'), pass the corresponding country code(s) — e.g. tokyo → ['JP'] — and keep the city name in the query. For news, politics, or local-events queries about a country ('news and politics in Ukraine'), ALWAYS set that country (usually with its language in `languages`): the audience wants that country's channels, not foreign channels covering it. Skip the country filter only for travel/culture coverage intent where creators from anywhere qualify ('travel vlogs about Japan'). |
| `faceless` | boolean | No | Filter by faceless-channel status. true returns only faceless channels, false excludes them. |
| `languages` | array | No | Filter by the actual language(s) the channels publish content in (ISO 639-1 codes, lowercase, e.g. ['en', 'es']). Always pass the user's requested content/channel language here; this is channel language, NOT channel country. When the USER'S REQUEST is written in a non-English language and does not request a different content language, or they explicitly ask for content in a specific language ('на русском', 'auf deutsch'), pass that actual content language here — e.g. query 'уроки макияжа' → languages: ['ru']. Do not translate the query; the search understands non-English text, but without this filter big channels in other languages will outrank local ones. By default matches any channel that *contains* a requested language (multilingual channels included). Set exactLanguage=true to return only monolingual channels whose language is exactly the requested value. |
| `avgViewsMax` | number | No | Maximum lifetime average views per video (total views / total videos). Use for 'averages under 10k views a video'. |
| `avgViewsMin` | number | No | Minimum lifetime average views per video (total views / total videos). Use for 'averages 100k+ views per video'. This is the per-video average, not total views. |
| `channelType` | string ("long" | "short" | "mixed") | No | Filter by content format: 'long' (longform), 'short' (shorts-first), or 'mixed'. |
| `description` | string | No | Require a phrase in the channel description: the words must appear consecutively, in order, each tolerating small typos. A hard filter (restricts the result set, works with any sort), unlike `query` which only ranks. Use when the user wants channels whose DESCRIPTION says something specific (e.g. description: 'redstone tutorials' or 'business inquiries'). For topic/niche discovery, prefer `query`. |
| `handleMatch` | string ("exact" | "fuzzy") | No | How to match handle. 'exact' (default) returns only the channel with that exact handle. 'fuzzy' does a partial/relevance match (e.g. 'beast' matches '@MrBeast'). Requires handle — rejected if set without it. |
| `channelTitle` | string | No | Optional channel title fragment to bias results toward channels whose title matches (e.g. 'Mark Rober'). |
| `mainCategory` | array | No | Filter by main category (YouTube topic labels as stored in the index — e.g. 'Knowledge' for educational content, 'Video game culture' for gaming, 'Lifestyle (sociology)' for lifestyle). Values are case-sensitive and must come from the enum; multiple values are OR-ed. |
| `viewCountMax` | integer | No | Maximum lifetime view count. |
| `viewCountMin` | integer | No | Minimum lifetime view count. |
| `exactLanguage` | boolean | No | When true, match languages exactly (only monolingual channels whose single language equals the requested code). Prefer true when the user wants content purely in that language — multilingual channels (e.g. 'hi, en') often produce content mostly in their other language. When false/omitted, match any channel containing the requested language(s). Requires a non-empty `languages` list — rejected if true without it. |
| `videoCountMax` | integer | No | Maximum total video count. |
| `videoCountMin` | integer | No | Minimum total video count. |
| `publishedAfter` | string | No | Filter by channel creation date (ISO YYYY-MM-DD): created on or after this date. |
| `breakoutChannel` | boolean | No | Filter by breakout-channel flag. true also switches ranking to emerging-channel mode: the popularity prior is disabled so small fast-rising channels rank by pure relevance instead of being outranked by established ones. Use breakoutChannel: true for any 'breakout / emerging / up-and-coming channels in X' intent. Omit to return both breakout and non-breakout channels with default ranking. |
| `publishedBefore` | string | No | Filter by channel creation date (ISO YYYY-MM-DD): created on or before this date. |
| `subsGrowth1yMax` | number | No | Maximum 1-year subscriber growth (percent). |
| `subsGrowth1yMin` | number | No | Minimum 1-year subscriber growth (percent). |
| `subsGrowth7dMax` | number | No | Maximum 7-day subscriber growth (percent). |
| `subsGrowth7dMin` | number | No | Minimum 7-day subscriber growth (percent, e.g. 5 = +5%). |
| `subsGrowth30dMax` | number | No | Maximum 30-day subscriber growth (percent). |
| `subsGrowth30dMin` | number | No | Minimum 30-day subscriber growth (percent). |
| `viewsGrowth1yMax` | number | No | Maximum 1-year view growth (percent). |
| `viewsGrowth1yMin` | number | No | Minimum 1-year view growth (percent). |
| `viewsGrowth7dMax` | number | No | Maximum 7-day view growth (percent). |
| `viewsGrowth7dMin` | number | No | Minimum 7-day view growth (percent). |
| `channelTitleMatch` | string ("exact" | "fuzzy") | No | How to match channelTitle. 'fuzzy' (default) ranks by title similarity (partial matches allowed). 'exact' restricts to channels whose title equals the value (case-insensitive). Requires channelTitle — rejected if set without it. |
| `viewsGrowth30dMax` | number | No | Maximum 30-day view growth (percent). |
| `viewsGrowth30dMin` | number | No | Minimum 30-day view growth (percent). |
| `longViewCount1yMax` | integer | No | Maximum long-form view count accrued in the trailing year. |
| `longViewCount1yMin` | integer | No | Minimum long-form view count accrued in the trailing year. |
| `longViewCount7dMax` | integer | No | Maximum long-form view count accrued in the trailing 7 days. |
| `longViewCount7dMin` | integer | No | Minimum long-form view count accrued in the trailing 7 days. |
| `nicheConfidenceMin` | number | No | Minimum niche-classification confidence (0–1). Each channel is tagged with a niche and a confidence score; this floors out low-confidence / likely-misclassified channels so results stay on-topic. Defaults to 0.3 to favor cleanly-classified channels — set to 0 to disable the floor and include unclassified/low-confidence channels. |
| `subscriberCountMax` | integer | No | Maximum subscriber count. |
| `subscriberCountMin` | integer | No | Minimum subscriber count. |
| `longVideoCount1yMax` | integer | No | Maximum number of long-form videos published in the trailing year. |
| `longVideoCount1yMin` | integer | No | Minimum number of long-form videos published in the trailing year. |
| `longVideoCount7dMax` | integer | No | Maximum number of long-form videos published in the trailing 7 days. |
| `longVideoCount7dMin` | integer | No | Minimum number of long-form videos published in the trailing 7 days. |
| `longViewCount30dMax` | integer | No | Maximum long-form view count accrued in the trailing 30 days. |
| `longViewCount30dMin` | integer | No | Minimum long-form view count accrued in the trailing 30 days. |
| `shortViewCount1yMax` | integer | No | Maximum short-form view count accrued in the trailing year. |
| `shortViewCount1yMin` | integer | No | Minimum short-form view count accrued in the trailing year. |
| `shortViewCount7dMax` | integer | No | Maximum short-form view count accrued in the trailing 7 days. |
| `shortViewCount7dMin` | integer | No | Minimum short-form view count accrued in the trailing 7 days. |
| `estimatedEarningsMax` | number | No | Maximum estimated MONTHLY channel earnings in USD. Hard filter: channels with unknown earnings are excluded. Use for 'channels making under $1000 a month'. |
| `estimatedEarningsMin` | number | No | Minimum estimated MONTHLY channel earnings in USD. Hard filter: channels with unknown earnings are excluded. Use for 'channels earning over $10k a month'. |
| `longAvgDuration1yMax` | number | No | Maximum average long-form video duration over the trailing year (seconds). |
| `longAvgDuration1yMin` | number | No | Minimum average long-form video duration over the trailing year (seconds). |
| `longAvgDuration7dMax` | number | No | Maximum average long-form video duration over the trailing 7 days (seconds). |
| `longAvgDuration7dMin` | number | No | Minimum average long-form video duration over the trailing 7 days (seconds). |
| `longVideoCount30dMax` | integer | No | Maximum number of long-form videos published in the trailing 30 days. |
| `longVideoCount30dMin` | integer | No | Minimum number of long-form videos published in the trailing 30 days. |
| `shortVideoCount1yMax` | integer | No | Maximum number of short-form videos published in the trailing year. |
| `shortVideoCount1yMin` | integer | No | Minimum number of short-form videos published in the trailing year. |
| `shortVideoCount7dMax` | integer | No | Maximum number of short-form videos published in the trailing 7 days. |
| `shortVideoCount7dMin` | integer | No | Minimum number of short-form videos published in the trailing 7 days. |
| `shortViewCount30dMax` | integer | No | Maximum short-form view count accrued in the trailing 30 days. |
| `shortViewCount30dMin` | integer | No | Minimum short-form view count accrued in the trailing 30 days. |
| `longAvgDuration30dMax` | number | No | Maximum average long-form video duration over the trailing 30 days (seconds). |
| `longAvgDuration30dMin` | number | No | Minimum average long-form video duration over the trailing 30 days (seconds). |
| `shortAvgDuration1yMax` | number | No | Maximum average short-form video duration over the trailing year (seconds). |
| `shortAvgDuration1yMin` | number | No | Minimum average short-form video duration over the trailing year (seconds). |
| `shortAvgDuration7dMax` | number | No | Maximum average short-form video duration over the trailing 7 days (seconds). |
| `shortAvgDuration7dMin` | number | No | Minimum average short-form video duration over the trailing 7 days (seconds). |
| `shortVideoCount30dMax` | integer | No | Maximum number of short-form videos published in the trailing 30 days. |
| `shortVideoCount30dMin` | integer | No | Minimum number of short-form videos published in the trailing 30 days. |
| `shortAvgDuration30dMax` | number | No | Maximum average short-form video duration over the trailing 30 days (seconds). |
| `shortAvgDuration30dMin` | number | No | Minimum average short-form video duration over the trailing 30 days (seconds). |
| `lastVideoPublishedAfter` | string | No | Last uploaded video on or after this date (ISO YYYY-MM-DD) — active channels. |
| `lastVideoPublishedBefore` | string | No | Last uploaded video on or before this date (ISO YYYY-MM-DD). |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `total` | number | Yes |  |
| `channels` | array | Yes |  |

### Vidiq channel stats

**Slug:** `VIDIQ_MCP_VIDIQ_CHANNEL_STATS`

Get YouTube channel statistics including subscriber count, total views, video count, and growth over a configurable time period.

Use this tool to:
- Look up any YouTube channel's current stats (subscribers, views, videos)
- See how much a channel has grown over a given period
- Get channel metadata (country, language, topics, creation date)

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `to` | string | No | End date (YYYY-MM-DD). Defaults to today |
| `from` | string | No | Start date (YYYY-MM-DD). Defaults to 30 days ago |
| `channelId` | string | Yes | YouTube channel ID (e.g. 'UCX6OQ3DkcsbYNE6H8uQQuVA') or handle (e.g. '@MrBeast') |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `title` | string | Yes |  |
| `growth` | object | Yes |  |
| `topics` | array | Yes |  |
| `country` | string | Yes |  |
| `channelId` | string | Yes |  |
| `thumbnail` | string | Yes |  |
| `dailyStats` | array | Yes |  |
| `publishedAt` | string | Yes |  |
| `currentStats` | object | Yes |  |
| `defaultLanguage` | string | Yes |  |

### Vidiq channel videos

**Slug:** `VIDIQ_MCP_VIDIQ_CHANNEL_VIDEOS`

Get videos from a YouTube channel by format (long-form, Shorts, or live streams). Use this when you already know which channel to look at. To discover videos across many channels, use vidiq_outliers or vidiq_trending_videos.

Use vidiq_user_videos instead when the user needs their owned-channel library, private or unlisted videos, title search, privacy filters, or cursor pagination.

Use this tool to:
- Browse a channel's recent uploads by video type (popular=false)
- Discover a channel's most popular videos by type (popular=true, default)
- Compare current views, likes, comments, views per hour (VPH), and breakout scores
- Get video metadata including titles, publish dates, thumbnails, and durations

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `popular` | boolean | No | When true (default), returns the most popular videos. When false, returns recent uploads. |
| `channelId` | string | Yes | YouTube channel ID (e.g. 'UCX6OQ3DkcsbYNE6H8uQQuVA') or handle (e.g. '@MrBeast') |
| `videoFormat` | string ("long" | "short" | "live") | Yes | Type of videos to retrieve: 'long' for long-form, 'short' for Shorts, 'live' for live streams |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videos` | array | Yes |  |
| `popular` | boolean | Yes |  |
| `channelId` | string | Yes |  |
| `videoFormat` | string ("long" | "short" | "live") | Yes |  |
| `channelTitle` | string | Yes |  |
| `channelThumbnail` | string | Yes | YouTube channel avatar thumbnail URL, or null if unavailable |

### Vidiq comment insights

**Slug:** `VIDIQ_MCP_VIDIQ_COMMENT_INSIGHTS`

Analyze YouTube audience comments for a niche.

Prefer discover/validate by default. Use raw only when underlying comments are needed. A new raw search costs the same as discover/validate; its cursor pages are free. Each page is approximately up to 10k tokens. If your host supports subagents, delegate clustering of raw comments to a cheaper subagent. Send a niche on the first page; continuations accept ONLY mode=raw and cursor.

What raw returns: indexed audience comments from channels qualified for the niche, grouped by thread, with deterministic cleanup only (spam patterns, duplicate text, size bounds, script-level language check). Raw does NOT check whether each comment is about the niche. Expect a meaningful share of off-topic creator chatter, jokes, generic praise, promos and wrong-language comments (in live tests roughly half of returned comments were directly useful). Before drawing conclusions: (1) drop comments not about the niche; (2) re-check language yourself, because the language filter is script-level only; (3) treat intent labels as hints, not truth; (4) count threads and distinct channels, not raw comments, as evidence of demand.

Sort defaults to relevance (semantic similarity to the niche). likes is engagement-ranked and favors big creators' fan chatter; newest favors whoever uploaded most recently. No results are representative samples. Each page includes at most maxThreadsPerChannel threads per channel (default 5, 0 = no limit); the rest move to later pages. Page size is a maximum; the byte bound usually returns 10–15 threads. Only indexed comments are available (the upstream index excludes low-like comments); replies may appear without their root. Threads contain at most four matching comments, root first when present, then viewer replies by time; the comment that established rank is always included. Thread rankValue is the relevance score (not a probability), like count, or publication timestamp; creator replies are excluded. Ranking is live within a fixed publication cutoff. Traversals are bounded to 1000 threads or 100 pages. Resubmitting a cursor is safe: a page that already completed is replayed without extra traversal, and a page that failed is retried. A submission made while the same cursor is still being processed is rejected; poll the original job or retry shortly.

Use mode="discover" to find recurring audience questions/content requests and recurring dislikes or pain points. Use mode="validate" with idea to test one proposed video idea. Validation separates direct evidence from adjacent needs and reports sparse evidence as insufficient, not as proof the idea is bad. Always pass 'niche' (and 'idea') in English — the channel taxonomy is English-only, so a non-English niche finds no channels; translate the user's niche to English and put the audience language in 'language' (e.g. niche="PC gaming", language="pl"). Omit language to search across all channel languages. Optionally set commentPublishedAfter (both modes) to analyze only comments posted on or after a date.

This runs asynchronously: it returns an `mcpJobId` immediately. Poll `vidiq_job_poll` with that id until it is completed. Failed or expired jobs, and analyses where no comments match the filters, are refunded automatically.

Cost: 5 credits per discover, validate, or new raw search. Raw cursor pages are free.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `idea` | string | No | Required only for validate mode. The specific video idea to test; it must add a proposition beyond the niche. Pass in English. |
| `mode` | string ("discover" | "validate" | "raw") | Yes | discover finds recurring audience requests and pain points; validate tests one supplied idea. |
| `sort` | string ("likes" | "newest" | "relevance") | No | Raw only. relevance (default): semantic similarity to the niche. likes: engagement-ranked, favors big creators' fan chatter. newest: most recent first. |
| `niche` | string | No | YouTube niche or topic used to select a semantic cohort of relevant active channels. ALWAYS pass this in English (the channel niche taxonomy is English-only, so a non-English niche selects no channels) — if the user names the niche in another language, translate it to the English equivalent (e.g. 'Gry komputerowe' -> 'PC gaming', 'cocina' -> 'cooking'). Put the audience language in the separate `language` field, not here. Do not pass a channel handle or URL. |
| `cursor` | string | No | Raw continuation: send ONLY mode=raw and cursor. Cursor pages are free. Expires after one hour. |
| `intents` | array | No |  |
| `language` | string | No | Optional two-letter language for the returned comment evidence (e.g. 'pl' for Polish comments). This is where the audience language goes — keep `niche` in English and set the language here. Omit to analyze all languages. In raw mode this filter is SCRIPT-LEVEL ONLY (it removes comments written in a different writing system, and romanized Hindi for 'en'); comments in other languages that share the script (e.g. English under 'de') can still appear, so re-check language yourself. |
| `minLikes` | integer | No |  |
| `pageSize` | integer | No |  |
| `includeReplies` | boolean | No |  |
| `maxThreadsPerChannel` | integer | No | Raw only. Maximum threads from one channel per page (default 5). Set 0 for no limit, e.g. to read one creator's audience in depth; without a limit a few large channels can fill whole pages. |
| `commentPublishedAfter` | string | No | Optional, both modes. Only analyze comments posted on or after this date (YYYY-MM-DD or ISO datetime). Filters by the COMMENT's publish date, not the video's, so recent comments on older videos still count. Use it to scope research to a recent window, e.g. since a platform or product change. Omit to analyze all indexed comments. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq compose

**Slug:** `VIDIQ_MCP_VIDIQ_COMPOSE`

Compose a short video from scenes (video clips and/or images), an optional
voiceover, background music, and overlays (text, image, or video), then render it
to an MP4.

Provide ordered `scenes` (each with an HTTPS `source` and `duration`) and an
output `format`. The video's length is the sum of the scene durations; audio
longer than that is cut off at the end, so size scenes to fit any voiceover.
Limits: at most 240s of total video, 50 scenes, and 50 overlays.

AUDIO: by default a video clip's native audio is muted and sound comes from
`voiceover`/`music`. To keep a clip's own audio (e.g. talking-head footage),
set `keepNativeAudio: true` on that scene. `music` can `duckTo` a lower volume
while the voiceover plays (with `fadeMs`) and `loop` to fill the video;
`voiceover` supports `startAtSeconds`/`trimStartSeconds`/`durationSeconds`/`volume`.

CLIPS: a video scene can trim-in with `startFromSeconds`, and any scene can set
`layout` to `"fit"` (scale to fit inside the frame, letterboxed) instead of the
default `"fill"` (scale + center-crop, edges lost).

ASSET URLS: use durable public HTTPS URLs, or freshly returned signed URLs from
vidIQ media tools. Signed voiceover, motion-graphic, and prior-render URLs expire;
use them immediately and never reconstruct stock-provider URLs or reuse old links.

OVERLAYS layer on top of the scene track for a time window (`start`/`duration`,
`position` normalized 0–1):
- `text` — captions/titles. Style knobs: fontSize, color, background,
  strokeWidth/strokeColor (outline), lineHeight, fontWeight, textAlign. If you
  omit sizing/contrast, a legibility floor bumps the font and adds an outline so
  text is never illegible — set `strokeWidth: 0` to opt out.
- `image` — a still (e.g. a logo/badge), with optional `opacity`.
- `video` — a video (e.g. a `vidiq_motion_graphics` clip) over the footage. The
  overlay is always muted. To narrate over your own clip while a motion graphic
  plays on top: use ONE clip scene with `keepNativeAudio: true` plus a `video`
  overlay — do NOT split the clip.

By default each scene is scaled and center-cropped to fill the output frame, so
sources whose aspect ratio differs from `format` lose their edges; set a scene's
`layout: "fit"` to scale it to fit inside the frame instead (letterboxed, no
cropping).

Rendering runs in the background and takes longer than one turn: this returns an
`mcpJobId` immediately — poll `vidiq_job_poll` with that id until it completes,
then read the signed `videoUrl` (plus `width`/`height`) from the result. Credits
are charged once on submit and automatically refunded if the render fails.

Pass the completed videoUrl directly to video editing, another composition, or Reel publishing. Poll again to refresh its signed URL while the rendered file exists. Rendered files are temporary: if deleted, keep the original upload URL (refresh it with its upload tool) and request approval to recompose. Never silently repeat a paid render. Composition re-encodes the video and audio; keepNativeAudio retains the intended audio track, not byte-identical media.

Cost: 1 credit(s) per 4s of output video (rounded up), minimum 2 credits.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `music` | object | No |  |
| `format` | string ("vertical" | "landscape" | "square") | Yes | Output aspect: vertical 9:16, landscape 16:9, or square 1:1. |
| `scenes` | array | Yes | Ordered scenes that make up the video. At least one is required; at most 50. Total duration across all scenes must not exceed 240 seconds. |
| `captions` | object | No | Caption style preset. (v1 selects a style only; caption text is not yet wired.) |
| `overlays` | array | No | Text overlays burned onto the video. At most 50. |
| `voiceover` | object | No | Voiceover audio, played from the start by default. The video's length is the sum of scene durations — audio longer than that is cut off at the end, so size scenes to fit it. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq connect youtube channel

**Slug:** `VIDIQ_MCP_VIDIQ_CONNECT_YOUTUBE_CHANNEL`

Connect a YouTube channel to the user's vidIQ account.

Call this tool when another vidIQ tool reports that no YouTube channel is connected, or when the user asks to connect a YouTube channel. Show the widget and wait for the user to use its controls. Connecting a first channel also establishes fresh YouTube authorization, so after the user completes the widget, retry the original request directly. When the account already has a channel, the widget may first ask the user to confirm it (status verification_required); after that, call this tool again to connect the new channel.

Cost: 0 credit(s) per call.

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `kind` | string | Yes |  |
| `status` | string ("connection_required" | "verification_required" | "already_connected") | Yes | connection_required: the user must connect a channel with the widget. verification_required: the user must first confirm an already connected channel with the widget, then call this tool again. already_connected: the account already has a channel; use vidiq_authorize_with_youtube instead. |

### Vidiq earnings calculate

**Slug:** `VIDIQ_MCP_VIDIQ_EARNINGS_CALCULATE`

Calculate estimated monthly YouTube earnings (low/mid/high USD) for a given number of monthly views.

This is a calculator, not a lookup: it does not fetch anything from YouTube, so you must supply the numbers. Use it for "how much would X views/month earn?", what-if scenarios, and niche/geo comparisons. To price a real, existing video by id or URL, use vidiq_video_earnings_estimate instead.

Set subject to 'video' for one video (then format 'long' or 'short' is required) or 'channel' for a channel's mixed output (then shortsShare is the fraction of views that are Shorts, default 0 = all long-form). Content format and the supplied context can significantly affect the estimate, so provide accurate inputs and ask the user when the format or mix is unknown.

Provide category, country, language, and subscriberCount when known. The result is an estimate, not the channel's actual revenue.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `format` | string ("long" | "short") | No | Video format. Required when subject is 'video'; must be omitted when subject is 'channel' (use shortsShare instead). Content format significantly affects the estimate |
| `country` | string | No | ISO-3166 alpha-2 country of the audience or channel |
| `subject` | string ("video" | "channel") | Yes | What the monthly views belong to: 'video' (a single video, so it is either long-form or a Short) or 'channel' (a mix, so pass shortsShare) |
| `category` | string ("Autos-&-Vehicles" | "Business" | "Education" | "Entertainment" | "Food" | "Gaming" | "Health" | "Lifestyle" | "Music" | "News-&-Politics" | "Pets-&-Animals" | "Religion" | "Sports" | "Technology" | "Travel") | Yes | Content category. Providing the accurate category improves the estimate |
| `language` | string | No | Content language. Use an ISO-639-1 code or a locale tag such as en-US |
| `shortsShare` | number | No | Channel only: fraction of monthly views that are Shorts (0.3 = 30%). Defaults to 0. Content mix significantly affects the estimate |
| `monthlyViews` | integer | Yes | Monthly views to price (the estimate returned is monthly) |
| `subscriberCount` | integer | No | Channel subscriber count, when known. Providing it improves the estimate |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `monthlyEstimate` | object | Yes |  |

### Vidiq edit media

**Slug:** `VIDIQ_MCP_VIDIQ_EDIT_MEDIA`

Edit a media file: trim a clip, extract its audio, grab a thumbnail frame,
normalize its loudness, or probe it for metadata (duration, dimensions, streams).

Set `op` and give a `sourceUrl` — a vidiq-generated media URL (an *.amazonaws.com
S3 URL, e.g. the output of vidiq_compose, vidiq_motion_graphics, vidiq_generate_music,
or a voiceover) or a YouTube URL. Other hosts (arbitrary CDNs, gs:// buckets) are not
supported. Import other MP4 URLs with vidiq_video_upload first and edit the returned videoUrl.

Per-op fields: trim_media needs `startSeconds`+`endSeconds`; extract_audio takes an
optional window + `outputFormat`/`bitrateKbps`/`sampleRateHz`/`channels`;
extract_thumbnail needs `atSeconds` (+ optional `width`/`height`/`outputFormat`);
normalize_loudness takes `targetLufs`/`outputFormat`/`bitrateKbps`; probe_media takes
nothing else.

Runs in the background and takes longer than one turn: this returns an `mcpJobId`
immediately — poll `vidiq_job_poll` with that id until it completes, then read the
signed `mediaUrl` (or, for probe_media, the metadata) from the result. Credits are
charged once on submit and automatically refunded if the edit fails.

Cost: 1 credit(s) per edit.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `op` | string ("extract_audio" | "trim_media" | "probe_media" | "extract_thumbnail" | "normalize_loudness") | Yes | The edit to perform: trim_media (cut a clip), extract_audio (pull an audio track), extract_thumbnail (grab a frame), normalize_loudness (level audio to a LUFS target), or probe_media (read duration/dimensions/streams — no output file). |
| `width` | integer | No | extract_thumbnail: output width. |
| `height` | integer | No | extract_thumbnail: output height. |
| `channels` | string | No | extract_audio: mono (1) or stereo (2). |
| `reencode` | boolean | No | trim_media: re-encode (default true) rather than stream-copy. |
| `atSeconds` | number | No | extract_thumbnail: the timestamp to grab, in seconds. |
| `sourceUrl` | string | Yes | HTTPS URL of the input media: a vidiq-generated file (an *.amazonaws.com S3 URL, e.g. from vidiq_compose, vidiq_motion_graphics, vidiq_generate_music/voiceover) or a YouTube URL. |
| `endSeconds` | number | No | Window end in seconds (must be > startSeconds). Required for trim_media. |
| `targetLufs` | number | No | normalize_loudness: integrated loudness target (default -16). |
| `bitrateKbps` | integer | No | Audio bitrate for extract_audio / normalize_loudness (32–320). |
| `outputFormat` | string | No | Output format; the valid set depends on op — extract_audio: mp3/wav/flac/aac/ogg; trim_media: mp4/mkv/mov/webm; extract_thumbnail: jpg/png/webp; normalize_loudness: mp3/wav/aac. |
| `sampleRateHz` | string | No | extract_audio: output sample rate. |
| `startSeconds` | number | No | Window start in seconds. Required for trim_media; optional for extract_audio. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq generate broll

**Slug:** `VIDIQ_MCP_VIDIQ_GENERATE_BROLL`

Find free stock B-roll video clips.

Provide a search query (optionally orientation and min/max duration filters).
Returns up to 4 clips with a direct mp4 link, a preview image, dimensions, and the
photographer credit. Attribution is required: always credit the photographer and
link back to the source page when using a clip.

Cost: 1 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `query` | string | Yes | Search term for the stock B-roll footage, e.g. 'city skyline at night'. |
| `orientation` | string ("landscape" | "portrait" | "square") | No | Optional orientation filter. Use 'portrait' for Shorts/Reels, 'landscape' otherwise. |
| `maxDurationSeconds` | integer | No | Optional maximum clip duration in seconds. |
| `minDurationSeconds` | integer | No | Optional minimum clip duration in seconds. |

### Vidiq generate clips

**Slug:** `VIDIQ_MCP_VIDIQ_GENERATE_CLIPS`

Turn a long video into short, vertical clips.

Provide either a YouTube link (videoUrl) or an already-hosted file (uploadedVideoUrl + videoDuration + videoFilename). Optionally steer selection with a prompt, set clipDuration, restrict the source to a section with processingStartSeconds/processingEndSeconds (both required together, span >= 30s), and pick a captionStyle preset (or "none" to turn captions off). Captions use the "Loud & Clear" style by default.
This runs asynchronously: it returns an `mcpJobId` immediately — poll `vidiq_job_poll` with that id until it is "completed" to get the clips. If generation fails, that poll refunds the credits.

Credits are charged per minute of the selected processing range when present, otherwise the full source video duration. Credits are automatically refunded if generation fails.

Cost: 9 credit(s) per minute of the selected processing range when present, otherwise the full source video duration (rounded up).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `imgUrl` | string | No | Optional. Image URL to use as an overlay/branding asset on the clips. |
| `prompt` | string | No | Optional. What to focus on when picking moments, e.g. 'funniest parts'. |
| `videoUrl` | string | No | YouTube video URL to clip. Provide this OR uploadedVideoUrl, not both. Duration is fetched automatically. |
| `captionStyle` | string ("Classic Style" | "Loud & Clear" | "Talk Show" | "Creator Cut" | "Hype Mode" | "Vlog Pop" | "Clean Fade" | "Snap Reaction" | "Soft Focus" | "Urban Voice" | "Renaissance" | "Chic Cut" | "Headline Heat" | "Comic Charge" | "Pop Blast" | "Deep Thought" | "Midnight Read" | "Grand Statement" | "none") | No | Caption style for the burned-in subtitles. Pick a named preset or "none" to disable captions. Defaults to "Loud & Clear" when omitted. |
| `clipDuration` | integer | No | Optional. Target length of each clip in seconds (0–120). |
| `videoDuration` | number | No | Source video length in seconds. Required when using uploadedVideoUrl. |
| `videoFilename` | string | No | Original filename of the uploaded video. Required when using uploadedVideoUrl. |
| `videoLanguage` | string | No | Optional. Language code of the spoken audio, used for captions/transcription. |
| `uploadedVideoUrl` | string | No | URL of an already-hosted video file (http/https/gs) to clip. Requires videoDuration and videoFilename. |
| `processingEndSeconds` | number | No | Optional. Only consider the source video up to this timestamp (seconds). Must be greater than processingStartSeconds and span at least 30s. |
| `processingStartSeconds` | number | No | Optional. Only consider the source video from this timestamp (seconds). Must be paired with processingEndSeconds. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq generate comment replies

**Slug:** `VIDIQ_MCP_VIDIQ_GENERATE_COMMENT_REPLIES`

Generate multiple draft replies to one viewer comment on a YouTube video, with one reply per requested tone. Use this when the user wants response ideas for a specific comment. To retrieve comments first, use `vidiq_video_comments`.

Provide the video's title and the exact viewer comment. Optionally provide 3–10 tone labels; otherwise the defaults are General, Humorous, Thankful, Witty, and Informal.

This tool returns draft text only. It never posts or otherwise changes anything on YouTube.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `title` | string | Yes | Title of the YouTube video that received the viewer comment. |
| `tones` | array | No | Three to ten tone labels for the reply options. Defaults to General, Humorous, Thankful, Witty, and Informal. |
| `comment` | string | Yes | Viewer comment to draft replies for. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `title` | string | Yes | Video title used to generate the replies. |
| `comment` | string | Yes | Viewer comment the replies address. |
| `replies` | array | Yes | Generated reply options, one per requested tone. |

### Vidiq generate music

**Slug:** `VIDIQ_MCP_VIDIQ_GENERATE_MUSIC`

Generate ONE original, royalty-free background-music track (WAV) from a text prompt.

Describe the music in the prompt (max 2000 characters): genre + mood +
instrumentation + tempo works best; add 'instrumental' to exclude vocals. Optionally set
durationSeconds (10-180, approximate).

This runs asynchronously: it returns an `mcpJobId` immediately — poll `vidiq_job_poll`
with that id until it is "completed" to get the actual audio duration and a permanent
download URL for the WAV. Rendering can take a couple of minutes for longer tracks.

Credits are charged on submit and automatically refunded if generation fails. If the
provider's safety filter blocks the prompt (this routinely happens to ordinary prompts),
the poll reports it with guidance to rephrase — suggest ONE rephrased prompt to the user
and wait for their agreement before calling again.

Cost: 25 credit(s) per generated track.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `prompt` | string | Yes | What the music should sound like. Best results follow: [genre/style] + [mood] + [instrumentation] + [tempo/rhythm] + [vocal style & language] + [lyrics]. Add the word 'instrumental' to exclude vocals. Do NOT use negative phrasing (e.g. 'no drums') — it is not supported; describe what you want instead. |
| `durationSeconds` | integer | No | Desired track length in seconds (10-180, default 30). Approximate — the model treats it as a hint; read the returned durationSeconds for the actual length. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq generate script

**Slug:** `VIDIQ_MCP_VIDIQ_GENERATE_SCRIPT`

Write a full long-form video script from a topic, title, concept, and research.

Provide the topic, the chosen title, the concept/angle, and research/context to ground it in; optionally set lengthMinutes (1–60, default 10) and a tone.
This runs asynchronously: it returns an `mcpJobId` immediately — poll `vidiq_job_poll` with that id until it is "completed" to get the finished script. If generation fails, that poll refunds the credits.

Credits are charged per minute of script on submit and automatically refunded if generation fails.

Cost: 1 credit(s) per minute of script (by lengthMinutes).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `tone` | string | No | Optional. Desired tone, e.g. 'engaging', 'educational'. Defaults to 'engaging'. |
| `title` | string | Yes | The chosen video title for the script. |
| `topic` | string | Yes | The video topic the script is about (a refined/clarified topic works best). |
| `concept` | string | Yes | The concept/angle for the video — what it covers and how it is framed. |
| `research` | string | Yes | Research/context to ground the script in (facts, sources, talking points). |
| `lengthMinutes` | integer | No | Target spoken length of the script in minutes (1–60). Defaults to 10. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq generate thumbnail

**Slug:** `VIDIQ_MCP_VIDIQ_GENERATE_THUMBNAIL`

Generate a YouTube thumbnail.

Provide at least one of videoId, title, description, or userQuery. With only a videoId, the video's current
title, description, and thumbnail are pulled in automatically.

This runs asynchronously: it returns an `mcpJobId` immediately. Poll `vidiq_job_poll` with that id until
it is "completed" to get the thumbnail (shown inline) with its imageUrl, a self-score, and short feedback.
Credits are charged on submit and automatically refunded if generation fails.

Include the imageUrl in your reply so the user can open or save the file. The inline preview isn't downloadable.

Treat the score as a rough estimate rather than a verdict: don't lead with it, and don't regenerate just to
raise it. To iterate, change one thing at a time and keep the best result. For a reliable critique, use
vidiq_score_thumbnail.

Cost: 22 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `title` | string | No | Video title used for grounding. When omitted but videoId is provided, fetched from yt-proxy. Caller-supplied value wins. |
| `videoId` | string | No | YouTube video ID (e.g. 'dQw4w9WgXcQ'). When provided, title, description, and currentThumbnail are auto-filled from YouTube unless the caller supplies them explicitly. Optional when at least one of title, description, or userQuery is given. |
| `feedback` | object | No | Optional scorer feedback from a prior thumbnail (typically the output of vidiq_score_thumbnail). When provided alongside referenceImages, triggers the feedback-iteration flow. |
| `userQuery` | string | No | Natural-language creative direction (e.g. 'show the host pointing at a glowing dollar sign'). Highest-priority generation signal upstream. |
| `transcript` | string | No | Optional transcript text. Used for subject detection in Quick Generate and as context in Pro Generate. Pair with vidiq_video_transcript when available. |
| `description` | string | No | Video description used for grounding. When omitted but videoId is provided, fetched from yt-proxy. Caller-supplied value wins. |
| `orientation` | string ("landscape" | "portrait") | No | Thumbnail orientation. 'landscape' is the standard 16:9 YouTube thumbnail (default when omitted); 'portrait' is a 9:16 Shorts thumbnail. |
| `subjectImage` | string | No | A subject/person image, a hosted image URL or an uploaded image. Highest-priority likeness reference for the main face in the thumbnail. |
| `referenceImages` | array | No | Reference thumbnails to emulate style/composition, hosted image URLs or uploaded images. Presence of this field switches the request out of Quick Generate into the Pro / Improve flow upstream. Capped at 10 entries; duplicates removed. |
| `currentThumbnail` | string | No | An existing/current thumbnail to reference for composition, a hosted image URL or an uploaded image. When omitted but videoId is provided, auto-filled with the best available resolution of the video's YouTube thumbnail. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq generate titles

**Slug:** `VIDIQ_MCP_VIDIQ_GENERATE_TITLES`

Generate scored YouTube title suggestions.

Provide at least one of `videoId`, `title`, or `description`. With
only `videoId`, the current title/description are fetched from YouTube.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `type` | string ("long" | "short") | No | Video format hint. Affects the generation prompt and scoring rubric. When omitted, upstream infers from duration and otherwise treats the video as long-form. |
| `title` | string | No | Current/working video title. When omitted but videoId is provided, fetched from yt-proxy. Caller-supplied value takes precedence. |
| `videoId` | string | No | YouTube video ID (e.g. 'dQw4w9WgXcQ'). When provided, the tool fetches the current title/description from yt-proxy to ground generation. Optional when title and/or description are supplied directly. |
| `language` | string | No | Target language for generated titles and the analysis pass (e.g. 'en', 'pt-BR'). Defaults to English when omitted. |
| `numTitles` | integer | No | How many title candidates to generate (default: 3) |
| `regionCode` | string | No | 2-letter ISO country code (e.g. 'US', 'BR'). Normalized to uppercase. Used by upstream when fetching competitive context. |
| `description` | string | No | Current video description. When omitted but videoId is provided, fetched from yt-proxy. Caller-supplied value takes precedence. |
| `previousTitles` | array | No | Recent titles from the same channel. Used by upstream to reduce repetition and improve novelty. Capped at 20 entries x 200 chars; duplicates removed. |
| `scoreThreshold` | integer | No | Return only suggestions with score >= threshold. Thresholds above 70 on long-form videos may legitimately yield no results, and the filter applies before the numTitles top-K slice (so the response may contain fewer items than numTitles). |
| `analysisSummary` | string | No | Pre-computed analysis summary. When provided, upstream skips its own analysis pass (transcript/frames → Gemini) and uses this directly. Useful when chaining after a tool that already produced video understanding. Capped at 4000 chars. |
| `competitorTitles` | array | No | Seed titles for the competitive context block. When provided, upstream skips its Outliers lookup and uses these directly — useful for deterministic output or when the caller already has a curated competitor set. Capped at 20 entries x 200 chars; duplicates removed. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `titles` | array | Yes |  |
| `videoId` | string | No |  |

### Vidiq generate video

**Slug:** `VIDIQ_MCP_VIDIQ_GENERATE_VIDEO`

Generate a short video from a text prompt. Or edit an MP4 using videoUrls from an upload, generation, or composition. The actual video is used without substitute frames. Select gemini-omni-flash or minimax-h3 explicitly for this mode, without start/end frames. H3 also accepts image ingredients; Omni does not.

Pick a model (default veo-3.1-fast), resolution and duration valid for that model, then describe the video in prompt. Optionally steer with an aspectRatio, seed image-to-video with startFrameB64/endFrameB64, or provide reference images via ingredients. startFrameB64/endFrameB64 and ingredients are mutually exclusive — use at most one.
Ingredients (reference images) are supported on minimax-h3 and seedance-2 / seedance-2-fast (up to 9), veo-3.1 / veo-3.1-fast (up to 3, duration must be 8), and gemini-omni-flash (up to 3); other models reject them. Per-model durations/resolutions are validated by the server, which returns a specific error you can use to retry.
This runs asynchronously: it returns an `mcpJobId` immediately — poll `vidiq_job_poll` with that id until it is "completed" to get the video URL. If generation fails, that poll refunds the credits.
For `content_policy_rejected`, `invalid_duration`, or `invalid_input`, change the rejected prompt or inputs before starting another generation; never retry the same request unchanged.

For video references, use a reachable MP4 URL. Refresh expired links with the producing tool; if a temporary compose output was deleted, request approval to recompose from the retained original. Never silently regenerate paid media. Credits are charged on submit and automatically refunded if generation fails.

Cost: scales with duration (seconds) × the model's per-second rate × 20 credits, quoted exactly at submit.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `model` | string ("minimax-h3" | "veo-3.1" | "veo-3.1-fast" | "veo-3.1-lite" | "kling-3" | "kling-3-pro" | "seedance-2" | "seedance-2-fast" | "gemini-omni-flash") | No | Generation model. Prefer minimax-h3 for compatible requests; use another model only when the requested duration, resolution, or capabilities require it. minimax-h3 → 768p/2k, 4–15s; seedance-2 → 720p/1080p, 1–15s; seedance-2-fast → 720p, 1–15s; veo-3.1 / veo-3.1-fast → 720p/1080p, 4/6/8s; gemini-omni-flash → 720p, any 3–10s (budget, audio included). |
| `prompt` | string | Yes | What the video should depict (1–4000 chars). |
| `duration` | integer | Yes | Clip length in seconds. Must be valid for the model — e.g. veo-3.1 → 4/6/8, minimax-h3 → any 4–15, seedance-2 and seedance-2-fast → any 1–15. |
| `videoUrls` | array | No | Ordered public HTTPS video URLs from upload, generation, or compose. Omni accepts one clip; source duration rounded to 0.1s must equal the requested integer 3–10 seconds. H3 accepts up to 3 clips, each 2–15 seconds and at most 50 MiB, totaling at most 15 seconds; output duration is independent. H3 may also use image ingredients. No start/end frames; Omni cannot combine video with ingredients. |
| `resolution` | string ("720p" | "768p" | "1080p" | "1024p" | "2k") | Yes | Output resolution. Must be valid for the chosen model — e.g. minimax-h3 → 768p or 2k; seedance-2 and veo-3.1 → 720p or 1080p (seedance-2-fast → 720p only). |
| `aspectRatio` | string ("9:16" | "16:9") | No | Optional. Frame aspect ratio; defaults per-model when omitted. |
| `endFrameB64` | string | No | Optional. Base64 last frame (JPEG/PNG/WebP, ≤10MB). |
| `ingredients` | array | No | Optional. Reference images (base64 or data-URI, ≤10MB each) to steer the result. Mutually exclusive with startFrameB64/endFrameB64. Per-model caps: minimax-h3 and seedance-2 / seedance-2-fast → up to 9 (JPEG/PNG/WebP); veo-3.1 / veo-3.1-fast → up to 3 (JPEG/PNG only, duration must be 8); gemini-omni-flash → up to 3; other models do not support ingredients. |
| `startFrameB64` | string | No | Optional. Base64 first frame for image-to-video (JPEG/PNG/WebP, ≤10MB). A data: prefix is stripped server-side. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq generate video chapters

**Slug:** `VIDIQ_MCP_VIDIQ_GENERATE_VIDEO_CHAPTERS`

Start precise YouTube chapter generation from a video's timestamped captions.

Use this when the user wants chapter timestamps, a video outline with exact boundaries, or a chapter block for a YouTube description. The work runs asynchronously: this tool returns a job handle, and `vidiq_job_poll` returns three title alternatives per completed chapter. It requires an accessible transcript and does not update the YouTube video.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videoId` | string | Yes | YouTube video ID or URL (watch, youtu.be, Shorts, embed, or live URL). The video must have an accessible transcript. |
| `language` | string | No | Preferred transcript and chapter-title language, such as en or pt-BR. |
| `chapterCount` | integer | No | Requested chapter count from 4 to 12. Omit to choose automatically from the video duration, normally 4 to 7 chapters. |
| `startBufferSeconds` | integer | No | Seconds to move each non-initial chapter earlier so transitions do not feel clipped. Defaults to 2; use 0 for exact caption boundaries. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq get channels by ids

**Slug:** `VIDIQ_MCP_VIDIQ_GET_CHANNELS_BY_IDS`

Get detailed information about YouTube channels by their IDs.

Use this tool to:
- Look up channel metadata (title, description, country) for one or more channels
- Get subscriber counts, view counts, and video counts
- Retrieve channel tags and topic categories
- Check channel thumbnails

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `channelIds` | array | Yes | List of YouTube channel IDs to look up |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `channels` | array | Yes |  |

### Vidiq get videos by ids

**Slug:** `VIDIQ_MCP_VIDIQ_GET_VIDEOS_BY_IDS`

Get detailed metadata for one or more YouTube videos.

Use this tool to:
- Fetch video details such as title, description, tags, and category
- Get current statistics (views, likes, comments) for specific videos
- Look up publishing info, channel details, and thumbnails for videos
- Check topic categories for videos

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videoIds` | array | Yes | One to 50 YouTube video IDs or URLs |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videos` | array | Yes |  |

### Vidiq ig accounts from outliers

**Slug:** `VIDIQ_MCP_VIDIQ_IG_ACCOUNTS_FROM_OUTLIERS`

Find Instagram creator/account candidates from existing outlier reel discovery.

Use this when the user asks for Instagram accounts, creators, competitors, influencers, partners, or examples to study. The service groups outlier reels into accounts and verifies candidates against profile and recent content.

How to call:
- `niche`: one-line content/account niche. Keep it about the creator's content, not audience demographics.
- `audienceQuery`: required audience context in this format: `Culture/Region: ...; Global: <true|false>; Demographics: ...;`
  Derive it from the user's stated target audience or profile/recent reels, not from handle alone. If audience is vague, ask before searching.
- Use optional `followersMin` / `followersMax` when account size matters.

Cost: 10 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `niche` | string | Yes | One-line description of the Instagram reel/content niche to search for. |
| `followersMax` | integer | No |  |
| `followersMin` | integer | No |  |
| `audienceQuery` | string | Yes | Format: Culture/Region: ...; Global: <true&#124;false>; Demographics: ...; |

### Vidiq ig profile

**Slug:** `VIDIQ_MCP_VIDIQ_IG_PROFILE`

Fetch public Instagram profile by handle: bio, follower/following counts, post count, verification, external URL, with the profile picture returned inline.

DO NOT USE FOR:
- Profile search/discovery — you must already have a handle.
- Reels — use `vidiq_ig_profile_reels` (up to 6, popularity-sorted, no pagination).
- Stories, Highlights, IGTV, private-account data.
- Engagement-rate or growth analytics — snapshot only.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `handle` | string | Yes | Instagram handle (with or without leading @). 1-30 chars; letters/digits/dot/underscore. |

### Vidiq ig profile reels

**Slug:** `VIDIQ_MCP_VIDIQ_IG_PROFILE_REELS`

Fetch a creator's reels by handle: shortcode, caption, play/like/comment counts, duration, timestamp, pinned-profile status, with each reel's cover returned inline as an image. Returns up to 12 reels from the first Instagram Reels-tab page in Instagram's order: pinned reels first, then the remaining reels newest-first. Form a full Instagram reel URL from a returned shortcode before passing that short-form content URL to `vidiq_watch_shortform_content`.

DO NOT USE FOR:
- More than 12 reels, or pagination — not supported.
- Strict newest-first ordering across the whole response — older pinned reels may appear before newer unpinned reels.
- Image posts, carousels, Stories.
- Account, creator, influencer, or competitor-account discovery - use `vidiq_ig_accounts_from_outliers`.
- Cross-platform outlier examples or topic search - use `vidiq_instagram_tiktok_outlier_search` (cannot filter by handle).
- Watching or critiquing short-form content — use `vidiq_watch_shortform_content` with a full Instagram reel URL.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `handle` | string | Yes | Instagram handle (with or without leading @). 1-30 chars; letters/digits/dot/underscore. |

### Vidiq instagram connected accounts

**Slug:** `VIDIQ_MCP_VIDIQ_INSTAGRAM_CONNECTED_ACCOUNTS`

List the signed-in user's Instagram accounts already connected to vidIQ. Use this first when the user says "my Instagram", "my account", or otherwise asks about their own Instagram data.

Each account says whether private owner insights and Reel publishing are available. Publishing permission is independent of insights permission. If publishingAvailable is false, connect or reauthorize Instagram at https://app.vidiq.com using the existing account connection flow and refresh this list. For `accessLevel: "owner"`, call `vidiq_instagram_owner_insights` with that exact `platformAccountId`. For `accessLevel: "public_fallback"`, private insights are unavailable; if `username` is present, `vidiq_ig_profile_reels` may be used for public Reel data, and the response must be described as public rather than owner insights.

Do not use this tool to search arbitrary Instagram handles or to connect, refresh, or repair Instagram OAuth.

Cost: 0 credit(s) per call.

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `accounts` | array | Yes |  |

### Vidiq instagram owner insights

**Slug:** `VIDIQ_MCP_VIDIQ_INSTAGRAM_OWNER_INSIGHTS`

Fetch private Instagram owner insights for an OAuth-backed account already connected to the signed-in vidIQ user. Always obtain `platformAccountId` from `vidiq_instagram_connected_accounts`; do not pass a handle or an account belonging to another user.

The Reel fields align with `vidiq_ig_profile_reels` where they mean the same thing, while owner-only metrics add shares, saves, watch time, watched percentage, skip rate, and `isPossibleTrial`. Instagram may delay owner metrics, so nullable values mean unavailable—not zero. `videoUrl` and `isPinned` are null because the owner-insights source does not provide those public fields.

If this returns `status: "unavailable"` and the connected-account result supplied a username, public Reel data may be fetched separately with `vidiq_ig_profile_reels`. Clearly disclose that fallback as public data. Do not claim public metrics are owner insights.

Cost: 0 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `recentMediaLimit` | integer | No |  |
| `platformAccountId` | string | Yes | Exact platformAccountId returned by vidiq_instagram_connected_accounts; never a username. |
| `recentMediaCursor` | string | No |  |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `reels` | array | Yes |  |
| `handle` | string | Yes |  |
| `method` | string | Yes |  |
| `reason` | string ("owner_account_not_found" | "owner_account_not_oauth_backed" | "owner_insights_scope_missing" | "owner_basic_scope_missing" | "owner_token_inactive" | "owner_account_ineligible" | "owner_insights_not_ready") | No |  |
| `status` | string ("available" | "unavailable") | Yes |  |
| `window` | object | No |  |
| `message` | string | No |  |
| `summary` | object | No |  |
| `dataSource` | string | Yes |  |
| `accessLevel` | string | Yes |  |
| `isTruncated` | boolean | Yes |  |
| `followersCount` | string | No |  |
| `completionReason` | string ("source_exhausted" | "result_limit") | No |  |
| `platformAccountId` | string | Yes |  |
| `recentMediaNextCursor` | string | No |  |

### Vidiq instagram publish reel

**Slug:** `VIDIQ_MCP_VIDIQ_INSTAGRAM_PUBLISH_REEL`

Publish an approved hosted MP4 using this same tool across short calls. First obtain approval for the exact video, account, caption and regular or Trial settings. Select a connected account with publishingAvailable=true. Start with videoUrl (use vidiq_video_upload for attachments); retain the returned containerId and platformAccountId. Continue with containerId and the same account, omitting videoUrl/caption/trialParams. The backend checks readiness and publishes when ready. IN_PROGRESS means wait about five seconds and call again. PUBLISHED confirms success; show permalink when available. Stop on any error; do not automatically retry failed calls or create a replacement. Continue processing checks for up to five minutes. The caller retains progress; closing the conversation pauses continuation. No YouTube channel or MFA is required. Continuation calls are free.

Cost: 0 credit(s) to start; continuation calls are free.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `caption` | string | No | Exact caption including hashtags, only when starting with videoUrl; omit for no caption. |
| `videoUrl` | string | No | Chosen hosted MP4 URL to start preparation. Provide exactly one of videoUrl or containerId. |
| `containerId` | string | No | Meta ID returned by this tool. Continue the same container; do not create a replacement. |
| `trialParams` | object | No | Only when starting: omit for a regular Reel, or explicitly choose MANUAL or SS_PERFORMANCE for a Trial Reel. |
| `platformAccountId` | string | Yes | Selected connected Instagram account; retain the same account for continuation calls. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string ("IN_PROGRESS" | "PUBLISHED") | Yes |  |
| `mediaId` | string | No |  |
| `permalink` | string | No |  |
| `shortcode` | string | No |  |
| `containerId` | string | Yes |  |
| `failureMessage` | string | No |  |
| `platformAccountId` | string | Yes |  |

### Vidiq instagram tiktok outlier search

**Slug:** `VIDIQ_MCP_VIDIQ_INSTAGRAM_TIKTOK_OUTLIER_SEARCH`

Search Instagram Reels and TikTok videos together for posts that substantially outperform each creator's median. Results are returned in separate Instagram and TikTok sections because relevance scores are not comparable across platforms.

Use `concept` for a complete content premise, `hook` for the first three seconds, or `format` for a subject-free production template. `audienceQuery` is a separate top-level audience rescore and must use: `Culture/Region: ...; Global: <true|false>; Demographics: ...;`.

Defaults to the last 30 days, English captions, at least 10K views, one result per creator within each platform, and 5 results per platform. `resultsPerPlatform` controls each section independently. Use at least two outliers from a platform before calling something a pattern. Use `vidiq_ig_accounts_from_outliers` instead for Instagram account discovery.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `query` | string | Yes |  |
| `viewsMax` | integer | No |  |
| `viewsMin` | integer | No |  |
| `durationMax` | number | No |  |
| `durationMin` | number | No |  |
| `followersMax` | integer | No |  |
| `followersMin` | integer | No |  |
| `audienceQuery` | string | Yes | Required audience-rescore context as one string using `Culture/Region: ...; Global: <true&#124;false>; Demographics: ...;`. Example: `Culture/Region: UK/British; Global: false; Demographics: working professional men 25-45, fat loss, busy lifestyle;` |
| `embeddingType` | string ("concept" | "hook" | "format") | No |  |
| `datePostedAfter` | string | No |  |
| `outlierScoreMax` | number | No |  |
| `outlierScoreMin` | number | No |  |
| `datePostedBefore` | string | No |  |
| `collapseByCreator` | boolean | No |  |
| `excludeContentIds` | array | No | Instagram reel shortcodes or TikTok video IDs to exclude. |
| `resultsPerPlatform` | integer | No | Number of results to return from each platform. |
| `descriptionLanguage` | array | No |  |
| `excludeCreatorHandles` | array | No | Creator handles to exclude from both platform searches, matched independently and without the leading @. Example: ["creator_one", "creator.two"]. |

### Vidiq job poll

**Slug:** `VIDIQ_MCP_VIDIQ_JOB_POLL`

Check the status of an asynchronous vidIQ job and retrieve its result.

Pass the `mcpJobId` returned by a `*_start` tool. Poll periodically until
`status` is no longer 'inprogress':
- 'completed' → the work is done; read `result`.
- 'failed'/'expired' → it did not finish; inspect `refunded` to confirm the credit rollback.
  When present, `errorCode` is the stable downstream failure reason.
For completed media jobs, repeat polling may return a freshly signed URL while
keeping the same result shape.

This tool is free.

Cost: 0 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `mcpJobId` | string | Yes | The job id returned by an asynchronous tool (e.g. `vidiq_generate_script`). |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `result` | string | Yes | The tool-specific result when status='completed'; null otherwise. |
| `status` | string ("inprogress" | "completed" | "failed" | "expired" | "refunded") | Yes | inprogress = still running; completed = done, see `result`; failed = downstream failed; expired = no result within the time limit; refunded = a failed/expired charge was returned. For failed/expired jobs, inspect `refunded` because a transient rollback failure may still be retrying. |
| `message` | string | Yes | Human-readable status note (e.g. why it failed). Null when not applicable. |
| `mcpJobId` | string | Yes |  |
| `refunded` | boolean | Yes | Whether credits were refunded. False for successful/in-progress jobs and while a failed/expired job's rollback is still retrying. |
| `toolName` | string | Yes | The tool that created this job. |
| `errorCode` | string | No | Stable machine-readable downstream failure code when available. Omitted for non-failures and failures without a stable code. |

### Vidiq jobs list

**Slug:** `VIDIQ_MCP_VIDIQ_JOBS_LIST`

List your asynchronous vidIQ jobs, newest first.

Filter by `toolName` and/or `status`. To find jobs that are still running,
filter `status: 'inprogress'`. Use the returned `mcpJobId` with
`vidiq_job_poll` to check a job's result.

This tool is free.

Cost: 0 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `limit` | integer | No | Max jobs to return (1-50, default 20). Newest first. |
| `status` | string ("inprogress" | "completed" | "failed" | "expired" | "refunded") | No | Filter by status. Omit for all. You usually want 'inprogress' to find jobs still running. |
| `toolName` | string | No | Filter to jobs created by this tool (e.g. 'vidiq_generate_script'). |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `jobs` | array | Yes |  |

### Vidiq keyword research

**Slug:** `VIDIQ_MCP_VIDIQ_KEYWORD_RESEARCH`

Research YouTube keywords to find search volume, competition, and related keyword opportunities. This tool returns keyword metrics, NOT videos. To find actual videos, use vidiq_outliers or vidiq_trending_videos instead.

This tool has six modes. Choose with the `mode` parameter based on what the user is asking for:

1. `research` (default): full keyword metrics for a seed keyword plus related keyword suggestions. Use for global/topic research ("research minecraft tips", "keyword ideas for cooking"). Returns for each keyword:
   - Volume (0-100): How often people search for this keyword on YouTube
   - Competition (0-100): How many videos target this keyword
   - Overall score (0-100): Combined keyword opportunity score
   - Estimated monthly search volume, plus calibrated-baseline demand context when available
   - View momentum: recent daily views-per-hour data for the seed keyword, when available
   - Top markets: the countries where the keyword is most searched, with each country's share of searches
   - In-country volume: optionally pass a `country` (ISO 3166-1 alpha-2) to also get each keyword's estimated search volume within that country (the `countryVolume` field)
   Related keyword rows preserve the upstream relevance order and are capped at 20 suggestions.

2. `questions`: question-style keyword searches matching a seed keyword, using the same indexed results and metrics as the vidIQ webapp. Requires `keyword`; use `language` to select the question-language index and `limit` to cap results. Set `sort='volume'` (default) for established demand or `sort='trending'` to preserve upstream raw-growth order. Treat `searchDemandGrowthPct` as a separate measured current-vs-baseline metric, not the server sort key; do not explain rows with null measured growth as sorted last by this tool. Results come back in `questions` with question, volume, competition, overall score, estimated monthly searches, normalized demand context, and raw upstream growth.

3. `matching_terms`: precise long-tail keyword variations that preserve every normalized seed term, using the same Matching Terms path as the vidIQ webapp. Requires `keyword`; use `limit` to cap results. Set `sort='volume'` (default) for established demand or `sort='trending'` to preserve upstream raw-growth order. Treat `searchDemandGrowthPct` as a separate measured current-vs-baseline metric, not the server sort key; do not explain rows with null measured growth as sorted last by this tool. Results come back in `matchingTerms` with keyword, volume, competition, overall score, estimated monthly searches, calibrated 30-day baseline, metrics timestamp, normalized demand context, raw upstream growth, and trend baseline. Use this when the user asks for exact/long-tail variations of a phrase (e.g. "matching terms for meal prep" or "long-tail variations of meal prep"), not broad semantic ideas.

4. `country_search`: the top keywords matching a TOPIC within ONE country and capped at `limit`. Use when the user names BOTH a topic AND a country — e.g. "give me the top 10 minecraft keywords in IN" → mode='country_search', keyword='minecraft', country='IN', limit=10. Requires `country` and `keyword`. Results come back in `relatedKeywords` (each row's `countryVolume` is the in-country volume; global YouTube metrics are null).
   - By default (`broad: false`) this is an EXACT/PHRASE match — every returned keyword literally contains the topic words (e.g. 'minecraft' → 'minecraft mods', 'minecraft house').
   - Set `broad: true` for a SEMANTIC match: the topic is first expanded into related keywords (the engine behind vidIQ's "Related Keywords" tab). Long-tail candidates preserving multiple meaningful seed terms rank before semantic-only candidates; within each tier, upstream related score then in-country volume determine order. The overlap boost is a lightweight heuristic: simple ASCII suffix matching applies only to ASCII Latin tokens, while other scripts require exact normalized token overlap. Country keyword text may be in any language; the `language` field only affects `questions` and `rising`. Returned keywords need NOT contain the topic words (e.g. 'minecraft' → 'redstone', 'survival mode'). Use this when the user wants a bigger/wider list, says "related"/"similar"/"broaden", or the exact-match list is too small.

5. `country_top`: the top keywords overall within ONE country (NO topic filter), ranked by in-country search volume and capped at `limit`. Use when the user names a country but no topic, e.g. "what are the top keywords in Brazil" → mode='country_top', country='BR'. Requires `country`; `keyword` is ignored. Results come back in `relatedKeywords` as above.

6. `rising`: keywords gaining search momentum over time, like the vidIQ dashboard's "Rising Keywords" tab. Use when the user asks for rising, trending, or gaining-momentum keywords. Choose the trend window with `period`. Optionally scope to a category with `topic`, using a value from the response's `availableTopics` (call 'rising' with no `topic` first to discover them). Topics are specific (e.g. 'roblox', 'minecraft', 'indie games', 'pop music', 'anime', 'cars', 'psychology', 'ai'), not broad labels like 'gaming' or 'business'. An unknown topic does not fail: the call returns overall trends plus `suggestedTopics` (the closest valid topics) and a `notes` entry explaining the fallback. Omit `topic` for overall trends, in which case `availableTopics` lists every category you can drill into. Rising trends are global (`country` is ignored) and support languages all, en, ru, es, pt (anything else falls back to all); any such adjustment is reported in `notes`. This returns keyword METRICS with growth, not videos. Results come back in `risingKeywords`, not `relatedKeywords`.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `mode` | string ("research" | "questions" | "matching_terms" | "country_top" | "country_search" | "rising") | No | Which kind of keyword research to run. Pick based on the user's question: - 'research' (default): full metrics for a seed keyword plus recent daily views-per-hour momentum and related keyword suggestions. Demand context distinguishes unknown, below-threshold (<750), and measurable monthly searches, with baseline, normalized growth, freshness, and webapp-aligned volume bands when upstream data exists. Optionally pass `country` to enrich every row with in-country search volume. - 'questions': indexed question-style searches matching a seed keyword, with the same normalized demand context plus volume, competition, and opportunity. Use `sort: 'volume'` for established demand or `sort: 'trending'` to preserve upstream raw-growth order. Treat `searchDemandGrowthPct` as a separate measured current-vs-baseline metric, not the server sort key; do not say null measured-growth rows were sorted last unless the upstream response itself proves that ordering. Requires `keyword`; `language` controls the question-language index. - 'matching_terms': precise long-tail keyword variations that preserve every normalized seed term, with the same normalized demand context plus the raw upstream growth/trend-baseline fields for compatibility. Use for exact phrase variants like 'long-tail variations of meal prep'. Requires `keyword`; use `sort: 'volume'` for established demand or `sort: 'trending'` to preserve upstream raw-growth order. Treat `searchDemandGrowthPct` as a separate measured current-vs-baseline metric, not the server sort key; do not say null measured-growth rows were sorted last unless the upstream response itself proves that ordering. - 'country_search': the top keywords matching a topic WITHIN one country. By default, exact/phrase matches are ranked by in-country volume. With `broad: true`, long-tail matches preserving meaningful seed terms rank before semantic-only discoveries; within each tier, upstream related score and in-country volume determine order. Requires `country` and `keyword`. - 'country_top': the top keywords overall within one country, ranked by in-country search volume, with NO topic filter. Use when the user names a country but no topic, e.g. 'what are the top keywords in Brazil'. Requires `country`; `keyword` is ignored. - 'rising': keywords gaining search momentum globally over a day, week, or month. Optionally scope to a category via `topic` (a value from `availableTopics`); omit `topic` for overall trends plus the discoverable topic list. Results include growth metrics in `risingKeywords`. |
| `sort` | string ("volume" | "trending") | No | Ranking for 'questions' and 'matching_terms' modes: 'volume' (default) ranks by search volume; 'trending' preserves upstream raw-growth order. Do not assume 'trending' is sorted by normalized searchDemandGrowthPct, and do not explain null searchDemandGrowthPct rows as locally sorted last. Ignored in other modes. |
| `broad` | boolean | No | Only applies to 'country_search' mode. Controls how the topic is matched within the country: - false (default) = EXACT/PHRASE match: returns only keywords whose text actually contains the topic words. E.g. topic 'minecraft' returns 'minecraft', 'minecraft mods', 'minecraft house'; every result literally contains 'minecraft'. Use when the user wants variants of a specific phrase. - true = SEMANTIC/BROAD match: first expands the topic into related keywords (the same engine behind vidIQ's 'Related Keywords' tab). For long-tail seeds, candidates preserving multiple meaningful seed terms rank before semantic-only candidates; within each tier, upstream related score then in-country volume determine order. This is a lightweight overlap heuristic, not language detection: simple ASCII suffix matching applies only to ASCII Latin tokens, while other scripts require exact normalized token overlap. Results need NOT contain the topic words, so a short topic such as 'minecraft' can still return 'redstone', 'survival mode', and 'building ideas'. Use when the user wants a BIGGER / wider list of related ideas, says 'related', 'similar', 'broaden', 'more than just X', or complains the exact-match list is too small. |
| `limit` | integer | No | Maximum number of results to return for 'questions', 'matching_terms', 'country_top', 'country_search', and 'rising' modes. Ignored in 'research' mode. |
| `topic` | string | No | Category to scope 'rising' results to, using a value from `availableTopics` for the requested period (call 'rising' without a `topic` first to discover them). Topics are specific (e.g. 'roblox', 'indie games', 'pop music'), not broad labels like 'gaming'. Matching is case-insensitive and tolerates plural/separator differences. An unknown topic falls back to overall rising trends and returns the closest valid topics in `suggestedTopics`. Omit for overall rising trends. Ignored outside 'rising' mode; use `keyword` for the research seed. |
| `period` | string ("day" | "week" | "month") | No | Trend window for 'rising' mode. Only meaningful in 'rising' mode. |
| `country` | string | No | ISO 3166-1 alpha-2 country code (for example 'US', 'IN'). In 'research' mode this is optional and enriches each keyword with its estimated in-country search volume (the `countryVolume` field). REQUIRED for 'country_top' and 'country_search' modes. Ignored in 'rising' mode (rising trends are global; the response notes it). |
| `keyword` | string | No | Seed keyword / topic (for example 'minecraft tips'). Required for 'research', 'questions', 'matching_terms', and 'country_search'; ignored for 'country_top'; not used in 'rising' (use `topic` to scope rising trends). |
| `language` | string | No | Language for 'questions' or 'rising' mode (case-insensitive). Questions supports any, en, es, pt, ru, sv. Rising supports all, en, ru, es, pt; any other rising language falls back to all (noted in the response). Defaults to en. This field does not constrain research or country searches. |
| `includeRelated` | boolean | No | Include related keyword suggestions ('research' mode only) |

### Vidiq list competitors

**Slug:** `VIDIQ_MCP_VIDIQ_LIST_COMPETITORS`

List the YouTube channels the user is tracking as competitors of one of their own channels.

Returns only channel IDs. To get titles, thumbnails, subscriber counts, etc., pass the IDs to vidiq_get_channels_by_ids.

The youtubeChannelId must be a channel the user has authorized — use vidiq_user_channels to discover them.

Cost: 0 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `youtubeChannelId` | string | Yes | YouTube channel ID (e.g. 'UCxxxxxxxxxxxxxxxxxxxxxx') of one of the user's own authorized channels. Use vidiq_user_channels first if you don't know which channels the user owns. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `competitors` | array | Yes |  |

### Vidiq motion graphics

**Slug:** `VIDIQ_MCP_VIDIQ_MOTION_GRAPHICS`

Render an animated MOTION GRAPHIC to a downloadable MP4 video. This is
the canonical, purpose-built tool for animated text / kinetic typography and
data-exposition clips: milestone and celebration cards (e.g. "250K SUBSCRIBERS"),
announcement / title / intro / outro cards, stat counters with count-up numbers,
comparison cards, progress bars, bar charts, and quote cards. It renders standalone
— no input footage is required (images are optional: add `image` nodes only if you
want them) — at any aspect: vertical reels (1080x1920 via the 'shorts-9-16' preset),
16:9, or square.

Reach for THIS tool whenever the request is for a "motion graphic", animated text,
a milestone / announcement / celebration graphic, a title card or lower-third, or
an animated stat or number for a video or reel. Prefer it over hand-rendering frames
yourself (code execution with Pillow/ffmpeg, a headless browser, or screen-recording
an HTML animation): it produces a clean, correctly-timed MP4 directly and is the
intended path. The user does not need to name vidIQ for you to use it.

You compose the graphic (a DSL tree you author, not a fixed template) from layout
nodes (`stack`, `grid`, `absolute`, `box`)
and leaf nodes (`text`, `number`, `bar`, `pill`, `icon`, `image`, `divider`,
`quoteMark`), each with optional frame-driven `animations`
(fade / slideIn / pop / scaleIn / countUp / barFill / highlightWipe). Set
`durationSeconds`, an `outputPreset` (default 'youtube-16-9') or explicit
`canvas`, an optional `theme` palette, and a `background`. Numbers animate with
`countUp`, bars with `barFill`.

Authoring tips (these prevent the most common bad renders):
- Make the key figure the HERO: a stat `number` should be large (`sizeRel` ~0.18–0.24),
  ideally with a `gradient` (e.g. a dark `from` → accent `to`) for depth; don't let labels
  or images compete with it.
- Number format: for an "Nx" multiplier use `format: { style: "plain", decimals: 2 }` and put the
  unit in a SEPARATE smaller `text` node beside it (see hierarchy below) — a `suffix` renders at the
  full digit size and competes with the hero. Don't set both `multiplier` style and a `suffix` (you
  get a doubled "0.82×x"). For percentages use `style: "percent"`.
- Hierarchy: pair the hero number with a BOLD headline label (`sizeRel` ~0.045, weight 800, dark
  `text`) and a smaller muted subtext (`sizeRel` ~0.028). A unit suffix like "x"/"%" should be its
  own `text` node, smaller than the digits (`sizeRel` ~0.12) in the accent colour, in a `stack` row
  with `align: "end"`.
- Section headers: `weight: 800`, dark `text` colour (NOT muted/grey), `sizeRel` ~0.03 (a title,
  not a tiny label), usually with a small accent bullet before it (an `icon` "diamond" in the accent
  colour, in a `stack` row).
- Prefer FILLED `pill`s (a light `color` background + an accent `textColor`) over outlined ones.
- A `bar` (progress) should be SUBSTANTIAL, not a thin sliver: `style.width` ~0.5–0.6 of the canvas,
  `thickness` ~0.016–0.022, `rounded: true`, on a light `track`. It anchors the lower part of the
  card — too short/thin reads as truncated.
- Sizes are NUMERIC fractions of the canvas (e.g. `sizeRel: 0.04`, `thickness: 0.012`).
  Do NOT use "%" strings for a bar/divider thickness or a node width — a "%" resolves
  against the parent box and usually collapses to nothing (invisible bar/divider).
- Thumbnails/images: use a bare `image` node with a `radius`, sized via `style.width`/
  `style.height` (`fit: "cover"` crops to any shape). Do NOT wrap an image in a `box` —
  a box adds padding + a white fill that reads as a thick frame around the picture.
- Animations: pair a `slideIn` with a `fade`, and keep slideIn `from` small (~0.05–0.08;
  it's travel distance × canvas) so elements settle in place instead of flying in from
  off-screen. Stagger a list of children with `staggerSeconds`. ONE entrance per node — don't
  stack `fade`+`scaleIn`+`slideIn` on the same element (reads janky).
- Sequence the timeline so it reads top-to-bottom: header ~0s → pills ~0.2s → number `countUp`
  ~0.3s → headline/subtext ~0.6s → the `bar` LAST, AFTER the number settles. Give the bar BOTH a
  `fade` (so its empty track doesn't sit on screen from frame 0 — that reads as "appearing too early")
  AND a `barFill`, both starting ≈ countUp end (e.g. ~1.2s). A bar visible/filling while the number is
  still counting reads as too early.
- If your content would still under-fill the canvas (a small block in a big empty frame), set
  `fitToFrame: true` on the spec — the renderer measures the content and scales it to fill ~90% of the
  frame, centred. Easiest way to avoid a top-heavy, empty-lower-half layout. Under `fitToFrame`, give
  every `image` an explicit `style.width` + `style.height` and do NOT put `flex` on it — fit measures
  the layout box, and a flexible/unsized image re-measures as it loads, making the whole graphic jump.
- Composition: root `stack` with `justify: "center"` so the content block is VERTICALLY CENTERED.
  Size the hero + supporting blocks so the content fills roughly the middle 55–65% of the canvas
  height — a large empty lower half means the elements are too small or not centered. Keep generous
  margins (root `padding` ~0.06–0.08) and a comfortable `gap` (~0.03–0.05) between groups. One element
  dominates.

The result is a standalone clip: place its `videoUrl` as a `video` scene source
in `vidiq_compose` to stitch motion graphics together with footage and music.

Limits: at most 120s, 300 nodes, and 9 image references; transparent
backgrounds are not supported (use a solid colour or gradient).

Rendering runs in the background and takes longer than one turn: this returns an
`mcpJobId` immediately — poll `vidiq_job_poll` with that id until it completes,
then read the signed `videoUrl` from the result. Credits are charged once on
submit and automatically refunded if the render fails.

Cost: 1 credit(s) per 4s of output (rounded up), minimum 2 credits.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `root` | string | Yes |  |
| `theme` | object | No |  |
| `canvas` | object | No | Explicit canvas dimensions; overrides `outputPreset` when set. |
| `background` | string | No | Canvas fill: a solid color, gradient, or image. (Transparent is not supported — the h264 render has no alpha channel.) |
| `fitToFrame` | boolean | No | Auto-scale the content to fill the frame (default ~90%), centred. Set true when content would otherwise under-fill the canvas; leave unset to position content via the root's align/justify. |
| `fitFraction` | number | No | Fill fraction for fitToFrame (default 0.9). |
| `outputPreset` | string ("shorts-9-16" | "shorts-9-16-60fps" | "youtube-16-9" | "square-1-1") | No | Named canvas preset: 'youtube-16-9' (1920x1080), 'shorts-9-16' (1080x1920), 'shorts-9-16-60fps', or 'square-1-1'. Default 'youtube-16-9'. |
| `durationSeconds` | number | Yes | Total clip length in seconds. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq outliers

**Slug:** `VIDIQ_MCP_VIDIQ_OUTLIERS`

Find viral, breakout, and overperforming YouTube videos — videos getting significantly more views than their channel's average. Use this when someone asks for: viral videos, breakout hits, hidden gems, or videos blowing up. Use `keyword` to focus discovery on a topic, `channelIds` to focus on specific creators or competitors, or both to combine those constraints. For a general request that names neither a topic nor channels, the tool can return a broad outlier feed using the remaining filters and defaults. Filter requested content by the actual video-title `language`; `channelCountry` only filters where channels are based, not audience location or video language. For Polish-language outliers, pass `language='pl'`; `channelCountry='PL'` alone only restricts results to channels based in Poland. Returns a breakout score showing how much each video exceeds its channel's typical performance. For finding videos whose *thumbnails* look visually similar (by image or text description of the imagery), use vidiq_similar_thumbnails instead.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `sort` | string ("breakoutScore" | "publishedAt" | "viewCount" | "vph" | "score") | No | Sort field (defaults to score) |
| `limit` | integer | No | Number of results to return |
| `minVph` | number | No | Minimum views per hour |
| `keyword` | string | No | Topic filter for outlier video titles. Use it to focus results on a subject, and combine it with `channelIds` to search for that subject within selected channels. |
| `language` | string ("en" | "es" | "ko" | "de" | "hi" | "ar" | "th" | "pl" | "it" | "ja" | "fr" | "tr" | "ru" | "pt" | "uk") | No | Language of the video TITLE to search within, as a single ISO 639-1 code. Supported: en, es, ko, de, hi, ar, th, pl, it, ja, fr, tr, ru, pt, uk. When the user explicitly requests a language, always pass its code here. If the request does not specify a language, this tool defaults to language: "en" and searches English titles only. Non-English languages support long-form videos only: contentType: "all" is narrowed to "long", while contentType: "short" is rejected. For example: Spanish-language outliers → language: "es"; German breakout videos → language: "de"; "видео на русском" → language: "ru". Pass exactly one code (not a list); codes outside the supported set are rejected. |
| `maxViews` | integer | No | Maximum video views |
| `minViews` | integer | No | Minimum video views |
| `channelIds` | array | No | Channel filter for focusing results on up to 50 specific creators or competitors. Each entry may be a channel ID (UC...), a handle (@MrBeast or MrBeast), or a channel URL — handles and URLs are resolved to channel IDs automatically. May be combined with `keyword`. |
| `contentType` | string ("all" | "long" | "short") | No | Filter by content type. Non-English title languages are available for long-form videos only: "all" is narrowed to "long", while "short" is rejected. |
| `channelCountry` | string | No | Restrict to channels BASED IN this country, as an ISO 3166-1 alpha-2 code (e.g. "PL", "US"). This is where the channel/creator is located — NOT the audience/viewer country, and NOT the language of the videos. To search by the content language, use `language` instead. Example: for Polish-language outliers pass `language='pl'`; `channelCountry='PL'` alone only restricts to channels based in Poland (which may publish in any language). |
| `maxSubscribers` | integer | No | Maximum channel subscribers |
| `minSubscribers` | integer | No | Minimum channel subscribers |
| `minOutlierScore` | number | No | Minimum outlier score |
| `publishedWithin` | string ("thisWeek" | "thisMonth" | "threeMonths" | "sixMonths" | "oneYear" | "allTime") | No | Filter by publish date. For non-English languages, the effective window defaults to "sixMonths" and is capped there; English supports every listed range, including "allTime". |
| `trendCategories` | array | No | Filter by trend category IDs (e.g. reaction, tier_list, mukbang). Use vidiq_trend_categories to list all available categories. |
| `minEngagementRate` | number | No | Minimum engagement rate |
| `requireAllTitleTerms` | boolean | No | Set true to require every analyzed keyword term to match the video title. Recommended for person names, technical phrases, and narrow queries. Leave false for broader semantic discovery across titles, tags, and channel tags. Strict mode can return few or no results for non-English queries. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videos` | array | Yes |  |
| `keyword` | string | No |  |

### Vidiq refine thumbnail

**Slug:** `VIDIQ_MCP_VIDIQ_REFINE_THUMBNAIL`

Change or improve a YouTube thumbnail by describing what you want in plain words.

Give it the thumbnail to change as sourceThumbnail (a hosted URL) or sourceThumbnailFile (a ChatGPT upload),
and say what to change (instructions) — for example "make the text bigger" or "change the background to a
football stadium".

This runs asynchronously: it returns an `mcpJobId` immediately. Poll `vidiq_job_poll` with that id until
it is "completed" to get the updated thumbnail (shown inline) with its imageUrl. Credits are charged on
submit and automatically refunded if refinement fails.

Include the imageUrl in your reply so the user can open or save the file. The inline preview isn't downloadable.

Cost: 22 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `mask` | string | No | Optional. To change only one area and leave the rest untouched, provide a base64 image that marks the area to change. |
| `videoId` | string | No | Optional. The YouTube video this thumbnail is for. |
| `orientation` | string ("landscape" | "portrait") | No | Thumbnail orientation. 'landscape' is the standard 16:9 YouTube thumbnail (default when omitted); 'portrait' is a 9:16 Shorts thumbnail. Ignored when a mask is supplied (mask edits keep the source dimensions). |
| `instructions` | string | Yes | What you want changed, in plain words, for example 'make the background darker' or 'make the face bigger'. Describe the change, not the whole picture. |
| `subjectImage` | string | No | Optional. A photo of the person who should be the main face in the thumbnail as a hosted image URL or base64 data URI. |
| `originalConcept` | string | No | Optional. A short description of what the original thumbnail shows. Helps keep the result on-topic. If left out, your instructions are used. |
| `referenceImages` | array | No | Optional. Up to 10 hosted image URLs or base64 data URIs for thumbnails whose style you'd like to copy. |
| `sourceThumbnail` | string | No | The thumbnail you want to change as a hosted image URL or base64 data URI. Usually this is the imageUrl from vidiq_generate_thumbnail. Use sourceThumbnailFile instead for a ChatGPT file upload. |
| `sourceThumbnailFile` | object | No | The thumbnail you want to change as a ChatGPT-uploaded file. Use this instead of sourceThumbnail when the user uploads the source image. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq score thumbnail

**Slug:** `VIDIQ_MCP_VIDIQ_SCORE_THUMBNAIL`

Score a YouTube video thumbnail for click-through-rate potential. Returns a score (0-100) with detailed feedback on strengths and improvements. Provide a video ID and title; optionally supply a custom thumbnail image URL to score instead of the current YouTube thumbnail.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `image` | string | No | Thumbnail image URL or an uploaded image. If omitted, the current YouTube thumbnail is used. |
| `title` | string | Yes | Video title (used together with the thumbnail for scoring) |
| `videoId` | string | Yes | YouTube video ID |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `score` | number | Yes |  |
| `feedback` | object | Yes |  |

### Vidiq score title

**Slug:** `VIDIQ_MCP_VIDIQ_SCORE_TITLE`

Score a YouTube video title for click-through-rate potential. Returns a score (0-100) indicating how compelling and clickable the title is. Use this to compare title variations and pick the best-performing option.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `type` | string ("long" | "short") | Yes | Video format: long-form or short-form |
| `title` | string | Yes | The title text to score |
| `videoId` | string | No | YouTube video ID (improves scoring accuracy) |
| `channelId` | string | No | YouTube channel ID (improves scoring accuracy) |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `score` | number | Yes |  |

### Vidiq similar channels

**Slug:** `VIDIQ_MCP_VIDIQ_SIMILAR_CHANNELS`

Find COMPETITORS of a channel — either the user's own channel or a specific named channel. Uses neural semantic search tuned for competitor matching; the user's own authorized channels are automatically excluded from legacy manual-mode results.

Use this tool ONLY when someone asks for competitors or similar channels relative to a channel:
- "Who are my competitors?" or "Find channels like mine" (the user's own channel — country/language are auto-detected in manual mode)
- "Channels similar to [channel]", "Competitors of [channel]", or "Channels like @handle" (a named reference channel)

Do NOT use this tool for generic channel discovery by topic, size, growth, or any other criteria ("find tech review channels", "top gaming channels in Brazil", "fastest growing fitness channels") — use vidiq_channel_search for that.

Choose exactly one mode: channelId or niche.

ADDITIVE CHANNEL ID MODE — when a canonical YouTube channel ID beginning with UC was supplied or already resolved, pass only channelId, plus optional size and sort. Do not copy resolved channel characteristics into this request or add niche/manual filters. Do not call vidiq_channel_search when a canonical ID is already available. A handle or URL must be resolved externally to a canonical channel ID before using this mode. The API derives the source classification and search tuning and excludes the reference channel.

LEGACY MANUAL NICHE MODE — Legacy manual niche behavior is unchanged. The niche parameter is required in this mode — always provide a clear topic or content theme. All existing manual inputs remain supported, including minSubscribers, maxSubscribers, avgViews, avgViewsMin, avgViewsMax, country, language, channelType, faceless, and excludeChannelIds.

SIMILAR TO A SPECIFIC CHANNEL IN LEGACY MANUAL MODE — when using the existing manual path, do NOT guess the reference channel's characteristics. Supply the same fields as before:
- niche: the reference channel's niche + subNiches, comma-separated (e.g. 'YouTube Growth, Monetization & SEO')
- country: the reference channel's country
- language: the first code from the reference channel's languages
- channelType: the reference channel's channelType
- faceless: the reference channel's isFaceless value
- minSubscribers / maxSubscribers: a band around its subscriberCount, roughly 10% as min and 5x as max, unless the user asks for a specific range
- avgViews: the reference channel's avgViews; do not also set avgViewsMin/avgViewsMax unless the user asks for a specific range
- excludeChannelIds: the reference channel's channelId

Omit sort for normal similarity ranking. When the user asks to rank these competitors by size or recent growth, set sort to subscriberCount, subsGrowth30d, or viewsGrowth30d; all explicit sorts reorder only the requested top similarity results.

Results include the metrics used for sorting plus channel type and faceless status. In manual niche mode, country is a ranking preference rather than a strict filter, while language filters the language channels publish in. When omitted, country and language are auto-detected from the user's authorized channel.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `size` | integer | No | Number of similar channels to return. Defaults to 30, maximum 50. |
| `sort` | string ("subscriberCount" | "subsGrowth30d" | "viewsGrowth30d") | No | Optional descending sort of the requested top similarity results: subscriberCount, subsGrowth30d, or viewsGrowth30d. Omit to keep neural similarity relevance order. |
| `niche` | string | No | Manual niche, topic, or content theme to search in. Use natural language — e.g. 'tech reviews' or 'vegan cooking tutorials'. Provide either this or channelId, not both; prefer channelId for a specific reference channel. |
| `country` | string | No | Two-letter ISO 3166-1 country code used to prefer channels BASED IN that country — e.g. 'US', 'GB', 'BR', 'JP'. Matching channels receive a ranking boost, but channels based elsewhere may still appear. This is where the channel is located — NOT the audience/viewer country, and NOT the channel's language (use `language` to filter by language). When omitted, the country is auto-detected from the user's authorized channel (if any). |
| `avgViews` | number | No | The reference channel's lifetime average views per video (total views / total videos). When searching for competitors of a specific channel, pass its avgViews here so results are auto-ranged to a similar per-video-views league (parallels passing the reference channel's subscriber band). Leave unset for generic niche searches. |
| `faceless` | boolean | No | Reference channel faceless status. When provided, candidates with the same status receive a ranking boost; other candidates remain eligible. |
| `language` | string | No | Two-letter ISO 639-1 language code to filter results to channels whose content is in that language — e.g. 'en', 'es', 'pt', 'ja'. Pass the user's requested content language here (the language the channel publishes in — this is the channel's language, not its country). Only a single language is accepted. When omitted, the language is auto-detected from the user's authorized channel (if any). |
| `channelId` | string | No | Canonical YouTube channel ID beginning with UC. It is passed directly to the Similar Channels API without a resolution request. |
| `avgViewsMax` | number | No | Manual upper bound for lifetime average views per video (total views / total videos), overriding the avgViews auto-range. Use together with avgViewsMin to define a specific per-video average-views range. |
| `avgViewsMin` | number | No | Manual lower bound for lifetime average views per video (total views / total videos), overriding the avgViews auto-range. Use to require results that average at least this many views per video — e.g. 50000 for '50k+ average views'. This is the per-video average, not total views. |
| `channelType` | string ("long" | "short" | "mixed") | No | Reference channel format. 'long' prefers long and mixed candidates; 'short' prefers short and mixed candidates; 'mixed' is neutral. This affects ranking, not eligibility. |
| `maxSubscribers` | integer | No | Upper bound for subscriber count. Use to filter out larger channels — e.g. 1000000 to cap results at channels under 1M subscribers. Use together with minSubscribers to define a specific range. |
| `minSubscribers` | integer | No | Lower bound for subscriber count. Use to filter out smaller channels — e.g. 10000 to only see channels with 10k+ subscribers. Use together with maxSubscribers to define a specific range. |
| `excludeChannelIds` | array | No | Manual niche mode only: channel IDs to exclude from results. The user's own authorized channels are excluded automatically and do not need to be listed. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `similarChannels` | array | Yes |  |

### Vidiq similar thumbnails

**Slug:** `VIDIQ_MCP_VIDIQ_SIMILAR_THUMBNAILS`

Find long-form YouTube videos whose thumbnails LOOK similar — visual/semantic similarity over the thumbnail images themselves. This tool searches long-form videos only; Shorts are not supported. This is not topic, title, or keyword search (for those use vidiq_outliers or vidiq_youtube_search). Two modes: pass `description` with a textual description of the imagery (e.g. "a shocked creator pointing at a red analytics chart") to find thumbnails matching that description, or pass `videoId` to find thumbnails that look like that video's thumbnail (resolved automatically — no image upload needed). Useful for thumbnail inspiration, checking how common a thumbnail concept is, or finding which visual styles perform well in a niche.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `limit` | integer | No | Number of results to return |
| `videoId` | string | No | YouTube video ID (e.g. 'dQw4w9WgXcQ') or video URL. The video's current thumbnail is resolved automatically and used as the search image. Provide exactly one of `description` or `videoId`. |
| `maxViews` | integer | No | Maximum video views |
| `minViews` | integer | No | Minimum video views |
| `description` | string | No | Natural-language description of the thumbnail imagery to find, e.g. "a shocked creator pointing at a red analytics chart". Provide exactly one of `description` or `videoId`. |
| `channelCountry` | string | No | Restrict to channels BASED IN this country (ISO 3166-1 alpha-2, e.g. 'US', 'PL'). This is where the channel is located — NOT the audience/viewer country, and NOT the language of the videos. |
| `maxSubscribers` | integer | No | Maximum channel subscribers |
| `minSubscribers` | integer | No | Minimum channel subscribers |
| `publishedWithin` | string ("thisWeek" | "thisMonth" | "threeMonths" | "sixMonths" | "oneYear" | "allTime") | No | Filter by publish date |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videos` | array | Yes |  |
| `keyword` | string | No |  |
| `resultKind` | string | Yes |  |

### Vidiq similar videos

**Slug:** `VIDIQ_MCP_VIDIQ_SIMILAR_VIDEOS`

Find high-performing YouTube videos similar to a seed video - the video-level counterpart of vidiq_similar_channels. Give it one video ID or URL and it returns videos ranked by combined similarity: textual (title/topic) and visual (thumbnail), fused with each video labeled by which signals matched (`matchedBy`; matching both earns a ranking boost). Use this for topic ideation ('find 50 videos like this outlier'), studying how a proven concept is packaged across channels, or expanding one winning video into a content cluster. Searches vidIQ's high-performing/outlier video index - results skew toward videos that overperform, which is what makes them useful as ideation references. Results are ordered most-similar-first; no numeric similarity score is exposed. Use `minEngagementRate` to filter copycat/re-upload spam around viral seeds. Check `signalsUsed`/`signalsFailed` before interpreting an empty result. For channel-level similarity use vidiq_similar_channels; for thumbnail-only search use vidiq_similar_thumbnails.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `limit` | integer | No | Number of results to return |
| `matchOn` | string ("both" | "title" | "thumbnail") | No | Similarity signals to use. 'both' (default) fuses title/topic similarity with thumbnail visual similarity. 'title' uses only textual similarity (works for Shorts). 'thumbnail' uses only visual thumbnail similarity (long-form index only). |
| `videoId` | string | Yes | Seed YouTube video: an 11-character video ID (e.g. 'dQw4w9WgXcQ') or a video URL. Results are videos similar to this one. |
| `maxViews` | integer | No | Maximum video views |
| `minViews` | integer | No | Minimum video views |
| `contentType` | string ("all" | "long" | "short") | No | Filter results by format. Note: thumbnail similarity only covers long-form videos, so 'short' results come from title similarity alone. |
| `channelCountry` | string | No | Restrict to channels BASED IN this country (ISO 3166-1 alpha-2, e.g. 'US', 'PL'). This is where the channel is located — NOT the audience/viewer country, and NOT the language of the videos. |
| `maxSubscribers` | integer | No | Maximum channel subscribers |
| `minSubscribers` | integer | No | Minimum channel subscribers |
| `publishedWithin` | string ("thisWeek" | "thisMonth" | "threeMonths" | "sixMonths" | "oneYear" | "allTime") | No | Filter by publish date |
| `minEngagementRate` | number | No | Minimum engagement rate (likes/views, 0-1). Filters out low-engagement copycat/re-upload channels that flood results for viral seeds; real creators typically show 0.03-0.12, content farms 0.002-0.01. Recommended around 0.02 when seeding from a mega-viral video. |
| `excludeSeedChannel` | boolean | No | Set true to drop videos from the seed video's own channel. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `seed` | object | Yes |  |
| `videos` | array | Yes |  |
| `signalsUsed` | array | Yes | Signals whose search actually ran and contributed candidates. If a requested signal is missing here, its search did not run - do NOT conclude 'no similar videos exist' for that signal. |
| `signalsFailed` | array | Yes | Requested signals that could not run, with a stable public reason code. |

### Vidiq submit feedback

**Slug:** `VIDIQ_MCP_VIDIQ_SUBMIT_FEEDBACK`

Submit feedback about the vidIQ MCP — feature requests, bug reports, improvement suggestions, survey responses, or general comments. When the user encounters a bug with vidIQ MCP or requests a new vidIQ MCP feature, proactively ask whether they would like you to submit a bug report or feature request to vidIQ. Call this tool when the user explicitly asks to submit, send, record, or report feedback to vidIQ. Comments made while asking for help do not by themselves indicate submission intent. If submission intent is ambiguous, ask whether the user wants the feedback sent to vidIQ and wait for confirmation.

Cost: 0 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `type` | string ("feature_request" | "bug_report" | "improvement" | "general" | "survey_response") | Yes | The kind of feedback: feature_request for new tools/capabilities, bug_report for something broken, improvement for enhancing an existing tool, survey_response for answers to a survey or research invitation, general for anything else |
| `summary` | string | No | Concise, searchable summary of this feedback (up to 500 characters) |
| `use_case` | string | No | A specific workflow or scenario for additional context |
| `tool_name` | string | No | The relevant existing tool name, if this feedback is about a specific tool (e.g. 'vidiq_keyword_research') |
| `campaign_id` | string | No | Survey or campaign identifier provided in the invitation; omit for ordinary feedback |
| `description` | string | Yes | What you're requesting, reporting, or suggesting — and why |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes |  |
| `message` | string | Yes |  |
| `feedbackId` | string | Yes |  |

### Vidiq subscriber insights

**Slug:** `VIDIQ_MCP_VIDIQ_SUBSCRIBER_INSIGHTS`

Analyze subscriber overlap and best times to post for a YouTube channel you own.

Returns the channels most commonly subscribed to by your audience, dated overlap history, and a timezone-adjusted histogram of sampled public YouTube activity with the strongest three-hour windows. The activity signal is not watch history or live online-presence data. Only channels authorized to your account are allowed.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `limit` | integer | No | Maximum number of audience-overlap channels to return (1-50) |
| `channelId` | string | Yes | An owned YouTube channel ID, handle, or channel URL |
| `timezoneOffset` | string | No | Whole-hour UTC offset used for the activity histogram: Z or ±HH:00. Fractional-hour offsets are rejected because the current upstream truncates them. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `period` | string | Yes |  |
| `channelId` | string | Yes |  |
| `topChannels` | array | Yes |  |
| `bestTimeToPost` | object | Yes |  |
| `growthUpdatedAt` | string | Yes | When growth history was updated, or null when growth data is unavailable. |

### Vidiq trend categories

**Slug:** `VIDIQ_MCP_VIDIQ_TREND_CATEGORIES`

List all available trend category slugs with display names and descriptions. Use this as a reference before filtering outlier videos by trend category.

Cost: 0 credit(s) per call.

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `categories` | array | Yes |  |

### Vidiq trending videos

**Slug:** `VIDIQ_MCP_VIDIQ_TRENDING_VIDEOS`

Find YouTube videos that are trending right now — gaining views rapidly based on views-per-hour velocity. Use this when someone asks: what's trending, what's hot right now, popular videos this week, or fastest-growing videos. Unlike vidiq_outliers (which measures performance vs channel average), trending measures absolute velocity — high VPH regardless of channel size.

Use this tool to discover:
- Videos that are trending right now on YouTube
- Trending content in specific niches via title search
- High-performing videos filtered by views per hour, engagement, or subscriber range

For language-specific discovery, pass the user's requested actual video-title language in `videoTitleLanguage`. `channelCountry` only restricts where channels are based; it does not represent audience geography or video language.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `limit` | integer | No | Number of results |
| `sortBy` | string ("relevance" | "vph" | "viewCount" | "engagementRate" | "videoPublishedAt") | No | Sort field |
| `vphMin` | number | No | Minimum views per hour |
| `titleQuery` | string | No | Search query to filter by video title (semantic search) |
| `videoFormat` | string ("long" | "short") | Yes | Video format: 'long' for regular videos, 'short' for YouTube Shorts |
| `viewCountMin` | integer | No | Minimum video view count |
| `channelCountry` | string | No | Restrict to channels BASED IN this country (uppercase ISO 3166-1 alpha-2 code, e.g. 'US', 'PL'). This is where the channel is located — NOT the audience/viewer country, and NOT the language of the videos. To filter by the video's language, use `videoTitleLanguage` instead. |
| `subscriberCountMax` | integer | No | Maximum channel subscriber count |
| `subscriberCountMin` | integer | No | Minimum channel subscriber count |
| `videoTitleLanguage` | string ("en" | "es" | "ja" | "ru" | "ko" | "ar" | "hi" | "vi" | "id" | "th" | "tr" | "de" | "fr" | "pl" | "pt" | "uk" | "it" | "mr" | "fa") | No | Filter by detected video-title language (ISO 639-1): en, es, ja, ru, ko, ar, hi, vi, id, th, tr, de, fr, pl, pt, uk, it, mr, or fa. Use the user's requested content language; omit for all supported languages. |
| `videoPublishedAfter` | string | No | Only videos published after this date (YYYY-MM-DD) |
| `requireAllTitleTerms` | boolean | No | Tighten titleQuery matching: when true, every term must appear in the title (strict AND), so high-velocity videos matching only a common token (e.g. 'ai') can't dominate. When false (default), titleQuery is a broad relevance signal. Only affects results when titleQuery is set. |
| `videoPublishedBefore` | string | No | Only videos published before this date (YYYY-MM-DD) |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videos` | array | Yes |  |

### Vidiq update competitors

**Slug:** `VIDIQ_MCP_VIDIQ_UPDATE_COMPETITORS`

Follow or unfollow competitor channels for one of the user's own YouTube channels.

- youtubeChannelId must be a channel the user has authorized (call vidiq_user_channels to discover).
- follow / unfollow are arrays of YouTube channel IDs — they must not overlap; at least one must be non-empty.
- Plan-based caps apply. Adding above the cap fails. Returns the resulting tracked-competitors list (channel IDs only).

Example arguments: { "youtubeChannelId": "UCowner123", "follow": ["UCcompA"], "unfollow": [] }

Cost: 0 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `follow` | array | No | Array of YouTube channel IDs to start tracking as competitors, e.g. ["UCabc123","UCdef456"]. |
| `unfollow` | array | No | Array of YouTube channel IDs to stop tracking, e.g. ["UCabc123"]. |
| `youtubeChannelId` | string | Yes | YouTube channel ID (starts with 'UC', e.g. 'UCabc123') of one of the user's own authorized channels. Call vidiq_user_channels first if unknown. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `competitors` | array | Yes |  |

### Vidiq update video

**Slug:** `VIDIQ_MCP_VIDIQ_UPDATE_VIDEO`

Update metadata or publishing settings for a YouTube video owned by the user.

Supported updates match the vidIQ web app: title, description, complete tag list, privacy status, and scheduled publish time. Omitted fields remain unchanged. An empty description clears the description, and an empty tags array clears all tags. Thumbnail updates use a separate endpoint and are not supported by this tool.

Call this write tool only after the user explicitly chooses the exact channel, video, and final values to publish. Do not call it merely to preview, recommend, score, or draft changes. The channel must be directly authorized with owner access (call vidiq_user_channels if unknown), and the current vidIQ OAuth token must include YouTube verification.

When the result status is verification_required, show the verification widget and wait for the user to use its controls. Do not retry the video update until the user confirms verification is complete.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `tags` | array | No | The complete replacement list of YouTube tags. Pass an empty array to clear tags. |
| `title` | string | No | The exact final YouTube title to publish, from 1 to 100 characters. |
| `videoId` | string | Yes | The YouTube video ID to update. |
| `channelId` | string | Yes | The directly authorized YouTube channel that owns the video. Call vidiq_user_channels if unknown. |
| `publishAt` | string | No | The UTC ISO 8601 time when a private video should become public. Also pass privacyStatus='private'. |
| `description` | string | No | The exact final YouTube description. Pass an empty string to clear it. |
| `privacyStatus` | string ("public" | "unlisted" | "private") | No | The video's final YouTube visibility. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `kind` | string | No | Present when status is verification_required. |
| `tags` | array | No |  |
| `title` | string | No |  |
| `video` | object | No | Current YouTube metadata refetched after the update was confirmed. |
| `status` | string ("updated" | "verification_required") | Yes | Whether the video was updated or YouTube verification must be completed first. |
| `videoId` | string | Yes |  |
| `channelId` | string | Yes |  |
| `publishAt` | string | No |  |
| `description` | string | No |  |
| `privacyStatus` | string ("public" | "unlisted" | "private") | No |  |
| `updatedFields` | array | No |  |

### Vidiq update video thumbnail

**Slug:** `VIDIQ_MCP_VIDIQ_UPDATE_VIDEO_THUMBNAIL`

Replace the thumbnail for a YouTube video owned by the user.

Call this write tool only after the user explicitly chooses the exact channel, video, and final thumbnail to publish. Do not call it to preview, recommend, score, or generate thumbnails. Provide exactly one of thumbnail (an HTTPS URL or PNG/JPEG data URI) and thumbnailFile. This tool accepts PNG or JPEG thumbnails up to 2 MiB. URLs must serve the image directly without redirects.

The channel must be directly authorized with owner access (call vidiq_user_channels if unknown), and the current vidIQ OAuth token must include YouTube verification. When the result status is verification_required, show the verification widget and wait for the user to use its controls. Do not retry the thumbnail update until the user confirms verification is complete. If the write outcome is uncertain, inspect the thumbnail on YouTube and ask the user before repeating the write.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videoId` | string | Yes | The YouTube video ID whose thumbnail to replace. |
| `channelId` | string | Yes | The directly authorized YouTube channel that owns the video. Call vidiq_user_channels if unknown. |
| `thumbnail` | string | No | The exact final thumbnail as an HTTPS URL or PNG/JPEG base64 data URI. |
| `thumbnailFile` | object | No | The exact final thumbnail supplied as an OpenAI uploaded-file object. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `kind` | string | No |  |
| `status` | string ("updated" | "verification_required") | Yes |  |
| `videoId` | string | Yes |  |
| `channelId` | string | Yes |  |
| `updatedFields` | array | Yes |  |

### Vidiq user channels

**Slug:** `VIDIQ_MCP_VIDIQ_USER_CHANNELS`

Get the list of YouTube channels authorized by the current user.

The response includes `authenticatedAs` (the email of the connected vidIQ account).
An empty `channels` list usually means the user authorized a different account than
they expected — tell them which account they're connected as and suggest reconnecting
with the intended one rather than treating it as an error.

Cost: 0 credit(s) per call.

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `channels` | array | Yes |  |
| `authenticatedAs` | string | No | Email of the vidIQ account this MCP connection is authenticated as. When the channel list looks wrong or empty, surface this so the user can confirm they connected the intended account. |

### Vidiq user videos

**Slug:** `VIDIQ_MCP_VIDIQ_USER_VIDEOS`

List videos from one of the current user's directly authorized YouTube channels through the authenticated vidIQ MCP connection, including public, unlisted, and private videos.

Use vidiq_user_channels when the channel ID is unknown. Supports privacy, video-type, title-search, ordering, limit, and cursor filters. Use vidiq_channel_videos for arbitrary public channels. Do not fall back to public results when channel authorization fails.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `limit` | integer | No | Maximum videos to return. |
| `order` | string ("newest" | "oldest") | No | Sort by publish date. |
| `search` | string | No | Optional title-only search string, from 1 to 100 characters. |
| `channelId` | string | Yes | Canonical YouTube channel ID owned by the current user. Call vidiq_user_channels if unknown. |
| `pageToken` | string | No | Opaque cursor returned by a previous call with the same filters. |
| `videoType` | array | No | Video type filters. Omit when all long, short, and live videos are acceptable. |
| `privacyStatus` | array | No | Video privacy filters. Defaults to public, unlisted, and private videos. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videos` | array | Yes |  |
| `channelId` | string | Yes |  |
| `nextPageToken` | string | Yes |  |

### Vidiq video change history

**Slug:** `VIDIQ_MCP_VIDIQ_VIDEO_CHANGE_HISTORY`

Get the observed title and thumbnail change history for one YouTube video.

Each change records when a title or thumbnail edit was observed. Thumbnail entries include the original YouTube URL and vidIQ's archived snapshot URL. The response also includes observed thumbnail A/B tests and their variants.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videoId` | string | Yes | YouTube video ID (for example 'dQw4w9WgXcQ'). |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `abTests` | array | Yes |  |
| `changes` | array | Yes |  |
| `videoId` | string | Yes |  |

### Vidiq video comments

**Slug:** `VIDIQ_MCP_VIDIQ_VIDEO_COMMENTS`

Get YouTube comment threads for a video or channel, including replies.

Provide exactly one of videoId or channelId.

Each returned thread carries the videoId and videoTitle it belongs to, so channel-wide results can be attributed to individual videos. Either field is omitted when YouTube does not report it or the video's metadata is unavailable.

Use this tool to:
- Understand audience sentiment and reactions to a video
- Find common questions or feedback themes in comments
- Browse recent comments across an entire channel
- Identify the most liked or discussed comments

Paging and filtering: maxResult is the upstream page size, and minLikes filters that page by top-level comment likes. A page can therefore come back with fewer threads than maxResult, or with none at all, while more matches still exist. Each page is a separate charged call, so do not sweep to exhaustion by default: fetch another page with the returned nextPageToken (same filters) only while you still need more evidence and the caller's budget allows, and stop as soon as you have enough. A null nextPageToken means the upstream corpus is exhausted and there is nothing left to read.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `order` | string ("time" | "relevance") | No | Sort order: 'relevance' (top comments) or 'time' (newest first) |
| `videoId` | string | No | YouTube video ID (e.g. 'dQw4w9WgXcQ'). Provide either videoId or channelId. |
| `minLikes` | integer | No | Optional inclusive like threshold on the top-level comment: keep only threads whose top-level comment has at least this many likes. Replies of kept threads are not filtered. Omit (or 0) to return every thread. |
| `channelId` | string | No | YouTube channel ID, handle (e.g. '@MrBeast'), or channel URL. Provide either videoId or channelId. |
| `maxResult` | integer | No | Upstream page size: how many comment threads are fetched per call (1–100). When minLikes is set, fewer threads than this can be returned because filtering is applied to the fetched page only — request another page with nextPageToken if the matches so far are not enough. |
| `pageToken` | string | No | Opaque cursor from a previous call's nextPageToken. Pass the same videoId/channelId, order, and minLikes when continuing. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videoId` | string | No |  |
| `comments` | array | Yes |  |
| `channelId` | string | No |  |
| `nextPageToken` | string | Yes |  |

### Vidiq video earnings estimate

**Slug:** `VIDIQ_MCP_VIDIQ_VIDEO_EARNINGS_ESTIMATE`

Estimate a single YouTube video's ad-revenue earnings as a low/mid/high range in USD.

Give it a video id or URL. It resolves whether the video is long-form or a Short, looks up the channel's category and country, and applies vidIQ's RPM model (category RPM x geo multiplier, with a much lower RPM for Shorts).

Use this to answer "how much did/does this video earn?".

Important: this is a rough estimate, not exact. It assumes the channel is monetized, uses the channel's country as a proxy for viewer geography, and counts all views as ad-serving. Channels under ~1,000 subscribers are usually not monetized.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videoId` | string | Yes | A YouTube video id (e.g. 'dQw4w9WgXcQ') or any YouTube video URL (watch, youtu.be, /shorts/, /embed/, /live/) |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `isShort` | boolean | Yes |  |
| `videoId` | string | Yes |  |
| `estimate` | object | Yes |  |
| `channelId` | string | Yes |  |
| `viewCount` | number | Yes |  |
| `mainCategory` | string | Yes |  |
| `categorySource` | string ("video" | "channel" | "default") | Yes |  |
| `channelCountry` | string | Yes |  |
| `durationSeconds` | string | Yes |  |

### Vidiq video stats

**Slug:** `VIDIQ_MCP_VIDIQ_VIDEO_STATS`

Get historical statistics for a YouTube video over time, including views, likes, comments, and views per hour (VPH).

Use this tool to:
- Track how a video's performance changes over time
- Compare view velocity (VPH) across different periods
- Analyze engagement trends (likes, comments) for a specific video

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `to` | string | No | End of time range (ISO-8601) |
| `from` | string | No | Start of time range (ISO-8601, e.g. '2026-01-01T00:00:00Z') |
| `order` | string ("asc" | "desc") | No | Sort order by timestamp |
| `videoId` | string | Yes | YouTube video ID or URL |
| `granularity` | string ("hourly" | "daily" | "monthly") | Yes | Time granularity for stats data points |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `data` | array | Yes |  |
| `videoId` | string | Yes |  |

### Vidiq video transcript

**Slug:** `VIDIQ_MCP_VIDIQ_VIDEO_TRANSCRIPT`

Get the full transcript (captions) of a YouTube video.

Use this tool to:
- Analyze what a video talks about without watching it
- Extract key topics, quotes, or timestamps from a video
- Compare content across multiple videos by reading their transcripts
- Research video content for SEO or content strategy purposes

When a language is requested, this tool never silently substitutes captions in another language.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videoId` | string | Yes | YouTube video ID (e.g. 'dQw4w9WgXcQ') or a YouTube video URL |
| `language` | string | No | Requested transcript language as a BCP-47 code (e.g. 'en', 'es', 'pt-BR'). When supplied, only a matching caption track is returned; omit it to use the video's default captions. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `videoId` | string | Yes |  |
| `language` | string | No |  |
| `transcription` | string | Yes |  |

### Vidiq video upload

**Slug:** `VIDIQ_MCP_VIDIQ_VIDEO_UPLOAD`

Import an MP4 attachment or public downloadable URL and return a hosted videoUrl plus uploadId. Provide exactly one of file, url, or uploadId. The server transfers and completes the upload; no separate upload or completion step is needed. MP4s must be at most 209715200 bytes with a public HTTPS download URL, Content-Length and MP4 or application/octet-stream content type; redirects are rejected. Local file paths cannot be read.
Pass uploadId to this same tool to check waiting/processing uploads or refresh an expired signed URL without transferring the file again. Failed uploads require a new import. Once ready, review videoUrl, then use it in vidiq_generate_video, vidiq_compose, or vidiq_instagram_publish_reel. No credits are charged.

Cost: 0 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `url` | string | No | Public downloadable MP4 URL to import, including its complete signature. |
| `file` | object | No | MP4 attachment supplied by an OpenAI client. Provide exactly one of file, url, or uploadId. |
| `title` | string | No | Name of the imported MP4 video. |
| `uploadId` | string | No | Existing upload ID to check status or refresh its signed video URL without uploading again. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string ("waiting" | "processing" | "ready" | "failed") | Yes |  |
| `duration` | string | Yes |  |
| `uploadId` | string | Yes |  |
| `videoUrl` | string | No |  |

### Vidiq video watch

**Slug:** `VIDIQ_MCP_VIDIQ_VIDEO_WATCH`

Watch a long-form YouTube video end-to-end and return a structured markdown walkthrough.

Use this tool to:
- Understand what happens visually in a video (not just what is said) — useful when transcripts miss context
- Generate scene-by-scene breakdowns with timestamps for editing or analysis
- Answer specific questions about a video by passing a custom `prompt`
- Compare visual structure across videos for SEO / hook research

This runs asynchronously: it returns an `mcpJobId` immediately. Poll `vidiq_job_poll` with that id until it is "completed" to get the markdown walkthrough in the `analysisText` field. Credits are charged on submit and automatically refunded if the analysis fails.

For short-form content, use `vidiq_watch_shortform_content` instead.

Note: prefer `vidiq_video_transcript` when you only need spoken words, since it is faster and cheaper.

Cost: 25 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `video` | string | Yes | Long-form YouTube video ID (e.g. 'dQw4w9WgXcQ') or watch/youtu.be URL. For short-form content, use vidiq_watch_shortform_content instead. |
| `prompt` | string | No | Optional custom analysis instruction. If omitted, a scene-by-scene markdown walkthrough is produced (### Scene N: Label headers with mm:ss timestamps + ### Summary bullets). Markdown structure is enforced regardless — do not ask for JSON. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq voiceover clone

**Slug:** `VIDIQ_MCP_VIDIQ_VOICEOVER_CLONE`

Clone a voice from an audio sample and save it to the user's voice library.

Provide a base64-encoded audio sample (a 60-600s MP3/WAV/M4A clip of a single
speaker who has consented to being cloned) and a display name. Each user may keep at
most 3 custom voices. Video samples are not accepted — extract the audio first.

This runs asynchronously: it returns an `mcpJobId` immediately — poll `vidiq_job_poll`
with that id until it is "completed" to get the new voiceId (usable with
vidiq_voiceover_generate). Credits are charged on submit and automatically refunded if
cloning fails. Cloning is NOT retried automatically: if the poll reports an ambiguous
failure, check vidiq_voiceover_list_voices before submitting again — the voice may
already exist.

Cost: 50 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Display name for the cloned voice (e.g. 'My Voice'). |
| `audioBase64` | string | Yes | Base64-encoded audio sample of a single consenting speaker. Must be a 60-600s MP3, WAV, or M4A clip. Video is not accepted — extract the audio first. |
| `contentType` | string | No | MIME type of the sample (e.g. 'audio/mpeg', 'audio/wav'). Defaults to audio/mpeg. |
| `description` | string | No | Optional description of the voice. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq voiceover clone start

**Slug:** `VIDIQ_MCP_VIDIQ_VOICEOVER_CLONE_START`

Start cloning the speaker's voice from a YouTube video.

Provide a public YouTube URL and a name for the voice. This runs asynchronously:
it returns an `mcpJobId` immediately — poll `vidiq_job_poll` with that id
until it completes, then use the returned `voiceId`.

Credits are charged on submit and automatically refunded if the clone fails.

Cost: 1 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | A name for the cloned voice, used to label it once the clone completes. |
| `youtubeUrl` | string | Yes | Public YouTube URL of a video whose voice should be cloned (watch / youtu.be / shorts URL). |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq voiceover generate

**Slug:** `VIDIQ_MCP_VIDIQ_VOICEOVER_GENERATE`

Generate a voiceover MP3 from a script.

Provide the script text (max 5000 characters) and a voiceId
from vidiq_voiceover_list_voices.

This runs asynchronously: it returns an `mcpJobId` immediately. Poll
`vidiq_job_poll` with that id until it is "completed" to get the audio
duration, character count, and hosted MP3 URL. Credits are charged on submit
and automatically refunded if generation fails.

Cost: 14 credit(s) per 1000 characters of script (rounded up).

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `output` | string ("url_only" | "url_and_audio") | No | How to return the completed audio. 'url_only' (default) returns the hosted MP3 URL. 'url_and_audio' also attaches the MP3 inline when the terminal poll first completes. |
| `script` | string | Yes | The text to synthesize into speech. |
| `voiceId` | string | Yes | Opaque voice identifier from vidiq_voiceover_list_voices. Copy it exactly as returned; do not modify or prefix it. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq voiceover list voices

**Slug:** `VIDIQ_MCP_VIDIQ_VOICEOVER_LIST_VOICES`

List the available voiceover voices.

Returns each voice's id, name, category, description, and an optional audio preview URL.
The user's own cloned/designed voices have isCustom=true and are listed first; prefer
them when the user asks for "my voice". Use the returned voiceId with vidiq_voiceover_generate.

Cost: 0 credit(s) per call.

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `voices` | array | Yes |  |

### Vidiq watch shortform content

**Slug:** `VIDIQ_MCP_VIDIQ_WATCH_SHORTFORM_CONTENT`

Watch one piece of short-form content from Instagram, TikTok, or YouTube and return a markdown scene-by-scene walkthrough.

Pass the full public URL. For YouTube Shorts, a /shorts/, watch, or youtu.be URL is accepted; the content is verified to be short-form. Call this tool in parallel to compare multiple pieces of short-form content.

This runs asynchronously: it returns an `mcpJobId` immediately — poll `vidiq_job_poll` with that id until it is "completed" to get the walkthrough. Credits are charged on submit and automatically refunded if the analysis fails.

DO NOT USE FOR:
- Long-form YouTube videos — use `vidiq_video_watch`.
- TikTok short links (vm.tiktok.com or tiktok.com/t/) — paste the full /@user/video/<id> URL.
- Bare platform IDs or Instagram shortcodes — pass a full URL.

Cost: 10 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `url` | string | Yes | Full URL to short-form content on Instagram, TikTok, or YouTube. TikTok short links and bare platform IDs are not supported. |
| `prompt` | string | No | Optional custom analysis instruction. Omit it for the tuned scene-by-scene walkthrough. Markdown output only; do not ask for JSON. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `status` | string | Yes | Always 'inprogress' on submit — the work runs asynchronously. |
| `message` | string | Yes | Human-readable next-step instruction for the caller. |
| `mcpJobId` | string | Yes | Opaque job id. Pass this to `vidiq_job_poll` to check progress and get the result. |

### Vidiq youtube search

**Slug:** `VIDIQ_MCP_VIDIQ_YOUTUBE_SEARCH`

Search all of YouTube for videos, channels, or playlists matching a query, with optional filters (topic, region, publish date, duration, channel). Use this when someone asks to "find videos about X", "search YouTube for Y", "find channels about Z", or wants results for a specific keyword.

Unlike vidiq_trending_videos (which returns what's hot right now) and vidiq_outliers (which finds videos over-performing relative to their channel), this is a general keyword search across the whole catalog. It returns raw YouTube search results, NOT keyword metrics — for search volume/competition use keyword research instead.

Use this tool to:
- Find videos, channels, or playlists by keyword (set 'type')
- Narrow results by topic, region, publish-date window, and (for videos) duration, definition (HD), or live/upcoming event type
- Search within a single channel by passing 'channelId'
- Sort by relevance, recency ('date'), or popularity ('viewCount')

Filters marked "Video only" require type='video'.

Cost: 5 credit(s) per call.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `type` | array | No | Kinds of result to return — any combination of video, channel, playlist. Defaults to all three. The video-only filters require type to be exactly ['video']. |
| `limit` | integer | No | Number of results to return |
| `order` | string ("relevance" | "date" | "viewCount" | "rating" | "title" | "videoCount") | No | Sort order. 'date' = newest, 'viewCount' = most viewed, 'videoCount' = channels with most videos. |
| `query` | string | Yes | Free-text search query (e.g. 'minecraft redstone tutorial') |
| `topic` | string ("music" | "christianMusic" | "classicalMusic" | "country" | "electronicMusic" | "hipHopMusic" | "independentMusic" | "jazz" | "musicOfAsia" | "musicOfLatinAmerica" | "popMusic" | "reggae" | "rhythmAndBlues" | "rockMusic" | "soulMusic" | "gaming" | "actionGame" | "actionAdventureGame" | "casualGame" | "musicVideoGame" | "puzzleVideoGame" | "racingVideoGame" | "rolePlayingVideoGame" | "simulationVideoGame" | "sportsGame" | "strategyVideoGame" | "sports" | "americanFootball" | "baseball" | "basketball" | "boxing" | "cricket" | "football" | "golf" | "iceHockey" | "mixedMartialArts" | "motorsport" | "tennis" | "volleyball" | "entertainment" | "humor" | "movies" | "performingArts" | "professionalWrestling" | "tvShows" | "lifestyle" | "fashion" | "fitness" | "food" | "hobby" | "pets" | "beauty" | "technology" | "tourism" | "vehicles" | "society" | "business" | "health" | "military" | "politics" | "religion" | "knowledge") | No | Restrict to a topic category (e.g. 'gaming', 'music', 'technology') |
| `channelId` | string | No | Restrict the search to a channel ID, @handle, or YouTube channel URL |
| `eventType` | string ("live" | "upcoming" | "completed") | No | Live broadcasts: 'live', 'upcoming', or 'completed'. Video only. |
| `regionCode` | string | No | ISO 3166-1 alpha-2 region code to localize results (e.g. 'US', 'DE') |
| `videoDuration` | string ("short" | "medium" | "long") | No | Length: short (<4min), medium (4-20min), long (>20min). Video only. |
| `publishedAfter` | string | No | Only results published after this RFC 3339 timestamp (e.g. '2026-01-01T00:00:00Z') |
| `publishedBefore` | string | No | Only results published before this RFC 3339 timestamp |
| `videoDefinition` | string ("high" | "standard") | No | Resolution: 'high' (HD) or 'standard' (SD). Video only. |

#### Output

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `results` | array | Yes |  |
