---
alwaysApply: true
---
# MCP Grid Design System Rules

## 1. Project Overview

MCP Grid is a **two-part project**:

| Layer | Language | Location | Purpose |
|-------|----------|----------|---------|
| **Backend** | Python 3.11+ | `mcp-grid-ws/src/mcp_bridge/` | MCP meta-server (FastMCP + Pydantic) |
| **Extension** | TypeScript | `mcp-grid-ws/extension/src/` | VS Code extension UI |

There is **no standalone web frontend**. All UI lives inside VS Code via TreeView providers and a single WebviewPanel dashboard.

---

## 2. Token Definitions (Design Tokens)

### 2.1 VS Code Theme Variables (Primary Token Source)

All colors, typography, and spacing derive from **VS Code CSS custom properties**. Never hardcode colors outside the badge palette below.

```css
/* Layout & surfaces */
--vscode-editor-background        /* Page / panel background */
--vscode-editor-foreground         /* Primary text */
--vscode-editorWidget-background   /* Card / widget surfaces */
--vscode-widget-border             /* Borders, dividers */

/* Typography */
--vscode-font-family               /* UI text */
--vscode-font-size                 /* UI text size */
--vscode-editor-font-family        /* Monospace / code */

/* Interactive */
--vscode-button-background         /* Primary button fill */
--vscode-button-foreground         /* Primary button text */
--vscode-button-hoverBackground    /* Primary button hover */
--vscode-textLink-foreground       /* Accent / link color */

/* Semantic */
--vscode-descriptionForeground     /* Muted / secondary text */
```

### 2.2 Custom Alias Tokens (Dashboard CSS)

Map VS Code variables to short aliases at the `:root` level inside WebviewPanel HTML:

```css
:root {
  --bg:      var(--vscode-editor-background);
  --fg:      var(--vscode-editor-foreground);
  --border:  var(--vscode-widget-border);
  --card-bg: var(--vscode-editorWidget-background);
  --accent:  var(--vscode-textLink-foreground);
  --muted:   var(--vscode-descriptionForeground);
}
```

### 2.3 Badge Color Palette (Hardcoded)

These are the **only** hardcoded colors permitted in the project:

| Token | Background | Foreground | Meaning |
|-------|-----------|------------|---------|
| `badge-green` | `#2ea04370` | `#3fb950` | Success / connected / enabled |
| `badge-red` | `#f8514970` | `#f85149` | Error / disconnected / failed |
| `badge-yellow` | `#d2992270` | `#d29922` | Warning / pending / initializing |

### 2.4 VS Code ThemeColor References (TypeScript)

Use `vscode.ThemeColor` for programmatic color references:

```typescript
// Status bar warning state
new vscode.ThemeColor("statusBarItem.warningBackground")

// Tree item decorations
new vscode.ThemeColor("charts.green")
new vscode.ThemeColor("charts.red")
new vscode.ThemeColor("charts.yellow")
new vscode.ThemeColor("charts.blue")
```

### 2.5 Rules

- ALWAYS prefer VS Code theme variables over hardcoded values.
- NEVER introduce new hardcoded colors without adding them to the badge palette table above.
- ALWAYS use the `:root` alias tokens (`--bg`, `--fg`, etc.) in dashboard HTML/CSS.
- Use `ThemeColor` for all programmatic color references in TypeScript.

---

## 3. Component Library

### 3.1 Architecture

The extension uses the **VS Code Extension API** exclusively. There is no React, Vue, or other UI framework.

| Component Type | API | Location |
|---------------|-----|----------|
| **TreeDataProvider** | `vscode.TreeDataProvider<T>` | `extension/src/providers/` |
| **WebviewPanel** | `vscode.WebviewPanel` | `extension/src/panels/` |
| **StatusBarItem** | `vscode.StatusBarItem` | `extension/src/utils/` |
| **Commands** | `vscode.commands.registerCommand` | `extension/src/commands/` |

### 3.2 Tree View Providers

Four providers populate the activity bar sidebar:

| Provider | View ID | Purpose |
|----------|---------|---------|
| `ServersTreeProvider` | `mcpGrid.servers` | Browse registered MCP servers by category |
| `InstancesTreeProvider` | `mcpGrid.instances` | Show active server instances and their tools |
| `MetricsTreeProvider` | `mcpGrid.metrics` | Display call metrics and latency stats |
| `MarketplaceTreeProvider` | `mcpGrid.marketplace` | Discover and install new servers |

### 3.3 Component Patterns

**TreeDataProvider pattern:**

```typescript
export class ExampleTreeProvider implements vscode.TreeDataProvider<ExampleItem> {
  private _onDidChangeTreeData = new vscode.EventEmitter<ExampleItem | undefined | void>();
  readonly onDidChangeTreeData = this._onDidChangeTreeData.event;

  constructor(private readonly _client: BridgeClient) {}

  refresh(): void {
    this._onDidChangeTreeData.fire();
  }

  getTreeItem(element: ExampleItem): vscode.TreeItem {
    return element;
  }

  async getChildren(element?: ExampleItem): Promise<ExampleItem[]> {
    // Fetch from BridgeClient, return tree items
  }
}
```

**TreeItem pattern:**

```typescript
export class ExampleItem extends vscode.TreeItem {
  constructor(
    label: string,
    collapsibleState: vscode.TreeItemCollapsibleState,
    public readonly kind: string,
    public readonly data?: SomeType
  ) {
    super(label, collapsibleState);
    // Assign iconPath using ThemeIcon based on kind
    this.iconPath = new vscode.ThemeIcon("server-process");
  }
}
```

**WebviewPanel pattern (singleton):**

```typescript
export class ExamplePanel {
  public static currentPanel: ExamplePanel | undefined;
  private static readonly _viewType = "mcpGrid.example";

  static createOrShow(client: BridgeClient): void {
    if (ExamplePanel.currentPanel) {
      ExamplePanel.currentPanel._panel.reveal();
      return;
    }
    const panel = vscode.window.createWebviewPanel(/* ... */);
    ExamplePanel.currentPanel = new ExamplePanel(panel, client);
  }

  dispose(): void {
    ExamplePanel.currentPanel = undefined;
    // Clean up intervals, disposables
  }
}
```

### 3.4 Rules

- All providers MUST accept `BridgeClient` via constructor injection.
- TreeDataProviders MUST expose a `refresh()` method that fires `_onDidChangeTreeData`.
- WebviewPanels MUST follow the singleton pattern (`createOrShow`).
- WebviewPanels MUST clean up intervals and disposables in `dispose()`.
- Use `retainContextWhenHidden: true` for panels with polling.

---

## 4. Frameworks & Libraries

### 4.1 Extension (TypeScript)

| Dependency | Version | Purpose |
|-----------|---------|---------|
| `vscode` | `^1.96.0` | VS Code Extension API |
| `ws` | `^8.19.0` | WebSocket client to bridge backend |
| `typescript` | `^5.7.3` | Language |
| `webpack` | `^5.98.0` | Bundler |
| `ts-loader` | `^9.5.2` | TypeScript loader for webpack |
| `eslint` | `^9.20.0` | Linting |

### 4.2 Backend (Python)

| Dependency | Version | Purpose |
|-----------|---------|---------|
| `fastmcp` | `>=2.14.5` | MCP server framework |
| `pydantic` | `>=2.12.5` | Data models / validation |
| `pydantic-settings` | `>=2.12.0` | Configuration management |
| `aiohttp` | `>=3.13.3` | HTTP client for subprocess servers |
| `httpx` | `>=0.28.0` | Alternative async HTTP |
| `websockets` | `>=16.0` | WebSocket server for extension |
| `uvicorn` | `>=0.40.0` | ASGI server |
| `starlette` | `>=0.52.1` | Management API framework |
| `pyyaml` | `>=6.0.3` | Catalog YAML parsing |
| `psutil` | `>=7.2.2` | System metrics |
| `aiosqlite` | `>=0.22.1` | Metrics persistence |

### 4.3 Rules

- NEVER add React, Vue, or any frontend framework to the extension. Use VS Code APIs only.
- Keep `ws` as the sole runtime dependency for the extension.
- Python dependencies MUST be pinned with minimum versions in `pyproject.toml`.

---

## 5. Asset Management

### 5.1 Structure

```
mcp-grid-ws/extension/media/
└── icons/
    ├── grid.svg          # 24x24, activity bar icon
    └── grid-128.svg      # 128x128, marketplace icon
```

### 5.2 Asset References

Icons are referenced in `package.json` via relative paths:

```json
{
  "icon": "media/icons/grid-128.svg",
  "viewsContainers": {
    "activitybar": [{
      "icon": "media/icons/grid.svg"
    }]
  }
}
```

### 5.3 Catalog Assets (Python)

Server definitions live in YAML files:

```
mcp-grid-ws/catalog/
├── browser-automation.yaml
├── data-analytics.yaml
├── development.yaml
├── search-web.yaml
└── utilities.yaml
```

### 5.4 Rules

- Custom SVG icons go in `extension/media/icons/`.
- SVGs MUST use `currentColor` for stroke/fill to respect VS Code themes.
- No image bundling, CDN, or optimization pipeline — SVGs are used directly.
- Catalog YAML files go in `mcp-grid-ws/catalog/` organized by category.

---

## 6. Icon System

### 6.1 Custom SVG Icons

Only two custom icons exist. They use `stroke="currentColor"` for theme compatibility:

```svg
<!-- grid.svg (24x24) -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  <rect x="3" y="3" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.5"/>
  <rect x="14" y="3" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.5"/>
  <rect x="3" y="14" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.5"/>
  <rect x="14" y="14" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.5"/>
  <circle cx="6.5" cy="6.5" r="1.5" fill="currentColor"/>
  <circle cx="17.5" cy="6.5" r="1.5" fill="currentColor"/>
  <circle cx="6.5" cy="17.5" r="1.5" fill="currentColor"/>
  <circle cx="17.5" cy="17.5" r="1.5" fill="currentColor"/>
</svg>
```

### 6.2 VS Code ThemeIcon Usage

All in-tree icons use `vscode.ThemeIcon`. Categorized by semantic purpose:

**Status indicators:**
| Icon | Usage |
|------|-------|
| `check` | Connected / success |
| `circle-slash` | Disconnected / offline |
| `error` | Error state |
| `warning` | Warning state |
| `pass` | Test passed |
| `loading~spin` | Loading / initializing |

**Object types:**
| Icon | Usage |
|------|-------|
| `server-process` | Server instance |
| `folder` | Category group |
| `symbol-method` | Tool / method |
| `database` | Data store |
| `browser` | Browser automation |
| `tools` | Utility category |
| `package` | Package / installable |
| `gear` | Configuration |

**Actions:**
| Icon | Usage |
|------|-------|
| `play` | Start / activate |
| `debug-stop` | Stop / deactivate |
| `refresh` | Refresh data |
| `search` | Search / discover |
| `cloud-download` | Download / install |
| `add` | Add new item |
| `plug` | Connect |
| `debug-disconnect` | Disconnect |

**Status bar codicons (inline text):**
| Codicon | Usage |
|---------|-------|
| `$(check)` | Connected status |
| `$(circle-slash)` | Offline status |
| `$(play)` | Start action |
| `$(refresh)` | Refresh action |
| `$(dashboard)` | Open dashboard |

### 6.3 Rules

- ALWAYS use `vscode.ThemeIcon` for tree view icons. Never use file-based icons for tree items.
- Custom SVGs are ONLY for the activity bar and marketplace icon.
- Use `$(codicon-name)` syntax in status bar text and QuickPick labels.
- Refer to the [VS Code Codicon reference](https://code.visualstudio.com/api/references/icons-in-labels) for available icons.

---

## 7. Styling Approach

### 7.1 Methodology

- **TreeViews:** No custom CSS. Styled entirely by VS Code via `TreeItem` properties (`iconPath`, `description`, `tooltip`, `ThemeColor` decorations).
- **WebviewPanels:** Inline `<style>` blocks within the HTML string. No external CSS files.
- **Status Bar:** `vscode.StatusBarItem` API with `ThemeColor` for background.

### 7.2 Dashboard CSS Architecture

The dashboard uses a minimal, flat CSS system inside inline `<style>` tags:

**Layout primitives:**

```css
.header          { display: flex; align-items: center; gap: 12px; }
.metrics-grid    { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; }
.toolbar         { display: flex; gap: 8px; }
```

**Component classes:**

```css
.badge           { padding: 2px 8px; border-radius: 10px; font-size: 0.85em; font-weight: 600; }
.metric-card     { background: var(--card-bg); border: 1px solid var(--border); border-radius: 8px; padding: 16px; text-align: center; }
.metric-value    { font-size: 2em; font-weight: 700; color: var(--accent); }
.metric-label    { font-size: 0.85em; color: var(--muted); margin-top: 4px; }
.btn             { cursor: pointer; border: none; border-radius: 4px; padding: 4px 10px; font-size: 0.85em; }
.btn-primary     { background: var(--vscode-button-background); color: var(--vscode-button-foreground); }
.btn-danger      { background: #f8514940; color: #f85149; }
```

**Typography scale:**

```css
h1               { font-size: 1.6em; }
h2               { font-size: 1.2em; border-bottom: 1px solid var(--border); }
code             { font-family: var(--vscode-editor-font-family); font-size: 0.9em; }
.muted           { color: var(--muted); }
```

**Tables:**

```css
table            { width: 100%; border-collapse: collapse; }
th, td           { text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--border); }
th               { font-weight: 600; color: var(--muted); font-size: 0.9em; }
```

### 7.3 Spacing System

No formal spacing scale. Current spacing values used:

| Context | Value |
|---------|-------|
| Body padding | `16px` |
| Grid gap | `12px` |
| Card padding | `16px` |
| Badge padding | `2px 8px` |
| Table cell padding | `6px 10px` |
| Button padding | `4px 10px` |
| Section margin-top | `24px` |

### 7.4 Responsive Design

The dashboard uses `grid-template-columns: repeat(auto-fit, minmax(140px, 1fr))` for the metrics grid, ensuring cards wrap on narrow panels. Tables scroll naturally within the webview.

### 7.5 Rules

- NEVER use external CSS files. All dashboard styles are inline in the HTML template.
- ALWAYS reference VS Code theme variables (`var(--vscode-*)`) for colors, fonts, and backgrounds.
- Keep CSS flat — no nesting, no preprocessors, no BEM.
- Use the existing spacing values. If a new spacing is needed, use multiples of `4px`.
- Buttons MUST use `.btn-primary` (from VS Code variables) or `.btn-danger` (red badge colors).
- All text sizing uses `em` units relative to `--vscode-font-size`.

---

## 8. Project Structure

### 8.1 Extension Directory Layout

```
extension/src/
├── extension.ts              # Activation entry point
├── bridge/
│   ├── client.ts             # BridgeClient: HTTP client to Python backend
│   ├── websocket.ts          # BridgeWebSocket: real-time event stream
│   └── autoSetup.ts          # Auto-start bridge on activation
├── commands/
│   └── index.ts              # All command registrations
├── panels/
│   └── dashboardPanel.ts     # WebviewPanel dashboard
├── providers/
│   ├── serversTreeProvider.ts
│   ├── instancesTreeProvider.ts
│   ├── metricsTreeProvider.ts
│   └── marketplaceTreeProvider.ts
└── utils/
    └── statusBar.ts          # StatusBarManager
```

### 8.2 Python Backend Layout

```
src/mcp_bridge/
├── __init__.py
├── server.py                 # FastMCP server entry + main()
├── meta_tools.py             # MCP tool definitions exposed to agents
├── api/
│   └── management.py         # Starlette REST API for extension
├── config/
│   └── settings.py           # Pydantic Settings (env-based config)
├── credentials/
│   └── store.py              # Credential storage
├── instances/
│   ├── manager.py            # Instance lifecycle management
│   └── connector.py          # Subprocess MCP server connector
├── metrics/
│   └── collector.py          # Call metrics + aiosqlite persistence
├── openapi/
│   ├── models.py, parser.py, executor.py, tools.py
│   └── __init__.py           # OpenAPI spec → MCP tool adapter
├── platforms/
│   ├── platform_tools.py     # Enterprise platform MCP tools
│   ├── websocket_adapter.py  # WebSocket execution adapter
│   ├── auth/
│   │   └── token_manager.py  # JWT token management
│   ├── models/
│   │   ├── workflow.py       # Workflow data models
│   │   └── messages.py       # WebSocket message models
│   └── workflow/
│       └── executor.py       # Workflow chain executor
└── registry/
    ├── catalog.py            # YAML catalog loader
    └── models.py             # Server registry data models
```

### 8.3 Naming Conventions

| Element | Convention | Example |
|---------|-----------|---------|
| TypeScript files | `camelCase.ts` | `dashboardPanel.ts` |
| TypeScript classes | `PascalCase` | `DashboardPanel` |
| TypeScript private members | `_camelCase` | `_client`, `_refreshInterval` |
| Python files | `snake_case.py` | `meta_tools.py` |
| Python classes | `PascalCase` | `BridgeSettings` |
| VS Code view IDs | `mcpGrid.viewName` | `mcpGrid.servers` |
| VS Code commands | `mcpGrid.commandName` | `mcpGrid.openDashboard` |
| CSS classes | `kebab-case` | `metric-card`, `badge-green` |

### 8.4 Build System

**Extension (webpack):**

```bash
npm run compile    # Dev build
npm run watch      # Watch mode
npm run package    # Production build
npm run lint       # ESLint
```

- Entry: `src/extension.ts` → `dist/extension.js`
- Target: Node.js (`commonjs2`)
- Externals: `vscode`, `bufferutil`, `utf-8-validate`

**Python (Hatchling):**

```bash
pip install -e ".[dev]"    # Editable install with dev deps
mcp-grid                   # Run the MCP server
ruff check .               # Lint
pytest                     # Test
```

### 8.5 Extension Settings

These user-facing settings are defined in `package.json`:

| Setting | Default | Purpose |
|---------|---------|---------|
| `mcpGrid.bridgeHost` | `127.0.0.1` | Python bridge host |
| `mcpGrid.bridgePort` | `19420` | Python bridge port |
| `mcpGrid.autoStart` | `true` | Auto-start bridge on activation |
| `mcpGrid.pollingInterval` | `5000` | Status polling interval (ms) |
| `mcpGrid.pythonPath` | `python3` | Python interpreter path |

### 8.6 Rules

- New TreeDataProviders go in `extension/src/providers/`.
- New WebviewPanels go in `extension/src/panels/`.
- New commands MUST be registered in `extension/src/commands/index.ts`.
- New MCP tools (Python) go in `src/mcp_bridge/meta_tools.py` or a dedicated module.
- YAML catalog entries go in `mcp-grid-ws/catalog/` named by category.
- Python config follows `pydantic-settings` with `MCP_BRIDGE_` env prefix.

---

## 9. Figma-to-Code Integration Notes

When implementing designs from Figma for this project:

1. **There is no web frontend.** All UI is either VS Code TreeViews or WebviewPanel HTML.
2. **Map Figma colors** to the VS Code theme variable closest in purpose (see Token Definitions above). Do not use Figma's exact hex values.
3. **Map Figma typography** to `--vscode-font-family` / `--vscode-font-size`. Do not import custom fonts.
4. **Map Figma icons** to the nearest VS Code ThemeIcon/Codicon. Only create custom SVGs for branding (activity bar).
5. **Map Figma spacing** to the existing spacing values (multiples of 4px). Use CSS Grid or Flexbox for layout.
6. **Map Figma buttons** to `.btn-primary` (theme-aware) or `.btn-danger`. No other button styles.
7. **Map Figma badges/chips** to `.badge` + `.badge-green` / `.badge-red` / `.badge-yellow`.
8. **Map Figma tables** to basic HTML `<table>` with the existing table styles.
9. **All dashboard HTML** is a template literal string in TypeScript — not a separate HTML file.

---

## 10. Quick Reference

### Adding a New Dashboard Section

```typescript
// In dashboardPanel.ts _getHtml() method:
const newSectionHtml = `
  <h2>Section Title</h2>
  <div class="metrics-grid">
    <div class="metric-card">
      <div class="metric-value">${value}</div>
      <div class="metric-label">Label</div>
    </div>
  </div>
`;
```

### Adding a New Tree View

1. Create provider in `extension/src/providers/newProvider.ts`
2. Register in `extension.ts`: `vscode.window.registerTreeDataProvider("mcpGrid.newView", provider)`
3. Add view to `package.json` under `contributes.views`

### Adding a New Command

1. Add to `package.json` under `contributes.commands`
2. Register in `extension/src/commands/index.ts`
3. Use `mcpGrid.` prefix for the command ID

### Adding a New Badge Color

1. Define background + foreground hex pair
2. Add CSS class `.badge-{name}` in dashboard style block
3. Document in Token Definitions table above
