Skip to content

Expand nested entries in MCP output when requested - #645

Open
i-just wants to merge 1 commit into
feature/mcp-supportfrom
feature/mcp-nested-entry-expansion
Open

i-just wants to merge 1 commit into
feature/mcp-supportfrom
feature/mcp-nested-entry-expansion

Conversation

@i-just

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

Copy link
Copy Markdown
Contributor

Prerequisite

craftcms/cms#20415

Description

Builds on #644; this PR targets that branch, so the diff only shows the changes on top of it. It requires craftcms/cms#20415, which adds dot paths and resolves elements inside values returned by getMcpValue().

When a CKEditor field is explicitly requested via fields (McpOutputContext::$requested), MCP tools now return its value as a list of chunks in document order, so nested entries behave like Matrix entries:

[
  {"type": "markup", "html": "<p>…</p>"},
  {"type": "entry", "entry": { …expanded entry… }},
  {"type": "markup", "html": "<p>…</p>"}
]
  • Expansion is done by core: it expands the entries with the usual permission checks, public scope, and nested element budget.
    • fields: ["cke.innerBlocks"] also includes each nested entry's innerBlocks, as summaries.
    • When the field is reached by a dot path such as blocks.cke, its entries are summarized.
    • Entries the user can't see are left out, with no placeholder chunk.
  • fields: null is unchanged: it still returns the annotated HTML from Add MCP output for nested entry tags #644.
  • Reuses FieldData::getChunks(): the chunks come from a copy of the value with no field attached, so oEmbed content isn't fetched (no network calls, and <oembed> tags stay as stored). The value's own cached chunks are left untouched.
  • Writes are unchanged: the field still accepts an HTML string.

Testing

Manual check with a fresh mcp/serve, on an entry with four nested entries in its CKEditor field:

  • fields: null: annotated HTML, unchanged.
  • fields: ["cke"]: 7 chunks in document order, with each nested entry expanded including its plainText value.
  • fields: ["cke.innerBlocks"]: the same, plus innerBlocks on each nested entry.

🤖 Generated with Claude Code

When a CKEditor field is explicitly requested via `fields`, MCP tools now
return its value as a list of chunks: {"type": "markup", "html": "…"} and
{"type": "entry", "entry": …}. Core expands the nested entries like Matrix
entries, applying permissions, the public scope, and dot paths.

The chunks come from FieldData::getChunks() on a copy of the value with
no field attached, so oEmbed content isn't fetched and the value's own
cached chunks are left untouched.

Requires the core MCP dot-path support.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@i-just
i-just requested a review from brandonkelly as a code owner November 6, 2026 08:36
@i-just
i-just requested a review from riasvdv November 6, 2026 08:43
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