Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/contributing/mcp-apps-architecture.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,18 @@ sequenceDiagram
Located in `client/src/components/ui/sandboxed-iframe.tsx`:

```typescript
export interface SandboxedIframeHandle {
postMessage: (data: unknown) => void;
getIframeElement: () => HTMLIFrameElement | null;
}

export const SandboxedIframe = forwardRef<SandboxedIframeHandle, SandboxedIframeProps>(
function SandboxedIframe({ html, sandbox, onMessage, ... }, ref) {
// Outer iframe loads sandbox proxy
// Waits for ui/notifications/sandbox-ready
// Sends HTML via ui/notifications/sandbox-resource-ready
// Forwards all non-sandbox messages to parent handler
// Exposes getIframeElement() for direct DOM access (e.g., resizing)
}
);
```
Expand Down Expand Up @@ -205,6 +211,16 @@ window.mcpApp = {
};
```

### Resize handling

When a widget calls `resize()` or sends `ui/notifications/size-changed`, the host:

1. Ignores resize requests in fullscreen/PiP modes (they use 100% height)
2. Applies border-box compensation to prevent feedback loops
3. Animates the iframe height change using the Web Animations API
4. Directly manipulates the iframe element (not React state) for performance
```

### Events

Widgets can listen for these events:
Expand Down