Page builders
Advanced Custom Fields
54 tools across field operations, ACF Pro repeaters + flexible content + galleries, options pages, relationships, and bulk updates. Registered automatically on any site where ACF is active.
Prerequisites
Respira auto-detects ACF at plugin init. You need one of:
- Advanced Custom Fields (free) — enables 28 tools (field ops, relationships, user/term fields, bulk operations).
- Advanced Custom Fields Pro — enables all 54 tools (adds repeaters, flexible content, galleries, options pages).
On sites without ACF, zero ACF tools register. The agent gets a clean tool list with no confusing "ACF tool but ACF not installed" state.
Field operations (18 tools)
Read and write any ACF field value. Plus field group CRUD, export/import between sites, validation, search, and cross-post comparison.
respira read page mysite.com about
// Use the tool surface programmatically:
acf_get_field({ post_id: 123, field_key: 'hero_title' })
acf_update_field({ post_id: 123, field_key: 'hero_title', value: 'Welcome' })
acf_update_fields({ post_id: 123, fields: { hero_title: 'X', hero_subtitle: 'Y' } })
// Field group management
acf_export_field_group({ group_key: 'group_hero' })
acf_import_field_group({ json: { title: '...', fields: [...] } })
acf_clone_field_group({ group_key: 'group_hero', new_name: 'Hero Alt' }) ACF Pro: Repeaters, flexible content, galleries (18 tools)
Row-level and layout-level ops for ACF Pro's composable field types. Pro-only; returns PRO_FEATURE_REQUIRED on free ACF with a remediation hint.
acf_get_repeater({ post_id: 123, field_key: 'team' })
acf_add_repeater_row({ post_id: 123, field_key: 'team', values: { name: 'Ana', role: 'Lead' } })
acf_update_repeater_row({ post_id: 123, field_key: 'team', row_index: 0, values: { role: 'CEO' } })
acf_reorder_repeater({ post_id: 123, field_key: 'team', new_order: [2, 0, 1] })
acf_get_flexible_content({ post_id: 123, field_key: 'sections' })
acf_add_flexible_layout({ post_id: 123, field_key: 'sections', layout_type: 'hero', values: {...} })
acf_get_gallery({ post_id: 123, field_key: 'gallery' })
acf_add_to_gallery({ post_id: 123, field_key: 'gallery', attachment_id: 42 }) ACF Pro: Options pages (8 tools)
Site-wide settings stored on ACF options pages.
acf_list_options_pages()
acf_get_options({ page_id: 'option' })
acf_update_option({ page_id: 'option', field_key: 'company_phone', value: '+40...' })
acf_create_options_page({ page_config: { page_title: 'Theme Settings', menu_slug: 'theme-settings' } }) Relationships and post objects (6 tools)
Follow relationships in either direction. User-profile and taxonomy-term ACF fields are first-class.
acf_get_relationship({ post_id: 123, field_key: 'related_posts' })
acf_update_relationship({ post_id: 123, field_key: 'related_posts', related_post_ids: [456, 789] })
// Find every post that references post 123 through any ACF field
acf_get_reverse_relationships({ post_id: 123 })
// User profile ACF fields
acf_get_user_field({ user_id: 5, field_key: 'user_bio' })
acf_update_user_field({ user_id: 5, field_key: 'user_bio', value: '...' }) Terms and bulk (4 tools)
Taxonomy term ACF fields plus two bulk writers (Builder tier required).
acf_get_term_field({ term_id: 10, field_key: 'badge' })
acf_update_term_field({ term_id: 10, field_key: 'badge', value: 'featured' })
// Copy fields between posts
acf_clone_fields({ source_post_id: 123, target_post_id: 456, field_keys: ['hero_title', 'cta'] })
// Apply same update across up to 500 posts
acf_bulk_update_fields({ post_ids: product_ids, fields: { warranty_months: 24 } }) Example workflows
Update a product spec sheet across 100 products
// Get all WooCommerce products matching a SKU pattern
const products = await respira.read.posts('mysite.com', { type: 'product', search: 'pattern' })
const ids = products.map(p => p.id)
// Bulk-update the spec_sheet ACF fields in one call
await acf_bulk_update_fields({
post_ids: ids,
fields: { warranty_months: 24, country_of_origin: 'Portugal' }
})
// Each product gets its own before/after snapshot.
// One approval entry covers the batch. Migrate a field group from staging to production
// On staging
const group = await acf_export_field_group({ group_key: 'group_hero' })
// On production (via a second MCP connection)
await acf_import_field_group({ json: group })
// Verify a sample post's values match
await acf_compare_fields({
post_id_a: 123,
post_id_b: 456,
field_keys: ['hero_title', 'hero_subtitle']
}) Bulk update team bios from a CSV
respira exec scripts/update-bios.ts
// scripts/update-bios.ts
import { respira } from '@respira/sdk'
import { readFileSync } from 'node:fs'
const rows = parseCsv(readFileSync('bios.csv', 'utf8'))
for (const row of rows) {
await respira.dispatchAcfTool('respira_acf_update_user_field', {
user_id: row.id,
field_key: 'user_bio',
value: row.bio,
})
} Safety
- Snapshot before and after every write. Roll back with
respira_restore_snapshotjust like any other content operation. dry_run: trueon every write tool. Returns the intended change without touching the database. Agents can preview bulk operations before committing.- Per-tier scope gating. Reads on Lite. Writes on Maker via the existing
writescope. Bulk operations on Builder via a newwrite_bulkscope. The PHP handler enforces each gate independently. - Audit log entry per call. Every invocation writes to
wp_respira_audit_logwith action, resource type, resource ID, and timestamp.
Troubleshooting
ACF_NOT_ACTIVE
The agent called an ACF tool against a site where ACF is not installed or not active. Install ACF from wordpress.org and reload. The tools register on the next request.
respira_acf_pro_required
A Pro-only tool (repeater, flexible content, gallery, options page) was called on a site with only the free ACF installed. Either upgrade to ACF Pro, or rewrite the workflow around free-tier alternatives (e.g. a single update_field with a JSON-encoded array instead of a repeater).
respira_acf_write_scope_required or respira_acf_bulk_scope_required
The calling API key does not have the required scope. The backend issues write on Maker tier and above, write_bulk on Builder tier and above. Upgrade the plan or generate a new API key with the right scope.
respira_acf_field_not_found
The field key does not resolve. Use acf_list_field_groups() then acf_get_field_group({ group_key: '...' }) to enumerate field definitions, or acf_search_fields({ q: '...' }) to full-text search.