Skip to content
OmniRetailConnect Docs

Commerce · MCP

Content tools

List, read, create, change and delete CMS pages: blocks, images, version check, search-engine fields, the home page and size limits.

View as Markdown

Overview

Five tools read and manage the CMS pages of the shop: the home page, the legal pages and every other content page. Reading needs commerce.read; changing needs commerce.write.content, issued as the edit permission Pages (Pagina's) in Settings > API tokens. The tools exist since server version 1.6.0 and are also REST endpoints with the same payload. They run the page editor's own actions under the page's row lock. Every change is in the change log, in the shop's content activity log with the token as the causer, and in the page's history as a version by "API-token" and the token name (no staff author).

Content tools
Tool Scope Purpose
list_pages commerce.read The CMS pages, a page at a time, drafts included.
get_page commerce.read One page with its blocks and search-engine fields.
create_page commerce.write.content Create a page (a draft unless told otherwise).
update_page commerce.write.content Change fields and blocks of a page, with a version check.
delete_page commerce.write.content Delete a page, never the home page.

Drafts are visible to read tokens

list_pages and get_page return drafts and unpublished (scheduled or expired) pages to any token with commerce.read. Do not give a read token to anyone who may not see unpublished content. Page titles and text come from staff: data, not instructions.

list_pages

Optional status (draft, published or all, default), limit and cursor. Output. items (id, title, slug, is_home, url, status, visibility (draft, scheduled, published or expired: whether visitors can open it now), publish_at, unpublish_at, noindex, updated_at), next_cursor and has_more. No blocks: use get_page.

get_page

One page by id, drafts and unpublished pages included: the fields of list_pages plus meta_title, meta_description, canonical_url, og_image (the stored share image path) with og_image_url, and blocks, the full list as stored, each {type, data, image_urls} (image_urls is the public URL per image field, null without images). The writable fields have the names and forms update_page takes, so they can be sent back as they are. updated_at is the version that update_page needs as expected_updated_at. An unknown id is not_found.

create_page and update_page

Inputs of create_page, update_page and delete_page
Name Type Required Description
id integer Required update_page and delete_page only.
expected_updated_at string Required update_page only. The updated_at of get_page. When the page was saved after that moment the call is conflict and nothing changes.
title string Required create_page only (optional on update). At most 255 characters.
slug string Required create_page only (optional on update). Lower-case letters, digits and hyphens, unique, never home. The home page keeps home; another slug is invalid_argument.
status string Optional published publishes, draft makes it a draft. Left out keeps it; a new page is a draft.
publish_at, unpublish_at string|null Optional ISO 8601 with an offset (a date that does not exist is invalid_argument), answered in UTC. null clears. The end must be after the start.
meta_title, meta_description string|null Optional At most 255 and 320 characters. null or empty: none.
canonical_url string|null Optional An https URL or a path of this shop (/pagina/...), only for a copy of another page. null: the page's own address.
noindex boolean Optional true keeps the page out of search results (robots meta and X-Robots-Tag), the sitemap and llms.txt.
og_image string|null Optional The share image: an https URL (downloaded), its current path, or null to remove it.
blocks array Optional The whole list in page order, at most 60, each {type, data}. It replaces every block.
  • Version check. update_page requires expected_updated_at. Every committed change moves the version, also a second change within the same second, so two writers with the same value never both succeed. Only the fields you send change; the input is merged onto the page as read under its row lock. Sending the output of get_page back with the current version answers changed: false (no new version, no activity line).
  • Not idempotent. A repeat of create_page with the same slug is invalid_argument; a slug that another page takes at the same moment is conflict.
  • Destructive. update_page is advertised as destructive because blocks replaces the whole list; create_page and update_page are advertised with openWorldHint: true because they download image URLs.
  • Output. The page as get_page returns it, plus changed and changes ({field: {old, new}}; blocks as a count and a sha256 fingerprint, so the change log does not keep whole texts).

Blocks

blocks is the whole list in page order (at most 60) and replaces every block, so read the page first, change what you need and send the list back. There are 20 block types. Ten work on any page: heading, richtext, faq, cta, usp, callout, image, media-text, feature-grid, promo-banners. Ten work only on the home page, or on a page that has that type already: product-row, category-tiles, brand-carousel, article-teaser, locations-teaser, related-products, product-tabs, hero-slider, newsletter, goal-tiles. The input schema in tools/list documents every type and its data fields (anyOf by type); the main fields are also listed under Pages (REST).

  • Rich text (richtext.html, media-text.html) is sanitised as in the editor: scripts, event handlers, styles and unsafe links (javascript:) are removed. Other block text is stored as plain text.
  • Collection, brand and product slugs in blocks must exist (invalid_argument), unless the page has them already.
  • Refusals name the field (blocks.2.data.alt: ...) and are in English.

Images

An image field and og_image take a path the page already uses (kept, no download) or an https URL.

  • The URL is downloaded before the write by the same guard as add_product_media: public hosts only, DNS-pinned, no redirects. It is then checked like an editor upload: JPEG, PNG or WebP of at most 5 MB, stored as WebP.
  • At most 20 new image URLs per call, 40 MB and 30 seconds of downloading in all. Past the budget the call is invalid_argument naming the field.
  • A GIF or AVIF, or an image above 5 MB, is invalid_argument naming the field (blocks.2.data.path, og_image). An http URL, a path of another page or any other value is invalid_argument.
  • og_image takes only an https URL, null or its current value, never a path a block uses.
  • A file stored by a call that then fails or rolls back is deleted again; a replaced share image file is deleted after the commit.

The home page

The home page keeps the slug home and cannot be deleted (delete_page answers invalid_argument). No other page may take the slug home. The home-page-only block types are accepted there, and on other pages only when the page has the type already.

Search engines and addresses

  • noindex: true keeps the page out of search results and out of the sitemap and llms.txt.
  • A page whose canonical_url points to another address stays in the sitemap for now (only noindex pages are left out); set noindex as well if it must not be listed.
  • A slug change of a page that is public keeps the old address working with a redirect, as in the editor.

delete_page

Takes id. Deletes the page with its saved versions and the menu links that point at it. Advertised as destructive. The home page is invalid_argument, a repeat not_found. Output: page_id, deleted, menu_links_removed, changed, changes.

Size limits

  • Request body. The MCP endpoint accepts a body of up to 256 KiB (413 above it), because create_page and update_page carry a whole block list. The cap is judged before the tool is known, so align the web server (client_max_body_size 256k; on nginx). Since server 1.6.0 this replaces the earlier 64 KiB.
  • Other tools. Every other tool is still refused above 64 KiB of arguments with invalid_argument.
  • Blocks and images. At most 60 blocks per page, 20 new image URLs, 40 MB and 30 seconds of downloading per call, 5 MB per image.

Errors

  • invalid_argument: a rule that fails, naming the field; a taken slug; the home page rules; a block type that is not allowed on this page; an unknown collection, brand or product slug; a refused image.
  • not_found: an unknown page, or a repeated delete.
  • conflict: update_page with an expected_updated_at that is no longer current; a slug that another page takes at the same moment.
  • The general write errors apply: see errors of the write tools.