Engineering Journal
Schema Editor
Schema Editor

Postmortem: We Wired the MCP Protocol Before We Had a Serialization Contract

2026-06-04

TLDR

The MCP protocol layer was wired in hours. The diagram serialization contract that makes the tool useful to an AI agent took days, required two redesigns, and is still the part most likely to need maintenance. Protocol first, contract second is the wrong order.


The Assumption That Seemed Reasonable

MCP integration is a protocol problem. The editor has state. MCP provides a way for an AI to read that state. Wire the protocol: handle the tool call, return the editor's state. Done.

The approach: return the SVG string when the read_diagram tool is called. SVG is the editor's native format. The AI can parse it.

This seemed correct. SVG is a standard format with a defined structure. An LLM trained on web content has seen SVG. Returning SVG should work.

When It Failed

The first test: ask the AI to list all resistors in the diagram. The AI returned a list that missed two resistors and included one element that was a wire junction, not a resistor. The SVG structure was correct. The AI's interpretation was not.

The resistors were encoded as <g class="domain-symbol" data-symbol="resistor"> elements with inner paths. The AI extracted elements whose class contained "resistor" but missed elements where the class was on a parent group and the child paths were unnamed.

The second test: ask the AI to describe the connections between components. The AI described visual proximity (elements that appeared close on screen) rather than actual wire connections. SVG has no native "connection" concept. The AI inferred topology from visual layout, which is unreliable.

The third failure: the SVG included system elements (grid lines, overlay groups, selection handles that happened to be in the snapshot) mixed in with diagram content. The AI could not reliably distinguish diagram content from editor UI.

What Was Actually Wrong

The AI does not have access to the editor's internal model. It only has the serialized form. When the serialized form is a rendering artifact (SVG), the AI must reverse-engineer the semantic structure from visual data. This is unreliable because visual proximity does not equal semantic connection, class names do not always encode semantic type, and editor UI artifacts are mixed with diagram content.

The correct approach: serialize the semantic structure, not the rendering artifact. Connections are described as structured records (from component A port X to component B port Y), not as SVG path elements that happen to be near each other.

The SVG was not wrong as a format. It was wrong as an AI communication channel. Those are different things.

What Got Deleted

The innerHTML return path: the handler that returned svgElement.innerHTML as the MCP response. This was the first implementation and the one that produced wrong AI results.

What Replaced It

A _buildDiagramPayload() method on the editor that produces a structured JSON representation:

{
    schema: 'ginexys-diagram-v2',
    domain: 'electrical',
    components: [...],  // type, position, properties, ports
    connections: [...], // from/to component+port pairs
    metadata: { ... }
}

The AI receives component types and explicit connection records. The resistors are listed with type: 'resistor'. Connections are explicit { from: 'R1.pin1', to: 'C2.positive' } records. There is no ambiguity about what connects to what.

The time to define this schema: two days, two redesigns. The protocol wiring once the schema existed: two hours.

The Lesson

For AI-facing APIs, define the serialization contract before writing the server. The contract answers: what does the AI need to reason about this tool's state? Start from the AI's perspective, not from the tool's native format. Native formats are optimized for rendering. AI communication channels are optimized for reasoning.

Read this post in the full Engineering Journal →