# MCPBundles Desktop Proxy - Message Protocol

## Overview

The proxy is a **passive, message-driven agent** that responds to commands from the backend through a WebSocket tunnel. All intelligence lives in the web app.

## Message Types

### 1. Service Discovery

**Web → Proxy:**
```json
{
  "type": "service_discovery",
  "ports": [5432, 5433, 6379, 3306, 27017, 9200, 9223]
}
```

**Proxy → Web:**
```json
{
  "type": "discovery_result",
  "ports": {
    "5432": {
      "available": true,
      "type": "postgresql"
    },
    "5433": {
      "available": true,
      "type": "postgresql"
    },
    "6379": {
      "available": false,
      "type": null
    }
  }
}
```

**Action:** Proxy scans specified ports on localhost and reports which are listening.

---

### 2. Service Verification

**Web → Proxy:**
```json
{
  "type": "service_verify",
  "target": "localhost:5432"
}
```

**Proxy → Web:**
```json
{
  "type": "verify_result",
  "verified": true,
  "target": "localhost:5432",
  "type": "postgresql"
}
```

Or if failed:
```json
{
  "type": "verify_result",
  "verified": false,
  "target": "localhost:5432",
  "error": "Connection refused"
}
```

**Action:** Proxy attempts actual connection to verify service is reachable.

---

### 3. Start Service

**Web → Proxy:**
```json
{
  "type": "service_start",
  "service": "browser",
  "config": {
    "headless": false,
    "port": 9223
  }
}
```

**Proxy → Web:**
```json
{
  "type": "service_started",
  "started": true,
  "service": "browser",
  "port": 9223,
  "mode": "visible"
}
```

Or if failed:
```json
{
  "type": "service_started",
  "started": false,
  "error": "Playwright not installed. Install with: pip install mcpbundles-proxy[browser]"
}
```

**Action:** Proxy starts the requested service (currently only browser supported).

---

### 4. Stop Service

**Web → Proxy:**
```json
{
  "type": "service_stop",
  "service": "browser"
}
```

**Proxy → Web:**
```json
{
  "type": "service_stopped",
  "stopped": true,
  "service": "browser"
}
```

**Action:** Proxy stops the running service.

---

### 5. Update Service Configuration

**Web → Proxy:**
```json
{
  "type": "service_update",
  "service": "browser",
  "config": {
    "headless": true
  }
}
```

**Proxy → Web:**
```json
{
  "type": "service_updated",
  "updated": true,
  "service": "browser",
  "mode": "hidden"
}
```

**Action:** Proxy updates service configuration (may restart service if needed).

---

### 6. HTTP Request Forwarding (Existing)

**Web → Proxy:**
```json
{
  "type": "http_request",
  "request_id": "req_abc123",
  "method": "POST",
  "path": "/api/users",
  "target": "localhost:5432",
  "headers": {"Content-Type": "application/json"},
  "body": "{\"name\": \"John\"}"
}
```

**Proxy → Web:**
```json
{
  "type": "http_response",
  "request_id": "req_abc123",
  "status": 200,
  "headers": {"Content-Type": "application/json"},
  "body": "{\"id\": 123, \"name\": \"John\"}"
}
```

**Action:** Proxy forwards HTTP request to localhost service and returns response.

---

### 7. Status Request

**Web → Proxy:**
```json
{
  "type": "status_request"
}
```

**Proxy → Web:**
```json
{
  "type": "status_update",
  "services": {
    "browser": {
      "enabled": true,
      "headless": false,
      "port": 9223,
      "mode": "visible"
    }
  }
}
```

**Action:** Proxy reports current status of all services.

---

## Service Types Supported

### Browser Service
- **Port:** 9223 (default)
- **States:** Started/Stopped
- **Modes:** Visible (headed) / Hidden (headless)
- **Requires:** `pip install mcpbundles-proxy[browser]` + `playwright install chromium`

### Database Services (Discovery Only)
Proxy can discover and verify, but doesn't manage lifecycle:
- PostgreSQL (5432, 5433)
- MySQL (3306)
- Redis (6379)
- MongoDB (27017)
- Elasticsearch (9200)

---

## Port Detection

Proxy automatically detects service type by port:

| Port | Service Type |
|------|-------------|
| 5432, 5433 | postgresql |
| 3306 | mysql |
| 6379 | redis |
| 27017 | mongodb |
| 9200 | elasticsearch |
| 9223 | browser |
| other | unknown |

---

## Error Handling

All operations return error information if they fail:

```json
{
  "type": "..._result",
  "error": "Human-readable error message"
}
```

Common errors:
- "Connection timeout"
- "Connection refused"
- "Service manager not available"
- "Playwright not installed..."
- "Unknown service: {name}"

---

## User Experience Flow

1. **User goes to MCPBundles.com → Local Services**
2. **Web sends:** `service_discovery` with common ports
3. **Proxy responds:** Which ports are listening
4. **Web UI shows:** "PostgreSQL found on localhost:5432"
5. **User clicks [+ Add Service]**
6. **Web sends:** `service_verify` for localhost:5432
7. **Proxy responds:** Verified ✓
8. **Web automatically creates Provider** with base_url
9. **Done - User never touched terminal**

---

## Browser Service Flow

1. **User clicks [Start Browser] with "Visible" mode**
2. **Web sends:** `service_start` with `headless: false`
3. **Proxy starts browser** - Window pops up on user's screen
4. **Proxy responds:** Started ✓, mode: visible
5. **Web UI updates:** "✅ Browser running (visible mode)"
6. **User toggles to "Hidden"**
7. **Web sends:** `service_update` with `headless: true`
8. **Proxy restarts browser** in headless mode
9. **Browser window disappears**

---

## Implementation Notes

### Proxy Side (Local)
- Completely passive - only responds to messages
- No configuration files needed
- No UI - pure message handler
- All logic in service_manager.py and tunnel.py
- **Never needs updates for new features** - just responds to new messages

### Backend Side (Cloud)
- Active intelligence - decides what to discover/verify/start
- Maintains state of user's services
- Auto-creates Providers when services verified
- Shows UI for service management
- **All new features added here**

---

## Adding New Services

To add support for a new service (e.g., Redis management):

**Proxy:** No changes needed - already handles start/stop/update for any service name

**Backend:**
1. Add UI for Redis service
2. Send appropriate messages:
   - `service_start` with `service: "redis"`
   - `service_stop` with `service: "redis"`

**That's it.** The protocol is generic - proxy just executes commands.

---

## Security

- **Discovery:** Only scans localhost, never remote hosts
- **Verification:** Only connects to localhost
- **HTTP Forwarding:** Validates target starts with "localhost:" or "127.0.0.1:"
- **Services:** Browser is sandboxed, only accesses what user's browser can access

---

## Future Extensions

Easy to add without proxy changes:
- `service_restart` - Restart a service
- `service_logs` - Get logs from a service
- `service_health` - Health check endpoint
- `batch_discover` - Discover multiple ranges at once

Just send new message types - proxy handles them.

