This is a technical decision aid. Confirm the current extension contract and validator evidence before implementation.
AI agents that generate raw OOXML or raw PDF bytes produce broken files. The solution is a separation of concerns: the AI produces a JSON schema describing the document's content, then a rendering engine converts it to a valid file. The AI handles what the document says. The engine handles what the file format requires. This is the JSON layer pattern — and it works with any LLM, any rendering engine, and any output format.
Why can't LLMs produce valid binary formats?
OOXML — the format behind PPTX, DOCX, and XLSX — is a ZIP archive containing interconnected XML files, embedded media, relationship manifests, and content type declarations. A single PPTX file contains 15–40 internal files with cross-references. Each chart embeds a complete Excel workbook as its data source. Element ordering within XML nodes is syntactically significant — PowerPoint validates it and triggers a repair dialog when ordering is wrong.
LLMs cannot reliably produce this structure. According to our analysis of PPTX repair dialog causes, AI-generated raw OOXML consistently triggers PowerPoint's repair dialog. OpenAI Codex issue #16315 documented this failure mode across multiple models. The OpenXML SDK itself had a bug (#1226) where incorrect element ordering in programmatically generated files caused repair dialogs — and that was a purpose-built XML library, not an LLM guessing at structure.
The same problem applies to PDF. According to analysis of PDF/UA compliance requirements, AI-generated PDFs frequently lose semantic structure. An LLM producing raw PDF bytes cannot reliably construct tagged structure trees, embed fonts correctly, set relationship IDs, or manage cross-reference tables. The result: files that render visually but fail accessibility validation and sometimes fail to render at all.
This is not a model quality problem that will be solved by GPT-6 or Claude 5. The issue is architectural: LLMs produce tokens sequentially, but binary file formats require global consistency — every reference must resolve, every ID must be unique, every element must appear in the correct order relative to every other element. Sequential token generation is fundamentally unsuited to this constraint.
The pattern: content vs compliance
The JSON layer pattern separates document generation into two stages with a clear contract boundary:
Stage 1 (AI): The LLM receives a user prompt ("create a quarterly report with revenue charts") and produces a JSON object describing slides/pages, their elements (text, charts, tables, images), element properties (font size, chart data, table rows), and document metadata (title, author, language). The AI makes all content decisions — how many slides, what data to highlight, what charts to use, what text to write. The output is a JSON schema that any developer can read, validate, test, and diff.
Stage 2 (Engine): A rendering engine accepts the JSON schema and produces a valid file. The engine handles everything the LLM cannot: OOXML element ordering, relationship ID assignment, embedded workbook creation for charts, font subsetting and embedding, PDF structure tree construction, content type manifest generation, and ZIP archive assembly. The engine guarantees format compliance regardless of what the AI produces — if the JSON is structurally valid, the output file opens without errors.
The contract between the two stages is the JSON schema. It is the only thing the AI produces. It is the only thing the engine consumes. This clean separation means you can swap the LLM (Claude → GPT → Gemini → open-source) without changing the rendering engine, and swap the rendering engine without changing the LLM integration.
Why is JSON the right intermediate layer?
Four properties make JSON the optimal contract layer for AI document generation:
- LLMs produce it natively. Every major LLM supports structured JSON output. According to the structured output guide from Agenta, OpenAI enforces JSON Schema compliance in function calling responses, Anthropic validates tool use inputs against schemas, and Google Gemini raises a
JSONSchemaValidationErrorwhen output does not match. JSON is the one structured format all LLMs agree on. - It is schema-validatable. JSON Schema provides compile-time validation — before the rendering engine runs, you can verify the AI's output is structurally correct. Invalid schemas are rejected with descriptive errors, not silently rendered as broken files.
- It is human-readable. When a generated document looks wrong, debugging starts with reading the JSON schema. The developer can see exactly what the AI produced — which slides, what chart data, what text — without reverse-engineering binary OOXML or PDF bytes.
- It is diffable and testable. JSON schemas can be snapshot-tested, JSON-diffed across versions, and unit-tested for specific content. You can write a test that asserts "the Q3 report schema contains a bar chart with exactly 4 categories" without generating and opening a PPTX file.
Implementations: how to apply the pattern
The JSON layer pattern can be implemented at three levels of integration.
Level 1: Direct API call (simplest)
Call the LLM API with a tool/function definition that describes the JSON schema. Extract the JSON from the tool call response. Pass it to the rendering engine.
const response = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 4096,
tools: [documentToolSchema],
tool_choice: { type: "tool", name: "generate_document" },
messages: [{ role: "user", content: userPrompt }]
});
const schema = response.content
.find(b => b.type === "tool_use").input;
const pptx = await generate(schema); // Runstamp
This is the approach used in the Claude + Runstamp agent tutorial. It works with any LLM that supports function calling — replace anthropic.messages.create with openai.chat.completions.create and the pattern is identical.
Level 2: MCP server (zero-code for end users)
Package the rendering engine as an MCP server. The AI agent discovers the tool automatically and calls it when the user requests a document. The user never sees JSON — they ask for a document and receive a file.
// claude_desktop_config.json
{
"mcpServers": {
"paperjsx": {
"command": "npx",
"args": ["@runstamp/mcp-server"]
}
}
}
According to Taskade's MCP ecosystem report, the protocol reached 97 million monthly SDK downloads
and 500+ public servers
by April 2026. According to Bloomberry's analysis of 1,400 MCP servers, server count grew 232% in six months — from 425 in August 2025 to 1,412 in February 2026. The MCP approach is the JSON layer pattern with standardized discovery and invocation. See the MCP server setup guide for the full implementation.
Level 3: Agent framework integration (LangChain, CrewAI)
In multi-step agent workflows, document generation is one tool among many. The agent researches data, analyzes it, then generates a report. The JSON layer pattern fits naturally: the agent's final step produces a JSON schema (via tool call), which the rendering engine converts to a file.
// pseudocode — applies to LangChain, CrewAI, AutoGen
agent.addTool({
name: "generate_report",
description: "Generate a report in PPTX, PDF, DOCX, or XLSX",
schema: documentJsonSchema,
execute: async (input) => {
const format = input.format || "pptx";
const gen = generators[format];
return await gen(input.schema);
}
});
According to MindStudio's 2026 agent model comparison, GPT-5.4's parallel function calling and Claude Opus 4.6's instruction fidelity both produce reliable structured output for tool calls. The JSON layer pattern works regardless of which model the agent framework uses.
Relationship to MCP
MCP and the JSON layer pattern operate at different levels:
| Layer | MCP | JSON layer pattern |
|---|---|---|
| Purpose | Transport: how agents find and call tools | Data model: what agents produce and tools consume |
| Scope | Any tool (search, calendar, documents, databases) | Document generation specifically |
| What it standardizes | Tool discovery, invocation, authentication | Document schema: slides, elements, charts, tables |
| Without the other | MCP works without JSON layer (imperative tools) | JSON layer works without MCP (direct API calls) |
| Together | MCP server exposes generate_document tool; AI produces JSON schema; engine renders file | |
Most document MCP servers today use imperative tools — add_slide(), add_text(), add_chart() — requiring 30–50 sequential tool calls to build one document. According to our MCP server comparison, the Office-PowerPoint-MCP-Server exposes 32 imperative tools. The JSON layer pattern replaces this with one tool and one JSON object. MCP is the delivery mechanism; the JSON layer pattern is the data architecture.
What does the pattern guarantee (and not)?
Guarantees
- Format compliance. If the JSON is structurally valid, the output file opens without repair dialogs. The rendering engine guarantees valid OOXML, valid PDF, and valid XLSX regardless of what content the AI produces.
- PDF/UA accessibility. The rendering engine can automatically add tagged structure trees, alt text from the schema, artifact marking, and font embedding — producing PDF/UA-compliant output without the AI knowing anything about accessibility standards.
- Multi-format output. The same JSON schema produces PPTX, DOCX, PDF, and XLSX through different rendering engines. The AI produces content once; format-specific adaptation is the engine's responsibility.
- LLM independence. Swap Claude for GPT for Gemini for Llama — the JSON schema contract is identical. No vendor lock-in at the AI layer.
- Debuggability. When a document looks wrong, inspect the JSON. The content decision (AI) and the rendering decision (engine) are independently auditable.
Does not guarantee
- Content quality. The AI might produce a chart with the wrong data, a heading that does not match the content, or too many slides. Content quality depends on prompt engineering, model selection, and context provided to the AI. The JSON layer pattern does not make bad content good — it makes bad content debuggable.
- Semantic accessibility. The engine adds structural tags automatically, but meaningful alt text requires the AI to produce it. If the AI writes
"alt": "image"instead of"alt": "Bar chart showing Q3 revenue by region", the PDF passes PDF/UA validation but fails the spirit of accessibility. Prompt engineering must instruct the AI to produce descriptive alt text. - Design quality. JSON schemas describe content and basic styling, not pixel-perfect design. The output is functional and clean, but it does not match what a human designer produces in Figma or PowerPoint. For design-critical presentations, template-based tools like Carbone or Plus AI may be more appropriate.
Keep the document workflow in your product.
Use the catalog to select a native action, prove it against a real artifact, then embed review and release evidence where your customer already works.

