Rename project to mcp-hal9002
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# mcp-hal9002
|
||||
|
||||

|
||||
|
||||
`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
|
||||
Reference in New Issue
Block a user