Skip to content

Script tools

Everything that produces or changes a script. In practice you call generate_script and then edit_script until the words are right; the other three are for reading state and for the cases where you want to be explicit.

generate_script

Start generating a social-video script, either from existing reporting (an article URL, pasted text, or an uploaded document) or, with `brief`, from a story the user describes and wants written for them. When the user has ALREADY WRITTEN the narration and wants it used as is, pass it as `script_text` instead: it is saved word for word, nothing is generated, and the returned script_id is ready for create_video_from_script immediately. Call this ONCE per story: it runs in the background and returns a script_id immediately; poll with get_generation_status and revise with edit_script. Calling it again for a story you already started returns the SAME script rather than writing a second one. Style settings omitted here fall back to the user's saved defaults. Documents uploaded in this conversation are attached automatically; you do not need to pass their URLs.

ParameterTypeDescription
sourcestringArticle URL or the full article text. Optional when the user uploaded a document to work from, or when you're passing a brief instead.
briefstringUse when there is NO article and the user wants the story written for them (e.g. announcing a partnership, a product, an event). Write the brief yourself from what the user told you: what the story is, who/what it names, the angle, the audience, and anything they want it to end on. Everything factual in it must come from the user. Confirm the scope with them first and never invent facts, figures, or quotes. Ignored if `source` is provided.
script_textstringThe user's own finished narration, to be spoken exactly as written. Saved verbatim with no rewriting and no generation; timing marks such as [1.9] or (0:03) are stripped so they are not read aloud. Use whenever the user pasted the words and wants THOSE words; never paraphrase them into a brief. Takes precedence over source and brief. (To lay narration over a video the user attached, use create_video_from_upload with narration_lines instead.)
titlestringOptional headline for the script.
force_newbooleanWrite a second, separate script for a story this conversation already covered. Only when the user explicitly wants a fresh take from scratch. To change an existing script, use edit_script.
article_file_urlstringURL of an uploaded document (PDF/DOCX/TXT) to use as the article itself. Chat uploads are attached automatically; pass this only over MCP, or to override which upload is the primary source.
evidence_file_urlsstring[]URLs of supporting documents the writer should reference alongside the article.
duration_secondsnumberTarget video length in seconds (10–600). Omit to use the user's defaults.
tonestringOverall tone, e.g. professional, conversational, dramatic, playful.
speaking_stylesstring[]Speaking styles, e.g. unbiased, professional, educational, conversational, serious, playful, casual, dramatic.
style_descriptionstringFreeform description of the desired style/voice.
story_focusstringStory focus: retelling, strengthen, or summary.
ctastringCall to action to end the script with.
custom_instructionsstringHigh-priority freeform instructions injected into the script prompt.

Returns: Generation runs detached, so `status` here is where the job STARTED, not where it ended. Poll get_generation_status. A `script_text` call (mode "verbatim") generates nothing and returns already completed.

FieldTypeDescription
card always"script"What kind of result this is.
script_id alwaysstringPass this to get_script, edit_script and create_video_from_script.
status alwaysstringLifecycle status. Not a closed set; treat an unfamiliar value as in progress and re-check.
idstringThe same value as script_id, under the row's own column name.
titlestring | nullThe headline. Null until the writer has produced one.
current_stagestring | nullThe step now running, while it is still being written.
progressnumber | nullPercent complete, 0-100.
error_messagestring | nullWhy it failed, when it did.
has_script_textboolean | nullWhether any text has been written yet. False on a script that is still generating.
script_textstring | nullThe script itself, once it exists.
linksobjectAbsolute page URLs for what this result is about. Give these to the user: they are how a script gets read and a planned cut gets watched or rendered.
notestringGuidance for you, not for the user. Act on it; do not read it out.
source_keystringIdentifies the story within this conversation, so a second call returns the same script.
modestring"source" when written from reporting, "prompt" when drafted from a brief, "verbatim" when the user's own words were saved as written.
briefstring | nullThe brief this was commissioned to, echoed back so the user can correct the scope.
reusedbooleanTrue when this story already had a script in this conversation and it was handed back.

generate_script takes either a source (a URL, or pasted text) or a brief describing the story you want. With a brief there is no article at all: you supply the facts and the angle, and Editory drafts from them.

{
"brief": "Announce our partnership with Northwind. Mention that it starts in March, and point viewers at their Instagram @northwind.",
"duration_seconds": 45,
"tone": "upbeat"
}

Everything in the brief is treated as fact, and the model is instructed not to invent specifics beyond it: no statistics, quotes, dates or outcomes you didn’t give it. If you want those in the script, put them in the brief.

edit_script

Ask the script-editing agent to revise a script conversationally (tone, length, structure, hook, CTA). Returns the updated script and persists it. Use for edits described in natural language; use update_script for verbatim replacement text you already have.

ParameterTypeDescription
script_id requiredstring
instruction requiredstringThe edit request, e.g. "make the hook punchier and cut it to 45 seconds".

Returns

FieldTypeDescription
card always"script"What kind of result this is.
script_id alwaysstringPass this to get_script, edit_script and create_video_from_script.
status alwaysstringLifecycle status. Not a closed set; treat an unfamiliar value as in progress and re-check.
script_text alwaysstring | nullThe script itself, once it exists.
idstringThe same value as script_id, under the row's own column name.
titlestring | nullThe headline. Null until the writer has produced one.
current_stagestring | nullThe step now running, while it is still being written.
progressnumber | nullPercent complete, 0-100.
error_messagestring | nullWhy it failed, when it did.
has_script_textboolean | nullWhether any text has been written yet. False on a script that is still generating.
linksobjectAbsolute page URLs for what this result is about. Give these to the user: they are how a script gets read and a planned cut gets watched or rendered.
notestringGuidance for you, not for the user. Act on it; do not read it out.
editor_notesstring | nullThe editing agent's own account of what it changed.

Revisions are conversational and cumulative. Each one is kept, so a later instruction can refer back to an earlier state.

{ "script_id": "…", "instruction": "Cut the third paragraph and make the ending land harder." }

get_script

Fetch a script's status, text, and the photos scraped from its source article. Use after generate_script completes, or to review/edit an existing script.

ParameterTypeDescription
script_id requiredstring

Returns

FieldTypeDescription
card always"script"What kind of result this is.
script_id alwaysstringPass this to get_script, edit_script and create_video_from_script.
status alwaysstringLifecycle status. Not a closed set; treat an unfamiliar value as in progress and re-check.
idstringThe same value as script_id, under the row's own column name.
titlestring | nullThe headline. Null until the writer has produced one.
current_stagestring | nullThe step now running, while it is still being written.
progressnumber | nullPercent complete, 0-100.
error_messagestring | nullWhy it failed, when it did.
has_script_textboolean | nullWhether any text has been written yet. False on a script that is still generating.
script_textstring | nullThe script itself, once it exists.
linksobjectAbsolute page URLs for what this result is about. Give these to the user: they are how a script gets read and a planned cut gets watched or rendered.
notestringGuidance for you, not for the user. Act on it; do not read it out.
article_image_countnumberPhotos from the source article currently switched on for b-roll.

update_script

Replace a script's text verbatim. Use when you (or the user) already have the exact final text; use edit_script for natural-language revisions.

ParameterTypeDescription
script_id requiredstring
script_text requiredstring

Returns

FieldTypeDescription
card always"script"What kind of result this is.
script_id alwaysstringPass this to get_script, edit_script and create_video_from_script.
status alwaysstringLifecycle status. Not a closed set; treat an unfamiliar value as in progress and re-check.
script_text alwaysstring | nullThe script itself, once it exists.
idstringThe same value as script_id, under the row's own column name.
titlestring | nullThe headline. Null until the writer has produced one.
current_stagestring | nullThe step now running, while it is still being written.
progressnumber | nullPercent complete, 0-100.
error_messagestring | nullWhy it failed, when it did.
has_script_textboolean | nullWhether any text has been written yet. False on a script that is still generating.
linksobjectAbsolute page URLs for what this result is about. Give these to the user: they are how a script gets read and a planned cut gets watched or rendered.
notestringGuidance for you, not for the user. Act on it; do not read it out.

scrape_article

Fetch and extract an article from a URL (title, text, authors, and the photos published with it). Use to preview/confirm an article before generating a script, or to show the user what images the story comes with. generate_script scrapes internally (it keeps the same photos), so you do NOT need to call this first unless you want to show the user what was found or answer questions about the article.

ParameterTypeDescription
url requiredstringThe article URL to scrape.

Returns

FieldTypeDescription
card always"status"What kind of result this is.
word_count alwaysnumberLength of the extracted body text.
image_count alwaysnumberHow many photos were published with the story.
images alwaysobject[]Up to 12 of them. The hero is used as b-roll by default; the rest start switched off.
titlestring | nullThe article's headline.
authorsarray | nullBylines, where the page declares any.
previewstring | nullThe first ~600 characters of the article.
urlstringThe article URL that was scraped.
notestringGuidance for you, not for the user. Act on it; do not read it out.

You rarely need this: generate_script scrapes a URL itself. It’s useful when you want to read the article first and decide whether it’s worth a script, or to pull the headline and photos out for something else.