A few things that are true for every tool
- One project per key. The agent key the server runs with is scoped to a single project. The agent doesn’t pick a project; it’s already decided by the key.
- You stay in control of approval and publishing. An agent can write, edit, and prepare posts all day, but it can only publish a post you have approved in the dashboard. More on this under publish_blog.
- Status drives everything. Most tools only work when a post is in the right status (for example, you can’t publish a post that’s still generating). The full map of statuses is in Blog Status Lifecycle. The relevant statuses are called out under each tool below.
- Generation runs in the background. Tools that create or generate a post return right away with a post ID — they don’t wait for the writing to finish. The agent checks progress by polling generation_status.
- Errors are clear. If a tool can’t do what was asked (the key is invalid, the post isn’t approved, a file can’t be read, a publish is blocked for compliance), it returns a readable error message instead of silently failing.
Planning and review
Start here. These tools let the agent understand the project and see what work is already lined up.get_project_context
Returns the project this agent key is attached to. What you get back:- The project’s ID
- The account it belongs to
- The project’s name
review_content_plan
The natural starting point for any real work. It returns two things together:- The blog list — every planned and draft post in the project, each with its ID, title, status, and scheduled date. This is the essential part.
- The plan summary — your content plan’s dates, whether it has expired, how many plans exist, and whether a new plan can be generated. This part is best-effort: if it can’t be loaded for any reason, the tool still returns the blog list and simply leaves the plan summary empty. Nothing breaks.
Generation
These tools create content. Remember: they all kick off work in the background and hand back a post ID immediately — the agent then polls generation_status to follow along.generate_blog
Generates a post that’s already in your plan, by its ID. What you pass:- blog_id (required) — the ID of the planned post to generate.
- additional_direction (optional, up to 2,000 characters) — extra steering for this one post (“lead with a customer story,” “keep it under 800 words,” “mention our weekend hours”).
generate_more
Adds brand-new planned posts to the project — handy when the plan is running low and you want the agent to line up more topics. What you pass:- count (required) — how many posts to add, from 1 to 10.
draft_from_abstract
Starts a brand-new post from the agent’s own brief, instead of from the auto-plan. Use this when the agent has a specific topic in mind that isn’t already a planned keyword. What you pass:- abstract (required, 10 to 4,000 characters) — what the article should be about, in plain words. Cover the angle, the points to hit, the audience — whatever should steer it.
- blog_type (optional) — the kind of article, for example
how_to. If you pass a type the generator doesn’t recognize, it falls back to a how-to.
generation_status
Checks how a post’s generation is going. The agent polls this aftergenerate_blog, draft_from_abstract, or generate_more-then-generate.
What you pass:
- blog_id (required).
- status — where the post is in its lifecycle (generating, done, failed, and so on).
- status_message — a short human-readable note about the current step.
- word_count — how many words have been written so far.
- images_generated and images_total — image progress (for example, 2 of 3 done).
- error — set if something went wrong.
Editing
Once a post exists, these tools let the agent read it and refine it.get_blog
Returns a single post in full: its complete content, title, excerpt, meta title and description, status, and other details. Use it before editing so the agent is working from the latest version. What you pass:- blog_id (required).
edit_blog
Saves changes to a post’s text and metadata. You only send the fields you want to change; anything you leave out is untouched. What you can change (all optional):- title
- content (the full article body)
- excerpt
- meta_title
- meta_description
regenerate_section
Rewrites one section of a post with AI — useful for tightening an intro or punching up a weak paragraph without touching the rest. What you pass:- blog_id (required).
- section_html (required, up to 100,000 characters) — the exact HTML of the section to rewrite.
- tone (0 to 100, default 50) — a slider from 0 = formal and professional to 100 = casual and conversational.
- length (0 to 100, default 50) — a slider from 0 = shorter to 100 = longer.
- additional_prompt (optional, up to 1,000 characters) — any extra instruction for the rewrite.
regenerate_image
Generates a fresh version of one image in the post. What you pass:- blog_id (required).
- image_src (required, up to 2,000 characters) — the current image’s source URL, so the system knows which image to replace.
- image_alt (up to 500 characters) — the image’s alt text, used as context for the new image when you don’t give a custom prompt.
- style (0 to 100, default 50) — a slider across three looks: 0 = modern/minimalist, 50 = abstract/artistic, 100 = realistic/photographic.
- custom_prompt (optional, up to 1,000 characters) — describe exactly what you want; this takes priority over the alt text as the basis for the image.
Images
upload_image
Puts your own image into a post — a real product photo, a screenshot, a team picture — instead of an AI-generated one. What you pass:- blog_id (required).
- file_path (required) — the path to a local image file. PNG, JPG, and WebP are the typical formats.
- alt_text (optional, up to 500 characters) — alt text for accessibility and SEO.
-
placement (default
replace) — where the image goes: - replace — swaps an existing image in the post for yours.
- append — adds your image at the end of the post.
- none — only stores the image in your library and hands back an HTML snippet you can place yourself with edit_blog.
-
image_index (default 0) — which existing image to replace when placement is
replace. It’s zero-based, so 0 is the first image, 1 is the second, and so on. If there’s no image at that position, the upload is added at the end instead.
- asset_id — the stored image’s ID in your asset library.
- public_url — the live URL of the stored WebP image.
- img_html — a ready-to-use
<img>snippet (handy when placement isnone).
Publishing
publish_blog
Publishes a post to the site connected to the project (WordPress, Webflow, Ghost, Shopify, Zepio, or a webhook). What you pass:- blog_id (required).
- integration_id (optional) — which connected destination to publish to. Leave it out to use the project’s active integration.
How the tools fit together
A typical agent run looks like this:- get_project_context — confirm which project we’re in.
- review_content_plan — see what’s planned and what’s waiting.
- generate_blog (or draft_from_abstract for a fresh topic) — write a post.
- generation_status — poll until it’s done.
- get_blog — read the result.
- edit_blog, regenerate_section, regenerate_image, upload_image — refine it.
- A human reviews and clicks Approve in the dashboard.
- publish_blog — push the approved post live.
Related reading
- Agent Keys & MCP Server — how to create an agent key and connect the MCP server.
- Blog Status Lifecycle — what every blog status means and how posts move between them.
- Public Blog API — read your published posts as JSON for a static site or custom frontend.
