Pular para o conteúdo

Ligar um assistente

O DumbMonit tem um servidor MCP incorporado: o Model Context Protocol, a forma como assistentes como o Claude, o ChatGPT, o Cursor ou o agente do VS Code chamam ferramentas externas. Ligue um, depois pergunte-lhe coisas como:

  • «Está tudo bem?»
  • «Silencia o NAS por duas horas, estou a trocar um disco.»
  • «O que aconteceu ontem à noite?»
  • «Quão cheio está o servidor de cópias de segurança, e está a piorar?»
  • «Publica uma atualização na página de estado: o servidor de email voltou.»

O assistente vê o que a interface vê — monitores, alertas, histórico, métricas, agentes, páginas de estado — e usa as mesmas palavras: reporting, unreachable, waiting, advisory, warning, suppressed by parent. Corre dentro do servidor: nada para instalar junto ao DumbMonit, e as ferramentas chamam o mesmo código que a interface web.

Settings → API & assistants (/settings#assistant). Nomeie o token com o assistente ou a máquina em que corre («Claude on my laptop»), depois escolha:

DefiniçãoEscolhas
ScopeRead: olhar — estado, monitores, alertas, histórico, métricas, regras, agentes, páginas de estado. Nunca pode alterar nada. Read and write: também agir — silenciar, confirmar, verificar, adicionar um monitor, reiniciar um contentor, publicar um incidente… (as ferramentas de escrita).
Expires30 dias, 90 dias (predefinição), 1 ano ou nunca. Um token expirado deixa de funcionar; crie um novo.
Allowed networksOpcional. Endereços ou intervalos CIDR de onde o token pode ser usado (192.168.1.0/24, 10.8.0.5). Vazio: de qualquer lugar.

O token parece-se com dmt_ seguido de 32 caracteres hexadecimais. É mostrado uma vez, logo depois da criação; o DumbMonit só guarda um hash. Perdeu-o, revogue-o e crie outro.

Prefira um token de leitura a menos que realmente queira que o assistente aja.

O mesmo token também abre a API REST a scripts e painéis — curl -H "Authorization: Bearer dmt_…" https://monit.example.lan/api/targets — onde read vê o que um leitor vê e write faz o que um administrador faz, contas, tokens e cópias de segurança excetuados.

A página de definições preenche-os com o endereço do seu servidor e o novo token. Abaixo, https://monit.example.lan representa o seu servidor.

Janela do terminal
claude mcp add --transport http dumbmonit https://monit.example.lan/api/mcp \
--header "Authorization: Bearer dmt_…"

Adicione --scope user para o ter em todo projeto, não só no atual.

O Claude Desktop inicia servidores locais a partir do seu ficheiro de configuração; o mcp-remote faz a ponte para o endpoint HTTP do DumbMonit (precisa do Node.js). O DumbMonit autentica com um cabeçalho bearer em vez de OAuth, por isso adicione-o através deste ficheiro em vez do ecrã Connectors. Settings → Developer → Edit Config, depois adicione a claude_desktop_config.json e reinicie o Claude Desktop:

{
"mcpServers": {
"dumbmonit": {
"command": "npx",
"args": [
"-y", "mcp-remote", "https://monit.example.lan/api/mcp",
"--header", "Authorization:${DUMBMONIT_AUTH}"
],
"env": { "DUMBMONIT_AUTH": "Bearer dmt_…" }
}
}
}

O cabeçalho passa por uma variável de ambiente, sem espaço depois dos dois pontos, porque algumas plataformas dividem argumentos em espaços. Para um servidor alcançado via HTTP simples na sua rede, adicione "--allow-http" a args — a página de definições fá-lo por si quando ela própria é servida via HTTP.

.vscode/mcp.json num espaço de trabalho (ou o comando MCP: Add Server → HTTP):

{
"servers": {
"dumbmonit": {
"type": "http",
"url": "https://monit.example.lan/api/mcp",
"headers": { "Authorization": "Bearer dmt_…" }
}
}
}

.cursor/mcp.json, e a mesma forma para a maioria dos clientes que suportam servidores Streamable HTTP com cabeçalhos personalizados:

{
"mcpServers": {
"dumbmonit": {
"url": "https://monit.example.lan/api/mcp",
"headers": { "Authorization": "Bearer dmt_…" }
}
}
}

Um cliente que só inicia servidores locais (stdio) pode usar a ponte mcp-remote mostrada para o Claude Desktop.

Settings → Connectors → Create (modo desenvolvedor). URL do servidor MCP: https://monit.example.lan/api/mcp, cabeçalho de autorização: Bearer dmt_….

O ChatGPT liga-se a partir dos servidores da OpenAI, não do seu navegador: o DumbMonit tem de ser acessível a partir da internet via HTTPS. Ver as notas de segurança antes de fazer isso.

O que um cliente precisa de saber: o endpoint é https://<server>/api/mcp, o transporte é Streamable HTTP, e todo pedido transporta Authorization: Bearer dmt_…. Uma chamada em bruto, para verificar o token e o caminho de rede a partir de um terminal:

Janela do terminal
curl -s https://monit.example.lan/api/mcp \
-H 'Authorization: Bearer dmt_…' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2026-07-28' \
-H 'Mcp-Method: tools/call' -H 'Mcp-Name: get_status' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_status","arguments":{},
"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28",
"io.modelcontextprotocol/clientCapabilities":{}}}}'

Vinte e sete ferramentas. Cada uma tem um título, uma descrição, um esquema de entrada, um esquema de saída e anotações (readOnlyHint, destructiveHint, idempotentHint), para que um cliente possa distinguir as que só olham e perguntar-lhe antes de executar as outras.

FerramentaÂmbitoFaz
get_statusreadO boletim, a resposta a «está tudo bem?»: contagens de monitor, alertas ativos e a formar-se, uma frase («2 advisories, 1 unreachable.»).
list_devicesreadMonitores e serviços com estado, pai e etiquetas; filtrar por subcadeia ou estado.
get_devicereadUm monitor: configuração, estado, alertas ativos, resumo de CPU / memória / disco mais cheio de 24 horas (disponibilidade e latência para uma verificação de serviço).
list_alertsreadAlertas ativos com palavras de severidade, desde quando, valor, supressão, confirmação.
alert_historyreadTransições de alerta, as mais recentes primeiro (since ou hours, monitor opcional, limite).
query_metricsreadUma consulta de intervalo MetricsQL, no máximo 60 pontos por série.
list_silencesreadJanelas de manutenção e se estão ativas agora.
list_rulesreadRegras de alerta com tipo, severidade, limiar, ativada.
list_device_typesreadOs tipos de monitor que este servidor pode monitorizar, com as opções e credenciais que cada um espera — o que add_device precisa.
list_agentsreadMáquinas a executar o agente: SO, versão do agente, modo relay, site, monitores relayed, último contacto, associação.
list_containersreadOs contentores Docker de uma máquina a executar o agente: estado, saúde, reinícios, atualização disponível, último comando.
list_heartbeatsreadMonitores heartbeat: intervalo esperado, última chamada, veredicto (à espera, a tempo, em falta, reportado em baixo). O URL secreto nunca é mostrado.
list_status_pagesreadPáginas de estado, publicadas ou não, com o seu caminho público (/s/<slug>), os monitores que mostram e os seus incidentes abertos.
list_channelsreadCanais de notificação: tipo, ativado, último erro, última mensagem enviada. Nunca os seus segredos.
list_packsreadPacotes de integração instalados: versão, tipo de monitor, ativado, monitores a usá-lo, erros.
silence_devicewriteUma janela de manutenção pontual num monitor, a começar agora (1 hora por predefinição, no máximo uma semana).
remove_silencewriteRemove uma janela de manutenção.
schedule_maintenancewriteUma janela de manutenção pontual numa data dada, num monitor ou em toda a instância, no máximo uma semana.
acknowledge_alertwriteConfirma um alerta por impressão digital durante um número de horas (4 por predefinição): os lembretes pausam, a resolução continua a ser notificada. hours: 0 levanta-a.
probe_devicewriteVerifica um monitor imediatamente e reporta o que foi medido.
set_device_enabledwriteAtiva ou desativa a monitorização de um monitor.
set_rule_enabledwriteAtiva ou desativa uma regra de alerta.
add_devicewriteAdiciona um monitor: nome, tipo, endereço, intervalo, pai, opções, credenciais, agente relay.
discover_networkwriteAnalisa uma rede (CIDR, no máximo 4096 endereços) por dispositivos SNMP e sugere um perfil para cada um.
restart_containerwritePede ao agente de uma máquina para reiniciar um dos seus contentores.
test_channelwriteEnvia uma mensagem de teste através de um canal de notificação.
post_incidentwriteAbre um incidente numa página de estado, ou publica uma atualização num existente.

Um token de leitura a chamar uma ferramenta de escrita recebe uma recusa clara como resultado da ferramenta (isError: true); o assistente explica-a e nada muda. O mesmo se aplica a qualquer coisa que a ferramenta não possa fazer — um monitor desconhecido, um nome ambíguo, uma janela mais longa do que uma semana: a mensagem diz o que corrigir.

POST /api/mcp implementa o MCP sobre o transporte Streamable HTTP: JSON-RPC 2.0, um pedido por POST, respondido com JSON simples (sem server-sent events). É sem estado: nenhum Mcp-Session-Id é emitido, um que um cliente envia é ignorado, e GET ou DELETE no endpoint respondem 405. Só a capacidade tools é oferecida — sem recursos, prompts, sampling ou OAuth.

Duas gerações do protocolo são servidas no mesmo endpoint:

VersõesComo um cliente o fala
2026-07-28Sem estado. Todo pedido transporta io.modelcontextprotocol/protocolVersion e io.modelcontextprotocol/clientCapabilities em params._meta, e os cabeçalhos MCP-Protocol-Version, Mcp-Method e, para tools/call, Mcp-Name, que tem de corresponder ao corpo. Métodos: server/discover, tools/list, tools/call. Os resultados transportam resultType: "complete" e a identidade do servidor em _meta (io.modelcontextprotocol/serverInfo); tools/list também transporta ttlMs e cacheScope.
2025-11-25, 2025-06-18, 2025-03-26O handshake initialize escolhe a versão (uma desconhecida recebe a mais recente destas três); notifications/initialized é confirmado com 202; depois ping, tools/list, tools/call.

Erros, além do 401, 403 e 429 das verificações de token, que vêm antes de qualquer JSON-RPC:

HTTPCódigo JSON-RPCQuando
400-32020 (incompatibilidade de cabeçalho)Um pedido 2026-07-28 sem MCP-Protocol-Version, Mcp-Method ou Mcp-Name, ou com valores que diferem do corpo.
400-32022 (versão de protocolo não suportada)Uma versão que este servidor não fala; error.data lista as supported e a requested.
400-32602 (parâmetros inválidos)Um pedido 2026-07-28 sem os campos _meta obrigatórios.
404-32601 (método não encontrado)Um pedido 2026-07-28 para um método que este servidor não implementa.
200-32602Uma ferramenta desconhecida, ou arguments que não é um objeto.
-32700, -32600JSON ilegível; não é um pedido JSON-RPC 2.0 (lotes não são suportados).
202—Uma notificação: aceite, sem corpo.

Uma ferramenta que corre mas falha — âmbito em falta, monitor desconhecido — não é um erro de protocolo: responde normalmente com isError: true e uma frase que o assistente pode transmitir.

  • Um token é uma senha. Quem o detém lê tudo o que a interface mostra — e, com um token de escrita, altera tudo o que um administrador pode através da API REST (monitores, regras, canais), contas, tokens e cópias de segurança excetuados. Mantenha-o fora de conversas partilhadas, capturas de ecrã e repositórios. Revogue um token de que não tem certeza; crie outro num minuto.
  • Prefira read. A maioria das perguntas («está tudo bem?») não precisa de nenhum âmbito de escrita. Crie um token de escrita só para um assistente que realmente quer que aja, e nomeie-o para o reconhecer na lista. A maioria dos clientes pergunta antes de executar uma ferramenta que não está marcada só de leitura; deixe essa confirmação ativa.
  • Dê-lhe uma vida e uma rede. Um token que expira em 90 dias e só funciona a partir da sua LAN ou VPN (192.168.1.0/24) vale pouco para quem o encontrar. Atrás de um proxy inverso, declare o proxy em DUMBMONIT_TRUSTED_PROXIES, caso contrário toda chamada parece vir do proxy e uma restrição de rede recusa-as todas.
  • Ligado ao seu criador. Um token deixa de funcionar quando a conta que o criou é desativada, perde o seu poder de escrita quando essa conta já não é administradora, e é revogado quando essa conta é eliminada.
  • Nada secreto volta. As ferramentas nunca devolvem credenciais de monitor (só o seu tipo), segredos de canal, URLs de heartbeat ou tokens. add_device recebe credenciais: viajam através da conversa do seu assistente, e portanto através do seu fornecedor. Para um monitor com credenciais sensíveis, prefira a interface web.
  • Navegadores e Origin. Um pedido que transporta um cabeçalho Origin (um cliente baseado em navegador) é recusado com 403 a menos que essa origem seja a do próprio servidor ou seja permitida por DUMBMONIT_API_CORS_ORIGINS (por predefinição qualquer origem, já que o token é obrigatório de qualquer forma). Liste as suas origens aí para a restringir; ver pedidos de origem cruzada.
  • Limite de taxa. Cada token é limitado a 120 chamadas por minuto, REST e MCP juntos: um assistente preso num loop recebe 429 com Retry-After, não toda a atenção do seu servidor.
  • HTTPS antes da internet. Os conectores do ChatGPT precisam de um URL público. Coloque o DumbMonit atrás de um proxy inverso com TLS (Caddy, Traefik, nginx…) e defina DUMBMONIT_COOKIE_SECURE=1. Nunca exponha a porta HTTP simples. O Claude Desktop, Claude Code, VS Code e Cursor correm na sua máquina e podem alcançar um endereço LAN diretamente, por isso não precisam de nenhuma exposição.
  • Vigie «last used». A lista de tokens mostra quando cada token foi usado por último e a partir de que endereço. Um token usado numa hora em que não estava a falar com o seu assistente, ou a partir de um endereço que não conhece, merece uma revogação.
  • Registos. Toda chamada de ferramenta é registada ao nível info com o nome do token e a ferramenta, nunca os argumentos; toda escrita através da API REST com o nome do token, o método, o caminho e o estado, nunca o corpo. Criar e revogar tokens está no registo de auditoria (Settings → Security).
SintomaCausa e correção
401 / «A valid API token is required.»O cabeçalho está em falta ou mal escrito (Authorization: Bearer dmt_…, um espaço depois de Bearer), ou o token foi revogado. Crie um novo.
401 / «The API token ”…” expired on …»Crie um novo token; escolha uma vida mais longa se foi demasiado curta.
403 / «cannot be used from …»O token está restrito a outras redes. O endereço na mensagem é o que o servidor vê: atrás de um proxy inverso, declare o proxy em DUMBMONIT_TRUSTED_PROXIES.
403 em toda chamada de um cliente baseado em navegadorA sua Origin não é permitida: adicione-a a DUMBMONIT_API_CORS_ORIGINS.
Uma ferramenta responde «needs a token with the “write” scope»O token é só de leitura, ou o seu criador já não é administrador. Crie um token de escrita se quiser que o assistente aja.
429120 chamadas num minuto: o assistente está provavelmente em loop. Espere por Retry-After, depois faça uma pergunta mais restrita.
«Unsupported protocol version»O cliente fala uma versão que o DumbMonit não fala; atualize o cliente.
O Claude Desktop mostra o servidor como falhadoO Node.js tem de estar instalado para o npx; via HTTP simples, --allow-http tem de estar em args.
O ChatGPT não consegue ligar-sePrecisa de um URL HTTPS público; um endereço LAN ou HTTP simples não funciona a partir dos servidores da OpenAI.