diff --git a/docs/apps/architecture.mdx b/docs/apps/architecture.mdx
index ee666568f..26588c2f8 100644
--- a/docs/apps/architecture.mdx
+++ b/docs/apps/architecture.mdx
@@ -10,7 +10,7 @@ import { VersionBadge } from '/snippets/version-badge.mdx'
-This page explains the internal architecture of Prefab apps — how your Python code becomes an interactive UI inside a host client's conversation. If you're building [custom HTML apps](/apps/low-level), the pipeline is simpler and covered on that page. You don't need to understand any of this to build Prefab apps, but the mental model is useful when you're debugging, extending, or contributing.
+This page explains how Prefab apps work under the hood — how your Python code becomes an interactive UI inside a host client's conversation. You don't need any of this to build apps, but the mental model is useful when something isn't rendering the way you expect, when tool calls from the UI aren't reaching your server, or when you're building [custom HTML apps](/apps/low-level) and need to understand the protocol directly.
## The Pipeline
diff --git a/docs/apps/low-level.mdx b/docs/apps/low-level.mdx
index 9ce86e3dd..adda74799 100644
--- a/docs/apps/low-level.mdx
+++ b/docs/apps/low-level.mdx
@@ -145,6 +145,8 @@ The `App` object provides:
- **`app.onhostcontextchanged`** — callback for host context changes (e.g., safe area insets)
- **`app.getHostContext()`** — get current host context
+See the full [ext-apps SDK documentation](https://github.com/modelcontextprotocol/ext-apps) for the complete API reference.
+
If your HTML loads external scripts, styles, or makes API calls, you need to declare those domains in the CSP configuration. See [Security](#security) below.
diff --git a/docs/apps/providers/file-upload.mdx b/docs/apps/providers/file-upload.mdx
index 7a0cea1c9..13cf2402e 100644
--- a/docs/apps/providers/file-upload.mdx
+++ b/docs/apps/providers/file-upload.mdx
@@ -33,7 +33,7 @@ This registers four tools:
| `list_files` | Model | Returns metadata for all uploaded files |
| `read_file` | Model | Returns a file's contents by name |
-The LLM sees `file_manager`, `list_files`, and `read_file`. It calls `file_manager` to show the upload interface, then uses `list_files` and `read_file` to work with whatever the user uploaded. `store_files` is app-only — the UI calls it directly through the `___` routing mechanism and the LLM never needs to know about it.
+The LLM sees `file_manager`, `list_files`, and `read_file`. It calls `file_manager` to show the upload interface, then uses `list_files` and `read_file` to work with whatever the user uploaded. `store_files` is app-only — the UI calls it directly and the LLM never needs to know about it.
## Configuration
diff --git a/docs/apps/providers/form.mdx b/docs/apps/providers/form.mdx
index 136e642b8..ca598f33f 100644
--- a/docs/apps/providers/form.mdx
+++ b/docs/apps/providers/form.mdx
@@ -17,6 +17,8 @@ import { VersionBadge } from '/snippets/version-badge.mdx'
```python
+from typing import Literal
+
from pydantic import BaseModel, Field
from fastmcp import FastMCP
from fastmcp.apps.form import FormInput
diff --git a/docs/apps/providers/generative.mdx b/docs/apps/providers/generative.mdx
index 9f5002221..a0795c939 100644
--- a/docs/apps/providers/generative.mdx
+++ b/docs/apps/providers/generative.mdx
@@ -40,10 +40,35 @@ GenerativeUI(
)
```
+## What the LLM Sees
+
+The tool description includes code examples that teach the LLM the Prefab patterns. The LLM calls `generate_prefab_ui` with a `code` argument containing Prefab Python, and optionally a `data` argument to pass in real data from the conversation:
+
+```python
+# The LLM generates something like:
+generate_prefab_ui(
+ code="""
+from prefab_ui.components import Column, Heading
+from prefab_ui.components.charts import BarChart, ChartSeries
+from prefab_ui.app import PrefabApp
+
+with PrefabApp() as app:
+ with Column(gap=4):
+ Heading("Revenue")
+ BarChart(data=data, series=[ChartSeries(data_key="revenue")], x_axis="quarter")
+""",
+ data={"data": [{"quarter": "Q1", "revenue": 42000}, ...]}
+)
+```
+
+The component search tool lets the LLM discover what's available before writing code — `search_prefab_components("Chart")` returns matching components with import paths.
+
## Requirements
-Requires `fastmcp[apps]` (installs `prefab-ui`). The Pyodide sandbox for server-side validation requires Deno, which installs automatically on first use. The streaming renderer loads Pyodide from CDN in the browser — CSP is configured automatically by the provider.
+Requires `fastmcp[apps]` (installs `prefab-ui`). The Pyodide sandbox for server-side validation requires Deno, which installs automatically on first use. The streaming renderer loads Pyodide from CDN in the browser — CSP is configured automatically.
+
+The sandbox includes the Python standard library and Prefab. External packages (NumPy, pandas, etc.) are not available.
## Learn More
-See the full **[Generative UI guide](/apps/generative)** for details on how streaming works, what the LLM writes, how to pass data, and the component search tool.
+The full **[Generative UI guide](/apps/generative)** covers the streaming mechanics in detail, how to pass data, the component search tool, and sandbox limitations.