MCP

Tool reference

Every tool the Reblog MCP server exposes, grouped by the permission that unlocks it, with arguments, credit cost and the project roles allowed to call it.


This page is generated from the running server, so it cannot drift: a tool that is added, renamed or re-scoped appears here and nowhere else has to be edited. Groups are ordered from least to most powerful.

How to read a tool

Permission is the scope a connection must have been granted. Roles are the project roles allowed to run it -- your own role caps the connection, so both have to allow the call. Credits marks the tools that bill AI usage when they run.

account.projects.read

read3 tools

See which projects and workspaces this app can access

find_projects_needing_articlesread onlyaccount level

Answer "which of my projects needs an article right now?" across every project this connection can access. Each project is analysed against its own publishing rhythm (or its automation routine) and ranked by urgency: how long since its last article, how late that makes it, what is still in its pipeline, and what to do next. Returns a compact ranked list plus a summary of how many projects are overdue, due, covered or on track. Call get_publishing_cadence with one project_id for the full detail of a single project.

Rolesany project role
ArgumentTypeDescription
min_urgencyintegerOnly return projects at or above this urgency score. Pass 50 for "only what actually needs writing".0-100 - default 0
statusstring"needs_attention" keeps overdue, due_now and never-published projects.any | needs_attention | overdue | due_now | due_soon | covered | on_track | no_history - default "any"
include_translationsbooleanCount translated versions as separate publications.
limitintegerMaximum projects returned (the ranking is computed first, so this keeps the most urgent).1-50 - default 20
get_my_capabilitiesread onlyaccount level

Report exactly what this connection can and cannot do: the app it is acting as, its granted permissions, the projects it reaches and your role on each, which tools are usable (and why the others are not), and where the account owner can review every call made through it. Call this when a tool was refused, before attempting anything destructive, or when the user asks what you are allowed to do here.

Rolesany project role

No arguments.

list_projectsread onlyaccount level

List the projects this connection can access. Use the returned project_id to target other tools when more than one project is available. project_url is the live published site; dashboard_url is the editor.

Rolesany project role

No arguments.

agents.read

read4 tools

See your AI agents and their job queue

get_jobread only

Fetch one background job (worker-request) by id, with its status, recent logs and final result or error. Use the job_id returned by list_jobs, translate_article or translate_missing.

Rolesadvanced editoradministrator
ArgumentTypeDescription
job_id*stringMongoDB ObjectId of the job (worker-request)
log_limitintegerHow many of the most recent log entries to return1-100 - default 20
list_agentsread only

List the AI agents configured for a project (translation, article-idea, recommendations, article-writer, image, cover, tweet-to-article, emphasis) with their status. For the translation agent, languages lists the target languages it can translate into. For an image agent, model is what draws article covers - pass its agent_id to generate_image, or to generate_article to choose which one illustrates the piece. For a tweet-to-article agent, thread_rules is how it reads an X thread and what it asks the article to be - pass its agent_id to tweet_to_article, scrape_tweet or analyze_tweet_discussion to read with those rules. For a cover agent, cover_rules is what the picture at the top of an article looks like and where it comes from - pass its agent_id to create_cover. A project can hold more than one of a type, so several cover agents can come back: the one a thread article is illustrated by is named in the tweet-to-article agent thread_rules as cover_agent_id, and configure_agent with create_new adds another. For an emphasis agent, emphasis_rules is how much italic the articles carry; a project with no such agent still gets the built-in light touch, so the absence of one here is a default and not an off switch. The same is true of the cover agent: articles are illustrated with the built-in defaults when there is none. Use this before launching work with translate_article, translate_missing or generate_image. To create or change a writer, image, cover or tweet-to-article agent, use configure_agent.

Rolesadvanced editoradministrator
ArgumentTypeDescription
agent_typestringOptional filter by agent type: "translation", "article-writer", "article-idea", "recommendations", "image", "cover", "tweet-to-article" or "emphasis"
include_inactivebooleanInclude agents whose status is not active

List the image models this account can generate with, to pass as `model` to generate_image. Includes every OpenRouter slug the model library carries (Gemini, GPT-image, FLUX, Seedream, Grok Imagine and the rest of the gateway) alongside the direct-provider models. Badges tell them apart: recommended is the product default, fast is cheap and quick, premium is the expensive high-detail tier. Filter with provider or search when the list is long.

Rolesadvanced editoradministrator
ArgumentTypeDescription
providerstringOnly models from this provider, e.g. "openrouter" or "openai"max 40 chars
searchstringSubstring match on the model id or its display name, e.g. "flux" or "gemini"max 80 chars
limitintegerHow many models to return (default 60)1-200 - default 60
list_jobsread only

List background jobs (worker-requests) for a project, newest first, with their status (pending, processing, completed, failed, cancelled). Filter by type or status to follow work launched with translate_article, translate_missing or generate_recommendations. Use get_job for the full detail of one job.

Rolesadvanced editoradministrator
ArgumentTypeDescription
request_typestringFilter by job typetranslation | article-generation | article-idea | recommendations | generation | other
statusstringFilter by statuspending | processing | completed | failed | cancelled
pageintegermin 1 - default 1
page_sizeinteger1-100 - default 20

articles.read

read14 tools

View your articles

Get a single-call overview of a project: its languages, article counts (total, by status, by language), idea backlog, and - when allowed - its active AI agents, its in-flight job queue and a setup block saying whether the writer and image agents are configured and whether X threads have house rules. Call this first to orient before using more specific tools.

Rolesany project role

No arguments.

List the published articles most worth updating rather than replacing: the oldest untouched ones, scored up by thin content, missing meta title or description, missing cover and missing internal links. Each candidate comes with a refresh score out of 100 and the reasons behind it. Word counts are approximated from the stored body length.

Rolesany project role
ArgumentTypeDescription
older_than_daysintegerOnly consider articles untouched for at least this long.7-2000 - default 180
langstringOptional language filter, e.g. "EN".max 10 chars
limitintegerHow many candidates to return, highest score first.1-50 - default 10
get_articleread only

Fetch one article by id or by handle. Returns the full document including markdown body. The article must belong to the targeted project.

Rolesany project role
ArgumentTypeDescription
article_idstringMongoDB ObjectId of the article
handlestringURL handle of the article

List the change history for one article, newest first. Each entry is a recorded mutation (create, update, edit, delete) with its source and a size delta. Use the returned history_id with rollback_article to restore a previous version. Set include_content to also return the before/after markdown of each version (heavier).

Rolesany project role
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article
limitintegerMaximum number of history entries to return1-100 - default 20
include_contentbooleanInclude the full before/after markdown of each version

Show the editorial calendar of a project around today: articles published in the recent window, everything booked ahead (scheduled articles and drafts with a future date), upcoming automation routine runs, and the days in the horizon with nothing planned. Flags booked slots whose article is still missing a cover or a meta description, because those cannot publish as-is. Dates are given both as instants and as local days in the project timezone.

Rolesany project role
ArgumentTypeDescription
days_aheadintegerHow far forward to look.1-180 - default 30
days_backintegerHow far back to include already published articles.0-180 - default 30
include_translationsbooleanInclude translated versions as separate calendar entries.

Find what a project is NOT covering: languages that lag behind the main one, categories declared in the project but never used (or untouched for months), published articles with no category at all, categories used on articles but missing from the project settings, and the share of the catalogue that has not been touched in a long time. Returns per-language and per-category coverage plus a prioritised list of gaps, each naming the tool that closes it. Pair with get_publishing_cadence: that one answers when to publish, this one answers about what.

Rolesany project role
ArgumentTypeDescription
stale_after_daysintegerHow long an article (or a category) can go untouched before it counts as stale.30-1000 - default 180

Answer "when should I publish the next article here?" for one project. Returns the real publishing rhythm (median gap between articles, articles per week/month, trend, usual weekday and hour), how long ago the last article went out, what is still in the pipeline (drafts, scheduled, review queue, ideas), and a verdict: on_track / due_soon / due_now / overdue / covered / no_history, with a due date, an urgency score out of 100 and the concrete next actions to take. Use find_projects_needing_articles instead when the question spans several projects.

Rolesany project role
ArgumentTypeDescription
include_translationsbooleanCount translated versions as separate publications. Off by default: a 3-language project would otherwise look 3x faster than it writes.
sample_sizeintegerHow many recent published articles feed the rhythm math.10-500 - default 200

Check whether cache purges are reaching the customer's site: whether revalidation is configured for the project, the recent delivery attempts with the site's HTTP answer, how many are waiting to be retried, and - when article_id is given - whether that article still owes a purge (its body changed more recently than the last purge we delivered, so the next automation tick will send one). Start here when someone reports that the live site shows an old title, an old body or a deleted article. Read-only: it never calls the site, revalidate_article does that.

Rolesany project role
ArgumentTypeDescription
article_idstringMongoDB ObjectId of one article, to narrow the log to it and report whether a purge is still owed for it.
limitnumberHow many delivery attempts to return, newest first.1-50 - default 10

List AI-generated article ideas for the targeted project. Optionally filter by status (new, approved, dismissed, promoted). Returns ideas plus per-status counts.

Rolesadvanced editoradministrator
ArgumentTypeDescription
statusstringFilter by idea statusnew | approved | dismissed | promoted
limitinteger1-200 - default 50

List every picture in one article: its cover, plus each image in the body with a position number, its alt text, caption, and which section it sits in. The position numbers are what add_article_image, replace_article_image, remove_article_image and move_article_image take, so call this first when the user says "the second photo" or "the image in the pricing section". Also flags images that are still hosted outside the project, which break when the other host does.

Rolesany project role
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the articlemax 40 chars
list_articlesread only

List articles in a project. Supports pagination, search by title/handle, optional language and category filters, and date range.

Rolesany project role
ArgumentTypeDescription
pageinteger1-indexed page numbermin 1 - default 1
page_sizeinteger1-100 - default 20
searchstringCase-insensitive substring match on title or handle
langstringISO language code (e.g. "en", "fr")
categorystringFilter by category slug
statusstringFilter by article statusdraft | published
date_fromstring
date_tostring
sort_bystringdefault "created_at"
sort_orderstringasc | desc - default "desc"

List the categories declared for a project, with how many articles each holds. These are the values create_article and update_article expect in `categories` and list_articles in `category`: pass one of these rather than inventing a label, because an undeclared category still saves but the dashboard filters never offer it. Also returns the categories found on articles that the project never declared, which is what get_content_gaps flags as a taxonomy gap.

Rolesany project role

No arguments.

Read an X (Twitter) post, the posts it is built on, and the discussion under each of them, ranked. Returns the post, the author's own follow-ups, and the replies that are actually worth reading - scored on engagement, substance, whether they push back with numbers or first-hand experience, and whether the author stopped to answer them. Promoted posts injected into the reply timeline are removed, so what comes back is the real conversation. By default the read goes one hop back: when the post quotes another post, answers one, or links to one, that post is read too and comes back in `sources` with its own replies, because a post commenting on another one usually leaves the numbers and the original claim in the post underneath. Also returns `dossier`: the whole thing compiled into one readable brief, which is exactly what analyze_tweet_discussion and tweet_to_article feed to the model. Also reports the picture the post carries (`cover_candidate`), every picture in the thread that would go inside the article (`images`), the video inside it (`video`), and the pages the posts link to (`links`), so what the article will be built from can be shown to the user before anything is spent. Free (no AI credits, no article created). Use it to decide whether a thread is worth writing about, or to quote what people said.

Rolesany project role
ArgumentTypeDescription
tweet_url*stringThe post: a link like https://x.com/user/status/123, a twitter.com link, or just the numeric idmax 500 chars
limitintegerHow many top replies to return. Omit it to use the project's tweet-to-article agent (15 when it has none).1-60
pagesintegerReply pages to walk, ~20-40 replies each (1-5). More pages means more of the thread and more API calls. Omit it to use the project's tweet-to-article agent (2 when it has none).1-5
ranking_modestringHow X orders the replies before they are re-scored: 'Relevance' (what the site shows), 'Likes', or 'Recency'. Omit it to use the project's tweet-to-article agent.Relevance | Likes | Recency
depthintegerHow far back to read (1-3). 1 reads only the post you passed. 2 also reads what it is built on - the post it quotes, the post it answers, an X link in its text - each with its own ranked reply section, because a post that comments on another one usually leaves the numbers and the original claim in the post underneath. 3 goes one hop further. Omit it to use the project's tweet-to-article agent (2 when it has none).1-3
max_sourcesintegerHow many other posts the read may follow in total (0-6). Omit it to use the project's tweet-to-article agent (3 when it has none).0-6
include_noisebooleanKeep the replies normally dropped as noise (one-word praise, bare mentions, promotional spam)
tweet_agent_idstringRead with the rules of one specific tweet-to-article agent (see list_agents). Omit to use the project's main one, or the built-in defaults when it has none.max 120 chars
refreshbooleanRead the thread again from X instead of reusing the read from a few minutes ago. Only worth it when you are watching a discussion that is still moving.

Propose the concrete dates for the next articles of a project, ready to pass to schedule_article. Slots follow the project's real rhythm (or its automation routine), reuse the weekday and hour it usually publishes at, are expressed in the project timezone, and skip any day that already has an article published or booked. Returns the slots plus the cadence verdict they were derived from.

Rolesany project role
ArgumentTypeDescription
countintegerHow many upcoming slots to propose.1-12 - default 3
start_fromstringOnly propose slots after this instant. Defaults to now (or to the moment the next article is due when the project is ahead of schedule).
include_translationsbooleanCount translated versions as separate publications when measuring the rhythm.

assets.read

read1 tool

See the images and files in your projects

list_assetsread only

List the files in a project's asset library: everything uploaded from the dashboard plus every image generated for this project (article covers, in-article images, anything drawn over MCP). Each one comes back with a durable public URL you can embed in markdown or set as an article cover - check here before generating a new image, the picture may already exist. Filter with search (matches the file name and the prompt an image was generated from), source, or article_id.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
searchstringMatch on the file name, the URL, or the prompt a generated image came frommax 200 chars
sourcestring"generated" for AI images only, "uploaded" for files a human added, "all" (default) for bothall | generated | uploaded - default "all"
article_idstringOnly the images generated for this articlemax 40 chars
limitintegerHow many assets to return (default 50)1-200 - default 50
offsetintegerSkip this many assets, to page through a large librarymin 0 - default 0

agents.run

writecredits10 tools

Launch agent runs and change how the agents are configured: write articles, translate them, generate images (spends AI credits)

Read an X thread, and the posts it is built on, and say what is actually going on. Returns the claim the post made, the disagreements and how each was answered, the quotes worth lifting with their handles, the observations that only become visible once the whole thread is read, the questions nobody settled, and a suggested headline, angle, keywords and cover prompt. When the post quotes or answers another one, that post and its own reply section are read too, and the analysis adds `source_chain`: what the original actually said, and whether the post on top represents it fairly. That gap is usually the article. Use it to judge whether a thread is worth publishing and to agree an angle with the user BEFORE writing. Spends AI credits (one model call). Writes nothing: call tweet_to_article when you want the article.

Rolesadvanced editoradministrator
ArgumentTypeDescription
tweet_url*stringThe post: a link like https://x.com/user/status/123, or the numeric idmax 500 chars
langstringLanguage for the analysis (defaults to the project main language)max 10 chars
limitintegerHow many top replies to compile. Omit it to use the project's tweet-to-article agent (15 when it has none).1-60
pagesintegerReply pages to walk (1-5). Omit it to use the project's tweet-to-article agent (2 when it has none).1-5
ranking_modestringHow X orders replies before they are re-scored. Omit it to use the project's tweet-to-article agent.Relevance | Likes | Recency
depthintegerHow far back to read (1-3). 1 reads only the post you passed. 2 also reads what it is built on - the post it quotes, the post it answers, an X link in its text - each with its own ranked reply section, because a post that comments on another one usually leaves the numbers and the original claim in the post underneath. 3 goes one hop further. Omit it to use the project's tweet-to-article agent (2 when it has none).1-3
max_sourcesintegerHow many other posts the read may follow in total (0-6). Omit it to use the project's tweet-to-article agent (3 when it has none).0-6
custom_instructionsstringEditorial direction for this call: an angle to favour, an audience, something to focus on. It is added to the agent's standing angle, not a replacement for it.max 2000 chars
tweet_agent_idstringRead with the rules of one specific tweet-to-article agent (see list_agents). Omit to use the project's main one.max 120 chars
refreshbooleanRead and analyse the thread again instead of reusing the answer given for it a few minutes ago. Costs a model call; only worth it when the discussion has moved or you changed your mind about the angle.

Cancel a background job that is still queued (status pending), for example a translation launched by mistake. Jobs already processing, completed or failed cannot be cancelled. Get the job_id from list_jobs.

Rolesadvanced editoradministrator
ArgumentTypeDescription
job_id*stringMongoDB ObjectId of the job (worker-request) to cancel

Set up or update a project AI agent - the article writer (its audience, tone and house rules), the image agent (its art direction), the cover agent (what the picture at the top of every article looks like and where it comes from), the tweet-to-article agent (how an X thread is read, whether its pictures and the pages it links to go into the article, and what the piece should be), or the emphasis agent (how much italic the articles carry). Call it with only agent_type to GET the questions to ask the user, together with what the project already says about itself so you can propose answers instead of interrogating. Call it again with the answers as fields to save them. A preset can be applied instead with template. A project can hold SEVERAL agents of a type: create_new adds another one and returns its agent_id, which is how a blog gets a second cover style for the articles it makes from X threads (point the tweet-to-article agent at it with cover_agent_id) without changing the covers of everything else. This is what generate_article points you to when a project has no configured writer yet, where create_cover gets the look of a cover from, and where tweet_to_article gets its reading depth and editorial rules from.

Rolesadvanced editoradministrator
ArgumentTypeDescription
agent_type*string"article-writer" for the agent that writes the articles, "image" for the art direction of every image, "cover" for the picture at the top of an article specifically (its look, its subject, and whether it is drawn at all), "tweet-to-article" for the rules that turn an X thread into an article, "emphasis" for how much italic emphasis every article carries.article-writer | image | cover | tweet-to-article | emphasis
agent_idstringUpdate one specific agent (see list_agents). Omit to configure the project's main agent of this type, creating it if there is none.max 120 chars
create_newbooleanAdd ANOTHER agent of this type instead of updating the project's existing one, and return its agent_id. Needs a name. This is how a blog ends up with two cover agents - the house look and a newsroom one for its X pieces - or two writers; point something at the new one afterwards (cover_agent_id on the tweet-to-article agent, or agent_id on create_cover). Leave it out to change the agent already there.
templatestringApply a ready-made preset instead of writing every field (the presets are listed in the questions response). Explicit fields still override it.max 60 chars
namestringDisplay name for the agent, e.g. "Main writer".max 120 chars
target_audiencestringarticle-writer: who reads the blog - job, expertise level, what they are trying to do.max 2000 chars
tone_and_stylestringarticle-writer: the voice the articles should have.max 2000 chars
writing_instructionsstringarticle-writer: house rules - length, structure, what to always or never do. tweet-to-article: the same, but only for articles made from a thread (how much to quote, whether to name the accounts, how to open).max 4000 chars
seo_instructionsstringarticle-writer: how keywords, titles and meta descriptions should be handled.max 4000 chars
prompt_instructionsstringimage: the art direction prepended to every image prompt (medium, palette, composition).max 4000 chars
negative_promptstringimage: what must never appear in the images.max 1000 chars
sizestringimage: output size, e.g. "1536x1024" for a landscape cover.max 20 chars
qualitystringimage: "low", "medium" or "high" for the models that support it.max 20 chars
images_per_articleintegerimage: how many images one article run may produce.1-4
body_imagesintegerimage: how many illustrations go INSIDE the article, on top of the cover (default 2, one drawn per section from what that section says). 0 means cover only.0-4
generate_coverbooleanimage: attach the first image as the article cover (usually true). tweet-to-article: false to leave these articles without a cover; covers are drawn by default, since publish_article refuses an article that has none.
depthintegertweet-to-article: how far back to read (1 the pasted post alone, 2 also the post it quotes or answers, 3 one hop further). 2 is the sensible default: a post that comments on another one leaves the numbers in the post underneath.1-3
max_sourcesintegertweet-to-article: how many other posts one read may follow in total. 0 turns the chain off whatever depth says.0-6
reply_pagesintegertweet-to-article: reply pages to walk under the pasted post, ~20-40 replies each (default 2).1-5
source_reply_pagesintegertweet-to-article: reply pages to walk under each post found behind it (default 1: the source is context, not the subject).1-5
ranking_modestringtweet-to-article: how X orders replies before they are re-scored.Relevance | Likes | Recency
comments_usedintegertweet-to-article: how many top replies are compiled and handed to the writer (default 15).1-60
include_noisebooleantweet-to-article: keep the replies normally dropped as noise (one-word praise, bare mentions, spam). Usually false.
min_repliesintegertweet-to-article: refuse to write below this much discussion (default 1). Raise it on a blog that should only cover threads people actually argued in; 0 lets any post through.0-200
angle_instructionsstringtweet-to-article: what the article should be about, applied to every thread. This steers the reading of the discussion, not just the writing.max 4000 chars
cover_instructionsstringtweet-to-article: a standing note added to the cover prompt written from the thread.max 2000 chars
content_typestringtweet-to-article: what kind of piece these become, e.g. "news analysis", "opinion roundup".max 60 chars
fact_check_chainbooleantweet-to-article: when the post is built on another one, tell the writer to check it against its source and say when it misrepresents it. On by default; that gap is usually the article.
keep_disagreementbooleantweet-to-article: forbid smoothing the pushback into "reactions were mixed". On by default.
writer_agent_idstringtweet-to-article: which article writer finishes these pieces (see list_agents). Empty means the project writer.max 120 chars
image_agent_idstringtweet-to-article: which image agent draws their covers. Empty means the project image agent. cover: which image agent supplies the model and the base art direction this cover style sits on top of.max 120 chars
cover_agent_idstringtweet-to-article: which COVER agent illustrates the articles made from a thread (see list_agents with agent_type "cover"). Empty means the project one, so they look like every other article. This is the way to give X pieces their own covers - a newsroom look, or the screenshot straight from the post - without restating the art direction here: create a second cover agent with configure_agent + create_new, then point this at its agent_id.max 120 chars
cover_sourcestringtweet-to-article: where the cover of these articles comes from. "ai" draws one for the piece (default). "tweet" uses the picture in the post itself - its photo, or the frame X shows before its video plays. "auto" uses the post's picture when it has one and draws one otherwise; it is the right setting for a news blog, where the chart or the screenshot in the post IS the picture of the story. "none" leaves these articles without a cover. A thread with no picture always falls back to a drawn cover, whatever this says.ai | tweet | auto | none
video_framesbooleantweet-to-article: when the post carries a video, open it and put stills from INSIDE it in the article, described by a vision model. Off by default, because most threads are text and this costs a download and a vision call per article. Turn it on for a blog whose material is demos, screen recordings and product videos, where the post text is a caption and the video is the whole story. It can still be asked for one link at a time with video_frames on tweet_to_article.
video_frame_countintegertweet-to-article: how many stills to take out of a video (1-8). Leave it out for one per 20 seconds, up to 4.1-8
thread_imagesbooleantweet-to-article: put the pictures the posts already carry inside the article - the charts, the benchmark tables, the screenshots, including the ones posted in the replies. ON by default, because they are the evidence the discussion is about and they cost no image generation. Turn it off for a blog that wants its X pieces to be text with one cover.
thread_image_countintegertweet-to-article: how many pictures from the thread one article may use (1-12). Leave it out for as many as the thread carries, up to 6.1-12
read_linksbooleantweet-to-article: open the pages the posts link to and write from what they actually say. ON by default. A post that is one sentence and a URL is the common case, and without this the article is a summary of how people reacted to a page nobody read. Links to X itself are not read here: those are the thread chain, which depth already follows.
link_countintegertweet-to-article: how many linked pages to open per article (1-4). Leave it out for 2.1-4
langstringtweet-to-article: language these articles are written in. Empty means the project main language.max 10 chars
intensitystringemphasis: how much italic the articles carry. "light" (the default everywhere) is about three italicised terms per thousand words, so a normal article gets three or four. "off" leaves articles exactly as written.off | light | medium | strong
max_spansintegeremphasis: ceiling on italics per article whatever its length (default 6).0-40
min_wordsintegeremphasis: articles shorter than this are left alone (default 120).0-5000
apply_on_generationbooleanemphasis: italicise every article as it is written (default true). False means it only happens when emphasize_article is called.
style_instructionsstringemphasis: what this blog italicises - product names, titles of works, jargon being defined. The built-in rule is "the term at the moment it is introduced".max 2000 chars
enabledbooleancover: draw a cover for every article (default true). false is the only way to have a blog with no automatic covers - and publish_article refuses an article without one, so those have to be set by hand.
sourcestringcover: where a cover comes from when the material the article was built on already carries a picture. "ai" always draws one (default). "tweet" uses the picture in the source post - its photo, or the frame X shows before its video plays. "auto" uses it when there is one and draws otherwise, which is the right setting for a news blog. Material with no picture always falls back to a drawn cover.ai | tweet | auto | none
art_directionstringcover: what the covers look like - medium, palette, composition, whether people appear. Added to the image agent art direction rather than replacing it.max 4000 chars
avoid_textbooleancover: forbid rendered text, letters and watermarks in the picture (default true). Rendered text is still the tell.
subject_fromstringcover: "article" (default) reads the piece and picks what should be in the frame, which is the difference between a cover about the article and one about its title. "title" uses the title and its keywords only, and costs nothing extra.article | title
subject_instructionsstringcover: what that pass should favour or never show ("prefer the object being discussed; never a handshake, never a lightbulb").max 4000 chars
subject_modelstringcover: the small text model that reads the article to pick the subject. Empty means the product default.max 120 chars
title_overlaystringcover: whether the article title is printed on a cover taken from the source material. "source" (default) turns the picture in the post into the illustration of a card that carries the headline and credits the handle it came from - it is drawn locally, costs nothing, and it is what stops an article about a leak going out under a banner that says nothing about it. "never" uses the picture exactly as the post shipped it. Drawn covers are never written on, whatever this says: avoid_text governs those.source | never
overlay_accentstringcover: the accent colour of that card, as a hex value like "#ff6a3d". Empty means the built-in one.max 20 chars
providerstringAI provider to run this agent on. Defaults to a configured one. For a cover agent this is the IMAGE provider, like the image agent.max 40 chars
modelstringModel id. For an image or cover agent see list_image_models.max 120 chars
activatebooleanSwitch the agent on (default) or off. Sending it alone reactivates a configured agent that was paused.
generate_articlespends credits

Write a brand-new article from a topic you provide. Creates the draft immediately and queues the AI writer to fill it in, so the article appears in the dashboard right away with a "writing" state. The same job also draws the cover and links it to the article, so no second call is needed and no article comes out unpublishable for want of one; the project image agent supplies the style when it has one. Set generate_cover false to skip it, or image_agent_id to pick which image agent draws it. Bring your own photos with images: a list of public URLs, which are copied into the project CDN, placed in the body by the writer where they fit the text, and used as the cover (the first one, unless you flag another) instead of drawing one. Returns article_id + job_id - poll get_job until it succeeds, then read the result with get_article. Spends AI credits. IMPORTANT: when the project has no configured writer yet, this writes NOTHING and returns status "setup_required" with questions to put to the user - ask them, save the answers with configure_agent, then call this again (or pass skip_setup true to write with a generic default). To review the topic first instead, use create_idea + promote_idea.

Rolesadvanced editoradministrator
ArgumentTypeDescription
topic*stringWhat the article should be about. A full brief works better than a bare title: audience, key points to cover, what to avoid.max 4000 chars
titlestringWorking title (defaults to the first line of the topic; the writer may refine it)max 200 chars
anglestringThe specific take or point of view for this piecemax 480 chars
target_keywordstringPrimary SEO keyword to rank formax 120 chars
secondary_keywordsarraySupporting keywords (max 10)of string
categoriesarrayArticle categories (max 10)of string
content_typestringe.g. "how-to guide", "comparison", "case study"max 60 chars
custom_instructionsstringExtra writing instructions for this article only (structure, tone, things to include)max 1000 chars
langstringLanguage code (defaults to the project main language)max 10 chars
agent_idstringWriter agent to use (defaults to the project writer)max 120 chars
generate_coverbooleanDraw a cover image in the same job and attach it to the article. On by default, because publish_article refuses an article with no cover; false leaves it for set_article_cover or a later generate_image.
body_imagesintegerHow many illustrations to draw INSIDE the article, on top of the cover, each from what its own section says. Leave it out for the project rule (two by default); 0 for a cover and nothing else.0-4
image_agent_idstringImage agent that draws the cover (defaults to the project image agent). See list_agents with agent_type "image".max 120 chars
cover_agent_idstringCover agent whose art direction the cover is drawn with, when the project keeps more than one. See list_agents with agent_type "cover". Omit for the project one, which is what makes every article on a blog look like the same publication.max 120 chars
image_promptstringYour own cover prompt, used verbatim instead of the one the image agent builds from the article.max 4000 chars
skip_setupbooleanWrite even though the project has no configured writer, using a generic default. Use it when the user is not available to answer the setup questions; the project is not asked again afterwards.
imagesarrayPhotos to use in this article, as public URLs (max 8). They are copied into the project CDN, handed to the writer so it places them where they illustrate the text, and any it leaves out are placed automatically. The first one becomes the cover unless another is flagged use_as_cover.of object
use_first_image_as_coverbooleanWhen images are supplied and none is flagged use_as_cover, take the first as the cover (default true). False keeps every supplied photo in the body.default true
rehost_imagesbooleanCopy the supplied images into the project CDN first (default true). False links the URLs exactly as given.default true
generate_imagespends credits

Generate an AI image for one project and get back a durable URL you can use as an article cover or embed in markdown. The image is filed in that project's asset library, so it also shows up on the Assets page of the dashboard and can be reused or removed later (list_assets / delete_asset). An image therefore belongs to a project: when this connection reaches more than one, ASK the user which project it is for and pass project_id - never pick one yourself, because it spends that project's credits and lands in its library. Runs through the project image agent by default: its model and art direction are applied, so the result matches the rest of the blog. Pass agent_id to pick a specific image agent, or override provider/model/size/quality yourself - with provider "openrouter" the model is any OpenRouter image slug ("google/gemini-3-pro-image", "black-forest-labs/flux.2-pro"); call list_image_models to see what is available. Pass article_id + set_as_cover to attach the result to an article in one call (also needs the "Edit articles" permission). Spends AI credits.

Rolesadvanced editoradministrator
ArgumentTypeDescription
prompt*stringWhat to draw. Be specific: subject, composition, style, mood.max 4000 chars
article_idstringMongoDB ObjectId of the article this image illustrates (used as context, and required for set_as_cover)
set_as_coverbooleanStore the generated image as the cover of article_id. Requires the "Edit articles" permission.
agent_idstringImage agent whose model and art direction to use (defaults to the project image agent). See list_agents with agent_type "image".max 120 chars
apply_art_directionbooleanWrap your prompt in the image agent style instructions so it matches the rest of the blog. Set false to send the prompt exactly as written.default true
providerstringImage provider. "openrouter" reaches every model on the gateway (defaults to the image agent, then the project setting)openai | openrouter | stability
modelstringImage model id, or an OpenRouter slug like "google/gemini-3-pro-image" (defaults to the image agent, then the project setting)max 120 chars
sizestringe.g. "1024x1024", "1536x1024" (defaults to the image agent, then the project setting)max 20 chars
qualitystringProvider quality tier, e.g. "high" (defaults to the image agent, then the project setting)max 20 chars
stylestringProvider style hint, e.g. "vivid" (defaults to the image agent, then the project setting)max 20 chars
countintegerHow many variations to generate (each one costs credits)1-4 - default 1

Queue a recommendations run (related-articles suggestions) for every published article in the project. Articles already queued are skipped. Spends AI credits per article when the worker runs. Requires an active recommendations agent.

Rolesadvanced editoradministrator
ArgumentTypeDescription
priorityintegerQueue priority (0-10, higher runs sooner)0-10 - default 5
promote_ideaspends credits

Promote an article idea into a draft article and queue its AI generation (the same "Accept & write" action as the dashboard). Returns the created article id and the generation job id (track it with get_job). Spends AI credits when the writer runs. Idempotent: promoting an already-promoted idea returns the existing job. When the project has no configured writer yet, this promotes nothing and returns status "setup_required" with questions to ask the user - see configure_agent, or pass skip_setup true.

Rolesadvanced editoradministrator
ArgumentTypeDescription
idea_id*stringMongoDB ObjectId of the idea (see list_article_ideas)
langstringOverride the article language (defaults to the idea language)
agent_idstringWriter agent to use (defaults to the project writer)
skip_setupbooleanPromote even though the project has no configured writer, using a generic default. The project is not asked again afterwards.
translate_articlespends credits

Queue a translation of one article into one or more target languages. Returns immediately with queued job ids (track them with list_jobs / get_job). Each translation lands as a DRAFT unless publish is true, in which case it goes live by itself as soon as it is done. Target languages must be languages the project is configured for (see describe_project); languages already translated or already queued are skipped. Each queued language spends AI credits when the worker runs it. Requires an active translation agent in the project (see list_agents).

Rolesadvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article to translate
target_langs*arrayTarget language codes the project is configured for, e.g. ["FR", "ES"]. Case-insensitive.of string
translate_imagesbooleanAlso localize text baked into images
publishbooleanPublish each translation as soon as its job finishes, instead of leaving it as a draft to publish one by one. A translation is never published ahead of its source, so this does nothing while the source article is a draft; a translation with no cover or no meta description is left as a draft too. Needs the "Edit articles" permission on top of the one this tool already takes.
priorityintegerQueue priority (0-10, higher runs sooner)0-10 - default 5
translate_missingspends credits

Queue translations for every missing (article, language) pair in the project. Skips pairs already translated or already queued. Each translation lands as a DRAFT unless publish is true, in which case every translation of an already-published article goes live by itself as soon as it is done. Set dry_run to see how many translations would be created (and which languages) without queuing anything. Each queued translation spends AI credits when it runs. Requires an active translation agent.

Rolesadvanced editoradministrator
ArgumentTypeDescription
target_langsarrayOptional subset of target language codes to limit to, e.g. ["FR"]. Defaults to all project languages.of string
translate_imagesbooleanAlso localize text baked into imagesdefault true
publishbooleanPublish each translation as soon as its job finishes, instead of leaving a draft per language to publish one by one. A translation is never published ahead of its source, so translations of articles that are still drafts stay drafts (the answer counts them as will_stay_draft); so does one with no cover or no meta description. Needs the "Edit articles" permission on top of the one this tool already takes.
priorityintegerQueue priority (0-10, higher runs sooner)0-10 - default 5
dry_runbooleanReport what would be queued without creating any jobs

Turn an X (Twitter) thread into an article. Reads the post, the post it is built on when it quotes or answers one, and the discussion under each, ranks the replies that matter (the ones with numbers, first-hand experience, real pushback, and the ones the author answered), works out what the whole chain adds up to, and hands all of it to the project writer as source material with the instruction to quote real people by handle and to say what the original post claimed before what the post on top made of it. Creates the draft immediately and queues the writer, so it appears in the dashboard right away in a "writing" state, and it always comes out with a cover: the same job draws one from a prompt written for this thread, so nothing else is needed before publishing. The pictures the posts carry - the charts, the benchmark tables, the screenshots, including the ones posted in the replies - go INSIDE the article by default: each one is copied into the project CDN, described by a vision model and placed by the writer where it belongs, because they are the evidence the discussion is about (pass thread_images false for a text-only piece). The pages the posts link to are opened and read the same way, so the article is written from the paper, the announcement or the benchmark itself rather than from the sentence somebody wrote above the link (read_links false skips them). When the post carries a picture worth showing - a chart, a screenshot, a demo video - pass cover_source "tweet" and the cover becomes that photo, or the frame from the video, instead of a drawing. When the post IS a video and the user wants the article to show it, pass video_frames: stills are cut from inside the video, read by a vision model and placed in the body by the writer, and what happens in the video goes to it as source material. Returns article_id + job_id - poll get_job, then get_article. Spends AI credits. Use analyze_tweet_discussion first when the user should approve the angle: this call reuses that read and that analysis instead of paying for them twice. Refuses a thread this project has already turned into an article in the same language, and names the existing one, so the same link pasted twice never quietly becomes two pieces (pass allow_duplicate to write a second take anyway). IMPORTANT: when the project has no configured writer this writes NOTHING and returns status "setup_required".

Rolesadvanced editoradministrator
ArgumentTypeDescription
tweet_url*stringThe post to write about: a link like https://x.com/user/status/123, or the numeric idmax 500 chars
langstringLanguage code (defaults to the project main language)max 10 chars
custom_instructionsstringEditorial direction for this article only: an angle to take, an audience, a section to insist onmax 2000 chars
content_typestringe.g. "analysis", "explainer", "opinion piece" (defaults to what the agent asks for, or an analysis of the thread)max 60 chars
tweet_agent_idstringWrite with the rules of one specific tweet-to-article agent (see list_agents) - useful when a project keeps one for news briefs and one for long analyses. Omit to use the project's main one.max 120 chars
limitintegerHow many top replies to give the writer. Omit it to use the project's tweet-to-article agent (15 when it has none).1-60
pagesintegerReply pages to walk (1-5). Raise it for a thread with hundreds of replies. Omit it to use the project's tweet-to-article agent (2 when it has none).1-5
ranking_modestringHow X orders replies before they are re-scored. Omit it to use the project's tweet-to-article agent.Relevance | Likes | Recency
depthintegerHow far back to read (1-3). 1 reads only the post you passed. 2 also reads what it is built on - the post it quotes, the post it answers, an X link in its text - each with its own ranked reply section, because a post that comments on another one usually leaves the numbers and the original claim in the post underneath. 3 goes one hop further. Omit it to use the project's tweet-to-article agent (2 when it has none).1-3
max_sourcesintegerHow many other posts the read may follow in total (0-6). Omit it to use the project's tweet-to-article agent (3 when it has none).0-6
agent_idstringWriter agent to use (defaults to the project writer)max 120 chars
cover_sourcestringWhere the cover comes from. "ai" draws one from a prompt written for this thread (the usual answer). "tweet" uses the post's OWN picture instead - the photo it carries, or, when it carries a video, the frame X shows before the video plays, which is the screenshot of it; the file is copied into the project CDN and nothing is paid to draw an image. "auto" takes the post's picture when it has one and draws one otherwise. "none" leaves the article without a cover, which publish_article then refuses. Pass "tweet" when the user says to use the image, the screenshot or the video from the post. A post with no picture falls back to a drawn cover, so the article is never left without one. Omit it to use the project's tweet-to-article agent.ai | tweet | auto | none
generate_coverbooleanDraw the cover in the same job. On by default, because an article with no cover cannot be published; false skips it and leaves the article for set_article_cover or generate_image.
image_agent_idstringImage agent that draws the cover (defaults to the project image agent)max 120 chars
cover_agent_idstringCover agent whose art direction the cover is drawn with (see list_agents with agent_type 'cover'). Omit to use the one the tweet-to-article agent names, then the project's own - which is what keeps a thread article looking like the rest of the blog.max 120 chars
image_promptstringYour own cover prompt, used instead of the one written from the threadmax 4000 chars
body_imagesintegerHow many illustrations to DRAW inside the article, on top of the cover, each from what its own section says. Omit it for the project rule (two by default), except when the thread supplied two or more real pictures of its own, where nothing is drawn: four charts out of the discussion with two generic drawings between them is a worse article than four charts. 0 is a cover and nothing else, and a number here always wins.0-4
video_framesbooleanOpen the video in the post and put stills from INSIDE it in the article. Off by default. When the whole content of a post is a screen recording or a demo, the text is a caption and the article has nothing to show: this cuts a few stills spread across the video, has a vision model say what each one shows and what happens across them, files them in the project CDN, and hands them to the writer to place where they illustrate its own text. The reading of the video also goes to the writer as source material, so the article describes what happened instead of "the video reportedly shows". Pass it when the user asks for screenshots, frames or images from the video. Costs a download, an ffmpeg run per still and one vision call. A post with no video, or a host with no ffmpeg, still produces the article and says why it has no stills.
video_frame_countintegerHow many stills to take (1-8). Omit it for one per 20 seconds of video, up to 4. Only used when video_frames is on.1-8
thread_imagesbooleanPut the pictures the posts already carry INSIDE the article. ON by default, and worth leaving on: a thread argues with charts, benchmark tables and screenshots, and an article that describes them without showing them is strictly worse than one that shows them. Every photo in the chain is taken - the post, the author's own follow-ups, the post it quotes, the posts behind it, and the replies - copied into the project CDN, read by a vision model for its alt text and caption, and handed to the writer to place where it illustrates its own text. The cover is never repeated in the body. It costs no image generation, since the pictures already exist; the only cost is one vision call on a thread that has any. Pass false for a deliberately text-only piece, or when the user says not to use the images from the post.
thread_image_countintegerHow many pictures from the thread to use (1-12). Omit it for as many as the thread carries, up to 6. Only used when thread_images is on.1-12
read_linksbooleanOpen the pages the posts link to and write from what they say. ON by default. A large share of the posts worth covering are one sentence and a URL - a paper, a release, a benchmark, a news story - and without this the article is a summary of how people reacted to something nobody read. The pages are fetched, reduced to their text and read in one pass that reports what each one argues, the figures worth citing and the lines worth quoting, all of which goes to the writer as primary source material. Links to X itself are not read here: those are the thread chain and depth already follows them. Pass false to write from the discussion alone.
link_countintegerHow many linked pages to open (1-4). Omit it for 2. Only used when read_links is on.1-4
skip_setupbooleanWrite even though the project has no configured writer, using a generic default.
allow_duplicatebooleanWrite a second article about a thread this project has already covered in this language. Without it the call is refused and tells you which article already exists, so the same link pasted twice does not quietly produce two pieces about one discussion.
refreshbooleanRead the thread again from X and pay for a fresh analysis, instead of reusing what analyze_tweet_discussion or scrape_tweet just read. Only worth it when the discussion has moved since.

articles.create

write2 tools

Create articles and add ideas to the backlog

Create an article from content you wrote yourself (no AI credits spent). The handle, slug and URL section are derived from the title and the project's URL structure unless you pass an explicit handle. Publishing straight away requires a cover and a meta description, exactly like publish_article - otherwise it is created as a draft.

Rolesany project role
ArgumentTypeDescription
titlestringmax 255 chars
handlestringURL path, unique within the project. Leave empty to derive it from the title as "<url-segment>/<slug>".max 300 chars
langstringLanguage code (defaults to the project main language)max 10 chars
mdstringMarkdown body of the article
coverstringCover image URL (generate_image can produce one)
meta_titlestringmax 150 chars
meta_descriptionstringmax 500 chars
categoriesarrayof string
statusstringdraft | published - default "draft"
datestringPublish date, defaults to now

Add an article idea to the project backlog. Use it to bring your own topic into Reblog: the idea shows up in the Ideas board for review, and promote_idea turns it into a written article. Free (no AI credits). Duplicate titles are not inserted twice - the existing idea is returned instead.

Rolesany project role
ArgumentTypeDescription
title*stringThe article title / headline this idea proposesmax 200 chars
anglestringThe specific take or point of view for this piecemax 2000 chars
summarystringWhat the article should cover, in a few sentencesmax 2000 chars
target_keywordstringPrimary SEO keyword to rank formax 120 chars
secondary_keywordsarraySupporting keywords (max 10)of string
content_typestringe.g. "how-to guide", "comparison", "case study"max 60 chars
categoriesarrayArticle categories (max 10)of string
audiencestringWho this article is formax 120 chars
search_intentstringe.g. "informational", "commercial"max 120 chars
rationalestringWhy this idea is worth writingmax 2000 chars
langstringLanguage code (defaults to the project main language)max 10 chars
scoreintegerPriority score, higher sorts first0-100
statusstring"new" queues it for human review, "approved" marks it ready to writenew | approved - default "new"

articles.edit

write16 tools

Edit articles, and publish, schedule or unpublish them

Insert one photo into the body of an article from a public URL (or an asset_id from list_assets), at the position you choose: at the end, under a section heading, after a numbered paragraph, after a sentence you quote, or next to an existing image. The file is copied into the project CDN first, so the article never points at someone else's host - pass rehost false to link the original URL as-is. Give it alt text (good for SEO and accessibility) and an optional caption. Use dry_run to see where it would land before saving. To place several photos at once, use attach_article_images; for the cover, set_article_cover.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the articlemax 40 chars
urlstringPublic http(s) URL of the imagemax 2000 chars
asset_idstringUse a file already in the project asset library instead of a URL (see list_assets)max 60 chars
altstringAlt text describing the image. Write one: it is what search engines and screen readers read.max 300 chars
captionstringCaption rendered in italics under the imagemax 300 chars
positionstring"end" (default), "top" (under the title), "after_heading" (+ heading), "after_paragraph" (+ paragraph), "after_text" (+ after_text), "before_image"/"after_image" (+ image_index)end | top | after_heading | after_paragraph | after_text | before_image | after_image - default "end"
headingstringFor position "after_heading": the section title to place it under (partial match is fine)max 200 chars
paragraphintegerFor position "after_paragraph": which paragraph to place it after (1 = the first)min 1
after_textstringFor position "after_text": a unique sentence from the article; the image goes right after itmax 500 chars
image_indexintegerFor position "before_image"/"after_image": the position of the existing image, as given by list_article_imagesmin 1
rehostbooleanCopy the file into the project CDN first (default true). False keeps the URL exactly as given.default true
filenamestringName to store the copy under (defaults to the name in the URL)max 200 chars
dry_runbooleanShow where the image would land, and the markdown that would be inserted, without saving

Make targeted edits to an article body by exact find-and-replace, without resending the whole markdown. Read it first with get_article, then pass one or more { old_string, new_string } edits. Each old_string must appear exactly once unless replace_all is set. Set dry_run to validate and preview the result without saving. Each applied edit returns a context snippet plus a preview_url to view the result.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article to edit
dry_runbooleanValidate and compute the result without saving. Returns the same per-edit context as a real run so you can confirm before committing.
edits*arrayOrdered list of edits applied to the markdown bodyof object

Decide on an article awaiting approval in the review queue. decision "approve" publishes it immediately (internal + configured CMS, fails without cover/meta description); "reject" returns it to draft and cancels any auto-publish deadline. Only works on articles with status awaiting_approval.

Rolespublishereditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article (see the review queue)
decision*stringapprove | reject

Put several photos into an article at once, from public URLs (or asset_ids). They are copied into the project CDN and spread through the body - one under the opening paragraph of each section that has no picture yet, in the order given - and the first one becomes the cover when the article does not have one. Use it when someone hands over a batch of photos for an article. placement "end" instead puts them all at the bottom in order; set_cover_from controls the cover. Use dry_run to see the plan first, and add_article_image when one photo must land in one exact spot.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the articlemax 40 chars
images*arrayThe photos to add, in the order they should appear (max 12)of object
placementstring"auto" (default) spreads them across the sections; "end" appends them all at the bottom in orderauto | end - default "auto"
set_cover_fromstring"first_if_missing" (default) uses the first photo as cover only when the article has none, "first" always, "none" neverfirst_if_missing | first | none - default "first_if_missing"
rehostbooleanCopy the files into the project CDN first (default true)default true
dry_runbooleanShow where each photo would land, without uploading or saving

Draw the cover image of an article and attach it, in one call. The picture is about the article, not about its title: a short pass reads the piece and picks what should be in the frame, then the project's cover agent decides what it looks like (list_agents shows it as cover_rules), so every cover on a blog comes out of the same art direction. This is what to call when publish_article says an article has no cover, or when someone asks to add or replace one. Pass subject to say what the picture should show, art_direction for a one-off look, or prompt to send an exact prompt of your own and skip both. When the article was made from an X thread and the rules say the cover comes from the source material, the picture in the post is used instead of a drawn one - the chart, the screenshot, the frame from its video - which costs nothing at all; source overrides that for one article. A picture taken that way goes out on a card carrying the article title and crediting the handle it came from, because a screenshot on its own says nothing about the piece (the cover agent's title_overlay turns that off). Use preview to see the rules, the model and what it would do for free before spending anything. An article that already has a cover is left alone unless replace is true. Spends AI credits when it draws.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article to illustrate (from list_articles).max 40 chars
subjectstringWhat the picture should show, in concrete things ("a folded paper map on a workbench"). Omit to let the cover agent read the article and choose.max 1000 chars
art_directionstringA one-off note about the look of THIS cover, added to the project's standing art direction rather than replacing it.max 2000 chars
promptstringAn exact prompt to draw, used verbatim. This skips both the subject pass and the art direction, so only pass it when you mean to ignore the house style.max 4000 chars
subject_fromstring"article" reads the piece to choose the subject (the default). "title" uses the title and its keywords only, and calls no extra model.article | title
sourcestringWhere the picture comes from for THIS article, beating the project rule. "ai" draws one. "tweet" takes the picture from the X post the article was built on - its photo, or the frame X shows before its video plays - which costs no credits at all; a post with nothing usable falls back to a drawing. "auto" takes the post's picture when there is one and draws otherwise. Only meaningful on an article that carries a source post; everything else is drawn whatever this says.ai | tweet | auto
sizestringOutput size, e.g. "1536x1024" for a landscape cover. Omit to use the project rule.max 20 chars
qualitystringProvider quality tier, e.g. "high". Omit to use the project rule.max 20 chars
agent_idstringUse a specific cover agent (see list_agents with agent_type "cover"). Omit for the project one.max 120 chars
image_agent_idstringWhich image agent supplies the model and the art direction. Omit for the one the cover agent names, then the project image agent.max 120 chars
replacebooleanDraw a new cover even though this article already has one. Off by default, so a cover somebody chose is never overwritten by accident.
previewbooleanReport the rules, the model and the prompt that would be used, WITHOUT drawing anything or spending anything. Free.

Add a light touch of italic emphasis to an article that reads flat, or strip the italics it already has. The typographer picks a few terms - the concept a sentence introduces, the two or three words it turns on - and italicises those and nothing else: it may only add asterisks, never change a word, so a bad suggestion is dropped rather than written. How much is the project's own house style, held by its emphasis agent (list_agents shows it as emphasis_rules), so pass intensity only when this one article should differ. Articles written from now on already come out formatted this way; this is for the ones written before. Use preview to see what would change without touching the article or spending anything, and mode "clear" to remove every italic instead.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article to format (from list_articles).
modestring"add" (default) puts a few italics in. "clear" takes every italic back out, which is free, instant and the way back from a pass somebody found too heavy.add | clear
intensitystringHow much emphasis this one article should carry. "light" is about three italics per thousand words. Omit to use the project rule, which is what keeps a library looking like one publication.light | medium | strong
max_spansintegerCeiling on how many italics this run may add, whatever the length says. Omit to use the project rule.1-40
style_instructionsstringWhat is worth italicising in this particular piece, on top of the project rule.max 2000 chars
agent_idstringUse a specific emphasis agent (see list_agents). Omit for the project one.max 120 chars
previewbooleanReport what the article carries now and how much the rules would add, WITHOUT calling a model or writing anything. Free.

Move a photo that is already in an article to another place in the body, keeping its alt text and caption. Target it by index (from list_article_images) or URL, and give the new position the same way add_article_image does: end, top, after_heading, after_paragraph, after_text, or before_image / after_image. Note that before_image / after_image count the images as they are once this one is lifted out. Use dry_run to preview.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the articlemax 40 chars
indexintegerPosition of the image to move, as given by list_article_imagesmin 1
urlstringAlternative to index: the URL of the image to movemax 2000 chars
positionstringWhere it goes: "end", "top", "after_heading" (+ heading), "after_paragraph" (+ paragraph), "after_text" (+ after_text), "before_image"/"after_image" (+ image_index)end | top | after_heading | after_paragraph | after_text | before_image | after_image - default "end"
headingstringFor position "after_heading": the section title to move it under (partial match is fine)max 200 chars
paragraphintegerFor position "after_paragraph": which paragraph it goes after (1 = the first)min 1
after_textstringFor position "after_text": a unique sentence from the articlemax 500 chars
image_indexintegerFor position "before_image"/"after_image": which remaining image to sit next tomin 1
dry_runbooleanShow where it would land without saving

Publish an article (set its status to published). Fails if the article has no cover image or no meta description, exactly like the dashboard. Also refreshes the linked translations and the recommendation references that point to it. Idempotent: publishing an already-published article is a no-op.

Rolespublishereditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article to publish

Remove one photo from the body of an article, together with its caption line. Target it by index (from list_article_images) or by URL. The file stays in the project asset library so other articles and translations keep working - use delete_asset if it should be gone for good. Use dry_run to check which image would go.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the articlemax 40 chars
indexintegerPosition of the image to remove, as given by list_article_imagesmin 1
urlstringAlternative to index: the URL of the image to removemax 2000 chars
dry_runbooleanShow which image would be removed without saving

Swap one photo in an article for another, or fix its alt text or caption, without touching the rest of the body. Target it by index (from list_article_images) or by its current URL. Pass url (or asset_id) to change the picture, alt/caption to change the wording - any combination. A new URL is copied into the project CDN first unless rehost is false. Use dry_run to preview.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the articlemax 40 chars
indexintegerPosition of the image to replace, as given by list_article_imagesmin 1
current_urlstringAlternative to index: the URL the image currently points atmax 2000 chars
urlstringPublic http(s) URL of the new imagemax 2000 chars
asset_idstringUse a file already in the project asset library as the new image (see list_assets)max 60 chars
altstringNew alt text. Pass an empty string to clear it.max 300 chars
captionstringNew caption (italic line under the image). Pass an empty string to remove it.max 300 chars
rehostbooleanCopy the new file into the project CDN first (default true)default true
filenamestringName to store the copy under (defaults to the name in the URL)max 200 chars
dry_runbooleanShow the change without saving

Force the customer's site to drop its cached copy of an article, now. Publishing, editing, renaming and deleting already do this on their own, so reach for it when a page on the live site is still showing something we changed - typically because the site was unreachable when the purge first fired. Call it with no article_id to send a test ping instead, which checks the endpoint and the secret without touching an article. Answers delivered true/false: false with a `reason` means revalidation is not configured for this project (nothing was sent, nothing is queued), false with an `error` means the site was reached and refused. Use get_revalidation_status to see the delivery history.

Rolespublishereditoradvanced editoradministrator
ArgumentTypeDescription
article_idstringMongoDB ObjectId of the article to purge. Omit to send a configuration test ping for the project instead.

Restore an article body to a previous version recorded in its history. Get the history_id from get_article_history. By default this restores the "before" snapshot (undoing that change); set side to "after" to re-apply it. The rollback is itself recorded in history, so it can be undone too.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article to restore
history_id*stringhistory_id of the version to restore (from get_article_history)
sidestringWhich snapshot of the chosen history entry to restorebefore | after - default "before"

Book an article to publish itself at a future date, or clear an existing booking. Sets the article to "scheduled" with a publish_at instant; when the slot comes due it publishes on its own, internally and to the configured CMS, with no further call. Pass publish_at null to unschedule (the article goes back to draft). Get the dates from suggest_publishing_slots rather than inventing them - it returns instants in the project timezone that avoid days already taken. Refuses an already-published article. Unlike publish_article this does NOT need a cover or a meta description yet, but the article must have both by the time the slot fires or it is parked in the review queue instead: the response says what is still missing.

Rolespublishereditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article to schedule
publish_at*string | nullISO-8601 instant for the publication, e.g. "2026-09-15T10:00:00Z" (a bare "2026-09-15" is read as midnight UTC). Null unschedules the article and returns it to draft.

Set an article's cover photo from a public URL, from a file in the asset library (asset_id), or by promoting one of the images already in the body (image_index, from list_article_images). The file is copied into the project CDN first unless rehost is false. Every article needs a cover before publish_article accepts it, so this is usually the last thing missing on a draft written from a topic with no image agent. Use generate_image instead when the picture has to be drawn.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the articlemax 40 chars
urlstringPublic http(s) URL of the cover imagemax 2000 chars
asset_idstringUse a file already in the project asset library (see list_assets)max 60 chars
image_indexintegerPromote an image already in the body to cover, by its position from list_article_imagesmin 1
rehostbooleanCopy the file into the project CDN first (default true)default true
filenamestringName to store the copy under (defaults to the name in the URL)max 200 chars
dry_runbooleanShow what the cover would become without saving

Unpublish an article (set its status back to draft). Also refreshes the linked translations and the recommendation references that point to it. Idempotent: unpublishing a draft is a no-op.

Rolespublishereditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article to unpublish

Update core fields of an existing article in the targeted project (title, handle, md, cover, meta, categories, status, date). Only the fields you pass are changed. Renaming the handle and flipping the status also refresh the copies other articles hold, so translations and recommendations stay in sync; switching to "published" needs a cover and a meta description.

Roleseditoradvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article to update
titlestringmax 255 chars
handlestringURL path, must stay unique within the projectmax 300 chars
mdstringMarkdown body
coverstringCover image URL
meta_titlestringmax 150 chars
meta_descriptionstringmax 500 chars
categoriesarrayof string
statusstringdraft | published
datestringPublish date

assets.create

write1 tool

Add images and files to your projects

Copy an image or video from a public URL into a project's asset library, so it is served from the project's own CDN and can be used as an article cover or embedded in markdown. Use this for any picture that does not come from generate_image - a screenshot, a logo, an image the user found - because an article must not point at a file hosted somewhere else. Returns the durable URL to use. Images and videos only, 15MB max; the file name must be free in this project (pass filename to rename it). To put a photo straight into an article instead, add_article_image and set_article_cover do this copy for you.

Rolesany project role
ArgumentTypeDescription
url*stringPublic http(s) URL of the file to copymax 2000 chars
filenamestringName to store it under, e.g. "team-photo.jpg". Defaults to the name in the URL. Lowercased and slugified.max 200 chars
article_idstringArticle this file illustrates, recorded on the asset so list_assets can filter on itmax 40 chars

articles.delete

write1 tool

Delete articles

delete_articledestructive

Permanently delete an article from the targeted project. This cannot be undone.

Rolesadvanced editoradministrator
ArgumentTypeDescription
article_id*stringMongoDB ObjectId of the article to delete

assets.delete

write1 tool

Delete images and files, including ones your published articles use

delete_assetdestructive

Permanently delete one file from a project's asset library: the record AND the stored file, so every article still pointing at its URL loses the image. Take the asset_id from list_assets (or from what generate_image / upload_asset returned). The call is refused when an article uses the file, and tells you which ones: read that list to the user and only pass force true if they confirm. This cannot be undone.

Rolesadvanced editoradministrator
ArgumentTypeDescription
asset_id*stringIdentifier of the asset to delete, as returned by list_assetsmax 300 chars
forcebooleanDelete even though articles still use this file. Only after the user has confirmed.

automation.manage

writesensitivecredits3 tools

Manage automation routines: list, run, pause (a routine can publish articles autonomously and spends credits)

list_routinesread only

List the automation routines of the targeted project: schedule, pipeline, output policy, guardrails, next/last run times, and each routine's latest run outcome. Optionally include recent run history.

Rolesadvanced editoradministrator
ArgumentTypeDescription
include_runsbooleanAlso return the last 10 runs per routine

Pause an automation routine (it stops firing on schedule; manual runs stay possible). Pass resume: true to re-enable it instead -- the next occurrence is recomputed from its schedule in the project timezone.

Rolesadvanced editoradministrator
ArgumentTypeDescription
routine_id*stringThe routine to pause or resume (see list_routines)
resumebooleantrue = re-enable instead of pausing
run_routinespends credits

Run an automation routine immediately (out of schedule). The run obeys the routine's guardrails and output policy; it produces articles asynchronously (follow progress with list_routines include_runs, or list_jobs). Fails if a run of this routine is already in progress. Spends AI credits.

Rolesadvanced editoradministrator
ArgumentTypeDescription
routine_id*stringThe routine to fire (see list_routines)

`project_id` is not in the schemas

Every project-scoped tool accepts it, but it is a routing argument handled by the dispatcher, not a tool parameter: it is stripped before the handler runs. Clients are offered it automatically when a connection reaches more than one project.

Which scopes a preset grants, and which roles confer them: permissions and scopes. How a call is dispatched and what a failure looks like: protocol.