Hermes Terminal Dashboard
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Hermes Terminal DashboardDisplay today's task list on the monitor"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Hermes Terminal Dashboard
╔════════════════════════════════════════════════════════════════╗
║ 1 0 1 0 1 0 1 1 0 0 0 1 1 0 1 ║
║ ║
║ ███╗ ███╗ █████╗ ████████╗ ██████╗ ██╗ ██╗ ██╗ ║
║ ████╗ ████║ ██╔══██╗ ╚══██╔══╝ ██╔══██╗ ██║ ╚██╗██╔╝ ║
║ ██╔████╔██║ ███████║ ██║ ██████╔╝ ██║ ╚███╔╝ ║
║ ██║╚██╔╝██║ ██╔══██║ ██║ ██╔══██╗ ██║ ██╔██╗ ║
║ ██║ ╚═╝ ██║ ██║ ██║ ██║ ██║ ██║ ██║ ██╔╝ ██╗ ║
║ ║
║ ██╗ ██╗ ██╗ ║
║ ██║ ██║ ██║ ACCESS_GRANTED ║
║ ██║ ██║ ██║ STATUS::ACTIVE ║
║ ╚██████╔╝ ██║ MATRIX_UI::READY ║
║ ╚═════╝ ╚═╝ ║
║ ║
║ [ booting interface ] [ neural display ] [ secure shell ] ║
╚════════════════════════════════════════════════════════════════╝
Hermes Terminal Dashboard · MatrixUI v1.7.0Um plugin MCP (Model Context Protocol) que dá a um agente de IA (Hermes) a capacidade de exibir informações visuais em um monitor físico ligado a um dispositivo Linux em modo CLI/terminal — sem X11/Wayland (ex.: Orange Pi com Ubuntu Server).
An MCP plugin that lets an AI agent draw rich, structured content on a physical monitor attached to a headless Linux box (e.g. an Orange Pi running Ubuntu Server in pure TTY mode).
🇧🇷 Português
O que é
O projeto tem dois processos desacoplados que conversam por um socket TCP local (asyncio), evitando problemas de concorrência e de permissão de arquivos:
┌──────────┐ stdio ┌───────────────┐ TCP NDJSON ┌────────────────┐ HDMI
│ Hermes │ ───────▶ │ mcp_server.py │ ────────────▶ │ tui_display.py │ ─────▶ Monitor TTY1
│ (IA) │ │ (ferramenta) │ localhost:9999│ (Textual) │
└──────────┘ └───────────────┘ └────────────────┘tui_display.py— Interface visual (Textual + Rich) rodando em primeiro plano no monitor. Abre um servidor TCP interno (asyncio) na porta9999para receber comandos. Layout estilo cyberpunk/hacker: header com relógio e status, painel principal que renderiza Markdown (títulos, listas, tabelas, código) e uma barra lateral de log de atividades.mcp_server.py— Servidor MCP (SDK oficialmcp, transporte stdio). Expõe as ferramentasatualizar_monitorelimpar_monitorpara a IA. Conecta no socket da TUI, envia o payload JSON e retorna sucesso/erro para o agente.
Protocolo
Mensagens em JSON delimitado por newline (NDJSON) — uma linha por mensagem. Dois formatos, ambos suportados:
{"conteudo": "# Título\n- item", "log": "Atualizando...", "acao": "update"}
{"tipo": "previsao_tempo", "dados": {"local": "SP", "dias": [...]}, "log": "..."}Campo | Descrição |
| Renderizador a usar. Default |
| Markdown a renderizar (usado quando |
| Objeto estruturado, específico de cada skill (quando |
| Linha adicionada ao log lateral (opcional). |
|
|
Compatibilidade: sem o campo
tipo, o comportamento é idêntico ao original (renderizaconteudocomo Markdown).
Skills disponíveis
Cada skill é uma ferramenta MCP dedicada que o agente Hermes pode invocar. Os dados são fornecidos pelo agente (o MCP não acessa rede); a TUI apenas os desenha em estilo ncurses.
Ferramenta MCP |
| O que renderiza |
|
| Cards de previsão do tempo com arte ASCII (wttr.in) |
|
| Tabela rica com bordas e cores |
|
| Gráfico de barras (plotext, com fallback unicode) |
|
| Gauges/barras coloridas por limiar (CPU, RAM, KPIs) |
|
| Banner com texto gigante (pyfiglet) |
|
| QR Code em ASCII |
|
| Checklist com ✓/☐ e prioridades |
|
| Lista de notícias com título, resumo e categorias |
|
| Partidas com placar, status ao vivo e destaques |
|
| Markdown livre (texto genérico) |
|
| Tela inicial: logo + cor + mensagem customizados |
| — | Restaura a tela de boas-vindas padrão com logo |
Exemplos de payload para teste via nc (uma linha cada):
# Previsão do tempo
printf '{"tipo":"previsao_tempo","dados":{"local":"São Paulo","dias":[{"dia":"Hoje","condicao":"chuva","temp_max":24,"temp_min":17,"descricao":"Pancadas","umidade":80,"vento":"15 km/h"},{"dia":"Ter","condicao":"sol","temp_max":28,"temp_min":18,"descricao":"Ensolarado"}]}}\n' | nc 127.0.0.1 9999
# Tabela
printf '{"tipo":"tabela","dados":{"titulo":"Vendas","colunas":["Produto","Qtd"],"linhas":[["Café","12"],["Pão","30"]]}}\n' | nc 127.0.0.1 9999
# Gráfico de barras
printf '{"tipo":"grafico","dados":{"titulo":"Temp","unidade":"°C","series":[{"label":"Seg","valor":23},{"label":"Ter","valor":27},{"label":"Qua","valor":19}]}}\n' | nc 127.0.0.1 9999
# Métricas / gauges
printf '{"tipo":"metricas","dados":{"titulo":"Sistema","metricas":[{"label":"CPU","valor":42,"unidade":"%%"},{"label":"RAM","valor":6,"max":8,"unidade":"GB"},{"label":"Disco","valor":91,"unidade":"%%"}]}}\n' | nc 127.0.0.1 9999
# Alerta / banner
printf '{"tipo":"alerta","dados":{"texto":"BACKUP OK","nivel":"info","subtitulo":"concluído às 03:00"}}\n' | nc 127.0.0.1 9999
# QR Code
printf '{"tipo":"qrcode","dados":{"conteudo":"https://exemplo.com","legenda":"Aponte a câmera"}}\n' | nc 127.0.0.1 9999
# Tarefas
printf '{"tipo":"tarefas","dados":{"titulo":"Hoje","itens":[{"texto":"Comprar pão","feito":false,"prioridade":"alta"},{"texto":"Pagar conta","feito":true}]}}\n' | nc 127.0.0.1 9999
# Notícias
printf '{"tipo":"noticias","dados":{"titulo":"Últimas Notícias","fonte":"G1","itens":[{"titulo":"Selic mantida em 13,75%","resumo":"O Copom decidiu manter a taxa de juros.","categoria":"Economia","tempo":"há 30 min"},{"titulo":"Seleção convoca 26 jogadores","resumo":"Lista com surpresas no ataque.","categoria":"Esportes"}]}}\n' | nc 127.0.0.1 9999
# Jogos de futebol
printf '{"tipo":"jogos_futebol","dados":{"titulo":"Rodada 15 — Brasileirão","data":"13/06/2026","jogos":[{"time_casa":"Flamengo","time_fora":"Palmeiras","placar_casa":2,"placar_fora":1,"status":"encerrado","estadio":"Maracanã","destaque":"Gol de Gabriel 78'"'"'"},{"time_casa":"Corinthians","time_fora":"São Paulo","placar_casa":0,"placar_fora":0,"status":"ao_vivo"},{"time_casa":"Atlético-MG","time_fora":"Cruzeiro","status":"agendado","horario":"16:00"}]}}\n' | nc 127.0.0.1 9999Instalação
git clone <seu-repo> matrixui
cd matrixui
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtRodando a TUI no monitor físico (TTY1)
Opção A — getty@tty1 + .bash_profile (recomendada, testada em produção)
A forma mais simples e confiável: getty faz login automático, e o .bash_profile
inicia a TUI. Use o script automatizado:
# Copie o repositório para a Orange Pi e execute:
sudo bash install.sh <SEU_USUARIO>Se preferir fazer manualmente:
Configure o override do getty:
sudo systemctl edit getty@tty1Adicione na seção [Service]:
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin <SEU_USUARIO> --noclear %I $TERM
Restart=always
RestartSec=3Adicione o bloco TTY1 ao
~/.bash_profile:
if [ "$(tty)" = "/dev/tty1" ]; then
cd ~/matrixui && source .venv/bin/activate && exec python tui_display.py
fiHabilite e inicie:
sudo systemctl daemon-reload
sudo systemctl enable --now getty@tty1Ao rebootar, a TUI aparece automaticamente no monitor.
Opção B — systemd (hermes-tui.service) (alternativa: sem login shell)
Se você prefere que o systemd reclame o TTY1 diretamente (sem shell de login):
# Ajuste os caminhos/usuário dentro do arquivo e instale:
sudo cp hermes-tui.service /etc/systemd/system/hermes-tui.service
sudo systemctl daemon-reload
sudo systemctl disable getty@tty1 # evita conflito
sudo systemctl enable --now hermes-tui.serviceO unit declara Conflicts=getty@tty1.service e assume o /dev/tty1, reiniciando
automaticamente se cair (Restart=always).
Opção C — openvt (sob demanda)
Inicia a TUI em um terminal virtual livre e troca para ele:
sudo openvt -c 1 -s -- python ~/matrixui/tui_display.pyOpção D — tmux (inspecionável)
tmux new-session -d -s hermes 'python ~/matrixui/tui_display.py'
tmux attach -t hermes # para visualizarConfigurando o Hermes para carregar o servidor MCP
Use o config.example.json como base. Copie o bloco hermes-monitor para dentro do
mcpServers do config.json do seu agente, ajustando o caminho absoluto:
{
"mcpServers": {
"hermes-monitor": {
"command": "python",
"args": ["/home/<SEU_USUARIO>/matrixui/mcp_server.py"],
"env": {
"HERMES_TUI_HOST": "127.0.0.1",
"HERMES_TUI_PORT": "9999"
}
}
}
}Use o
pythondo virtualenv (ex.:/home/<SEU_USUARIO>/matrixui/.venv/bin/python) para garantir que as dependências sejam encontradas.
Testando
Com a TUI rodando, teste o socket manualmente (sem o MCP):
printf '{"conteudo":"# Olá\n- item 1\n- item 2","log":"teste manual"}\n' | nc 127.0.0.1 9999
printf '{"acao":"clear"}\n' | nc 127.0.0.1 9999Teste a ferramenta MCP com o inspector oficial:
mcp dev mcp_server.py
# invoque atualizar_monitor(conteudo_markdown="# Teste", mensagem_log="oi")Solução de Problemas
getty@tty1 não sobe no boot
Se o serviço getty@tty1 não inicializa automaticamente ao ligar a Orange Pi:
systemctl is-active getty@tty1 # verifica o statusSe estiver inativo, crie um override com autologin e restart automático:
sudo systemctl edit getty@tty1Adicione ou descomente as linhas (editor abre a seção [Service]):
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin orangepi --noclear %I $TERM
Restart=always
RestartSec=3Depois salve e execute:
sudo systemctl daemon-reload
sudo systemctl start getty@tty1
systemctl status getty@tty1 # confirma que está ativoTUI não aparece no monitor
Se a TUI não renderiza após reboot:
Se você está usando Opção A (getty + .bash_profile):
systemctl is-active getty@tty1 # confirma que getty está ativo
systemctl status getty@tty1 # mostra se há erros
journalctl -u getty@tty1 -n 30 --no-pager # logs do getty
cat ~/.bash_profile | grep -A 3 'HERMES TUI LAUNCHER' # verifica o bloco TTY1
python ~/matrixui/tui_display.py # testa a TUI manualmenteSe você está usando Opção B (hermes-tui.service):
systemctl status hermes-tui.service # status do serviço
journalctl -u hermes-tui.service -n 50 --no-pager # últimos 50 logsCausas comuns em ambos os casos:
Virtualenv não criada ou dependências não instaladas →
pip install -r requirements.txt.Python ou path incorreto no
.bash_profileou.service→ edite e verifique os caminhos.Permissões de TTY → confirme que o usuário tem acesso a
/dev/tty1.
Porta 9999 já em uso
Se receber erro Address already in use ao iniciar a TUI:
ss -tlnp | grep 9999 # identifica qual processo ocupa a porta
sudo lsof -i :9999 # alternativa (se lsof estiver instalado)Para usar uma porta diferente, ajuste as variáveis de ambiente no
/etc/systemd/system/hermes-tui.service (campo Environment) e no config.json do Hermes:
sudo systemctl edit hermes-tui.service
# [Service]
# Environment=HERMES_TUI_PORT=9998
sudo systemctl daemon-reload && sudo systemctl restart hermes-tui.serviceVariáveis de ambiente
Variável | Default | Descrição |
|
| Host do socket da TUI. |
|
| Porta do socket da TUI. |
Atalhos da TUI
Tecla | Ação |
| Sair |
| Limpar o painel |
Exemplos de uso
Cada skill foi desenhada para um caso de uso específico. Veja cenários práticos:
1. Previsão do tempo
Quando usar: o usuário pede "mostre a previsão do tempo" ou você quer exibir dados meteorológicos visualmente. A renderização em cards com arte ASCII é muito mais legível que uma tabela.
# O agente obtém dados de clima (via API ou integração) e envia:
{
"tipo": "previsao_tempo",
"dados": {
"local": "São Paulo, SP",
"dias": [
{"dia": "Hoje", "condicao": "chuva", "temp_max": 24, "temp_min": 17,
"descricao": "Pancadas", "umidade": 80, "vento": "15 km/h"},
{"dia": "Amanhã", "condicao": "sol", "temp_max": 28, "temp_min": 20,
"descricao": "Ensolarado"}
]
}
}2. Tabela
Quando usar: dados estruturados em linhas/colunas (vendas, relatórios, inventário,
etc.). Superior à renderização Markdown porque rich.Table alinha perfeitamente e
colore as bordas.
{
"tipo": "tabela",
"dados": {
"titulo": "Vendas do mês",
"colunas": ["Produto", "Qtd", "Preço", "Total"],
"linhas": [
["Café", "120", "R$ 15", "R$ 1.800"],
["Pão", "450", "R$ 0,75", "R$ 337,50"]
]
}
}3. Gráfico de barras
Quando usar: série temporal ou comparação de valores (temperatura por dia, vendas
por mês, retorno de investimento, etc.). plotext desenha barras profissionais; se
falhar, cai para unicode.
{
"tipo": "grafico",
"dados": {
"titulo": "Temperatura por dia",
"unidade": "°C",
"series": [
{"label": "Seg", "valor": 23},
{"label": "Ter", "valor": 27},
{"label": "Qua", "valor": 25}
]
}
}4. Métricas / Gauges
Quando usar: monitorar status em tempo real (CPU, RAM, disco, progresso, KPIs). As barras mudam de cor por faixa: verde (<60%), amarelo (<85%), vermelho (>=85%).
{
"tipo": "metricas",
"dados": {
"titulo": "Status do Servidor",
"metricas": [
{"label": "CPU", "valor": 42, "unidade": "%"},
{"label": "RAM", "valor": 6.8, "max": 8, "unidade": "GB"},
{"label": "Disco", "valor": 540, "max": 600, "unidade": "GB"}
]
}
}5. Alerta / Banner
Quando usar: notificar de algo importante (backup terminado, erro crítico, aviso de espaço). Texto gigante chama atenção e a cor varia por severidade.
{
"tipo": "alerta",
"dados": {
"texto": "BACKUP OK",
"nivel": "info", # ou "aviso", "critico"
"subtitulo": "Concluído com sucesso"
}
}6. QR Code
Quando usar: compartilhar um link (acesso ao painel, doc) ou credencial (Wi-Fi, token). O usuário aponta a câmera direto na tela.
{
"tipo": "qrcode",
"dados": {
"conteudo": "https://dashboard.exemplo.com",
"legenda": "Aponte a câmera"
}
}7. Tarefas / Checklist
Quando usar: lista de afazeres, checklist de deploy, roteiro de procedimento.
Mostra status (✓/☐) e prioridade colorida.
{
"tipo": "tarefas",
"dados": {
"titulo": "Checklist de Deploy",
"itens": [
{"texto": "Testes OK", "feito": true, "prioridade": "alta"},
{"texto": "DB migration", "feito": false, "prioridade": "alta"},
{"texto": "Notificar usuários", "feito": false}
]
}
}8. Notícias
Quando usar: exibir manchetes de qualquer fonte (o agente busca os dados via API ou ferramenta de busca). Lista numerada com título em destaque, resumo, categoria e hora da publicação.
{
"tipo": "noticias",
"dados": {
"titulo": "Últimas Notícias",
"fonte": "G1",
"itens": [
{"titulo": "Selic mantida em 13,75%",
"resumo": "O Copom decidiu manter a taxa básica de juros.",
"categoria": "Economia", "tempo": "há 30 min"},
{"titulo": "Seleção convoca 26 jogadores",
"resumo": "Lista com surpresas no ataque e ausências por lesão.",
"categoria": "Esportes", "tempo": "há 2 horas"},
{"titulo": "Tempestade causa apagão no Nordeste",
"resumo": "Ventos de até 90 km/h derrubaram torres de transmissão.",
"categoria": "Brasil"}
]
}
}9. Jogos de futebol
Quando usar: mostrar a rodada atual, resultados ou agenda de qualquer campeonato.
Status colorido (🔴 AO VIVO, ✅ FIM, 🕐 HH:MM), placar em destaque e linha
de evento por partida.
{
"tipo": "jogos_futebol",
"dados": {
"titulo": "Rodada 15 — Brasileirão Série A",
"data": "13/06/2026",
"jogos": [
{"time_casa": "Flamengo", "time_fora": "Palmeiras",
"placar_casa": 2, "placar_fora": 1,
"status": "encerrado", "estadio": "Maracanã",
"destaque": "Gol de Gabriel Barbosa aos 78'"},
{"time_casa": "Corinthians", "time_fora": "São Paulo",
"placar_casa": 0, "placar_fora": 0,
"status": "ao_vivo", "estadio": "Neo Química Arena",
"destaque": "45+2' — 2º Tempo"},
{"time_casa": "Atlético-MG", "time_fora": "Cruzeiro",
"status": "agendado", "horario": "16:00", "estadio": "Arena MRV"},
{"time_casa": "Botafogo", "time_fora": "Vasco",
"status": "agendado", "horario": "18:30"}
]
}
}10. Tela de boas-vindas customizável
A tela inicial (exibida no boot e ao pressionar C) mostra o logo do projeto com
informações de sistema. O agente pode personalizá-la e a customização persiste até
um reset ou reinício da TUI.
# Personalizar: mudar cor do tema e mensagem de boas-vindas
{
"acao": "set_welcome",
"tipo": "boas_vindas",
"dados": {
"mensagem": "Sistema de produção — acesso restrito",
"cor_tema": "#ff5c7c", # vermelho neon
"subtitulo": "Monitoramento 24/7"
}
}
# Restaurar o padrão com logo verde original
{"acao": "reset_welcome"}Via nc:
# Personalizar
printf '{"acao":"set_welcome","tipo":"boas_vindas","dados":{"mensagem":"Olá!","cor_tema":"#00e5ff"}}\n' | nc 127.0.0.1 9999
# Resetar
printf '{"acao":"reset_welcome"}\n' | nc 127.0.0.1 9999Ver arquivo examples.py para payloads prontos de cada skill.
Related MCP server: textual-mcp-server
🇬🇧 English (quick guide)
Hermes Terminal Dashboard is an MCP plugin that lets an AI agent render rich Markdown on a physical monitor attached to a headless Linux device.
tui_display.py— a Textual/Rich TUI that runs on the monitor and opens an internal asyncio TCP server (port9999) to receive commands. Cyberpunk-styled layout: header with live clock + connection status, a 70% Markdown panel, and a 30% activity log.mcp_server.py— an MCP server (officialmcpSDK, stdio transport) exposingatualizar_monitor/limpar_monitorplus specialized skills:exibir_previsao_tempo(weather cards),exibir_tabela(rich table),exibir_grafico(bar chart),exibir_metricas(gauges),exibir_alerta(big-text banner),exibir_qrcode,exibir_tarefas(checklist),exibir_noticias(news feed with title + summary), andexibir_jogos_futebol(football matches with score and live status). It sends a newline-delimited JSON payload to the TUI.renderers.py— registry mapping each skilltipoto a Rich renderable (ncurses-style).
Install
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txtRun the TUI on TTY1 — recommended: use the install.sh script to set up getty@tty1
autologin + .bash_profile launcher (tested in production). Alternative: use the bundled
hermes-tui.service if you prefer systemd to claim /dev/tty1 directly. Other options:
openvt or tmux.
Wire it into the agent — copy the hermes-monitor block from config.example.json
into your agent's config.json under mcpServers, pointing args at the absolute path
of mcp_server.py.
Test
printf '{"conteudo":"# Hello","log":"manual test"}\n' | nc 127.0.0.1 9999
mcp dev mcp_server.pyProtocol — newline-delimited JSON, one message per line:
{"conteudo": "...", "log": "...", "acao": "update|clear"}.
Env vars — HERMES_TUI_HOST (default 127.0.0.1), HERMES_TUI_PORT (default
9999). Keys — Q quit, C clear panel.
Troubleshooting
getty@tty1 won't start on boot — Create an override:
sudo systemctl edit getty@tty1, add[Service],ExecStart=(clear line), thenExecStart=-/sbin/agetty --autologin <YOUR_USER> --noclear %I $TERM,Restart=always,RestartSec=3. Reload:sudo systemctl daemon-reload && systemctl is-active getty@tty1.TUI not appearing — For option A (getty + .bash_profile): check
systemctl status getty@tty1andjournalctl -u getty@tty1 -n 30 --no-pager. Verify.bash_profilecontains the launcher block. For option B (hermes-tui.service): checksystemctl status hermes-tui.service. In both cases, verify venv and Python path.Port 9999 in use — Find owner:
ss -tlnp | grep 9999. Change port viaHERMES_TUI_PORT=9998env var in service file (option B) or.serviceoverride and agent config.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/antunesls/matrixui-hermes-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server