Skip to content

Add MCP output for nested entry tags - #644

Open
i-just wants to merge 2 commits into
5.xfrom
feature/mcp-support
Open

i-just wants to merge 2 commits into
5.xfrom
feature/mcp-support

Conversation

@i-just

@i-just i-just commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Prerequisite

craftcms/cms#20414

Description

MCP tools return CKEditor field values as raw HTML, where nested entries appear as bare <craft-entry data-entry-id="…"> tags. An agent knows only the ID, and on the public MCP server the tags expose IDs of entries outside its approved scope.

CKEditor fields now implement craft\base\McpOutputFieldInterface (added in craftcms/cms#20414):

  • Annotated tags: each <craft-entry> tag gets data-entry-type (the entry type handle) and data-entry-status. The nested entries are loaded in a single query.

    <craft-entry data-entry-id="216" data-entry-type="block" data-entry-status="live"> </craft-entry>
  • Public MCP server: tags follow the same scope core applies to nested entries. A tag is only kept if:

    • the field is an approved public nested-entry field, and
    • the entry is live, or inactive elements are allowed (drafts and revisions follow the corresponding settings too).

    Other tags are removed. If the public scope can't be determined, all tags are removed.

  • Writes: serializeValue() strips the two MCP-only attributes, so they're never stored if an agent writes the annotated HTML back. HTML Purifier already drops them by default, but this also covers fields with purification turned off.

Requires Craft CMS 5.12.1 or later, so this can't be released until that version, with craftcms/cms#20414, is out.

Testing

  • Manual check with elements_get on an entry with nested entries in its CKEditor field (fields: ["cke"] and fields: null): the tags have data-entry-type and data-entry-status, and the rest of the HTML is unchanged.
  • serializeValue() on annotated HTML returns tags without the MCP-only attributes.
  • Public output with no approved nested-entry fields removes all <craft-entry> tags and keeps the surrounding HTML.

🤖 Generated with Claude Code

i-just and others added 2 commits November 6, 2026 08:16
CKEditor fields now implement craft\base\McpOutputFieldInterface. MCP
tools return the field's HTML with each <craft-entry> tag annotated with
data-entry-type and data-entry-status, loaded with a single query.

On the public MCP server, tags are only kept for nested entries within
its approved scope (approved nested-entry field, live unless inactive
elements are allowed, no drafts or revisions unless allowed), and are
removed if the scope can't be determined.

The MCP-only attributes are stripped in serializeValue(), so they're
never stored if an agent writes the HTML back.

Requires Craft CMS 5.12.1 or later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
McpOutputFieldInterface::getMcpValue() now receives a McpOutputContext
object instead of a $public flag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants