Skip to content

Repository files navigation

ol-ops-mcp

Servidor MCP (Model Context Protocol) para operação de hosts Oracle Linux 8+ via SSH, com capabilities curadas em YAML — sem exec(command: string) livre. O modelo chama capabilities nomeadas (system.disk_usage, não df -h); parâmetros são tipados e validados; toda mutação passa por confirmação em duas etapas; e tudo é auditado.

Ver ARCHITECTURE.md para o design completo, ROADMAP.md para o estado da implementação e SECURITY.md para modelo de ameaça e hardening de deploy — leia o SECURITY.md antes de apontar este servidor para um host de produção.

Por que não é só mais um MCP de SSH

MCPs de SSH genéricos expõem um exec livre: qualquer texto que chegue ao contexto do modelo (uma página web, um log, a saída de outro MCP) se torna instrução em potencial. Este servidor inverte o default — comandos vivem num catálogo YAML versionado, com parâmetros tipados (nunca string livre), renderização via shlex.quote, e saída remota sempre envelopada como dado não confiável, nunca como instrução. Se um diagnóstico realmente não cabe em capability curada, existe uma única porta de escape — ol_raw_exec — gated por três barreiras independentes (ver SECURITY.md).

Instalação

De um clone (desenvolvimento)

uv venv --python 3.11 --seed
source .venv/bin/activate      # ou .venv\Scripts\activate no Windows
uv pip install -e ".[dev]"

# validação rápida
ruff check src tests && ruff format --check src tests
mypy --strict src
pytest -m "not integration"

# validação completa (exige podman ou docker; roda containers OL8/OL9 reais)
pytest

Via uvx

uvx ol-ops-mcp

Configuração mínima

  1. Gere um par de chaves dedicado para o servidor (não reutilize uma chave pessoal):

    ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_claudeops -C claudeops@ol-ops-mcp
  2. Registre a chave pública no authorized_keys do usuário remoto — com as restrições descritas em SECURITY.md (restrict,pty=no,...).

  3. Registre a host key no seu known_hosts local. O servidor não aceita host desconhecido automaticamente (sem AutoAddPolicy) — é preciso este passo manual:

    ssh-keyscan -t ed25519 -H <address> >> ~/.ssh/known_hosts
  4. Copie examples/hosts.toml.example para ~/.config/ol-ops-mcp/hosts.toml (ou o caminho apontado por OL_OPS_MCP_CONFIG) e ajuste os hosts:

    mkdir -p ~/.config/ol-ops-mcp
    cp examples/hosts.toml.example ~/.config/ol-ops-mcp/hosts.toml
    chmod 600 ~/.config/ol-ops-mcp/hosts.toml

    O servidor recusa subir se o arquivo estiver mais aberto que 0600 (em sistemas POSIX). Um esqueleto mínimo:

    [server]
    audit_path = "~/.local/state/ol-ops-mcp/audit.jsonl"
    known_hosts = "~/.ssh/known_hosts"
    
    [defaults]
    mode     = "readonly"
    user     = "claudeops"
    key_file = "~/.ssh/id_ed25519_claudeops"
    
    [hosts.meu-host]
    address         = "10.0.0.10"
    description     = "Descrição do host"
    capability_sets = ["system", "storage", "systemd", "network"]
  5. Se algum host precisa de mutação (mode = "operator" ou acima) com sudo, gere o sudoers a partir do catálogo em vez de escrever à mão:

    ol-ops-mcp emit-sudoers --host meu-host --output /etc/sudoers.d/ol-ops-mcp

Variáveis de ambiente

Só estas três têm efeito — nenhuma outra é lida pelo servidor:

Variável Efeito
OL_OPS_MCP_CONFIG Caminho do hosts.toml. Default: ~/.config/ol-ops-mcp/hosts.toml.
OL_OPS_MCP_ALLOW_RAW Precisa ser 1 para ol_raw_exec funcionar, mesmo em host com allow_raw = true. Ver SECURITY.md.
OL_OPS_MCP_LOG_LEVEL Nível de log do processo (DEBUG, INFO, WARNING, ...).

Rodando o servidor

Por padrão, sem argumentos, o processo sobe o servidor MCP via stdio:

ol-ops-mcp

Existem também subcomandos de CLI que não sobem o servidor:

# consulta o audit log local
ol-ops-mcp audit --host meu-host --since 24h --format table

# gera o bloco de sudoers a partir da config atual de um host
ol-ops-mcp emit-sudoers --host meu-host

# compara o sudoers instalado no host remoto com o que a config geraria
ol-ops-mcp verify --host meu-host

Conectando ao Claude Code / Claude Desktop

Ver docs/claude-integration.md para o passo a passo completo (claude mcp add, configuração equivalente no Claude Desktop e como confirmar que a conexão subiu).

Tools disponíveis

Tool O que faz
ol_list_hosts Lista hosts configurados: endereço, modo, capability_sets.
ol_list_capabilities Lista capabilities do catálogo, opcionalmente por domínio.
ol_describe_capability Detalha uma capability: template, parâmetros, risco, timeout.
ol_run_capability Executa uma capability. safe executa direto; risco maior devolve PlanResponse para confirmar com ol_confirm.
ol_plan / ol_confirm Two-phase commit explícito para qualquer capability, mesmo safe.
ol_describe_host Retrato agregado de um host (release, kernel, memória, disco, unidades com falha, interfaces) numa chamada.
ol_fan_out Executa a mesma capability safe em vários hosts, concorrentemente. Nunca aceita capability de risco acima de safe.
ol_audit_query Consulta o audit log local por host, capability, janela de tempo ou risco mínimo.
ol_fetch_file Lê um arquivo de texto via SFTP, restrito a allow_read_paths.
ol_tail_log Últimas linhas de log — de uma unit systemd (journalctl) ou de um arquivo (tail).
ol_raw_exec Escape hatch gated — comando arbitrário, sempre two-phase, sempre com justification. Ver SECURITY.md antes de habilitar.

Exemplo de uso

Depois de conectado, um fluxo típico de diagnóstico via um cliente MCP:

> ol_list_hosts
[{"name": "meu-host", "mode": "readonly", ...}]

> ol_describe_host(host="meu-host")
{"release": "Oracle Linux Server 8.10", "disk": [...], "failed_units": [], ...}

> ol_run_capability(host="meu-host", capability="storage.disk_usage")
{"parsed": [{"filesystem": "/dev/sda1", "use_pct": 78, ...}], ...}

Para uma mutação (ex. reiniciar um serviço na allowlist do host):

> ol_plan(host="meu-host", capability="systemd.restart", params={"service": "mariadb"})
{"rendered_command": "sudo /usr/bin/systemctl restart mariadb", "confirm_token": "...", "expires_at": "..."}

> ol_confirm(confirm_token="...")
{"exit_code": 0, ...}

O comando renderizado aparece por completo antes de qualquer execução — o token expira em 120 segundos e só pode ser usado uma vez.

Avisos

  • Leia SECURITY.md antes de usar em produção. Em particular: este servidor não é um sandbox à prova de operador malicioso — ele protege contra prompt injection e erro de julgamento do modelo, não contra alguém que configure deliberadamente mode = "raw" com sudo irrestrito.
  • Hosts de produção devem começar em mode = "readonly". Escalar para operator ou raw é ato explícito no hosts.toml, nunca default.
  • Nunca coloque senha em texto claro na configuração — só key_file é aceito.
  • Redaction de segredos na saída remota (core/redact.py) é heurística, não garantia criptográfica. Trate qualquer stdout/stderr retornado como dado potencialmente sensível até prova em contrário.
  • Este projeto cobre diagnóstico e operação do sistema operacional. Backup/recovery, HA, auditoria de segurança avançada e tuning dentro do banco estão fora de escopo — ver ARCHITECTURE.md seção 1.3.

Licença

Apache-2.0.

About

No description, website, or topics provided.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages