---
name: adom-viewer
description: Display visual content in the Adom Viewer. Use when the user wants to show, preview, or visualize files, generated content, charts, diagrams, or any visual output in the Adom Viewer panel.
---

# Adom Viewer

The Adom Viewer (AV) lets you send visual content from the Docker container to the Adom App front-end so the user can see it in their browser. Content appears in an iframe panel with tabs, dark theme, and auto-reconnecting WebSocket.

## What the user asked to display

$ARGUMENTS

## Supported content types

| Type | Extensions / format | Notes |
|------|-------------------|-------|
| SVG | `.svg`, raw SVG markup | Vector graphics, diagrams, schematics |
| Images | `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp` | Raster images |
| HTML | `.html`, `.htm` | Interactive HTML with `<script>` tags runs in an iframe |
| Markdown | `.md`, `.markdown` | Rendered client-side in the viewer |

## How to display content

### Option A: Display an existing file

Use the `av_display_file` MCP tool:

```
mcp__adom-viewer__av_display_file({ file_path: '/absolute/path/to/file.svg', title: 'My Diagram' })
```

This auto-detects the content type from the file extension.

### Option B: Display generated content

Use the `av_display` MCP tool:

```
mcp__adom-viewer__av_display({
  content_type: 'html_interactive',
  content: '<html>...</html>',
  title: 'My Visualization'
})
```

For images, provide a data URI: `data:image/png;base64,...`

### Option C: Internal HTTP API fallback

If MCP tools are not available, POST directly to the AV internal API:

```javascript
const http = require('http');
const crypto = require('crypto');

const payload = JSON.stringify({
  action: 'display',
  content: {
    contentType: 'svg',
    content: '<svg>...</svg>',
    title: 'My Diagram',
    id: crypto.randomUUID(),
    source: 'av_display',
    skill: 'av-creator',
    author: 'Your Name'
  }
});

const req = http.request({
  hostname: '127.0.0.1',
  port: 8771,
  method: 'POST',
  headers: { 'Content-Type': 'application/json' }
}, (res) => {
  let data = '';
  res.on('data', c => data += c);
  res.on('end', () => console.log(res.statusCode, data));
});
req.write(payload);
req.end();
```

The `source`, `skill`, and `author` fields appear in a tooltip when the user hovers over the tab. Always include them.

## Built-in interactive views

The viewer dropdown menu includes built-in interactive views for several skills:

| View | Description |
|------|-------------|
| **JLCPCB Search** | Interactive component search with rich cards showing images, pricing, stock, attributes. |
| **Google Chat** | Architecture overview and capabilities of the Kel Google Chat integration. |

## MCP Tools

| Tool | Purpose |
|------|---------|
| `av_display` | Display generated content (HTML, SVG, markdown, images) |
| `av_display_file` | Display an existing file by path |
| `av_3d_display` | Display a GLB 3D model in the Babylon.js viewer |
| `av_symbol_3d_display` | Split-pane symbol SVG + 3D model |
| `av_library_review` | 3-pane library review (symbol + footprint + 3D) |
| `av_screenshot_paste` | Open clipboard screenshot paste utility |
| `av_file_explorer` | Browse files in the viewer |
| `av_symbol_prefs` | Configure symbol generation preferences |
| `av_clear` | Clear all displayed content |
| `av_status` | Check if the viewer is connected |
| `av_reload` | Force browser to reload the AV page (survives server restarts) |
| `av_capture` | Capture a screenshot of just the AV panel content |
| `av_tab_capture` | Capture the full browser tab via Screen Capture API |
| `av_set_camera` | Set the 3D camera position (alpha, beta, radius, target) |
| `av_set_view` | Set a named camera preset (front, back, top, bottom, etc.) |
| `av_set_bottom_light` | Toggle/set the bottom light for inspecting underside features |
| `av_stop_tour` | Stop the cinematic camera tour, freeze camera |

## Screenshot Paste

The `av_screenshot_paste` tool opens an interactive paste utility in the viewer. Users paste screenshots from their clipboard and the system automatically resizes, compresses, AI-names, and saves them.

```
mcp__adom-viewer__av_screenshot_paste({ title: 'Paste Screenshots' })
```

## Management relay (port 8772)

A separate lightweight server runs on port 8772, independent of the main AV server (8770/8771). The browser connects to BOTH WebSockets. This solves two problems:

1. **Forced reload after server restart** — when you restart the main AV server, the mgmt relay stays alive, so `av_reload` can tell the browser to reload.
2. **AI-initiated screenshot capture** — `av_capture` asks the browser to screenshot whatever it's showing and returns the image.

## Tab capture (Screen Capture API)

`av_tab_capture` captures the **entire browser tab** as a pixel-perfect screenshot using the browser's Screen Capture API.

- `av_capture` — captures just the AV panel. Fast, no setup. But fails on multi-iframe layouts.
- `av_tab_capture` — captures the full browser tab. Works on all content including nested iframes. Requires one-time user setup.

**Setup:** Click the camera button in AV → opens the capture companion tab → click "Share This Tab" → select the IDE tab.

## 3D Model Display

Use `av_3d_display` to display GLB files in the viewer's built-in Babylon.js 3D view:

```
mcp__adom-viewer__av_3d_display({
  glb_path: '/path/to/model.glb',
  body_size: { x: 4.4, y: 5.0, z: 1.2 },
  part_name: 'PART_NAME',
  manufacturer: 'Manufacturer',
  package_type: 'TSSOP-14',
  pad_count: 14,
  title: 'PART 3D Model'
})
```

`av_3d_display` blocks until the model is fully loaded (up to 15s). Call `av_capture` immediately after — no sleep needed.

### Camera controls

- `alpha` = azimuth (0 = front, π/2 = right side)
- `beta` = elevation (0 = top-down, π/2 = eye-level, π = bottom-up)
- `radius` = zoom multiplier
- Bottom light: illuminates underside for inspecting board pads

## Adom Theme — styling guide for widgets

All AV widgets MUST use the Adom theme (`viewer/adom-theme.js`).

### Key color tokens

| Token | Value | Usage |
|-------|-------|-------|
| `bg` | `#0d1117` | Page background |
| `bgSurface` | `#161b22` | Cards, panels |
| `bgElevated` | `#1c2128` | Hover states |
| `border` | `#30363d` | Standard borders |
| `text` | `#e6edf3` | Primary text |
| `textSecondary` | `#8b949e` | Labels |
| `accent` | `#00b8b0` | Primary teal accent |
| `accentBright` | `#00e6dc` | Hover/focus |
| `success` | `#3fb950` | Success |
| `warning` | `#d29922` | Warning |
| `danger` | `#f85149` | Error |

### Rules

1. Never use the old deprecated palette.
2. All widget HTML must set its own background to `#0d1117`.
3. Use the font stack: `-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif`.
4. Semantic colors only for status: green=success, amber=warning, red=error.

## Ports

| Port | Purpose |
|------|---------|
| 8770 | HTTP server + WebSocket (public) |
| 8771 | Internal API (localhost only) |
| 8772 | Management relay (reload, capture) |
