> ## Documentation Index
> Fetch the complete documentation index at: https://docs.videngineer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Analyses

> MCP tools for listing, searching, analyzing, polling, reading, and bundling teardowns on your account.

Library tools: browse and search your analyses, start a teardown, poll status, read one report, or package several for an external generation tool.

Parent: [Connector API](/agents/connector-api). All of these are **`mcp:read`** except `analyze_video` (**`mcp:analyze`**).

***

## `list_analyses`

List the analyses on your account, newest first — `job_id`, title, status, created date.

**Charges:** read-only, 0 credits.

**Byte budget:** first page of 25 ≈ **5.1 KB wire / \~3.4 KB compact** (measured).

### Parameters

| Name     | Type   | Allowed / notes                                  | Default |
| -------- | ------ | ------------------------------------------------ | ------- |
| `limit`  | int    | 1–**60**                                         | `25`    |
| `offset` | int    | ≥ 0                                              | `0`     |
| `query`  | string | Optional title filter; max 120 chars on the wire | `""`    |

### Example call

```text theme={null}
list_analyses(limit=25, offset=0)
```

### Example response (trimmed — real excerpt)

```json theme={null}
{
  "count": 25,
  "limit": 25,
  "offset": 0,
  "has_more": true,
  "next_offset": 25,
  "analyses": [
    {"job_id": "2356a0d6d6ad", "title": "SOL hook-label dogfood — prompt change proof", "status": "complete"},
    {"job_id": "d4433eec4255", "title": "X", "status": "complete"},
    {"job_id": "50d79f04d723", "title": "X", "status": "complete"}
  ],
  "note": "Pass a job_id to get_report(), or several to get_context_bundle()."
}
```

***

## `find_analyses`

Find useful references in **your** analysis library. Filters and paging are free; results contain no analysis bodies or media URLs. Pass `intent` for five semantically relevant references with inspectable scores (recommend mode — see [Discovery](/agents/api-discovery)).

**Charges:** read-only, 0 credits. **Scope:** `mcp:read`.

**Byte budget:** keyword shortlist of 5 ≈ **2.2 KB wire / \~1.4 KB compact**. Recommend-empty envelope ≈ **58 B compact** until labeler backfill.

### Parameters

| Name             | Type   | Allowed / notes                                                                                                           | Default    |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `query`          | string | Free-text match on titles; max 120 chars                                                                                  | `""`       |
| `hook_type`      | string | Hook carrier when stamped — e.g. `promise`, `contradiction`, `big_claim`, `question`, `cold_open`, `story_open`, `reveal` | `""`       |
| `format`         | string | Format key filter (e.g. `launch`)                                                                                         | `""`       |
| `min_hook_score` | number | Clamped to `0..10`                                                                                                        | `0`        |
| `sort`           | string | `newest`, `oldest`, `viral`, `hook`, `scenes`, `az` (unknown → `newest`)                                                  | `"newest"` |
| `limit`          | int    | Connector max **25**                                                                                                      | `25`       |
| `offset`         | int    | ≥ 0                                                                                                                       | `0`        |
| `intent`         | string | When set (max 500 chars), recommend path; empty keyword filters still apply on the keyword path                           | `""`       |

### Example call

```text theme={null}
find_analyses(query="launch", sort="viral", limit=5)
```

### Example response (trimmed — real excerpt; keyword path)

```json theme={null}
{
  "total": 26,
  "limit": 5,
  "offset": 0,
  "has_more": true,
  "next_offset": 5,
  "analyses": [
    {
      "title": "Thariq - Lots of people asked how I used Fable to edit its own launch video so...",
      "duration": 399.381,
      "hook_score": 8,
      "format_key": ["tutorial"],
      "scene_count": 30,
      "job_id": "0322815c4dbd"
    },
    {
      "title": "MG Buff Motion × Fresco — Brand Launch Promo",
      "duration": 44.002,
      "hook_score": 7,
      "format_key": ["cinematic"],
      "scene_count": 6,
      "job_id": "69633490748e"
    }
  ]
}
```

Rows may also expose `metric_views` when present (inspectable viral ordering). No bodies, no media URLs.

**Recommend mode** (`intent` set) — honest empty until backfill:

```json theme={null}
{"recommendation": true, "count": 0, "analyses": [], "bytes": 58}
```

***

## `analyze_video`

**SPENDS CREDITS:** starts a new analysis on your plan. Reverse-engineers a video from a supported URL. Returns a `job_id` — pass it to `get_report()` once it is done (\~90 seconds).

**Charges:** plan minutes/credits (same as starting a teardown in the app). Unsupported URL → `charged: 0`, no request. **Scope:** `mcp:analyze`. Annotation title: *Analyze a video — spends plan minutes/credits*.

### Parameters

| Name    | Type   | Allowed / notes         | Default  |
| ------- | ------ | ----------------------- | -------- |
| `url`   | string | Absolute `http`/`https` | required |
| `label` | string | Name in your Library    | `""`     |

**Supported sources** (connector-side check before the request): YouTube, TikTok, Instagram, Vimeo, X/Twitter, Google Drive, or a direct `.mp4` URL.

### Example call

```text theme={null}
analyze_video("https://www.youtube.com/watch?v=EXAMPLE", label="Launch study")
```

### Example response (shape from code)

```json theme={null}
{
  "job_id": "EXAMPLE_JOB_ID",
  "status": "queued",
  "note": "Call get_report(job_id) to retrieve the breakdown (usually ready in ~90s)."
}
```

Unsupported URL (no charge):

```json theme={null}
{
  "error": "Use a supported absolute video URL: YouTube, TikTok, Instagram, Vimeo, X/Twitter, Google Drive, or direct .mp4.",
  "charged": 0
}
```

***

## `get_status`

Check whether an analysis is queued, running, complete, or errored.

**Charges:** read-only, 0 credits. **Scope:** `mcp:read`.

**Byte budget:** tiny (\~tens of bytes).

### Parameters

| Name     | Type   | Allowed / notes | Default  |
| -------- | ------ | --------------- | -------- |
| `job_id` | string | Analysis id     | required |

### Example call

```text theme={null}
get_status("EXAMPLE_JOB_ID")
```

### Example response

```json theme={null}
{
  "job_id": "EXAMPLE_JOB_ID",
  "status": "running",
  "progress": 0.55
}
```

***

## `get_report`

Read one analysis from your library. `preset="lean"` (default) is the compact read: hook, scorecard verdict + top moves, beat preview, voice, counts. `preset="full"` adds the complete blueprint, transcript, script analysis, voice profile, recreation prompts, technique clusters, cast, and ROI. Or pass `fields=[...]` to pull exactly what you need (see `available_fields` in the lean response). If `wait=True` (default), polls until complete (up to \~5 minutes / `VIDENGINEER_WAIT_CAP`).

**Charges:** read-only, 0 credits. **Scope:** `mcp:read`.

**Byte budget:** lean is small (\~2–3 KB class). Full is large — prefer lean or `fields`.

### Parameters

| Name     | Type                    | Allowed / notes                                               | Default  |
| -------- | ----------------------- | ------------------------------------------------------------- | -------- |
| `job_id` | string                  | Analysis id                                                   | required |
| `preset` | string                  | `lean` \| `full`                                              | `"lean"` |
| `fields` | list of strings or null | Exact keys from `available_fields`; overrides preset when set | `null`   |
| `wait`   | bool                    | Poll until complete when true                                 | `true`   |

`available_fields` (full map keys, alphabetical as returned): `assets`, `beats`, `blueprint`, `cast`, `classification`, `hook_report`, `recreation_prompts`, `roi`, `scene_clusters`, `scorecard`, `script`, `style_card`, `transcript`, `voice_profile` — prefer dedicated `get_cast` / `get_sound` for those packages.

### Example call

```text theme={null}
get_report("EXAMPLE_JOB_ID", preset="lean")
```

### Example response (lean shape)

```json theme={null}
{
  "job_id": "EXAMPLE_JOB_ID",
  "owned": true,
  "status": "complete",
  "video": "Contradiction launch — product cold open",
  "hook_type": "contradiction",
  "hook": "Everyone says ship weekly. We ship when it's right.",
  "scorecard": {
    "overall": 8.4,
    "verdict": "Strong open; middle sags before the product turn",
    "top_moves": [
      "Hook 9/10 — contradiction lands in the first line",
      "Pacing 8/10 — holds the pause long enough to hurt"
    ]
  },
  "beats_preview": [
    "0:00 · cold_open — hands only · text:\"Everyone says ship weekly\"",
    "0:04 · product_reveal — device on desk"
  ],
  "voice": "male · 30s · calm · measured · dry · mid energy",
  "counts": {
    "scenes": 24,
    "duration_seconds": 91,
    "recreation_prompts": 18,
    "keyframes": 40
  },
  "assets": { "thumb_url": "<signed thumbnail URL>" },
  "available_fields": [
    "assets", "beats", "blueprint", "cast", "classification",
    "hook_report", "recreation_prompts", "roi", "scene_clusters",
    "scorecard", "script", "style_card", "transcript", "voice_profile"
  ],
  "note": "Lean view. get_report(job_id, preset=\"full\") or fields=[...] for more."
}
```

Still running (when `wait` is false or the cap expires):

```json theme={null}
{
  "job_id": "EXAMPLE_JOB_ID",
  "status": "running",
  "progress": 0.42,
  "note": "Not finished yet — call get_report again in a bit."
}
```

***

## `get_context_bundle`

Package 1–10 of **your** analyses into one generation-ready payload for an external image/video tool.

**Charges:** read-only, 0 credits. **Scope:** `mcp:read`.

**Byte budget:** `hooks_only` / `synthesis` stay small; `remix` on one video is larger (beats, style, voice, capped transcript, recreation prompts, keyframe URLs). Prefer synthesis for multi-video comparison.

### Parameters

| Name           | Type            | Allowed / notes                                               | Default   |
| -------------- | --------------- | ------------------------------------------------------------- | --------- |
| `analysis_ids` | list of strings | 1–10 unique job ids (hard cap 10; extras dropped with a note) | required  |
| `preset`       | string          | `remix` \| `synthesis` \| `hooks_only`                        | `"remix"` |

| Preset       | Best for             | Shape                                                                               |
| ------------ | -------------------- | ----------------------------------------------------------------------------------- |
| `remix`      | One video, deep dive | Beats, pacing, style, voice, transcript (capped), recreation prompts, keyframe URLs |
| `synthesis`  | Comparing N videos   | `pattern_layer` + thin per-video refs; no transcripts                               |
| `hooks_only` | Opening comparison   | Hooks, opening beats, scorecard slice                                               |

Ids you do not own land in `not_owned` as redacted previews. Incomplete analyses land in `unavailable`.

### Example call

```text theme={null}
get_context_bundle(
  ["JOB_A", "JOB_B", "JOB_C"],
  preset="synthesis"
)
```

### Example response (synthesis shape, trimmed)

```json theme={null}
{
  "preset": "synthesis",
  "requested": 3,
  "included": 3,
  "truncated": false,
  "pattern_layer": {
    "videos_merged": 3,
    "common_beats": [
      { "scene_type": "cold_open", "in_videos": "3/3", "avg_position_pct": 0 }
    ],
    "divergent_hooks": [
      { "id": "JOB_A", "title": "…", "hook_type": "contradiction", "hook": "…" }
    ],
    "shared_voice_traits": { "tone": "calm", "pace": "measured" }
  },
  "videos": [
    {
      "id": "JOB_A",
      "owned": true,
      "title": "Contradiction launch — product cold open",
      "hook_type": "contradiction",
      "duration_seconds": 91,
      "scene_count": 24
    }
  ]
}
```

Recreation prompts (remix) are image-first: still from `image_prompt`, animate with `video_prompt`, keep on-screen text in your editor, swap `[YOUR PRODUCT]` / `[YOUR TEXT]` placeholders.
