# Agent UI
Dynamic canvas interface for Claude Code interaction via MCP (Model Context Protocol).
## Overview
Agent UI provides a visual canvas where Claude Code can render dynamic Vue 3 components, HTML content, and interactive UIs in real-time. It bridges the gap between CLI-based AI assistance and rich visual interfaces.
## Architecture
```
agent-ui/
├── frontend/ # Vue 3 + Vite + Pinia
│ └── src/
│ ├── components/ # Canvas, Toolbar, StatusBar
│ ├── services/ # Dynamic components system
│ ├── stores/ # Pinia state management
│ └── styles/ # Global CSS
├── server/ # Bun HTTP API + SQLite
└── .mcp.json # MCP server configuration
```
## Quick Start
```bash
# Install dependencies
npm install
# Start development (frontend + server)
npm start
```
- **Frontend**: http://localhost:4100
- **API Server**: http://localhost:4101
- **WebMCP**: ws://localhost:4102
## Connecting to Claude Code
1. Start the development server: `npm start`
2. In Claude Code, run `/mcp` to reconnect
3. Click the widget (bottom-right) in the browser
4. Paste the token from Claude Code
---
# Dynamic Canvas
The dynamic canvas system allows Claude Code to render fully-featured Vue 3 components at runtime.
## MCP Tools
### `render_vue_component`
Renders a Vue 3 component directly in the canvas.
```javascript
{
id: "my-counter", // Unique component ID
name: "MyCounter", // Component name
template: `
...
`, // Vue template
setup: `...`, // Composition API setup code
style: `.class { ... }`, // Scoped CSS
props: ["title"], // Props list
imports: ["ref", "computed"], // Vue imports needed
componentProps: { title: "Hello" }, // Props values
mode: "replace" | "append" // Render mode
}
```
### `save_vue_component`
Saves a component to SQLite for later reuse.
```javascript
{
id: "my-component", // Optional, auto-generated if empty
name: "MyComponent",
template: `...`,
setup: `...`,
style: `...`,
props: [...],
imports: [...]
}
```
### `load_vue_component`
Loads and renders a previously saved component.
```javascript
{
id: "my-component",
componentProps: { ... },
mode: "replace" | "append"
}
```
### `list_vue_components`
Lists all saved components in the database.
### `delete_vue_component`
Deletes a component from the database.
```javascript
{
id: "my-component"
}
```
### `render_html`
Renders raw HTML with script/style support (legacy, simpler option).
```javascript
{
html: "
...
",
mode: "replace" | "append" | "prepend"
}
```
---
## Setup Function API
Inside the `setup` string, components have access to:
### Vue Reactivity (via `imports`)
```javascript
ref, reactive, computed, watch, watchEffect,
onMounted, onUnmounted, nextTick, provide, inject, h
```
### Props & Context
```javascript
props // Component props
ctx // { emit, attrs, slots, expose }
```
### Event Bus
```javascript
$emit(event, ...args) // Emit global event
$on(event, callback) // Listen (returns unsubscribe fn)
$once(event, callback) // Listen once
$off(event, callback) // Stop listening
```
### Utilities
```javascript
$fetch(url, options) // Native fetch
$nextTick(callback) // Vue nextTick
useCanvasStore() // Pinia store (shared with main app)
```
### Components API
```javascript
$components.load(id) // Load component from DB
$components.list() // List all components
$components.save(comp) // Save component to DB
```
---
## Example: Interactive Counter
```javascript
// MCP call: render_vue_component
{
id: "counter",
name: "Counter",
template: `