AgentSkillsCN

annotator

介绍如何使用 vite-plugin-ai-annotator,通过可视化元素选择来促进 AI 与人类的协作。当用户提及“标注器”、“AI 标注器”、“vite-plugin-ai-annotator”、“选择元素”、“浏览器选择”、“从浏览器截取屏幕截图”、“注入 CSS/JS”等关键词,或需要以可视化方式操作网页元素时,即可使用此技能。

SKILL.md
--- frontmatter
name: annotator
description: Guide for using vite-plugin-ai-annotator to enable AI-human collaboration through visual element selection. Use when user mentions "annotator", "ai-annotator", "vite-plugin-ai-annotator", "select elements", "browser selection", "capture screenshot from browser", "inject CSS/JS", or needs to work with web elements visually.

vite-plugin-ai-annotator

AI-powered element annotator for Vite - enables real-time collaboration between AI and humans through visual element selection, annotation, and manipulation in the browser.

Architecture

code
┌─────────────────┐     WebSocket      ┌──────────────────┐
│  Browser Page   │◄──────────────────►│  Annotator       │
│  (Toolbar UI)   │                    │  Server (:7318)  │
└─────────────────┘                    └────────┬─────────┘
                                                │
                                           MCP (stdio)
                                                │
                                       ┌────────▼─────────┐
                                       │   Claude Code    │
                                       │   (MCP Client)   │
                                       └──────────────────┘

Setup

1. Install vite-plugin-ai-annotator

bash
bun add -d vite-plugin-ai-annotator

2. Add Vite Plugin

typescript
// vite.config.ts
import { defineConfig } from 'vite'
import annotator from 'vite-plugin-ai-annotator'

export default defineConfig({
  plugins: [
    annotator({
      port: 7318,              // Default port
      listenAddress: 'localhost', // Default bind address
      injectSourceLoc: true,   // Inject data-source-loc attributes (default: true)
      verbose: false,          // Enable for debugging
    }),
  ],
})

Team Collaboration (optional): For network access:

typescript
annotator({
  port: 7318,
  listenAddress: '0.0.0.0',
  publicAddress: 'https://myapp.com:7318',
})

3. Configure MCP Server

Run in Claude Code:

bash
claude mcp add annotator -- bunx vite-plugin-ai-annotator mcp -s http://localhost:7318

Or add to .mcp.json in your project root (or ~/.claude/settings.json for global):

json
{
  "mcpServers": {
    "ai-annotator": {
      "command": "bunx",
      "args": ["vite-plugin-ai-annotator", "mcp", "-s", "http://localhost:7318"]
    }
  }
}

4. Start Development Server

bash
bun dev

The annotator toolbar appears in the bottom-right corner of your app.

MCP Tools

Session Management

annotator_list_sessions List all connected browser sessions.

code
Parameters: (none)
Returns: Array of BrowserSession objects

Note: The MCP server is stateless. Each tool accepts an optional sessionId parameter. If only one browser session is connected, it auto-selects. If multiple sessions exist, you must pass sessionId to each tool call.

Page Context

annotator_get_page_context Get current page information.

code
Parameters:
- sessionId: (optional) Browser session ID

Returns:
- url: Current page URL
- title: Page title
- selectionCount: Number of selected elements
- isInspecting: Whether inspect mode is active

Element Feedback

annotator_select_feedback Enter inspect mode or select elements by selector.

code
Parameters:
- sessionId: (optional) Browser session ID
- mode: 'inspect' | 'selector' (default: 'inspect')
- selector: CSS or XPath selector (required when mode is 'selector')
- selectorType: 'css' | 'xpath' (default: 'css')

Examples:
- Inspect mode: { mode: 'inspect' }
- CSS selector: { mode: 'selector', selector: '.btn-primary' }
- XPath: { mode: 'selector', selector: '//button[@type="submit"]', selectorType: 'xpath' }

Returns:
- success: boolean
- count: number (elements selected)
- error?: string

annotator_get_feedback Get detailed data about selected elements.

code
Parameters:
- sessionId: (optional) Browser session ID
- fields: (optional) array of ['xpath', 'attributes', 'styles', 'children']

Default fields (always returned):
- index, tagName, cssSelector, textContent, comment, componentData

Additional fields (when requested):
- xpath: Full XPath
- attributes: All HTML attributes
- computedStyles: width, height, fontSize, colors, etc.
- children: Nested selected elements

Returns: Array of ElementData objects

annotator_clear_feedback Clear all selected elements.

code
Parameters:
- sessionId: (optional) Browser session ID

Screenshots

annotator_capture_screenshot Capture viewport or specific element.

code
Parameters:
- sessionId: (optional) Browser session ID
- type: 'viewport' | 'element' (default: 'viewport')
- selector: CSS selector (required when type is 'element')
- quality: 0-1 (default: 0.7)

Returns: File path to saved WebP screenshot

Code Injection

annotator_inject_css Inject CSS styles into the page.

code
Parameters:
- sessionId: (optional) Browser session ID
- css: CSS code to inject

annotator_inject_js Execute JavaScript in page context.

code
Parameters:
- sessionId: (optional) Browser session ID
- code: JavaScript code to execute

Returns:
- success: boolean
- result?: unknown (execution result)
- error?: string

Console

annotator_get_console Get captured console logs from the browser.

code
Parameters:
- sessionId: (optional) Browser session ID
- clear: boolean - Clear buffer after reading (default: false)

Returns: Array of console entries with type, args, timestamp.

Workflows

Workflow 1: Understand Page Structure

  1. Check page context: annotator_get_page_context
  2. Enter inspect mode: annotator_select_feedback({ mode: 'inspect' })
  3. Ask user to click elements they want to discuss
  4. Get selected elements: annotator_get_feedback
  5. Analyze structure and provide recommendations

Workflow 2: Debug Styling Issues

  1. Select problematic element: annotator_select_feedback({ mode: 'selector', selector: '.problem-element' })
  2. Get element details: annotator_get_feedback({ fields: ['styles', 'attributes'] })
  3. Inject test CSS: annotator_inject_css('...')
  4. Capture screenshot to verify: annotator_capture_screenshot({ type: 'element', selector: '.problem-element' })

Workflow 3: Implement User Feedback

  1. User selects elements and adds comments via toolbar
  2. Get selections with comments: annotator_get_feedback
  3. Read component files based on componentData.componentLocation
  4. Make code changes based on user comments
  5. User verifies changes in browser

Element Data Structure

typescript
interface ElementData {
  index: number
  tagName: string
  cssSelector: string
  textContent: string
  comment?: string
  componentData?: {
    componentLocation: string  // File path with line number
    componentName?: string
    framework?: 'vue' | 'react' | 'angular' | 'svelte' | 'vanilla'
  }
  // Optional fields (request via fields parameter):
  xpath?: string
  attributes?: Record<string, string>
  computedStyles?: {
    width: number
    height: number
    fontSize: string
    fontFamily: string
    color?: string
    backgroundColor?: string
    display?: string
    position?: string
  }
  children?: ElementData[]
}

Tips

  • Always call annotator_get_page_context first to verify connection
  • Use inspect mode for user-driven selection, CSS/XPath for programmatic selection
  • Element comments from users provide valuable context for code changes
  • componentData.componentLocation points directly to the source file with line number
  • Screenshots are saved as WebP to temp directory
  • Console logs are buffered; use clear: true to prevent duplicates
  • The plugin is disabled during vite build - safe for production configs