chaipro v0.4.0
Released 2026-09-21. Upgrading from v0.3.7.
A minor bump, so in the pre 1.0 line this is where breaking changes land. The headline
is an MCP server: Claude, Cursor, VS Code or any MCP client can now read, edit and publish
pages on your site, signed in as a real user and limited to that user's permissions. Around
it, permission rules that used to live only in the builder interface are enforced on the
server for every caller, revision restore becomes selective and attributed, and Tailwind v3
support is retired.
Read the breaking group before upgrading. One import path moves, one Tailwind version goes, and some roles may lose SEO write access through the API.
Breaking
- Tailwind CSS v3 is no longer supported. The
chaipro/tailwind/v3entry point is removed,CHAI_TAILWIND_VERSIONis ignored, thetailwindcsspeer is now^4.0.0, andautoprefixeris no longer a peer dependency. Projects still on a v3 config need to migrate first. See Theming. Persisted page styles recompile once after the upgrade, so the first render of each page is slower than usual. ChaiAnimationProvidermoves to its own entry point. Import it fromchaipro/plugins/animation/renderinstead ofchaipro/nextjs/render-client, and import its stylesheet once fromchaipro/plugins/animation/render.css. The old import fails at build time.- SEO writes require
pages:edit_seoon the server. Saving a page's SEO fields, its JSON-LD or its shared JSON-LD now needspages:edit_seoin addition topages:update, for every caller: the builder, the HTTP API, the instance API and MCP. The rule used to be checked only in the builder interface, so API callers could bypass it.pages:*and*satisfy both, so the default roles are unaffected. A custom role withpages:updatebut notpages:edit_seothat writes SEO through the API will now be refused. - Restoring a revision requires page permissions too.
revisions:restoreis no longer enough on its own: a restore also needspages:update, pluspages:edit_seowhen it restores SEO or JSON-LD. A restore writes the same fields a save does, so it now needs the same rights.
Added
- A built-in MCP server. Register
mcpPluginfromchaipro/plugins/serverand mount one route withcreateChaiMcpRouteHandlersfromchaipro/mcp, and an MCP client can work on your site through 33 tools covering page discovery and management, block reads and edits, SEO, publishing, revisions, translations, image upload, redirects and edit sessions. The plugin is opt in and is not part of the Pro preset, because it exposes an agent driven write surface. It needs@modelcontextprotocol/sdkinstalled, a new optional peer dependency (>=1.26.0 <2). See MCP Server Setup. - An
mcp:usepermission gates the MCP surface as a whole, separately from the per tool permissions, so an account can edit in the builder without being allowed to drive an agent. Editors and designers get it by default, viewers do not. Tools the caller lacks permission for are hidden from the tool list and refused if called anyway. - The tool set adapts to your config. Revision tools appear only with the revisions
plugin, image upload only with a media backend, and edit session tools only with the AI
plugin.
mcpPlugintakespreviewUrlto build preview links against your own preview route,getLivePageEditorsto tell agents when a person has a page open, andexcludeInstructionSectionsto drop built-in agent instructions you want to replace. - Custom MCP tools. Apps and plugins register their own tools and agent instructions through the same API the built-in ones use. See MCP Custom Tools.
- Payload API keys authenticate builder requests. A headless caller such as an MCP
client, a script or CI can send a Payload API key, either as a plain bearer token or in
Payload's own header format, and gets the permissions of the user who owns the key.
Nothing new is issued or stored. The
permissionsoption now receivesauthStrategy, so you can treat a machine credential differently from a person's session, for example capping API keys at read only. - "AI is editing" status in the builder. When an agent holds an edit session on a
page, the builder opens that page read only and shows who is editing, since when, their
last activity and last action, with a Check now button. When the session ends, the
page reloads without saving. A person who already has the page open keeps it: the
agent's writes are refused instead. The check is served by
aiAdvancedPluginand displayed by the realtime client plugin. - Selective revision restore. The restore dialog offers four parts, blocks, SEO, tracking and JSON-LD, with blocks only selected by default. Rolling back an AI SEO edit no longer requires restoring the page body too. The restore itself is recorded as a labelled revision saying what it restored and what it kept, and the snapshot taken before it covers all four parts, so undoing a restore brings everything back. See Revisions.
- Revisions record where an edit came from: the builder, the settings panel, an MCP agent or a service account. Bulk writes from the settings panel get their own revision rows instead of merging into your open builder draft.
- A data provider can return a 404. A page type data provider can return
$notFound: truewhen no item matches the URL, and the dynamic route responds with a 404 instead of an empty page served as 200. Cache tags are still registered, so publishing the item later brings the route to life. The Payload collection provider does this out of the box. See Data Providers. - New pages get your default shared JSON-LD. Shared schemas flagged to be added to new pages are attached on create for every caller, not only the builder. Language pages, partials and folders are skipped.
- Favicon and markdown uploads. The media manager accepts
.icoand.mdfiles. - Children override props. A block config can declare
childrenOverrideProps, the props it stops rendering once it has children. The settings panel hides those fields while the block has a child, instead of offering edits that never reach the page. Heading, Span, Paragraph, ListItem, Link and Button declare it forcontent, and Button for its icon props too. Stored values are kept, so removing the children brings the field back. See Custom Blocks. - Two plugin API seams. Server plugins can read an incoming request header with
getChaiRequestHeader(name), and client plugins can add headers to and observe every builder request withregisterChaiFetchInterceptor. See Developing Plugins. - Binding pickers show collection names instead of collection ids.
Changed
- Images are served from your origin. The Image block no longer routes through the
Next.js image optimizer at
/_next/image. The file is served as stored, and next/image is kept only for layout and sizing. On Vercel this removes image optimization usage for ChaiBuilder pages. - The revision compare view is rebuilt. It diffs the two versions as structured data, scrolls smoothly on large pages, and follows the builder's light or dark theme. It is side by side only; the Split View toggle is gone.
- Node.js 22 or later. The package now declares
node >=22inengines. Package managers warn on older versions and fail the install when engine strict mode is on. - Faster builder and render path. The builder boots without an artificial delay, save state no longer re-renders on every block change, and the top bar re-renders less. On the server, data binding and link resolution no longer deep copy every block, and a memory leak that grew with every styled block is fixed.
- Saves from any caller now behave the same way. Whether a save creates a draft revision is decided on the server from your revisions config, rather than by a flag the builder happened to send.
Security
- Revision lookups are scoped to your site. Reading or comparing a revision by id now checks that it belongs to the calling site. This matters most on multi tenant deployments sharing one database.
- The MCP route authenticates by header only. It ignores browser session cookies, so a signed in browser tab cannot be used to drive it. Request bodies are size capped before authentication, error responses never include internal details such as connection strings or SQL, and audit arguments are truncated with secrets redacted.
- Server side SEO and restore permissions, described under Breaking above, close
paths that let API callers change titles, canonicals, noindex and JSON-LD without
pages:edit_seo. - Extensionless AVIF and HEIF images are rejected instead of being mislabelled and stored as video.
Fixed
- Block props keep their types after an AI edit. Arrays, objects, booleans and
numbers came back from the AI panel, HTML import or an agent edit as strings, so a
gallery could crash the page and
"false"read as true. Props are restored to the type their schema declares, and a nullable prop saved as"null"comes back asnull. - AI edits keep block identity. An AI edit replaced a block's internal id, breaking anything that referenced it, and rewrote props the model never touched. Only props that actually changed are updated now.
- Pending changes are not lost. A save that touched only SEO or tracking cleared the marker left by an earlier block save, so the page stopped showing as having changes to publish. Markers accumulate now, and tracking changes get their own label.
- Saves from callers other than the builder no longer blank a page's links and design tokens, which also broke revalidation of pages linking to it.
- Saving right after a restore no longer overwrites the restore's revision row.
{{page.*}}bindings resolve correctly on rendered pages:page.slugrendered the full path, andpage.path,page.pathWithParams,page.querySeparatorandpage.basePathwere undefined.- Sites whose default language is not English link correctly from data providers, sitemaps and feeds. The fallback language is read from site settings instead of being assumed to be English.
- Newly picked gallery images render at their real size instead of 100x100.
- Uploads with
#or?in the file name, such asCapture #3.png, are accepted, and so are large PNGs the media manager converts to JPEG before upload. - Unpublished drafts no longer appear in Payload backed repeaters.
- Removing a redirect asks for confirmation.
- Activity in settings screens such as custom blocks, the translation center and revisions is attributed to the right user again.
- Builder menus, selects, popovers and tooltips keep their positioning and height limits under Tailwind v4.
- The
fetchpriorityattribute on blocks reaches the rendered page. - The
chaipro/plugins/plans/cliententry point is published. The plans client plugin from v0.3.0 had no import path until now.
Removed
- The
chaipro/tailwind/v3entry point, theCHAI_TAILWIND_VERSIONsetting and theautoprefixerpeer dependency. ChaiAnimationProviderfromchaipro/nextjs/render-client.- The Split View toggle in the revision compare view.
Upgrade notes
- Move to Tailwind v4 if you have not already, then remove
CHAI_TAILWIND_VERSIONfrom your environment andautoprefixerfrom your dependencies if nothing else uses it. - Update the animation import. Import
ChaiAnimationProviderfromchaipro/plugins/animation/renderand addimport 'chaipro/plugins/animation/render.css'once in your layout. - Check custom roles. Any role that writes SEO through the API needs
pages:edit_seo, and any role that restores revisions needspages:updateas well asrevisions:restore. - Run your database migrations.
aiAdvancedPlugincontributes a newai_page_editstable that holds agent edit sessions. Generate and apply migrations as usual; see Database Setup. - Check your Node version. Build and runtime should be on Node 22 or later.
- Dynamic pages backed by Payload collections now 404 for URLs with no matching document. If you relied on the empty page rendering, handle the missing item yourself.
- MCP is opt in. Nothing changes until you register
mcpPluginand mount the route. Follow MCP Server Setup when you are ready.
Related
- MCP Server Setup - enable the server and connect a client.
- MCP Custom Tools - register your own tools and instructions.
- Revisions - drafts, compare and restore.
- Data Providers - page type providers and
$notFound. - Theming - Tailwind v4 setup.
- chaipro Changelog - all releases.

