Craft MCP Field Agent

Craft Plugin Store
I made a safety first content modelling tool that extends Craft MCP. Create, modify and delete fields, entry types and sections from an AI assistant

Tags:

  • AI
  • MCP
  • Content Modelling
  • Craft CMS
Craft MCP Field Agent

Craft MCP Field Agent is a plugin I maintain that allows developers to manipulate sections, entry types and fields via an AI assistant. It works by extending the Craft MCP plugin written by Stimmt Digital; this exposes an MCP server and tools that AI agents can use to perform various actions. 

While the original Craft MCP plugin is read only, my extension adds write capability around content modelling; the original plugin provides discovery (what currently exists) and my extension now brings write operations to the table (note: there are other plugins available for writing content using agents).

My work builds on an earlier iteration I worked on with the same goal, a now archived plugin that used structured output against a strict JSON schema. This was used to inform the shape of requests that were made using Craft's internal API. This part is important; without exposing specific tools and establishing a contract between the agent and Craft, LLMs will often naively try to manipulate Craft by editing project config files directly or by making ad hoc database queries - I know through trial and error that this is a mistake; we have to guide the agent correctly so that it can:

  • Discover the current structure of the site
  • Understand what is available for it to create
  • Only execute operations using Craft's APIs

I abandoned my first attempt at the plugin because the results were too unpredictable, even with structured output, JSON schemas and so on. This route also had a heavy maintenance burden, because I needed to keep my schema in sync with future versions of Craft manually (in order that agents understood what field types were available, what the shape of their settings were). It was also necessary to use Claude or ChatGPT with an API subscription in order to use structured output mode, and operations were one-shot; requests were made to whichever LLM from within the plugin and there couldn't be any back and forth.

Model Context Protocol (MCP)

When MCP servers as a concept began to gain traction, I knew I could utilise what I learned on my first try to write a much simpler and much more robust plugin that would do what I wanted. I no longer have to rely on shaping requests perfectly from within the plugin, instead, the LLM can discover what is available, is correctly guided as to the right way of doing things and is provided hints about what settings exist; especially useful on native fields unlikely to change much between versions. I no longer need an exhaustive field registry; using the MCP server for discovery, an agent knows what is available. This route also works for 3rd party plugins such as Neo, Hyper etc. Responses and operations will be quicker on plugins the LLM knows well (according to its training), but even a plugin released tomorrow providing some exotic new field type will work fine with this plugin, because your LLM will just work out how to work with it - most likely by reading its source directly. 

In a nutshell, what Field Agent now does is marshall your LLM so that it operates within specific confines, is given the context it needs where appropriate and provides guardrails for potentially destructive operations (more on that below). The keyword in MCP really is context, that's what it all boils down to.

Safety first by design

This is a plugin I use myself and which I've made available publicly on the Craft plugin store, so I wanted some guardrails on destructive operations.

  • If you try using this in an environment with allowAdminChanges off, the plugin doesn't register any tools. The assistant never sees them, so it can't call one or be talked into calling one
  • The MCP plugin I extend allows tools to be marked dangerous - a convention I adhere to and which requires a full access token (more on this in the MCP Plugin docs, if you're curious)
  • Writing requires an admin; Every tool that writes checks that the Craft user behind the token is an admin, which matches the control panel

These are what I'd consider "base" level safety rails. On top of these, I also require that operations which modify or delete require two steps:

  1.  The assistant asks for a report. This call is read-only. The report lands in your conversation and says:
    1. how many entries hold a value;
    2. where the field is used;
    3. whether Craft thinks the old and new types store data the same way;
    4. what Craft will actually do. (For example, a type change doesn't convert stored values, it reads them with the new type, and deleting a field leaves values behind, unreachable, until each entry is next saved).
  2. The report comes with a one-time code, and the tool that makes the change won't run without it. The code is strict:
    1. The plugin generates it, so the assistant can't invent one.
    2. It works once. It's used up even if the change fails, so a failed change means a fresh report.
    3. It expires after 15 minutes.
    4. It only works for the tool it was issued for.
    5. It's tied to the exact change that was reported. If the assistant tries to apply anything different, even slightly, the code is rejected.

In real world terms, if you ask your assistant to delete all your plain text fields, you'll get a response like this:

"I haven't deleted anything yet. There are 71 Plain Text fields in this install, and they hold a lot of the site's content..." 

Your assistant will follow with a list of examples of how the field is used, ramifications of deleting, etc. 

It should be noted that if you are intent on circumventing this protection, your assistant will probably just skip the MCP altogether and run some script to do what you want, but I guess you'd have to be very specific with your choice of words. LLMs are still prone to errors of judgement and going off piste - so this plugin comes with all the usual disclaimers. Always backup your data before performing any potentially destructive operation.

I hope you find the plugin useful, I'm open to feedback; let me know what you think.

Credit to the Phosphor Icons team whose spy icon is the face of my plugin