5.1 KiB
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.pyapplicazione GTK4/VTE con un controllo locale via socket Unixsrc/gnome_vte_mcp/server.pyMCP server basato suFastMCPche parla con la GUIsrc/gnome_vte_mcp/control.pyprotocollo client per il socket locale
Il server MCP lancia automaticamente la GUI se non e gia in esecuzione.
Uso con uvx
Entrypoint principali:
mcp-hal9002avvia il server MCPmcp-hal9002-guiavvia la GUI GTK/VTE
Esempi locali dal checkout:
uvx --from . mcp-hal9002
uvx --from . mcp-hal9002-gui
Esempio da repository Git:
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
PYTHONPATH=src python3 -m gnome_vte_mcp.gui
Per usare un socket custom:
PYTHONPATH=src python3 -m gnome_vte_mcp.gui --socket /tmp/mcp-hal9002-demo.sock
Avvio del server MCP
PYTHONPATH=src python3 -m gnome_vte_mcp.server
Variabile opzionale:
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 renderizzatotarget="tab"cattura solo il widgetVte.Terminaldella tab attiva o della tab indicata contab_id, escludendo header bar e tab bartarget="tab-container"cattura il container GTK della tab, utile se serve includere il bordo o eventuali scrollbarpathpermette di scegliere il file PNG di destinazionediagnostic_overlay=Trueannota lo screenshot con una griglia e i bounds del target perwindow,tabetab-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:
titleesplicito, 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
- aggiungere eventi di output incrementale e subscription
- introdurre persistenza dello stato tab/sessioni
- migliorare il modello UI con veri tab drag-and-drop e split view
- aggiungere policy locali per limitare i comandi consentiti
- usare gli screenshot e i sidecar JSON per confronti UI before/after automatizzabili