Architecture
Vibe Annotations is split into two independent pieces that communicate over HTTP.
Browser Extension ← HTTP sync/CRUD → MCP Server ← MCP tools → AI Agents
(Chrome) (port 3846) (Claude Code,
Cursor, etc.)
Browser Extension
A Chrome MV3 extension built with WXT. The content scripts are ES modules that WXT bundles into the MV3 extension — wxt dev gives a live-reloading dev build, wxt build / wxt zip produce the loadable/publishable output.
- Content scripts inject a floating toolbar overlay on localhost pages via a Shadow DOM root
- Inspection mode lets users hover and click elements to annotate them, with a live selector hint on the highlight
- Annotation popover provides comment input, design property editors (font, spacing, layout, colors), raw CSS editing, image attachments, and a variants intent
- Badge manager renders numbered pins on annotated elements and rehydrates pending design changes
- Background service worker handles storage CRUD with a serialization lock, bidirectional sync with the server, and browser action badge updates
The extension works standalone for the basics — Copy, .md/.json export, and import all run client-side with no server. The .html export and MCP integration need the server running.
MCP Server
A global npm package (vibe-annotations-server) that runs as a background process on port 3846.
- HTTP API (
/api/annotations) — CRUD endpoints for the extension to sync annotations - MCP endpoint (
/mcp) — Streamable HTTP transport for AI coding agents - SSE endpoint (
/sse) — Legacy Server-Sent Events transport - Watcher system — Long-poll mechanism for watch mode, with grace periods and auto-cleanup
- Attachments (
/api/annotations/:id/attachments) — image files (auto element screenshots + user reference images) stored under~/.vibe-annotations/attachments/, deleted with their annotation - Export (
/api/export) — renders a single self-contained.htmlwith every image embedded as base64 (the.md/.jsonformats are produced client-side in the extension) - Storage — JSON file at
~/.vibe-annotations/annotations.json, atomic writes with corruption recovery
Data Flow
- User creates an annotation in the extension (stored in Chrome Storage)
- Background worker syncs it to the server via HTTP POST
- AI agent calls
read_annotationsvia MCP to fetch pending annotations - Agent implements the changes in source code
- Agent calls
delete_annotationto mark it as resolved - Server deletion syncs back to the extension, removing the badge
Annotation Types
Element annotations target a specific DOM element:
- CSS selector for re-targeting
- Element context (tag, classes, text, computed styles, position)
- Optional
pending_changes(design property diffs likefontSize: "16px" → "18px") - Optional
cssfield (rules like:hover,::before,@media) - Optional
attachments(auto element screenshots + user-attached reference images) - Source mapping hints (file path, line range, framework detection)
Variant annotations (mode: 'variants') carry a self-contained variant_instructions contract: the agent scaffolds several coexisting, previewable design variants in your codebase, you pick one in the extension, and the agent finalizes it (stripping all scaffolding). See Variant generation.
Stylesheet annotations (type: 'stylesheet') apply broad CSS changes:
- No selector or element context
- Only a
cssfield with raw CSS rules - Created by agents via the bridge API (
window.__vibeAnnotations.createStyleAnnotation())