ACF (Advanced Custom Fields)
When Advanced Custom Fields (Free or Pro) is active, EMCP exposes ACF as a first-class integration. An agent can discover the active field registry, build a content model, validate values, and write fields without bypassing ACF’s own APIs.
The integration arrived in v3.2.1 and received broad Free/Pro field validation plus structured batch imports in v3.16.0. The v3.16.0 coverage was verified through the real MCP transport against ACF Pro 6.8.9, including all 36 public field types registered by that build.
Two tools, not eighteen
Section titled “Two tools, not eighteen”To keep the MCP tool-list small, the whole domain is exposed as two dispatcher tools rather than one tool per operation:
acf-read: all read operations (enabled by default)acf-write: all write operations (ships disabled by default)
Each takes an operation and an arguments object. Call a tool with no operation to get its catalog of operations, then call it again to run one:
// discoveracf-read({})// → { mode: "read", operations: [ { operation: "list-field-groups", … }, … ] }
// actacf-read({ operation: "get-fields", arguments: { post_id: 123 } })This is the same discover → act pattern as the widget catalog. The two dispatchers only register when ACF is active, and each operation still enforces its own WordPress capability, checked per call.
The 18 operations
Section titled “The 18 operations”Read (acf-read)
Section titled “Read (acf-read)”| Operation | Arguments | Returns |
|---|---|---|
list-field-types | None | Every field type registered by the active ACF build, its Pro status, and supported settings. |
list-field-groups | None | Field groups: key, title, active, field count. |
get-field-group | { key } | One group’s location rules + recursive field tree. Read this before writing values. |
list-options-pages | None | ACF PRO options pages (empty on free ACF). |
get-fields | { post_id } or { options_page } | Current field values, formatted. |
list-post-types | None | ACF-managed custom post types (ACF 6.1+). |
get-post-type | { key } | One CPT’s definition (6.1+). |
list-taxonomies | None | ACF-managed taxonomies (6.1+). |
get-taxonomy | { key } | One taxonomy’s definition (6.1+). |
Write (acf-write)
Section titled “Write (acf-write)”| Operation | Arguments | Notes |
|---|---|---|
update-fields | { post_id|options_page, fields: { name: value } } | Writes values by field name (resolved to keys). |
validate-fields | { items: [{ client_ref, source?, data }] } | Validates a structured import without writing and returns a deterministic plan_hash. |
batch-update-fields | { items, plan_hash, confirm: true } | Applies the exact validated batch, then reads every item back. |
create-field-group | { title, fields: […], location: [[…]] } | Creates a group with fields + location rules. |
update-field-group | { key, … } | Edit settings / add fields. No deletes or renames. |
create-post-type | { post_type, title, … } | Registers a CPT as data through ACF (6.1+). |
update-post-type | { key, … } | Edit a CPT. Slug is immutable. (6.1+) |
create-taxonomy | { taxonomy, title, object_type: […] } | Registers a taxonomy as data (6.1+). |
update-taxonomy | { key, … } | Edit a taxonomy. Slug is immutable. (6.1+) |
The Custom Post Type / Taxonomy operations require ACF 6.1+; they’re omitted from the catalog on older ACF.
Free and Pro field coverage
Section titled “Free and Pro field coverage”list-field-types reads ACF’s active runtime registry instead of a hard-coded catalog. This means the agent sees the edition and field types actually available on the connected site.
| Edition | Field types verified in v3.16.0 |
|---|---|
| ACF Free | text, textarea, number, range, email, url, password, image, file, wysiwyg, oembed, select, checkbox, radio, button group, true/false, link, post object, page link, relationship, taxonomy, user, Google Map, date picker, date-time picker, time picker, color picker, icon picker, message, accordion, tab, group |
| ACF Pro | repeater, flexible content, gallery, clone |
Thirty-three of those types store values. message, accordion, and tab are presentation controls, so value operations intentionally reject writes to them. Group, repeater, flexible-content, and clone values use nested structured JSON; galleries and relationship fields use validated collections of object IDs.
Built-in validation covers required values, scalar and collection shapes, text length, email, HTTP(S) URLs, numeric min/max/step, configured choices, booleans, links, attachment and media constraints, related object existence and type, taxonomy and user restrictions, map coordinates, stored date/time formats, colors, icons, nested subfields, and collection limits. ACF Pro bidirectional relationship add and remove behavior is also supported.
Coverage boundaries
Section titled “Coverage boundaries”The integration is broad, but it does not claim complete parity with every ACF administration screen.
| ACF feature | Coverage | Current boundary |
|---|---|---|
| Field discovery | Covered | Reads the active runtime, including registered third-party types and their setting keys. |
| Field values | Covered for posts and existing options pages | Read, validated write, dry-run planning, hash-bound batch apply, provenance, and read-back. |
| Field groups | Partial | List/get/create/update, append fields, and update field settings. No delete, duplicate, move, reorder, rename, or field-type mutation. |
| Built-in field settings | Broad | Built-in settings are preserved. Some field-group presentation settings are not authorable yet. |
| Location rules | Partial | Rule groups are stored, but extension-defined location types and values are not exhaustively validated. |
| Options pages (Pro) | Partial | Existing pages can be listed and used for field reads/writes. Options-page create/update/delete/reorder is not exposed. |
| Bidirectional relationships | Covered | Relationship target settings, reverse writes, and reverse cleanup are supported. |
| ACF-managed post types and taxonomies | Partial | Core labels, visibility, REST, hierarchy, supports/archive, taxonomies, and object types are covered; the complete ACF UI schema is not. |
| ACF Blocks (Pro) | Not covered | EMCP’s Gutenberg tools do not create or manage ACF block definitions. |
| Local JSON and PHP-registered groups | Read only | Local groups are discoverable, but EMCP refuses to create a database copy that would shadow code. JSON sync/import/export is not exposed. |
| Other ACF object targets | Not covered | Value operations accept numeric post IDs or options-page names, not term, user, comment, widget, or menu-item targets. |
| Third-party field types | Partial | Discovery and basic schema creation work; custom validation and settings are not guaranteed. |
Import fields from documents
Section titled “Import fields from documents”PDFs, spreadsheets, CSV files, DOCX files, and OCR output are handled by the connected agent, not uploaded to a parser inside WordPress. The agent extracts the source into bounded structured JSON and sends that JSON to ACF over MCP.
The safe batch flow is:
- The agent inspects the field group and parses the source document locally.
validate-fieldsvalidates every item and returns a deterministicplan_hash. It writes nothing.- The human reviews the plan.
batch-update-fieldsreceives the same items, the matching hash, andconfirm: true.- WordPress rejects the whole batch before mutation if any item is invalid, and returns per-item read-back after a successful apply.
// 1. Validate the agent-structured payload. No write occurs.acf-write({ operation: "validate-fields", arguments: { items: [ { client_ref: "catalog-row-42", source: { file: "catalog.pdf", page: 7 }, data: { post_id: 123, fields: { subtitle: "The Spice Must Flow", rating: 5 } } } ] }})
// 2. Apply only the exact payload that produced the returned hash.acf-write({ operation: "batch-update-fields", arguments: { items: [/* the unchanged validated items */], plan_hash: "<hash returned by validate-fields>", confirm: true }})WordPress never needs to parse the PDF or spreadsheet itself. It receives only the structured field targets and values it is responsible for validating and storing.
Safety by design
Section titled “Safety by design”- Data, not code. Custom post types and taxonomies are registered through ACF’s own
acf_import_post_type/acf_import_taxonomy: nothing executable is written, and ACF registers them itself. - No deletes. There is no delete operation for anything.
- Immutable identifiers. A field’s
name/key/type, and a post type / taxonomy slug, can never change: renaming would orphan stored content. - PRO fields. Repeaters, flexible content (rows validated against the field’s layouts), galleries, groups and clones round-trip as nested JSON; on free ACF those field types are rejected with
acf_pro_required. - Atomic batch validation. An invalid item rejects the complete batch before any write, and a changed payload cannot reuse an earlier
plan_hash. - Per-operation capabilities. Field reads need
edit_posts; field-value writes neededit_poston the target; field-group / CPT / taxonomy writes needmanage_options.
Full worked example
Section titled “Full worked example”// 1. a custom post typeacf-write({ operation: "create-post-type", arguments: { post_type: "book", title: "Books", singular: "Book", supports: ["title","editor","thumbnail"] } })
// 2. a taxonomy on itacf-write({ operation: "create-taxonomy", arguments: { taxonomy: "genre", title: "Genres", object_type: ["book"] } })
// 3. a field group on that post typeacf-write({ operation: "create-field-group", arguments: { title: "Book Details", fields: [ { label: "Subtitle", name: "subtitle", type: "text" }, { label: "Rating", name: "rating", type: "number", min: 0, max: 5 } ], location: [[ { param: "post_type", operator: "==", value: "book" } ]] } })
// 4. create a book (with the content tools), then write its valuesacf-write({ operation: "update-fields", arguments: { post_id: 123, fields: { subtitle: "The Spice Must Flow", rating: 5 } } })
// 5. read it backacf-read({ operation: "get-fields", arguments: { post_id: 123 } })In the admin
Section titled “In the admin”The dispatchers appear under EMCP Tools → Tools → Plugins → ACF as two toggles, acf-read (on) and acf-write (off by default), each card listing the operations it covers. Toggle a tool to allow or block all of its operations at once.
Agent skill
Section titled “Agent skill”Pro ships an emcp-plugins Agent Skill that teaches a connected agent the dispatcher pattern, discovery flow, ACF operation reference, and agent-structured document import boundary, so it drives the integration correctly without sending source documents to WordPress for parsing.