Skip to content

MCP abilities

RowSprout Pro

RowSprout Pro 3.1 registers 15 WordPress Abilities in the category rowsprout. An agent calls them through the MCP adapter’s mcp-adapter-execute-ability tool; your own PHP code calls them with wp_get_ability( 'rowsprout/…' )->execute( $input ). How to connect an agent is explained in AI agents (MCP).

The descriptions below are the ones the agent receives, so they are written for an AI model and name the other abilities by their tool name (generate_pages is the ability rowsprout/generate-pages).

Ability What it does
rowsprout/list-templates List rowsprout_template posts, optionally filtered by status or search term.
rowsprout/get-template Get a template’s full details: title, content, href pattern, properties (field_types), and groups merged with their current generation status.
rowsprout/create-template Create a new rowsprout_template with an href pattern and optional initial properties.
rowsprout/update-template Update a template’s title, content, href pattern, and/or status.
rowsprout/list-template-properties List a template’s properties (field_types — the columns every group shares), plus “available_types”: the live registry of types valid for add_template_property’s own “type” argument.
rowsprout/add-template-property Add a new property (field/column) to a template.
rowsprout/list-template-groups List a template’s groups (the rows generated pages are built from) with their field values and current generation status.
rowsprout/add-template-group Add a new group to a template.
rowsprout/update-template-group Update one group’s field values (partial — only listed keys change) and/or its parent link.
rowsprout/generate-pages Queue pages for background generation — for the whole template or a specific set of groups — using a chosen save-action behavior.
rowsprout/get-generated-page Read a generated rowsprout_page post directly by its page_id (get_generation_status’s “rowsprout_page_id”): real title, slug, post status, permalink, and content.
rowsprout/get-generation-status Check generation status for a template’s groups — use this to poll after calling generate_pages.
rowsprout/get-group-planning Read the planning of a template’s groups — the same overview as the Planning tab in the template editor.
rowsprout/set-group-planning Plan — or clear — the moment each group is generated (which is when its page goes live).
rowsprout/autofill-group-planning Spread planned moments over a set of groups from a few parameters, like the Planning tab’s auto-fill wizard.

List rowsprout_template posts, optionally filtered by status or search term.

Parameter Type Required Description
status string: any, publish, draft, pending, private
search string
page integer
per_page integer

Get a template’s full details: title, content, href pattern, properties (field_types), and groups merged with their current generation status.

Parameter Type Required Description
template_id integer yes

Create a new rowsprout_template with an href pattern and optional initial properties. Creates no groups and generates no pages. Placeholder syntax: write “@code_<code>_<id>@” anywhere in content or href_pattern to insert a property’s value at generation time. “<code>” is a property’s own “code” (see list_template_properties/get_template — most commonly just its key, e.g. “href”, “title”); a few reserved words also work as shortcuts regardless of a property’s own code: “title” for the title-type property, “href”/“slug” for the href-type property, “textarea”/“content” for a textarea property. “<id>” is normally this template’s own post ID (template_id) — but for a property this template only has because it INHERITS it from a parent template (see get_template’s “field_types”), use the PARENT template’s post ID instead, since that is where the value actually lives.

Parameter Type Required Description
title string yes
content string HTML content. May contain @code_<code>_<id>@ placeholder tokens — see tool description.
href_pattern string yes URL slug pattern for generated pages. May contain @code_<code>_<id>@ placeholder tokens — see tool description.
status string: draft, publish
parent_id integer The post ID of a PARENT TEMPLATE (a rowsprout_template post), if this template should inherit its properties. Not related to a group’s own parent link — see add_template_group/update_template_group’s “parent_group_id” for that.
field_types array

Update a template’s title, content, href pattern, and/or status. Does not touch properties, groups, or generation. Placeholder syntax: write “@code_<code>_<id>@” anywhere in content or href_pattern to insert a property’s value at generation time. “<code>” is a property’s own “code” (see list_template_properties/get_template — most commonly just its key, e.g. “href”, “title”); a few reserved words also work as shortcuts regardless of a property’s own code: “title” for the title-type property, “href”/“slug” for the href-type property, “textarea”/“content” for a textarea property. “<id>” is normally this template’s own post ID (template_id) — but for a property this template only has because it INHERITS it from a parent template (see get_template’s “field_types”), use the PARENT template’s post ID instead, since that is where the value actually lives. Fails with an error (rather than silently overwriting) if this template’s properties/groups were changed by anyone else — another API call, or someone saving via the classic/Elementor editor — after you last read them. On that error, call get_template again and retry with the current data.

Parameter Type Required Description
template_id integer yes
title string
content string HTML content. May contain @code_<code>_<id>@ placeholder tokens — see tool description.
href_pattern string URL slug pattern for generated pages. May contain @code_<code>_<id>@ placeholder tokens — see tool description.
status string

List a template’s properties (field_types — the columns every group shares), plus “available_types”: the live registry of types valid for add_template_property’s own “type” argument. Properties can only be listed and added via this API, never modified or removed — a deliberate safety limit given generated pages can already be live in production; use the admin UI for that.

Parameter Type Required Description
template_id integer yes

Add a new property (field/column) to a template. Every existing group gets an empty value for it. Properties can only be added here, not modified or removed (deliberate — see list_template_properties). Call list_template_properties first: its “available_types” is the authoritative, current list of valid values for “type” (not fixed here since it’s filterable/site-specific). Fails with an error (rather than silently overwriting) if this template’s properties/groups were changed by anyone else — another API call, or someone saving via the classic/Elementor editor — after you last read them. On that error, call get_template again and retry with the current data.

Parameter Type Required Description
template_id integer yes
type string yes One of list_template_properties’ “available_types” for this template (e.g. “title”, “href”, “textarea”, “item-list”, “thumbnail”).
label string yes Human-readable name shown in the admin UI (e.g. the column header). Not used in placeholder tokens or as the fields{} key.
key string The internal identifier for this property: the key used in a group’s “fields” map (add_template_group/update_template_group) and in get_template’s “field_types”/group output. Must be unique on this template — properties are never removed, so a collision here is permanent. Auto-generated (matching the admin UI’s own convention) if omitted; only pass one explicitly if you need a specific, predictable key.
code string The “<code>” used in this property’s own @code_<code>_<id>@ placeholder token (see create_template’s own description). Defaults to “key” if omitted — most properties never need to set this separately.
options array
can_be_overruled boolean
required boolean

List a template’s groups (the rows generated pages are built from) with their field values and current generation status. Each field value comes back nested: {“key”: {“type”:…, “value”:…, “code”:…}}. group_id values are stable across normal add_template_group/update_template_group calls, but are NOT guaranteed to survive a WPML translation update being applied to this template (WPML can regenerate its whole group list with new ids) — re-fetch via list_template_groups/get_template after one if this template has translations, rather than reusing an id read beforehand.

Parameter Type Required Description
template_id integer yes
group_ids array
status string: not_queued, pending, scheduled, waiting, in-process, completed, failed, stale, deleted-completed “not_queued” = no DB queue row yet (e.g. a group with nothing generated for it yet). The rest are real queue statuses; “stale” means the config changed since this group’s page was last built and it is waiting to be picked up by a future generate_pages call.
page integer
per_page integer

Add a new group to a template. Fields not specified default to an empty value. Accepts either a plain scalar per field key ({“href”: “the-hague”}) or the nested shape get_template/list_template_groups return ({“href”: {“value”: “the-hague”, …}}) — both work. Generates no page — call generate_pages afterwards; the new group is marked ready for that automatically. Groups can only be added and modified via this API, never removed. group_id values are stable across normal add_template_group/update_template_group calls, but are NOT guaranteed to survive a WPML translation update being applied to this template (WPML can regenerate its whole group list with new ids) — re-fetch via list_template_groups/get_template after one if this template has translations, rather than reusing an id read beforehand. Fails with an error (rather than silently overwriting) if this template’s properties/groups were changed by anyone else — another API call, or someone saving via the classic/Elementor editor — after you last read them. On that error, call get_template again and retry with the current data.

Parameter Type Required Description
template_id integer yes
fields object Map of field key to its new value — plain scalar or {“value”: …}. See tool description.
parent_group_id string The group_id of a group on this template’s PARENT TEMPLATE, if this group should inherit from it. A string identifying a GROUP — unrelated to create_template’s “parent_id”, which is an integer identifying a TEMPLATE POST.

Update one group’s field values (partial — only listed keys change) and/or its parent link. Accepts either a plain scalar per field key ({“href”: “the-hague”}) or the nested shape get_template/list_template_groups return ({“href”: {“value”: “the-hague”, …}}) — both work. If this group already has a generated page, it is marked stale so the next generate_pages call (even without listing this group_id, and without force_full_regenerate) will rebuild it. Never generates a page itself. Groups can only be modified via this API, never removed. group_id values are stable across normal add_template_group/update_template_group calls, but are NOT guaranteed to survive a WPML translation update being applied to this template (WPML can regenerate its whole group list with new ids) — re-fetch via list_template_groups/get_template after one if this template has translations, rather than reusing an id read beforehand. Fails with an error (rather than silently overwriting) if this template’s properties/groups were changed by anyone else — another API call, or someone saving via the classic/Elementor editor — after you last read them. On that error, call get_template again and retry with the current data.

Parameter Type Required Description
template_id integer yes
group_id string yes
fields object yes Map of field key to its new value — plain scalar or {“value”: …}. See tool description.
parent_group_id string The group_id of a group on this template’s PARENT TEMPLATE, if this group should inherit from it (empty string clears it). A string identifying a GROUP — unrelated to create_template’s “parent_id”, which is an integer identifying a TEMPLATE POST.

Queue pages for background generation — for the whole template or a specific set of groups — using a chosen save-action behavior. Only queues; actual generation happens on the next background queue tick (usually within about a minute). Mirrors the admin “Generate” row action exactly. A (re)generated page always updates the SAME rowsprout_page post in place (same post ID) — it is never duplicated; only its slug can change, and only if a field that feeds the href pattern changed (note: this API leaves no redirect behind when that happens — see get_generated_page). save_action: “update_pages” (default) actually (re)builds pages; “save_template” only marks groups stale/queued without building anything (mirrors “Save template only” in the editor). This tool always generates NOW; to choose WHEN groups are generated use get_group_planning / set_group_planning / autofill_group_planning. Called for the whole template (no group_ids) it leaves planned groups alone; naming a planned group in group_ids, or force_full_regenerate=true, generates it immediately regardless of its plan. With save_action=update_pages and no group_ids: by default (force_full_regenerate not set) only groups already marked stale or newly added are rebuilt — a group whose fields were changed via update_template_group IS included (that call marks it stale), but a change made outside these tools may not be picked up without force_full_regenerate=true, which unconditionally rebuilds every group. Use get_generation_status to check progress afterwards.

Parameter Type Required Description
template_id integer yes
group_ids array
save_action string: update_pages, save_template Defaults to “update_pages” if omitted.
force_full_regenerate boolean Only applies when group_ids is empty and save_action is “update_pages”. true = rebuild every group in the template regardless of whether it changed. false/omitted = only rebuild groups already marked stale or newly added.

Read a generated rowsprout_page post directly by its page_id (get_generation_status’s “rowsprout_page_id”): real title, slug, post status, permalink, and content. “content” is a fresh, uncached render of the actual live page (bypasses page caching so it reflects the current data, not what happens to be cached right now — see generate_pages/get_generation_status for whether the page has actually been rebuilt since a change; this tool answers “what would the current data produce”, not “what is currently cached”). Use this to diagnose a page directly through the API instead of fetching its live URL by hand — e.g. to confirm whether page_link’s slug-collision warning actually applies to this page.

Parameter Type Required Description
page_id integer yes

Check generation status for a template’s groups — use this to poll after calling generate_pages. “page_link” is a real get_permalink() lookup of the generated post (not a computed/guessed URL) — but generated-page slugs deliberately don’t go through WordPress’s own slug-uniqueness check, so it CAN collide with another post’s URL; if a returned link doesn’t show the page you expect, that’s the first thing to check. “generated_at” is when this group’s page was last actually (re)built (null if never, or on a site whose database hasn’t finished migrating yet) — distinct from “status”: a “completed” group can still be showing older content than the current config if nothing has queued it for rebuild since (see generate_pages).

Parameter Type Required Description
template_id integer yes
group_ids array
status string: pending, scheduled, waiting, in-process, completed, failed, stale, deleted-completed

Read the planning of a template’s groups — the same overview as the Planning tab in the template editor. For every group: its “state” (unplanned = not generated yet, planned, waiting_parent, queued, processing, live, stale = outdated, failed, deleted), “planned_at” (the moment it will be generated), its parent group’s planned moment (a child can never be planned earlier than its parent), when it was last generated (“generated_at”) and its page link. Generating a group’s page IS what makes it live, so “planned_at” is effectively the go-live moment (plus a short delay for the background queue). All date-times are in the site’s timezone (returned as “timezone”); “processing_window” says whether generation is restricted to a daily time window. Read-only; works on any language’s template.

Parameter Type Required Description
template_id integer yes
state string: unplanned, planned, waiting_parent, queued, processing, live, stale, failed, deleted
page integer
per_page integer

Plan — or clear — the moment each group is generated (which is when its page goes live). “plan” maps a group_id to a date-time in the site’s timezone, “YYYY-MM-DD HH:MM”, or to “” (empty) to clear that group’s plan. All-or-nothing: if any entry is invalid nothing is saved and the error names the group. A child group (one with a parent_group_id) cannot be planned earlier than its parent group’s planned moment; a child whose parent group has no page yet simply waits for it. Groups currently being generated are skipped and reported. This only changes WHEN generation happens — it never generates anything now. Like the other write tools it is refused on a template that is a WPML translation of another (plan the original-language template; a translation is planned in the template editor’s Planning tab). A group that already has a page is refreshed at its planned moment while the old page stays live until then. Clearing a plan sets the group back to “stale”. Changing a group’s data later does not cancel its plan.

Parameter Type Required Description
template_id integer yes
plan object yes Map of group_id to “YYYY-MM-DD HH:MM” (site timezone), or “” to clear.

Spread planned moments over a set of groups from a few parameters, like the Planning tab’s auto-fill wizard. Starting at “start” (site timezone, “YYYY-MM-DD HH:MM”), it hands out “per” groups per “period” (“day” or “hour”), between the daily times “from” and “to” (default 09:00–17:00; a day’s slots are spread evenly across that window), optionally only on certain “weekdays” (0 = Sunday … 6 = Saturday). “order”: “table” (the template’s own order, default), “title” (alphabetical) or “random”. Which groups: “group_ids” if given, otherwise “apply”: “empty” (default — groups that have no plan yet) or “all”. A child group is never placed earlier than its parent group’s planned moment (it is moved later, and a note says so). By default this is a PREVIEW — nothing is stored; pass save=true to store it (same rules and errors as set_group_planning). The preview works on any language’s template; save=true is refused on a template that is a WPML translation, like the other write tools.

Parameter Type Required Description
template_id integer yes
start string yes “YYYY-MM-DD HH:MM” in the site’s timezone.
per integer Groups per period. Default 5.
period string: day, hour Default “day”.
from string “HH:MM”. Default 09:00.
to string “HH:MM”. Default 17:00.
weekdays array of integer Allowed weekdays, 0 = Sunday … 6 = Saturday. Default: every day.
order string: table, title, random
apply string: empty, all Which groups when group_ids is not given. Default “empty”.
group_ids array of string Plan exactly these groups (overrides “apply”).
save boolean false (default) = preview only; true = store the planning.

Besides the descriptions above, an agent that discovers the abilities gets this general guidance about RowSprout (the description of the ability category). On a site with WPML, the part after it is added.

Guidance for every site
This category manages "rowsprout" content on a WordPress site: templates
that define a pattern of properties, and the generated pages built from
per-row "groups" of values for that pattern (e.g. one template per product
category, one generated page per city/location).
Data model:
- A TEMPLATE (rowsprout_template post) has PROPERTIES and GROUPS.
- PROPERTIES (aka "field_types") are the columns every group shares: a
key, a type (title/href/textarea/thumbnail/etc.), a label, and a "code"
used in @code_<code>_<id>@ placeholder tokens inside the template's own
title/content/href pattern — see create_template's own description for
the full placeholder syntax, it's the single most important thing to
read before writing any template content/href_pattern. Properties can
only be listed and added here — not modified or removed (deliberate;
same for templates and groups themselves — nothing in this API deletes
anything, use the admin UI for that).
- GROUPS are the actual data rows — one group normally becomes one
generated PAGE (rowsprout_page post). Each group has a value per property.
Groups can be listed, added, and modified (field values, parent link) —
never removed. A group's own "group_id" is stable across normal edits
but NOT guaranteed to survive a WPML translation update on that
template — see add_template_group/update_template_group's own
description.
- A CHILD template (has a parent template) automatically shares any
property whose key also exists on its parent — those show first, in the
parent's own order, followed by the child's own properties. A child's
group inherits an empty field from its parent's matching group at
generation time.
- A group's field values are read back nested: {"key": {"type":...,
"value":..., "code":...}}. When writing (add_template_group /
update_template_group), either that nested shape or a plain scalar per
key ({"key": "value"}) is accepted — no need to strip it down yourself
before sending values back.
- "parent_id" means two different things depending which tool: an integer
TEMPLATE post id on create_template, but a string GROUP id
("parent_group_id") on add_template_group/update_template_group. Same
concept (inheritance), different namespace — don't confuse the two.
Generating pages:
- generate_pages only QUEUES groups for background generation — it never
builds a page synchronously. Actual generation happens on the next
background tick, usually within about a minute. Poll
get_generation_status afterwards to see when it's done and get the
resulting page id/link.
- A (re)generated page always updates the SAME underlying rowsprout_page
post in place — same post ID, every time. It is never duplicated. Only
its slug/URL can change, and only if a field feeding the template's href
pattern changed.
- save_action controls what a queue does, default "update_pages" if
omitted: "update_pages" actually (re)builds the queued group(s);
"save_template" only marks them stale/queued without generating
anything (mirrors the editor's "Save template only" option).
generate_pages always generates NOW; to choose WHEN groups are generated,
use the planning tools described under "Planning" below.
- With save_action="update_pages" and no group_ids given (whole-template
mode): by default only groups already marked stale, or newly added,
actually get rebuilt — NOT every "completed" group whose data might
have changed. update_template_group marks the group(s) it touches
stale, so a follow-up generate_pages call picks them up correctly. Pass
force_full_regenerate=true to unconditionally rebuild every group
regardless of whether anything changed.
- Adding a property, or changing a group's field values, never triggers
generation by itself — call generate_pages afterwards for the change to
actually produce/update a page.
- get_generation_status's "page_link" is a genuine get_permalink() lookup
of the real post, not a guessed URL — but generated-page slugs
deliberately skip WordPress's own slug-uniqueness check, so two pages
(even from different templates) can end up sharing one slug; if the
link doesn't show the expected content, a slug collision is the first
thing to suspect. Its "generated_at" is when that specific page was
last actually rebuilt — a "completed" status alone doesn't mean the
content is current. get_generated_page reads a page directly by its
rowsprout_page_id (title/slug/status/permalink/content) — use it to
confirm what's actually on a page instead of fetching its live URL.
- No redirect is left behind when a field change moves a page's slug —
rowsprout_page is a hierarchical post type, which WordPress's own
old-slug-redirect mechanism explicitly excludes. An href-driven slug
change on an already-published, already-indexed page is a real broken-
link risk with no built-in mitigation; flag this to the user rather
than assuming it's handled.
Planning (choosing WHEN groups are generated):
- Generating a group's page IS what makes it live — there is no separate
publish date. So "planning" a group means choosing the moment it gets
generated: get_group_planning shows every group's state and planned
moment, set_group_planning plans or clears them, and
autofill_group_planning spreads moments over many groups from a few
parameters (preview by default; save=true stores it). All date-times are
in the site's timezone.
- A planned group is generated by the background queue shortly after its
moment (within the queue's normal cadence, and only inside the site's
processing window if one is set) — planning never generates anything by
itself. A group that already has a page keeps that page live until its
planned moment, when it is refreshed.
- A child group (one with a parent_group_id) can never be planned earlier
than its parent group, and is only generated once its parent group's page
exists.
- Reading the planning works on any language's template, but WRITING it
(set_group_planning, autofill_group_planning with save=true) is refused on
a WPML translation, like every other write tool — plan the
original-language template; a translation is planned by a person in the
template editor's Planning tab. The autofill preview works everywhere.
- Editing a planned group's data later does not cancel its plan: it is
generated with the then-current data when its moment arrives.
- generate_pages generates now. Called for the whole template (the default),
it leaves planned groups alone; naming a planned group in group_ids, or
passing force_full_regenerate=true, generates it immediately regardless of
its plan.
Suggested order for common tasks: list_templates → get_template (to see
current properties/groups/status) → add_template_property /
add_template_group / update_template_group as needed → generate_pages (now)
or autofill_group_planning / set_group_planning (later) → get_generation_status
or get_group_planning → get_generated_page to confirm.
Added on sites with WPML
WPML (multilingual):
- Each language of a template/page is its own separate WordPress post with
its own id — a WPML translation is not a variant of the same post, it's
a whole different rowsprout_template post that started as a copy of the
source language's config. None of these tools expose which language a
template is in or which other post is its translation; if you need a
specific language's version of a template and aren't sure of its post
id, ask the user for it rather than guessing from the source-language
template's id.
- Translations are created/managed through WPML's own Translation
Editor/Dashboard in the WordPress admin, not through this API — there
is no tool here for creating or managing a translation.
- A template that IS a WPML translation of another template can be read
(including its planning) and have its pages (re)generated, but
update_template/add_template_property/add_template_group/
update_template_group/set_group_planning (and autofill_group_planning
with save=true) all refuse to write to it — edit the original-language
template, or use WPML's own Translation Editor, instead.