Files
mcp-hal9002/README.md
T

5.1 KiB

mcp-hal9002

mcp-hal9002 logo

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:

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 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