Tool result messages reach MCP clients with HTML entities
Problem/Motivation
ToolApi::execute() casts the Tool API result message to a string and returns it as MCP text content:
$formatted = $tool->getFormattedResult();
$message = (string) $formatted->getMessage();Tools build result messages as TranslatableMarkup, and @ placeholders HTML-escape their values. Quotes in a message reach the MCP client as entities. For example, a canvas_tools publish denial from canvas_tools!15 (merged) reads:
Publish failed: Unable to update entities: 'About us'.The model reads ' literally. Tool API tracks the same bug for tool:run and tool_ai_connector in tool#3583042 (closed), which names this module as a follow-up.
Proposed resolution
Render the message as plain text before returning it:
use Drupal\Component\Render\PlainTextOutput;
$message = PlainTextOutput::renderFromHtml((string) $formatted->getMessage());Remaining tasks
- Test: a tool whose failure message has quotes in a placeholder returns them unescaped from
tools/call.