# Web Viewer Extension - System Introduction
## 1. System Blueprint
### App Description & Functions
VS Code extension template cung cấp webview tương tác qua MCP (Model Context Protocol). Extension hoạt động như **bridge** giữa AI agents và web UI, cho phép AI thực hiện actions như navigate, click, input trên webview.
**Core Features:**
- Generic webview management (configurable viewType, title, mediaFolder)
- HTTP Bridge với auto-forward pattern (port 54321)
- Standalone MCP Server với generic tool forwarding
- Vite-based webview build system (HTML, SCSS, TypeScript)
- **2-file tool addition** - chỉ cần sửa 2 files để thêm tool mới
### Source Structure
```
src/
├── extension.ts # Entry point + panel handlers + defaultHandler
├── core/ # GENERIC modules (không sửa khi thêm tool)
│ ├── ViewerProvider.ts # Configurable webview panel management
│ └── HttpBridge.ts # Generic HTTP router với setDefaultHandler()
├── mcp/
│ └── mcp-server.ts # Generic MCP Server (auto-forward all tools)
├── tools/
│ └── index.ts # ⭐ Tool schemas (THÊM TOOL TẠI ĐÂY)
└── webview/ # Webview source (Vite build)
├── index.html
├── styles.scss
├── bridge.ts # ⭐ Tool handlers (THÊM HANDLER TẠI ĐÂY)
└── main.ts
```
### Architecture Flow
```
AI Agent <--stdio--> MCP Server <--HTTP:54321--> VS Code Extension <--postMessage--> Webview
| |
(generic forward) (defaultHandler forward)
| |
tools/index.ts webview/bridge.ts
```
---
## 2. Deep Reasoning Insights
### Challenge 1: Rườm rà khi thêm tool mới
**Vấn đề:** Ban đầu cần sửa 4 files: tools/index.ts, mcp-server.ts, extension.ts, bridge.ts
**Giải pháp:**
- MCP Server: Generic forwarding - loop qua all tools, strip prefix `web_` → gọi sendToExtension
- Extension: `setDefaultHandler()` - forward tất cả unregistered commands đến webview
- Kết quả: **Chỉ cần sửa 2 files** (tools/index.ts + bridge.ts)
### Challenge 2: Navigation phức tạp
**Vấn đề:** handleNavigate dùng pushState + popstate + custom event, main.ts có 3 listeners
**Giải pháp:**
- bridge.ts: Chỉ cần `window.location.hash = page`
- main.ts: Chỉ cần `hashchange` listener
- `hashchange` event tự động handle tất cả nguồn navigation
### Challenge 3: Circular import
**Vấn đề:** `import { ToolDefinition } from './index'` - file tự import chính nó
**Giải pháp:** Định nghĩa interface trực tiếp trong file, không import từ chính nó
---
## 3. Decision Logic
| Quyết định | Lý do | Trade-off |
|------------|-------|-----------|
| Generic tool forwarding | Giảm code khi thêm tool mới | Mất control over từng tool |
| setDefaultHandler pattern | Extension không cần biết về business logic | Debug khó hơn |
| Hash-based routing only | Đơn giản, webview không cần history API | Chỉ support hash routes |
| onStartupFinished | Extension ready trước MCP | Luôn chạy khi VS Code mở |
---
## 4. Pattern Recognition
### Anti-patterns tránh
1. **Circular imports** - Không import từ chính file
2. **Duplicate event dispatch** - Một event type là đủ (hashchange)
3. **Hardcoded switch cases** - Dùng generic forwarding thay vì switch cho mỗi tool
### Recurring patterns
1. **Generic forwarding** - MCP → Extension → Webview không cần biết về từng command
2. **Prefix stripping** - `web_navigate` → `navigate` để mapping tool name ↔ command
3. **Hash-based SPA routing** - Đơn giản và hoạt động với webview
---
## 5. Hướng dẫn thêm Tool MCP mới
### Chỉ cần sửa 2 files:
**File 1: `src/tools/index.ts`** - Thêm schema
```typescript
{
name: 'web_scroll',
description: 'Scroll page by pixels',
inputSchema: {
type: 'object',
properties: {
y: { type: 'number', description: 'Pixels to scroll (positive=down)' },
},
required: ['y'],
},
},
```
**File 2: `src/webview/bridge.ts`** - Thêm handler
```typescript
// Trong switch(type)
case 'scroll':
result = handleScroll(payload);
break;
// Thêm function
function handleScroll(payload: { y: number }): boolean {
window.scrollBy(0, payload.y);
return true;
}
```
**Build:** `npm run build`
---
## Evolved Identity
Tôi là AI assistant chuyên về **Web Viewer Extension** - một VS Code extension template với:
- **2-file tool addition pattern**: tools/index.ts (schema) + bridge.ts (handler)
- **Generic forwarding architecture**: MCP → HTTP → Extension → Webview
- **Hash-based SPA routing**: Đơn giản, một hashchange listener handle tất cả
Tôi hiểu luồng `web_[action]` → strip prefix → forward → bridge.ts handler và có thể hướng dẫn thêm tools, customize UI, hoặc debug communication issues.