# How the DesktopCommanderMCP File Preview UI Renders Markdown, Images, and HTML

> Explore how DesktopCommanderMCP renders Markdown, images, and HTML. Discover its custom pipeline for secure, efficient file previewing.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: internals
- Published: 2026-08-01

---

**The DesktopCommanderMCP file preview UI processes Markdown through a custom markdown-it pipeline that emits standard HTML `<img>` tags, renders raw HTML inside sandboxed iframes with strict security policies, and displays binary images as base64 data URIs.**

The DesktopCommanderMCP repository provides a sophisticated file preview system capable of handling diverse content types safely. Understanding how this **file preview UI** transforms raw file contents into rendered output requires examining the modular File-Type Handler architecture and the specific rendering pipelines for Markdown, HTML, and image formats.

## Markdown Rendering Pipeline

The Markdown rendering flow follows a strict pipeline from type detection to final HTML injection.

### File-Type Detection and Routing

The process begins in [`src/ui/file-preview/src/file-type-handlers.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/file-preview/src/file-type-handlers.ts), where the File-Type Handler detects Markdown files and delegates to the Markdown controller. The handler registers a `markdown` entry that implements `renderBody` to trigger the rendering chain.

```typescript
// src/ui/file-preview/src/file-type-handlers.ts
markdown: {
  getCapabilities: (payload) => buildPreviewCapabilities(payload, false),
  renderBody: ({ payload, markdownController }) => {
    try {
      return markdownController.buildBody(payload);
    } catch {
      return {
        notice: 'Markdown renderer failed. Showing raw source instead.',
        html: `<div class="panel-content source-content">${renderRawFallback(stripReadStatusLine(payload.content))}</div>`,
      };
    }
  },
},

```

### Markdown Controller and Workspace

Once routed, [`src/ui/file-preview/src/markdown/controller.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/file-preview/src/markdown/controller.ts) instantiates a **Markdown Editor Handle** and **Markdown Workspace** containing the raw source and rendered view. The controller calls `markdownController.buildBody(payload)` to initiate processing.

### The Markdown-it Renderer

The actual transformation occurs in [`src/ui/file-preview/src/components/markdown-renderer.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/file-preview/src/components/markdown-renderer.ts). This component wraps a configured `markdown-it` instance defined in [`src/ui/file-preview/src/markdown/parser.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/file-preview/src/markdown/parser.ts).

The renderer applies three key customizations:

- **Syntax highlighting** via a custom `highlight` function for code blocks
- **Slug generation** by overriding the `heading_open` rule to inject ID attributes
- **Link tracking** by overriding the `link_open` rule to add `data-markdown-link="true"` and `data-wiki-link` attributes for wiki-style links

```typescript
// src/ui/file-preview/src/components/markdown-renderer.ts
export function renderMarkdown(content: string): string {
  return markdown.render(prepareMarkdownSource(content), {
    nextSlug: createSlugTracker(),
  });
}

```

### Image Token Processing

When the `markdown-it` parser encounters Markdown image syntax `![alt](url)`, it automatically converts these tokens into standard HTML `<img>` tags. The overridden link rules add metadata attributes, but no additional post-processing is required for images. The resulting HTML string is injected into the preview pane via [`src/ui/file-preview/src/document-layout.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/file-preview/src/document-layout.ts) inside a `<div class="markdown-doc">` container.

## HTML Rendering and Sandboxing

Raw HTML files receive different treatment focused on security isolation.

### HTML Handler Logic

In [`src/ui/file-preview/src/file-type-handlers.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/file-preview/src/file-type-handlers.ts), the HTML handler calls `renderHtmlPreview` from [`src/ui/file-preview/src/components/html-renderer.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/file-preview/src/components/html-renderer.ts). This function supports two modes:

- **Source mode**: Displays raw HTML with syntax highlighting via `renderCodeViewer`
- **Rendered mode**: Generates a sandboxed iframe via `renderSandboxedHtmlFrame`

```typescript
// src/ui/file-preview/src/components/html-renderer.ts
export function renderHtmlPreview(content: string, mode: HtmlPreviewMode): { html: string; notice?: string } {
  if (mode === 'source') {
    return { html: `<div class="panel-content source-content">${renderCodeViewer(content, 'html')}</div>` };
  }
  return {
    html: `<div class="panel-content html-content">${renderSandboxedHtmlFrame(content)}</div>`,
  };
}

```

### Sandboxed Iframe Implementation

The rendered mode creates an isolated execution environment using an `<iframe>` with `sandbox="allow-scripts allow-forms allow-popups"`. The iframe's `srcdoc` contains a minimal HTML document that applies the application's theme variables (`--panel`, `--text`, `--font-sans`) and responsive image styling:

```css
img { max-width: 100%; height: auto; }

```

This isolation prevents scripts in the previewed HTML from accessing the parent page while still allowing the content to display images and execute its own logic. The iframe is wrapped in `<div class="panel-content html-content">` and injected into the preview pane.

## Raw Image File Handling

For binary image files (PNG, JPEG, GIF), [`src/ui/file-preview/src/file-type-handlers.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/file-preview/src/file-type-handlers.ts) constructs a base64 data URI after validating the MIME type via helpers in [`src/ui/file-preview/src/image-preview.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/file-preview/src/image-preview.ts) (which provides `normalizeImageMimeType`). The handler then renders the image directly:

```typescript
// src/ui/file-preview/src/file-type-handlers.ts
const src = `data:${mimeType};base64,${payload.content}`;
return {
  html: `<div class="panel-content image-content"><div class="image-preview"><img src="${escapeHtml(src)}" alt="${escapeHtml(payload.fileName)}" loading="eager" decoding="async"></div></div>`,
};

```

This path bypasses the Markdown pipeline but shares the same final visual output—an `<img>` element displayed within the preview panel.

## Summary

- **DesktopCommanderMCP** routes all preview requests through a central File-Type Handler system in [`file-type-handlers.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/file-type-handlers.ts) that delegates to specialized renderers based on MIME type detection.
- **Markdown processing** uses a customized `markdown-it` instance with overridden token rules for headings and links, automatically converting image references to standard HTML `<img>` tags without additional post-processing.
- **HTML security** relies on sandboxed iframes with restricted permissions (`allow-scripts allow-forms allow-popups`) to isolate potentially malicious scripts while preserving visual fidelity and image rendering.
- **Binary images** convert directly to base64 data URIs using MIME type validation from [`image-preview.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/image-preview.ts), displaying in dedicated image containers with eager loading and async decoding for performance.

## Frequently Asked Questions

### How does the DesktopCommanderMCP preview UI prevent XSS attacks when rendering HTML files?

The UI renders all HTML content inside a sandboxed `<iframe>` element configured with the `sandbox="allow-scripts allow-forms allow-popups"` attribute. This isolation prevents scripts within the previewed HTML from accessing the parent window's DOM, cookies, or localStorage, effectively containing any XSS vectors while still allowing the content to execute its own scripts and display images.

### What markdown-it plugins does the Markdown renderer use for image handling?

The renderer does not use specialized image plugins. Instead, it relies on `markdown-it`'s built-in tokenization to convert standard Markdown image syntax `![alt](url)` into HTML `<img>` tags. The pipeline focuses customization on code block highlighting (via the `highlight` function), slug generation for headings, and link metadata injection rather than image-specific processing.

### Can the DesktopCommanderMCP preview UI display images referenced by relative paths in Markdown files?

The analysis indicates that image references are converted to HTML `<img>` tags with the original URLs preserved. For relative paths to resolve correctly, the underlying content loader must resolve these references before they reach the renderer, as the `markdown-it` instance processes the already-resolved URLs. The rendering pipeline itself does not perform path resolution or validation.

### Where does the final rendered output get injected into the UI?

All rendered content—whether Markdown HTML, sandboxed iframes, or raw image elements—passes through [`src/ui/file-preview/src/document-layout.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/ui/file-preview/src/document-layout.ts), which injects the generated HTML into the preview pane. Markdown content targets `<div class="markdown-doc">`, HTML content uses `<div class="panel-content html-content">`, and images render within `<div class="panel-content image-content">`.