@hubfluencer/mcp 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,7 +28,7 @@ Hubfluencer app, and a scoped access token is saved locally to `~/.hubfluencer/c
28
28
  (mode 0600) — the MCP server reads it from there automatically.
29
29
 
30
30
  ```bash
31
- npx -y @hubfluencer/mcp login "Claude Code"
31
+ npx -y @hubfluencer/mcp@0.17.0 login "Claude Code"
32
32
  # 1. Open: https://app.hubfluencer.com/connect?code=ABCD-EFGH
33
33
  # 2. Confirm code: ABCDEFGH
34
34
  # 3. Click Approve. → ✓ Connected.
@@ -37,13 +37,14 @@ npx -y @hubfluencer/mcp login "Claude Code"
37
37
  Then register the server (no token env needed — it uses the stored credential):
38
38
 
39
39
  ```bash
40
- claude mcp add hubfluencer -- npx -y @hubfluencer/mcp
40
+ claude mcp add hubfluencer -- npx -y @hubfluencer/mcp@0.17.0 --profile creator
41
41
  ```
42
42
 
43
43
  Verify it connected:
44
44
 
45
45
  ```bash
46
46
  claude mcp list # → hubfluencer: ... ✓ Connected
47
+ npx -y @hubfluencer/mcp@0.17.0 doctor --profile creator
47
48
  ```
48
49
 
49
50
  ### Alternative: paste an access token
@@ -52,7 +53,14 @@ Create a token in the app (**Settings → Access tokens**, scoped `video:generat
52
53
  it **cannot** delete your account, change credentials, publish, or create more tokens), then:
53
54
 
54
55
  ```bash
55
- claude mcp add hubfluencer --env HUBFLUENCER_API_TOKEN=YOUR_TOKEN -- npx -y @hubfluencer/mcp
56
+ claude mcp add hubfluencer --env HUBFLUENCER_API_TOKEN=YOUR_TOKEN -- npx -y @hubfluencer/mcp@0.17.0 --profile creator
57
+ ```
58
+
59
+ Install the concise Agent Skill and its advanced reference in one command:
60
+
61
+ ```bash
62
+ npx -y @hubfluencer/mcp@0.17.0 install-skill --client claude-code
63
+ # clients: claude-code, codex, opencode, pi; add --project for project scope
56
64
  ```
57
65
 
58
66
  ### Environment variables
@@ -65,10 +73,34 @@ claude mcp add hubfluencer --env HUBFLUENCER_API_TOKEN=YOUR_TOKEN -- npx -y @hub
65
73
  | `HUBFLUENCER_CREDENTIALS` | no | `~/.hubfluencer/credentials.json` | Path to the device-link credentials file (`login` writes it; the server reads it as the token fallback). |
66
74
  | `HUBFLUENCER_INPUT_DIR` | no | current working dir | **Read confinement.** Every local file the agent uploads (video clips, product / logo / closing / poster images, catalog assets) must resolve **inside** this directory — a path outside it is refused. This is a security control: it stops an agent from reading arbitrary local files (`~/.ssh/...`, `.env`, …). |
67
75
  | `HUBFLUENCER_OUTPUT_DIR` | no | current working dir | **Write confinement.** Downloads via `save_path` (`make_video` / `wait_for_completion` / `download_result` / `create_tracking_video`) must resolve inside this directory and end in `.mp4`; anything outside is refused. |
76
+ | `HUBFLUENCER_MCP_PROFILE` | no | `full` | Tool discovery surface. `creator` exposes 31 high-level create, lifecycle, recovery, and delivery tools to reduce agent context; `full` preserves all 99 tools. CLI `--profile` takes precedence. |
77
+
78
+ ## Generation lifecycle authority
79
+
80
+ Every Editor and Short product read includes a non-null `generation_summary`. Treat it as the sole
81
+ lifecycle authority. Product status fields and `latest_render` describe authoring or delivery, not
82
+ another lifecycle. Poll only while
83
+ `generation_summary.timing.poll_after_ms` is a positive integer, at that server cadence; `null`
84
+ means stop polling. Read terminality from `generation_summary.status`, invoke only
85
+ `generation_summary.available_actions`, and download only when `download_result` is advertised for
86
+ a verified delivery artifact. Never derive polling, retry, cancel, or download availability from
87
+ product detail fields.
88
+
89
+ Editor lifecycle authority and Editor delivery freshness are separate contracts. The summary still
90
+ owns terminality and actions, while normalized `stale`, `active_segment_ids`, and
91
+ `stale_segment_ids` preserve the product's raw `latest_render.is_stale`, scene `video_stale`, and
92
+ narration/voice/music staleness. An active summary phase always wins. Once the summary is completed,
93
+ `stale:true` forces `ready:false` and `stage:"editing_required"`; the retained MP4 is historical and
94
+ must be re-rendered before delivery. Missing/unknown freshness is never proof that an old render is
95
+ current. The generic `list_projects.projects` lane is discovery metadata from the mixed-kind
96
+ `/video-factories` index and intentionally has no `generation_summary`; call `get_status` or
97
+ `get_editor` for authoritative lifecycle state.
68
98
 
69
99
  ## Tools
70
100
 
71
- 97 tools, grouped by workflow. Every tool prices its action in its own `description` — costs
101
+ 99 tools in the backward-compatible `full` profile, grouped by workflow. New agent setups should
102
+ use `--profile creator` for a focused 31-tool discovery surface and switch to `full` only for
103
+ granular campaign/operations work. Every tool prices its action in its own `description` — costs
72
104
  below are the ground truth. **"$0" means it spends no video credits**; planning/AI-helper tools
73
105
  instead draw a **free daily quota of 20 AI assists** (top up with `unlock_ai_assists`: 1 credit
74
106
  → +10). Reads need the `video:read` scope; writes need `video:generate`. Nothing here needs
@@ -81,15 +113,16 @@ instead draw a **free daily quota of 20 AI assists** (top up with `unlock_ai_ass
81
113
  | **`make_video`** | **One shot: prompt → finished MP4** (create → **price** → start → poll → download). `kind:"auto"` picks a multi-scene editor ad for ad/promo/story briefs, a short for simple ones (reported as `kind_inferred`). Pass `dry_run:true` to preview the cost without spending, or `max_credits` to cap it. | short **15**, editor ~**28** (`dry_run`/`max_credits` gate it) |
82
114
  | `create_short` | Create a short draft (12s vertical: two 6s AI segments + title overlay + music; 14s when it ends on a poster or brand-lockup end card). Set `headline` (≈4 words, ≤40 chars), `subheadline`, `music_vibe`, and an explicit `visual_language` (`kinetic_creator` is a strong default) — and **always `cta_text`** (a short without a CTA doesn't convert; blank `cta_text` → the server renders a neutral localized ask, e.g. "Learn more" — a truly CTA-less short is not currently supported). End-card fields: `closing_claim` (≤80), `brand_name` (≤40), `end_card` (`"auto"`\|`"none"`). Other opt-in conversion graphics: `offer_text`/`badge_text`/`star_rating` — only what you can substantiate. | **0** |
83
115
  | `update_short` | Patch an existing short draft — brief (`product_prompt`), copy, styling, end-card fields (`closing_claim`/`brand_name`/`poster_includes_lockup`/`end_card`), logo overlay placement (`short_logo_position`/`short_logo_treatment`), or the opt-in conversion graphics; only the fields you pass change. Clear one with `""` (`[]` for `text_beats`, `0` for `star_rating`). Apply text/style/CTA/end-card/logo edits to a generated short free with `rerender_short`; footage/music edits need `generate_short`. | **0** |
84
- | `generate_short` | Render an existing short — re-rolls the footage + music (fresh AI generation). If headline/subheadline/beats are all blank the server auto-writes the copy first (`skip_auto_text:true` for a deliberately bare clip). Safe to re-call (in-flight = reported, no double charge; a failed short can re-generate). | **15** |
85
- | `cancel_short_generation` | Stop the caller-observed paid short attempt, fence late workers from publishing, preserve the draft, and restore its 15 credits idempotently. Requires `generation_attempt` from `get_status`; stale commands cannot cancel a newer run. | **full refund** |
116
+ | `generate_short` | Render an existing short — re-rolls the footage + music (fresh AI generation). If headline/subheadline/beats are all blank the server auto-writes the copy first (`skip_auto_text:true` for a deliberately bare clip). Safe to re-call (in-flight = reported, no double charge; a failed or cancelled paid Short can re-generate when its summary advertises `start_generation`). | **15** |
117
+ | `cancel_short_generation` | Stop the caller-observed paid short run, fence late workers from publishing, preserve the editable draft, and restore its 15 credits idempotently. The MCP tool re-reads the canonical summary and sends its run fence automatically; callers may optionally supply `generation_run_id` to reject a stale command. Raw REST callers must send the latest `generation_summary.run_id` plus `Idempotency-Key`, reusing the key only for transport retries of this exact cancellation. After cancellation, re-read the summary and generate a successor only when it advertises `start_generation`. | **full refund** |
86
118
  | `rerender_short` | **FREE re-render** — applies the short's current text/style/CTA/end-card/logo state over the already-paid footage + music. Use after `update_short` for copy/style/CTA tweaks, or after a logo change (`set_short_logo`, or `short_logo_position`/`short_logo_treatment`); footage or music changes need `generate_short` instead. Needs one completed generation first (422 `short_not_ready` otherwise); changed footage/music inputs return 422 `short_paid_regeneration_required`. A failed free re-render leaves the delivered video intact — retry `rerender_short`, it stays free. | **0** |
87
119
  | `generate_short_text` | AI-draft editable headline / subheadline / caption beats for a short. | 1 assist |
88
- | `create_editor_ad` | Create an editor project, attach optional local product/logo/closing assets, and return the live autopilot quote. Omit `max_credits` to stop free; provide an approved cap to launch. Write every required person, product, object, and continuity decision directly in the prompt. | **0** until capped launch |
89
- | `start_autopilot` | Quote autopilot on an **existing** editor draft when called with only `slug`; launch only with an explicit `max_credits` that covers the estimate and an adequate balance. On a completed project, pass `restart:true` to quote and build a fresh creative run; omit it to resume pending edits. | **0** quote; credits on capped launch |
90
- | `retry_editor_batch` | Recover `batch_retry_required` by atomically re-queueing the failed scene and resuming its prepaid batch. If the parent Autopilot run is terminal, quote/relaunch it separately afterward. | **0 additional** |
91
- | `cancel_editor_batch` | Cancel an editor batch only while it is `preparing` or `paused_for_retry` (awaiting-previews/running batches are worker-owned and not cancellable). Preparing cancellation releases the uncharged preflight; paused cancellation is destructive prepaid credits are not refunded. | **0 additional** |
92
- | `cancel_autopilot` | Stop a **running** Autopilot run: flips `autopilot_status` to `cancelled` so the chain (scenario scenes narration voice music render) advances no further. Charged scenes stay charged and all completed work is kept; a step already enqueued may still finish. Idempotent a no-op when Autopilot isn't running. (Use `cancel_editor_batch` for a non-Autopilot prepaid batch, `cancel_segment_generation` for one scene.) | **0 additional** |
120
+ | `create_editor_ad` | Create an editor project, attach optional local product/logo/closing assets, and return the live autopilot quote. Pass `segments_count` (3–10) as the exact structural target. Omit `max_credits` to stop free; provide an approved cap to launch. Write every required person, product, object, and continuity decision directly in the prompt. | **0** until capped launch |
121
+ | `start_autopilot` | Quote autopilot on an **existing** editor draft when called with only `slug`; `segments_count` (3–10) overrides an older brief and is reflected in the matching quote. Launch only with an explicit `max_credits` that covers the estimate and when `generation_summary.available_actions` advertises `start_generation`. A completed Autopilot run additionally requires `restart:true`; non-completed starts reject it. | **0** quote; credits on capped launch |
122
+ | `retry_editor_batch` | Invoke only when the authoritative summary advertises `retry_generation` for the observed batch; atomically re-queues the exact failed scene, preview, render, or delivery step and resumes its prepaid batch. The route returns only the updated `generation_summary`; only a named failed scene (`batch_generation_failed_position`) may be repaired first — positionless render/delivery work is not authoring permission. If the parent Autopilot run is terminal, quote/relaunch it separately afterward. | **0 additional** |
123
+ | `cancel_editor_batch` | Invoke only when the authoritative summary advertises `cancel_generation` for the observed batch (any active batch, pay-as-you-go or prepaid, or a failed in-place batch parked for retry). Use it to unlock a permanently failed project without paying for another provider retry. Completed scenes stay settled; charges for scenes that never delivered are refunded on settlement. The raw REST route requires `Idempotency-Key`; reuse one key only for transport retries of the same observed batch command. | **0 additional** |
124
+ | `cancel_autopilot` | Invoke only when the authoritative summary advertises `cancel_generation` for Autopilot. The tool re-reads and forwards the observed canonical `generation_run_id`, so a delayed predecessor cancel cannot stop a successor. Charged scenes and completed work remain, and an already-running provider call may still finish. Transport retries are idempotent for that observed run; once the action disappears, the tool fails closed without POST. | **0 additional** |
125
+ | `provide_generation_input` | Resolve the exact advertised `edit_required_input` or `review_spend_cap` action for an Editor or Short. The tool re-reads and forwards the run, revision, and blocking-step fences; stale actions fail closed. | **0 additional** |
93
126
  | `create_slider` | Create an image-carousel draft: one prompt → N still slides + a ready-to-post caption + hashtags. `mode` `creative` (story) or `ad_driven` (facts). | **0** |
94
127
  | `generate_slider` | Render a carousel (copy → AI backgrounds → composite). Poll `get_slider` until `completed`. | **1 / slide** (3–10) |
95
128
  | `get_slider` | Read a carousel's status and, when completed, the per-slide image URLs + caption + hashtags. | **0** |
@@ -102,16 +135,17 @@ instead draw a **free daily quota of 20 AI assists** (top up with `unlock_ai_ass
102
135
  | Tool | What it does | Cost |
103
136
  |---|---|---|
104
137
  | `create_editor_draft` | Editor project, **no** autopilot. Accepts `creative_format` / `visual_language` / `theme`; the prompt is the complete scene-content contract. | **0** |
105
- | `get_editor` | Full project state by default for compatibility; pass `response_format:"concise"` for a smaller review projection. | **0** |
138
+ | `get_editor` | Concise project review by default; pass `response_format:"full"` for all authoring details. Both formats validate and include the required `generation_summary`. | **0** |
106
139
  | `set_scenario` / `generate_scenario` | Write your own scenario (free) **or** AI-draft it. `generate_scenario` can also persist `creative_format` / `visual_language` / `theme`. | free / 1 assist |
107
140
  | `apply_scenario` | Compile the **ready** scenario into per-scene prompts on the timeline (`segments_count` 0 or 3..10; omitted uses the generated scenario count, then 5; AI scenes replaced, uploads preserved). Polls until applied (~2 min budget). | **0** |
108
141
  | `set_scene_count` | Grow/shrink to N scenes (1–20); deletes only trailing un-generated scenes. Each AI scene is a fixed 8s. | **0** |
109
142
  | `set_segment_prompt` | Write one scene's prompt (1–2000 chars), identified by segment id. | **0** |
110
143
  | `generate_segment` | Render one **pending/failed** scene (re-call to retry a failed one). | **5** |
111
- | `cancel_segment_generation` | Stop the caller-observed individually generated scene, fence its provider job from publishing, and restore any charged credits idempotently. Requires that scene's `generation_claim_token` from `get_editor`; stale commands cannot cancel a newer attempt. Batch/Autopilot scenes use their workflow-level controls. | **full refund** |
144
+ | `retry_segment_generation` | Retry the exact failed Generation Kernel scene run in place only when its summary advertises `retry_generation`. Re-reads and echoes the run, revision, step, and materialized scene fences; it never creates a replacement run. | **0 additional** |
145
+ | `cancel_segment_generation` | Stop the caller-observed individually generated scene, fence its provider job from publishing, and restore any charged credits idempotently. Requires that scene's `generation_claim_token` from `get_editor`; stale commands cannot cancel a newer attempt. The raw REST route requires `Idempotency-Key`; reuse one key only for transport retries of this exact cancellation. Batch/Autopilot scenes use their workflow-level controls. | **full refund** |
112
146
  | `regenerate_segment` | Re-roll a **completed** scene as a new version (optional new `prompt`). Mid-timeline: the next scene's transition can degrade because it was seeded from the old version's last frame. | **4** |
113
147
  | `generate_all_segments` | Render every not-yet-completed scene in order (continuity preserved); capped ~280s → re-run to continue. | **5 / segment** |
114
- | `set_narration_script` / `generate_narration` | Write your own voiceover script (free) **or** AI-draft one coherent script after every scene has completed with a known positive duration. AI drafting requires at least one scene without retained original audio and consumes an assist only when a fresh job is queued (exact retries dedupe for free). | free / 1 assist |
148
+ | `set_narration_script` / `generate_narration` | Write the exact words to read aloud (free)—never pass a production prompt, camera directions, or a creative brief as `script`—**or** AI-draft one coherent script after every scene has completed with a known positive duration. AI drafting requires at least one scene without retained original audio and consumes an assist only when a fresh job is queued (exact retries dedupe for free). | free / 1 assist |
115
149
  | `generate_voice` | Synthesize the voiceover. `voice_id` required (see `list_voices`). | **3** |
116
150
  | `generate_music` | Generate background music (each call is a fresh take). Optional `instruments` is a string array (≤10 non-empty hints, ≤80 chars each), not a comma-separated string. | **5** |
117
151
  | `render` | Final MP4. Auto-charges and generates any pending or failed scenes first (4/scene in a batch of ≥3). | **0** |
@@ -137,58 +171,55 @@ images at **8 MiB (8,388,608 bytes)**; closing/short/catalog images at **20 MiB
137
171
  | `set_closing_image` | Set the ~2s end-card image (JPEG/PNG, ≤20 MiB; upload a file, or reuse the product image with `from_product:true`). |
138
172
  | `set_logo` | Upload a brand logo overlay (JPEG/PNG, ≤5 MiB; editor only; optional treatment/position/duration). |
139
173
  | `set_short_product` | Attach a product image (JPEG/PNG, ≤20 MiB) to a **short**. |
140
- | `set_short_logo` | Attach an exact deterministic logo overlay (JPEG/PNG, ≤5 MiB) to a **short**; choose its preferred corner and `throughout`/`end_card`/`none` (hide) treatment. Forge moves it away from text/CTA/chips. The logo is never sent to the video model. |
174
+ | `set_short_logo` | Attach an exact deterministic logo overlay (JPEG/PNG, ≤5 MiB) to a **short**. The corner is preferred and Forge moves it away from text/CTA/chips. Omit treatment to auto-select: transparent marks use `throughout`, opaque square lockups use `end_card`; explicit `throughout`/`end_card`/`none` still wins. The logo is never sent to the video model. |
141
175
  | `set_short_poster` | Set a short's end-card poster (JPEG/PNG, ≤20 MiB; extends the render 12s → 14s). Phone-shaped portrait art is cover-cropped to 9:16; square, classic portrait, and landscape art is contained over a blurred backdrop. Pass `poster_includes_lockup:true` if the poster already carries brand name/CTA/badges — suppresses the overlaid claim/CTA and an end-card-only logo so they don't collide. |
142
176
 
143
177
  ### Status & delivery
144
178
 
145
179
  | Tool | What it does |
146
180
  |---|---|
147
- | `get_status` | Normalized `{stage, terminal, ready, video_url, error}` for a short / editor / tracking / slider. While a paid short is rendering, also exposes `segments_completed`, `segments_total`, and `active_segment_positions`; `generation_attempt` is the cancellation fence. |
148
- | `wait_for_completion` | Block-poll until terminal (bounded ≤280s; returns `terminal:false` to re-call). `save_path` downloads the MP4 when ready. |
149
- | `download_result` | Get (or save, to `HUBFLUENCER_OUTPUT_DIR`) the finished MP4 URL. Not for sliders — use `get_slider`. |
150
- | `get_credits` / `list_voices` / `list_projects` | Credit balance; narration voices (including normalized verified `languages`); recent projects (`include_completed:true` to recover a finished short's slug). |
181
+ | `get_status` | For Editor/Short, validates and passes through the required `generation_summary`; normalized lifecycle fields come from that authority. Editor delivery freshness remains a separate product diagnostic: a completed summary with raw staleness becomes `stage:"editing_required"`, `ready:false`, `stale:true`. Canonical run/revision/step identities remain explicit command fences only. Tracking/slider keep their product-specific contracts. |
182
+ | `wait_for_completion` | Block-poll Editor/Short only while `generation_summary.timing.poll_after_ms` is positive, at the server cadence (bounded ≤280s; returns `terminal:false` to re-call). `save_path` downloads only when `download_result` is advertised. |
183
+ | `download_result` | Get (or save, to `HUBFLUENCER_OUTPUT_DIR`) the finished MP4 only when the current summary advertises `download_result` for a verified delivery artifact. Not for sliders — use `get_slider`. |
184
+ | `get_credits` / `list_voices` / `list_projects` | Credit balance; narration voices (including normalized verified `languages`); recent projects (`include_completed:true` to recover a finished short's slug). Shorts are summary-bearing; mixed Editor/campaign/creative factory rows are lightweight discovery records, so use a product status tool before acting. |
151
185
  | `get_ai_assists` / `unlock_ai_assists` | The free daily assist quota / spend 1 credit for +10. |
152
186
 
153
187
  ### Creative export contract
154
188
 
155
- - Production prompts (`product_prompt`, `scenario_prompt`, and scene `prompt`) are visual directions. Narration scripts are read aloud verbatim, so `set_narration_script.script` must contain only the exact spoken words—never camera notes, prompt syntax, labels, or scene directions. Prefer `generate_narration` or Autopilot when exact wording is unnecessary.
189
+ - Production prompts (`product_prompt`, `scenario_prompt`, and scene `prompt`) are visual directions. Narration scripts are read aloud verbatim, so `set_narration_script.script` must contain only the exact spoken words—never camera notes, prompt syntax, labels, or scene directions. Never copy a creative brief into `script`; prefer `generate_narration` or Autopilot unless the user supplied final voice-over copy.
156
190
  - Do not rely on the video model to spell essential brand names, UI, signs, prices, offers, or CTAs. Put exact copy in Hubfluencer overlays, narration, or supplied ending artwork.
157
- - `short_logo_position` is a preferred corner. Forge moves the logo away from headline, captions, CTA, offer, and badge areas. Use a tight transparent wordmark; use square/full-bleed art as the poster. `end_card` logos are suppressed when `poster_includes_lockup:true` to avoid double branding.
191
+ - `short_logo_position` is a preferred corner. Forge moves the logo away from headline, captions, CTA, offer, and badge areas. Omit treatment so transparent marks default to `throughout` and opaque square lockups default to `end_card`. Use a tight transparent wordmark; use square/full-bleed art as the poster. `end_card` logos are suppressed when `poster_includes_lockup:true` to avoid double branding.
158
192
  - Short posters fill the ending frame: phone-shaped portrait art is cover-cropped, while square, classic portrait, and landscape art is contained over a blurred backdrop. Editor closing images are always cover-cropped. Keep important content in the central 9:16 safe area. An Editor closing image gets no generic CTA, so put the CTA in the artwork or state it in the preceding narration/scene.
159
193
  - Each Editor AI scene is 8 seconds. Request 3 scenes (about 24 seconds) for a concise social ad unless the brief needs a longer story.
160
194
 
161
- For editor projects, `video_url` may remain the last delivered MP4 after the timeline changes.
162
- It is current only when `ready:true` and `stale:false`. `stale:true` means the delivered render
163
- does not match the live timeline; regenerate the reported stale scenes/audio and render again.
164
- An absent/`null` server `is_stale` is **unknown** (for example a legacy render), not proof that
165
- the render is current. Failure stages take precedence over active stages and are terminal.
166
-
167
- Editor state uses `narration_status` (`none | generating | ready | failed`),
168
- `current_audio`, and `current_music` (selected version status `pending | processing |
169
- completed | failed`). Batch state is `idle | preparing | awaiting_previews | running |
170
- paused_for_retry | paused_insufficient_credits | completed | cancelled | failed`.
171
- Only `paused_for_retry` is resumed by `retry_editor_batch`; `cancel_editor_batch` works
172
- only while the batch is `preparing` or `paused_for_retry` awaiting-previews/running
173
- batches are worker-owned and cannot be cancelled. While `paused_for_retry` you may first
174
- REPAIR the one failed scene before retrying: `set_segment_prompt` edits its prompt (and
175
- `use_previous_frame`), but only for the exact failed position the server names in
176
- `batch_generation_failed_position` the rest of the paused batch stays mutation-locked, and
177
- explicit paused retries are capped (`free_retries_exhausted`). Preparing cancellation releases
178
- the uncharged preflight (nothing was charged yet); paused cancellation is destructive and
179
- non-refundable. To stop a **running** parent Autopilot run (not a paused batch), use
180
- `cancel_autopilot` — it flips `autopilot_status` to `cancelled`, keeps completed work and
181
- charged scenes, and is a no-op once the run has finished. Both tools re-read the editor state and echo `expected_batch_run_id` +
182
- `expected_batch_status` with the REST command, so a phase change between poll and command
183
- is a safe 409 `batch_command_stale` (re-poll and retry) instead of acting on newer work;
184
- the REST endpoints reject editor commands that omit these fields with 409
185
- `batch_command_required` (client >= 0.12 sends them automatically). For
186
- `paused_insufficient_credits`, top up or reduce scope and invoke generation/render again.
195
+ For Editor/Short, `generation_summary` owns terminality, progress, blockers, failure, cost, polling,
196
+ and action availability. Normalized lifecycle formatting is derived from that validated contract.
197
+ Editor staleness is the deliberate exception: product wire fields decide whether a completed
198
+ artifact still represents the current timeline, and a stale completed Editor is not ready even if
199
+ the historical summary advertises `download_result`. `download_result` is otherwise the delivery
200
+ signal; it is absent for completed scene, narration, audio, and non-render batch workflows.
201
+
202
+ Editor `narration_status`, `current_audio`, `current_music`, `latest_render`,
203
+ and batch progress fields remain display data and never create retry/cancel availability.
204
+ Product projection fields are display metadata or explicit route fences only; never derive
205
+ polling, retry, cancel, or download availability from them.
206
+ When `generation_summary.available_actions` advertises a batch retry or cancel, use the matching
207
+ MCP tool. It re-reads the summary and echoes its canonical `generation_run_id`; an `editor.batch`
208
+ retry also echoes `generation_summary.revision` as `generation_revision`. Raw REST callers must do
209
+ the same. Missing or malformed fences fail with 422 `batch_command_required`; a fence that was
210
+ valid but moved on fails safely with 409 `generation_authority_changed`, so re-read and re-issue.
211
+ While retry is advertised, only the server-named
212
+ failed scene may be repaired; included retry caps and cancellation/refund semantics still apply.
187
213
 
188
214
  For raw REST Autopilot calls, reuse one `Idempotency-Key` only for transport retries of the
189
215
  same logical launch. Mint a fresh key for a deliberate resume, restart, or changed cap; a
190
216
  successful response is replayed for 24 hours under the old key.
191
217
 
218
+ Every raw REST generation cancellation now requires `Idempotency-Key`: Short generation, Editor
219
+ Autopilot, Editor scene, and Editor batch cancellation. Reuse a key only for transport retries of
220
+ the same fenced command. A deliberate successor command gets a fresh key. Missing keys fail with
221
+ 422 `idempotency_key_required` before the mutation runs.
222
+
192
223
  ### Campaign engine — onboard a product, plan, and draft (the delegation surface)
193
224
 
194
225
  Everything here is **$0** (draft creates + planning against the free assist quota). Generation
@@ -298,7 +329,18 @@ If it returns `terminal:false`, the render is still going — call `wait_for_com
298
329
  `create_short` → optional `generate_hook_variations` (test hook angles free) / `generate_short_text` → `generate_short` → `wait_for_completion {kind:"short"}` → `download_result`, or
299
330
  `create_editor_ad` (free configure + quote) → obtain spend approval → `start_autopilot {slug, max_credits}` → `wait_for_completion {kind:"editor"}` → `download_result`.
300
331
 
301
- If waiting returns `stage:"batch_retry_required"`, call `retry_editor_batch` to continue the prepaid failed scene (optionally repairing its prompt first with `set_segment_prompt` see the batch-state notes above), or `cancel_editor_batch` to abandon the batch. Resolve that child batch before calling `start_autopilot` again; a retry does not itself authorize a new parent Autopilot run. To halt a **running** Autopilot run outright, call `cancel_autopilot`.
332
+ If the returned `generation_summary.available_actions` advertises a batch `retry_generation` or
333
+ `cancel_generation`, call the matching Editor batch tool (optionally repair only the server-named
334
+ failed scene first). Resolve that child batch before calling `start_autopilot` again; a retry does
335
+ not itself authorize a new parent Autopilot run. Call `cancel_autopilot` only when the current
336
+ Autopilot summary advertises `cancel_generation`; the tool forwards that summary's run/start fence,
337
+ so a stale predecessor request fails instead of cancelling a successor.
338
+
339
+ If a stopped summary advertises `edit_required_input` or `review_spend_cap`, call
340
+ `provide_generation_input` with the advertised action and its input object or approved
341
+ `max_credits`. If a failed `editor.scene.generate` or `editor.scene.regenerate` summary advertises
342
+ `retry_generation`, call `retry_segment_generation` with that materialized `segment_id`. Both tools
343
+ re-read the summary and fail closed if the run/revision/step changed.
302
344
 
303
345
  **Iterate a short for free (never re-roll):** the first `generate_short` (15 credits) buys the footage +
304
346
  music; after that, every text/style/CTA/end-card/logo tweak re-renders over them for **0 credits** —
@@ -352,7 +394,7 @@ start a NEW project (omit `slug`, pass `video_path`).
352
394
  | `/mcp` → **Failed to reconnect: -32000** | The server process never started — almost always because `claude mcp add` was run **inside a Claude session** (a nested `claude` runs the line as a prompt, not the subcommand), so nothing was registered. Re-run the `claude mcp add` above in a **normal terminal**, then `claude mcp list` to confirm. |
353
395
  | `npm error could not determine executable to run` | You're on a cached **0.1.x** (which shipped two bins). 0.2.0+ ships a single bin and resolves cleanly. Force a fresh fetch: `npx --ignore-existing -y @hubfluencer/mcp`. |
354
396
  | `npm error 404 … @hubfluencer/mcp` immediately after a release | npm registry/CDN propagation lag (a couple of minutes after publish). Wait and retry — it self-heals. |
355
- | Tools fail with **"Not connected to Hubfluencer"** | No token resolved. Run `npx -y @hubfluencer/mcp login`, or pass `--env HUBFLUENCER_API_TOKEN=…`. |
397
+ | Tools fail with **"Not connected to Hubfluencer"** | No token resolved. Run `npx -y @hubfluencer/mcp@0.17.0 login`, or pass `--env HUBFLUENCER_API_TOKEN=…`. |
356
398
  | A local-file tool fails with a **path-outside-base** error | The file is outside `HUBFLUENCER_INPUT_DIR` (reads) or `save_path` is outside `HUBFLUENCER_OUTPUT_DIR` (writes). Move the file into the allowed dir, or point the env var at it. |
357
399
  | An asset-catalog tool returns **subscription required** | `list_assets` / `get_asset_quota` / `upload_asset` need an active subscription — subscribe in the app. |
358
400
 
@@ -367,7 +409,22 @@ bun run build # emits dist/
367
409
 
368
410
  The package exposes a single bin, `hubfluencer-mcp`: with no args it starts the stdio MCP
369
411
  server; `hubfluencer-mcp login [name]` runs the device-link login. This is why
370
- `npx -y @hubfluencer/mcp` and `npx -y @hubfluencer/mcp login` both work without `-p`.
412
+ `npx -y @hubfluencer/mcp@0.17.0` and `npx -y @hubfluencer/mcp@0.17.0 login` both work without `-p`.
413
+
414
+ ### Release
415
+
416
+ Publish npm before the official MCP Registry: the Registry hosts metadata and
417
+ verifies the already-public package's `mcpName`, name, and version.
418
+
419
+ ```bash
420
+ bun run release
421
+ npm view @hubfluencer/mcp version
422
+ mcp-publisher login github
423
+ bun run release:registry
424
+ ```
425
+
426
+ Deploy the developer page only after npm reports the matching version, because
427
+ its copy-and-paste setup commands are intentionally pinned to that release.
371
428
 
372
429
  ## License
373
430