155 lines
5.1 KiB
Markdown
155 lines
5.1 KiB
Markdown
# mcp-hal9002
|
|
|
|
<p align="center">
|
|
<img src="assets/mcp-hal9002-logo.svg" width="200" alt="mcp-hal9002 logo">
|
|
</p>
|
|
|
|
`mcp-hal9002` e un terminal workspace GTK4 + VTE controllabile via MCP, con GUI locale, control plane Unix socket e strumenti per screenshot/debug UI.
|
|
|
|
Il nome definitivo del progetto, del pacchetto distribuibile e delle CLI e allineato alla cartella root: `mcp-hal9002`.
|
|
|
|
## Obiettivo
|
|
|
|
|
|
Il progetto evita di dipendere da API non ufficiali di GNOME Terminal. Invece espone direttamente una GUI propria, che supporta:
|
|
|
|
- apertura tab
|
|
- elenco tab
|
|
- focus tab
|
|
- invio comandi a una shell esistente
|
|
- lettura dello scrollback della tab
|
|
- screenshot della finestra, del contenuto VTE della tab, o del container della tab per debug UI/UX
|
|
- chiusura tab
|
|
|
|
## Architettura
|
|
|
|
- `src/gnome_vte_mcp/gui.py`
|
|
applicazione GTK4/VTE con un controllo locale via socket Unix
|
|
- `src/gnome_vte_mcp/server.py`
|
|
MCP server basato su `FastMCP` che parla con la GUI
|
|
- `src/gnome_vte_mcp/control.py`
|
|
protocollo client per il socket locale
|
|
|
|
Il server MCP lancia automaticamente la GUI se non e gia in esecuzione.
|
|
|
|
## Uso con uvx
|
|
|
|
Entrypoint principali:
|
|
|
|
- `mcp-hal9002` avvia il server MCP
|
|
- `mcp-hal9002-gui` avvia la GUI GTK/VTE
|
|
|
|
Esempi locali dal checkout:
|
|
|
|
```bash
|
|
uvx --from . mcp-hal9002
|
|
uvx --from . mcp-hal9002-gui
|
|
```
|
|
|
|
Esempio da repository Git:
|
|
|
|
```bash
|
|
uvx --from git+https://git.enne2.net/enne2/mcp-hal9002.git mcp-hal9002
|
|
```
|
|
|
|
## Requisiti
|
|
|
|
Nel sistema devono essere disponibili:
|
|
|
|
- Python 3.12+
|
|
- PyGObject (`gi`)
|
|
- GTK4
|
|
- VTE con binding GI (`Vte 3.91`)
|
|
- package Python `mcp`
|
|
|
|
In questa macchina il runtime necessario risulta disponibile.
|
|
|
|
## Avvio locale della GUI
|
|
|
|
```bash
|
|
PYTHONPATH=src python3 -m gnome_vte_mcp.gui
|
|
```
|
|
|
|
Per usare un socket custom:
|
|
|
|
```bash
|
|
PYTHONPATH=src python3 -m gnome_vte_mcp.gui --socket /tmp/mcp-hal9002-demo.sock
|
|
```
|
|
|
|
## Avvio del server MCP
|
|
|
|
```bash
|
|
PYTHONPATH=src python3 -m gnome_vte_mcp.server
|
|
```
|
|
|
|
Variabile opzionale:
|
|
|
|
```bash
|
|
export MCP_HAL9002_SOCKET=/tmp/mcp-hal9002-demo.sock
|
|
```
|
|
|
|
La variabile legacy `GNOME_VTE_MCP_SOCKET` resta accettata per compatibilita.
|
|
|
|
## Tool MCP disponibili
|
|
|
|
- `open_tab(title=None, cwd=None, command=None)`
|
|
- `list_tabs()`
|
|
- `focus_tab(tab_id)`
|
|
- `exec_command(tab_id, command, newline=True)`
|
|
- `read_tab(tab_id, last_n_lines=200)`
|
|
- `capture_screenshot(target="window", tab_id=None, path=None, diagnostic_overlay=False)`
|
|
- `close_tab(tab_id)`
|
|
|
|
Per `capture_screenshot`:
|
|
|
|
- `target="window"` prova a catturare l'intera finestra, inclusa la titlebar GTK; se la piattaforma non lo consente ripiega sul contenuto renderizzato
|
|
- `target="tab"` cattura solo il widget `Vte.Terminal` della tab attiva o della tab indicata con `tab_id`, escludendo header bar e tab bar
|
|
- `target="tab-container"` cattura il container GTK della tab, utile se serve includere il bordo o eventuali scrollbar
|
|
- `path` permette di scegliere il file PNG di destinazione
|
|
- `diagnostic_overlay=True` annota lo screenshot con una griglia e i bounds del target per `window`, `tab` e `tab-container`
|
|
|
|
Il tool restituisce contenuto MCP di tipo testo + immagine, seguendo lo stesso approccio di `local-image-mcp`, quindi l'agente puo ispezionare direttamente lo screenshot senza passare da un path locale separato.
|
|
|
|
Per ogni screenshot viene salvato anche un file JSON sidecar con metadati di debug UI, tra cui:
|
|
|
|
- widget target effettivo
|
|
- allocazione del widget rispetto alla finestra
|
|
- renderer GSK usato per la cattura
|
|
- dettagli di superficie e scala
|
|
- stato dell'overlay diagnostico richiesto/applicato
|
|
|
|
## Primo avvio e onboarding
|
|
|
|
La prima tab mostra un piccolo pannello di onboarding centrato sopra il terminale, con un riepilogo delle azioni MCP disponibili e del workspace corrente.
|
|
|
|
Il pannello sparisce automaticamente:
|
|
|
|
- alla prima pressione di tasto dentro il terminale
|
|
- al primo `exec_command(...)` inviato via MCP
|
|
|
|
## Titoli tab dinamici
|
|
|
|
I titoli delle tab sono derivati in modo compatto da:
|
|
|
|
- `title` esplicito, se fornito e non generico
|
|
- comando iniziale o ultimo comando eseguito
|
|
- `cwd`, quando non c'e un comando significativo
|
|
|
|
Questo rende il `StackSwitcher` piu compatto e piu utile quando ci sono piu tab aperte.
|
|
|
|
## Limiti attuali
|
|
|
|
- non salva ancora layout o sessioni persistenti
|
|
- non gestisce ancora rename tab automatico da processo o cwd
|
|
- il canale di controllo locale non ha ancora autenticazione aggiuntiva oltre ai permessi del socket Unix
|
|
- il recupero testo usa un transcript locale della shell, ma non implementa ancora stream incrementale o eventi
|
|
- la cattura screenshot dipende dal fatto che il widget sia già renderizzato nella sessione grafica corrente
|
|
- se una GUI gia avviata resta in esecuzione, i test del control plane continueranno a usare quel processo: dopo modifiche a screenshot o titlebar conviene riavviare la GUI prima di ritestare
|
|
|
|
## Prossimi passi naturali
|
|
|
|
1. aggiungere eventi di output incrementale e subscription
|
|
2. introdurre persistenza dello stato tab/sessioni
|
|
3. migliorare il modello UI con veri tab drag-and-drop e split view
|
|
4. aggiungere policy locali per limitare i comandi consentiti
|
|
5. usare gli screenshot e i sidecar JSON per confronti UI before/after automatizzabili |