Skip to main content
Glama
dominick253

roku-debug-mcp

by dominick253
README.md
# roku-debug-mcp

[![CI](https://github.com/dominick253/roku-debug-mcp/actions/workflows/ci.yaml/badge.svg)](https://github.com/dominick253/roku-debug-mcp/actions)
[![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
[![License](https://img.shields.io/badge/license-Apache%202.0-green.svg)](https://www.apache.org/licenses/LICENSE-2.0)
[![MCP](https://img.shields.io/badge/MCP-stdio-8A2BE2.svg)](https://modelcontextprotocol.io/)

**MCP server giving AI agents the full VS Code Roku debug experience.**

Exposes Roku's BrightScript debugging capabilities as MCP tools so AI agents can
read logs, inspect the scene graph, step through code, read variables, and set
breakpoints — the same info a developer sees in the VS Code Roku extension.

## Architecture

```mermaid
graph TB
    subgraph "AI Agent (Hermes, VS Code, etc.)"
        MCP[<b>MCP Client</b><br/>stdio JSON-RPC]
    end

    subgraph "roku-debug-mcp (MCP Server)"
        Server[<b>MCP Server</b><br/>21 tools]
        Config[<b>Config</b><br/>ROKU_* env vars]
        Server --> Config
    end

    subgraph "Roku Device"
        direction LR

        subgraph "Port 80 — HTTP"
            Installer[<b>Sideloader</b><br/>Digest auth<br/>Expect: 100-continue]
        end

        subgraph "Port 8060 — ECP"
            ECP[<b>ECP Client</b><br/>Device info<br/>Scene graph<br/>Postback/keys]
        end

        subgraph "Port 8081 — Binary Debug"
            Debug[<b>Debug Client</b><br/>Binary protocol<br/>BSDBG magic]
        end

        subgraph "Port 8085 — Telnet"
            Console[<b>Text Console</b><br/>Fallback logs]
        end
    end

    MCP --> Server
    Server --> Installer
    Server --> ECP
    Server --> Debug
    Server --> Console
```

### Protocol Layers

| Port | Protocol | Auth | Purpose |
|------|----------|------|---------|
| 80 | HTTP | Digest + Expect: 100-continue | Channel sideloading |
| 8060 | ECP HTTP | None | Device info, scene graph, screenshots |
| 8081 | Binary | None | **Primary debug protocol** (VS Code uses this) |
| 8085 | Telnet | None | Text console (fallback) |

### Binary Debug Protocol (Port 8081)

```mermaid
sequenceDiagram
    participant C as Client (roku-debug-mcp)
    participant R as Roku Device (port 8081)

    C->>R: Handshake<br/>[magic(8)][protocol_version(4)]
    R-->>C: [magic(8)][protocol_version(4)][packet_len(4)][revision]

    Note over C,R: Request/Response Format:<br/>[packet_length(4)][request_id(4)][cmd_code(4)][payload]

    C->>R: GET_THREADS (cmd=3)
    R-->>C: THREADS response

    C->>R: STACKTRACE (cmd=4, thread_index)
    R-->>C: Stack frames

    C->>R: ADD_BREAKPOINTS (cmd=7)
    R-->>C: Confirmation

    Note over C,R: Update notifications (request_id=0):<br/>CONNECT_IO_PORT, ALL_THREADS_STOPPED, etc.
```

**Handshake Magic:** `0x0067756265647362` (`b"bsdebug\0"` little-endian)

### Sideloading Flow (Port 80)

```mermaid
sequenceDiagram
    participant C as Client
    participant R as Roku (port 80)

    C->>R: POST /plugin_package (Expect: 100-continue)
    R-->>C: 401 Unauthorized (WWW-Authenticate: Digest)
    C->>C: Compute digest hash
    C->>R: POST /plugin_package (Authorization: Digest)
    R-->>C: 100 Continue
    C->>R: [ZIP payload]
    R-->>C: 200 OK [chunked response with Dev Kit HTML]
```

## What AI Can Do With This

- **Read device info** — model, version, app currently running
- **Inspect scene graph** — the full node hierarchy of the running app
- **Read console logs** — stdout from the running BrightScript channel
- **List threads** — see all execution threads and their stop states
- **Read stack traces** — frame-by-frame call stack for any stopped thread
- **Inspect variables** — locals, globals, and scene graph component state
- **Execute code** — run arbitrary BrightScript in a stopped frame
- **Manage breakpoints** — add, list, remove breakpoints by file/line
- **Step execution** — step over, step into, step out, or continue
- **Sideload channels** — upload and install test channels with remote debug

## Quick Start

### 1. Install

```bash
cd /home/dom/src/roku-debug-mcp
pip install -e .
```

### 2. Configure Environment

```bash
export ROKU_DEVICE_IP=192.168.1.10      # Roku device IP
export ROKU_DEV_USER=rokudev            # Dev channel username
export ROKU_DEV_PASSWORD=your-password  # Dev channel password
```

### 3. Register in Hermes

Add to `~/.hermes/mcp-servers.json`:

```json
{
  "roku-debug-mcp": {
    "command": "roku-debug-mcp",
    "args": []
  }
}
```

### 4. Use in a Hermes Session

The AI agent will now have access to 21 new tools:

```python
roku_device_info()
roku_scene_graph()
roku_debug_threads()
roku_debug_stacktrace(thread_index=0)
roku_debug_variables(thread_index=0, frame_index=0)
roku_debug_execute(thread_index=0, frame_index=0, code="x = 42")
roku_debug_breakpoints_add(breakpoints=[{...}])
roku_debug_console_output()
```

## Available Tools

### Device / UI Tools (ECP — port 8060)

| Tool | Description |
|------|-------------|
| `roku_device_info` | Device model, version, etc. |
| `roku_current_app` | Currently running app |
| `roku_scene_graph` | Full scene graph node hierarchy |
| `roku_postback` | Send postback to channel |
| `roku_launch_uri` | Launch a URI |
| `roku_key` | Send remote control key |
| `roku_screenshot` | Capture screen image |

### Debug Tools (Binary Protocol — port 8081)

| Tool | Description |
|------|-------------|
| `roku_debug_threads` | List all threads |
| `roku_debug_stacktrace` | Get stack frames |
| `roku_debug_variables` | Read variables in a frame |
| `roku_debug_execute` | Run BrightScript code |
| `roku_debug_breakpoints_add` | Add breakpoints |
| `roku_debug_breakpoints_list` | List active breakpoints |
| `roku_debug_breakpoints_remove` | Remove specific breakpoints |
| `roku_debug_breakpoints_remove_all` | Clear all breakpoints |
| `roku_debug_continue` | Resume execution |
| `roku_debug_step` | Step execution |
| `roku_debug_stop` | Pause execution |
| `roku_debug_console_output` | Get stdout lines |
| `roku_debug_protocol_info` | Debug protocol version |

### Installer Tools (HTTP — port 80)

| Tool | Description |
|------|-------------|
| `roku_install` | Sideload a channel ZIP |
| `roku_launch_remote_debug` | Launch with remote debugging enabled |

## Testing

### Unit Tests (Mock Roku Server)

```bash
# Run all tests (uses mock server on ephemeral ports)
pytest tests/ -v

# Mock server runs automatically via conftest fixtures
# No manual setup required
```

### Integration Tests (Real Roku Device)

```bash
# Requires env vars set
ROKU_DEV_IP=10.71.71.151 \
ROKU_DEV_PASSWORD=your-password \
pytest tests/test_integration_real_device.py -v
```

### CI/CD

- **Unit tests** run on GitHub Actions Ubuntu runners
- **Integration tests** run on self-hosted runner (10.71.71.90) with LAN access to real Roku

## Project Structure

```
src/rokumcp/
  config.py          # Environment-based configuration
  protocol.py        # Binary protocol constants and Stream I/O
  debug_client.py    # Synchronous binary debug client (port 8081)
  text_console.py    # Telnet text console client (port 8085)
  ecp.py             # ECP HTTP client (port 8060)
  installer.py       # HTTP Digest-auth sideloader (port 80)
  server.py          # MCP server entrypoint — 21 tools

tests/
  conftest.py                  # Pytest fixtures (mock server setup)
  mock_roku_server.py          # Mock Roku device simulator
  test_protocol.py             # Stream round-trips, ProtocolVersion
  test_config.py               # Config defaults, from_env
  test_ecp.py                  # ECP HTTP client
  test_text_console.py         # Telnet console client
  test_installer.py            # Digest auth + multipart
  test_debug_client.py         # Full E2E vs mock binary server
  test_integration_real_device.py  # Real device (gated on env vars)
  fixtures/                    # Test channel ZIP fixtures
```

## Protocol Reference

Implementation derived from Roku's official reference:

- [rokudev/remote-debugger](https://github.com/rokudev/remote-debugger)
- [Roku Remote Debugging Protocol](https://developer.roku.com/docs/developer/roku-platform-fundamentals/developer-guide/brightscript-apps/debugging-and-testing/remote-debugging-protocol.md)

See `AGENTS.md` for the full protocol specification and wire formats.

## Development

### Debugging the Protocol

```bash
# Run mock server manually
python tests/mock_roku_server.py

# Test specific protocol interaction
ROKU_DEVICE_IP=127.0.0.1 ROKU_DEBUG_PORT=8081 python -m rokumcp.server
```

### Building

```bash
pip install -e .
roku-debug-mcp  # runs MCP server over stdio
```

## License

Apache-2.0

TDQS

A3.5/5.0

Scored across 21 tools

Disambiguation4/5

Most tools are clearly separated by domain (device control, debugging, breakpoints), but there are several debugger control tools (continue, step, stop) and multiple breakpoint tools that could be confused if descriptions were skimmed. The overlap is mild and the descriptions are specific enough to disambiguate in most cases.

Naming Consistency4/5

The tool names consistently use a 'roku_' prefix followed by a category and action (e.g., roku_debug_breakpoints_add, roku_debug_variables, roku_key). There are some minor inconsistencies like roku_sideload_and_connect versus the more structured debugger tools, and roku_postback is less descriptive, but the overall pattern is predictable.

Tool Count4/5

21 tools is on the high end but each tool serves a distinct purpose in the Roku debugging workflow. The count is justified given the breadth: device info, app control, screenshot, postback, and a full debugger suite. It feels slightly heavy but well-scoped for the domain.

Completeness5/5

The tool surface covers the full Roku development/debugging lifecycle: device discovery, app launching, remote control, scene graph inspection, breakpoint management, execution control, stack/variable inspection, and console output. There are no obvious missing operations for the stated debugging purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues