easypanel-mcp-server

Servidor MCP para controle completo do Easypanel via Claude Code, Cursor e Claude Desktop.

Documentação

easypanel-mcp-server

Servidor MCP para controle total do Easypanel via Claude Code, Cursor e Claude Desktop.

npm version License: MIT GitHub Stars GitHub Forks GitHub Issues CI Glama Quality

TypeScript Node.js MCP Claude Code Cursor Claude Desktop

Instagram YouTube LinkedIn Buy Me A Coffee Strat Academy


O que é isso

easypanel-mcp-server conecta Claude Code, Cursor e Claude Desktop diretamente à sua instância Easypanel — um painel de controle de servidor moderno baseado em Docker — por meio do Model Context Protocol.

Em vez de alternar entre seu editor e o painel do Easypanel, você controla tudo de dentro do Claude: implantar a partir do GitHub, atualizar variáveis de ambiente, ler logs ao vivo, executar comandos em contêineres, gerenciar domínios, bancos de dados, volumes e portas, definir limites de recursos, executar manutenção do Docker e monitorar seu servidor — tudo em linguagem natural.

Ele mapeia a API do Easypanel para 57 ferramentas tipadas em 15 categorias, além de uma única porta de escape easypanel_raw que alcança qualquer uma das ~375 operações da API do Easypanel para tudo que não é coberto por uma ferramenta dedicada. Ele fala todas as três gerações de API — a API tRPC de painéis ≤ 2.30, a camada RPC de 2.31–2.32 e a API pública introduzida no Easypanel 2.33 — detectando automaticamente qual delas seu painel usa. Toda ação destrutiva é bloqueada por uma confirmação explícita, toda resposta abre com um banner de contexto para que o Claude sempre saiba o que está tocando, e um modo somente leitura opcional permite conectar com segurança a um painel de produção.

📖 Referência da API: docs/easypanel-api.md — arquitetura, as gerações de API, operações confirmadas mapeadas ferramenta por ferramenta e como descobrir novas.


Compatibilidade

O Easypanel mudou sua API duas vezes em rápida sucessão:

  • 2.31 substituiu a API tRPC interna por uma camada RPC (/api/rpc/*). Em painéis ≥ 2.31, toda chamada v1.x que carrega parâmetros falha com 400 Input validation failed.
  • 2.33 lançou uma API pública documentada (/api/<operation>, GET para leituras, POST para escritas) e declarou que a antiga API interna "pode mudar sem aviso e não deve ser usada como base". A v3 tem como alvo a API pública nesses painéis.
Sua versão do EasypanelUso
qualquer (recomendado)easypanel-mcp-server@latest (v3.x) — detecta automaticamente a geração, funciona em todas as três
≤ 2.30.x apenas, fixadaeasypanel-mcp-server@legacy (v1.3.x) — linha congelada somente tRPC, última validada contra v2.30.1

A v3 detecta a geração com uma única solicitação de teste na primeira chamada (em cache) e registra a versão do painel no stderr. Para pular a detecção, defina EASYPANEL_API_FLAVOR como trpc (≤ 2.30), rpc (2.31–2.32) ou public (≥ 2.33).

Atualizando da v2? Se você fixou EASYPANEL_API_FLAVOR=rpc para contornar os problemas da 2.32, remova-o — caso contrário, o cliente permanece na API interna que o Easypanel agora declara instável.

Este MCP vs. o MCP integrado do Easypanel

O Easypanel 2.33 também inclui seu próprio endpoint MCP (/api/mcp, detalhes de conexão ao lado da sua chave de API). É um wrapper fino sobre a API pública. Este servidor é uma troca diferente:

MCP integrado do Easypaneleasypanel-mcp-server
Logs de contêiner em tempo de execução—✅ via /ws/serviceLogs (sem necessidade de Loki/licença)
Executar dentro de um contêiner—✅ exec_in_container com bloqueio de comandos destrutivos
Eventos Docker ao vivo—✅ get_docker_events
Modo somente leitura—✅ MCP_ACCESS_MODE=readonly bloqueia toda escrita na origem
Bloqueio de confirmação em operações destrutivas—✅ confirm: "CONFIRMO"
Redação de segredos (list_users)—✅ remove apiToken / twoFactorSecret
Leitura-modificação-escrita de variáveis de ambiente—✅ nunca sobrescreve outras variáveis
Construção de string de conexão—✅ inspect_database
Cobertura de toda operação da API✅✅ via easypanel_raw
Instalação zero✅precisa de npx/node

Usar ambos ao mesmo tempo é tranquilo — eles não conflitam.


Pré-requisitos

  • Instância do Easypanel em execução e acessível
  • Token de API — gere em Easypanel → Configurações → API → Gerar Token
  • Node.js ≥ 18 e Claude Code, Cursor ou Claude Desktop

Início rápido

Opção A — npx (sem necessidade de instalação)

Adicione .mcp.json à raiz do seu projeto:

{
  "mcpServers": {
    "easypanel-mcp": {
      "command": "npx",
      "args": ["-y", "easypanel-mcp-server"],
      "env": {
        "EASYPANEL_URL": "https://your-panel.example.com",
        "EASYPANEL_TOKEN": "your-api-token"
      }
    }
  }
}

Opção B — build local

git clone https://github.com/helbertparanhos/easypanel-mcp-server
cd easypanel-mcp-server
npm install && npm run build
{
  "mcpServers": {
    "easypanel-mcp": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/easypanel-mcp-server/dist/index.js"],
      "env": {
        "EASYPANEL_URL": "https://your-panel.example.com",
        "EASYPANEL_TOKEN": "your-api-token"
      }
    }
  }
}

Cursor — reutilizar variáveis de ambiente entre projetos

Em Cursor Settings → Tools & MCPs → Environment Variables, defina:

  • EASYPANEL_URL = https://your-panel.example.com
  • EASYPANEL_TOKEN = your-api-token

Então seu .cursor/mcp.json usa referências que se aplicam automaticamente a todo projeto:

{
  "mcpServers": {
    "easypanel-mcp": {
      "command": "npx",
      "args": ["-y", "easypanel-mcp-server"],
      "env": {
        "EASYPANEL_URL": "${EASYPANEL_URL}",
        "EASYPANEL_TOKEN": "${EASYPANEL_TOKEN}"
      }
    }
  }
}

Variáveis de ambiente

VariávelObrigatórioPadrãoDescrição
EASYPANEL_URL✅—URL do painel, sem barra final (ex.: https://panel.example.com)
EASYPANEL_TOKEN✅—Token da API (Easypanel → Configurações → API → Gerar Token)
MCP_ACCESS_MODE—fullDefina como readonly para bloquear todas as escritas (ferramentas selecionadas e easypanel_raw). Leituras permanecem disponíveis — ideal para conectar a um painel de produção apenas para inspeção.
EASYPANEL_API_FLAVOR—(automático)Força a geração da API do painel em vez de detecção automática: trpc (≤ 2.30), rpc (2.31–2.32) ou public (≥ 2.33). Aliases: legacy / modern. Deixe sem definir a menos que tenha um motivo — uma fixação rpc desatualizada mantém um painel 2.33 na API interna.
EASYPANEL_RAW_DISABLED—(habilitado)Defina como 1 para desabilitar completamente a porta de escape easypanel_raw. Recomendado quando o MCP está exposto a conteúdo não confiável (risco de injeção de prompt), pois leituras easypanel_raw podem retornar segredos e não são cobertas pelo modo somente leitura.

Adicionando contexto a um projeto

Coloque isto no CLAUDE.md do seu projeto para que o Claude saiba em qual projeto e serviço do Easypanel deve operar por padrão:

## Easypanel
Project: `my-project` | Service: `my-api` | Branch: `main`
Repo: `owner/repo`

Não é necessário copiar pastas — uma instalação do MCP atende a todos os seus projetos.


Casos de uso

"Implantar meu app" — Claude lista projetos, inspeciona o serviço atual, dispara deploy_service e então observa list_actions até concluir.

"Por que meu serviço está fora do ar?" — Claude chama get_service_error, get_service_logs e get_build_logs, e pode exec_in_container para inspecionar arquivos/env ao vivo.

"Adicionar DATABASE_URL ao staging" — Claude lê as variáveis de ambiente atuais com get_env_vars, adiciona apenas a nova chave com set_env_var (nunca apaga outras) e lembra você de reimplantar.

"Dar a este serviço 512MB e meio núcleo" — Claude chama set_service_resources (lê os limites atuais e mescla sua alteração) e lembra você de reiniciar.

"Persistir /app/data e expor a porta 5432" — Claude chama create_mount (volume nomeado) e create_port, ambos aplicados no próximo deploy.

"Meu disco está cheio" — Claude executa get_storage_stats e depois cleanup_docker_images ou prune_docker (com confirmação) para recuperar espaço.

"Mostrar a configuração do painel Traefik" — para qualquer coisa sem ferramenta dedicada, Claude usa easypanel_raw para chamar o procedimento diretamente.


Ferramentas disponíveis (57)

CategoriaFerramentas
Projetoslist_projects, get_project, create_project, delete_project ⚠️
Serviçosinspect_service, create_service, rename_service ⚠️, destroy_service ⚠️, deploy_service, start_service, stop_service ⚠️, restart_service, get_service_error, get_exposed_ports, get_service_notes, set_service_notes, set_service_resources
Deploy / GitHubset_source_github, set_source_image, enable_github_deploy, disable_github_deploy, list_actions, get_action
Variáveis de ambienteget_env_vars, set_env_var, delete_env_var ⚠️
Logsget_service_logs, get_build_logs, get_system_stats
Contêinereslist_containers, exec_in_container ⚠️, get_docker_events
Domínioslist_domains, add_domain, remove_domain ⚠️, set_primary_domain
Bancos de dadoscreate_database, inspect_database, destroy_database ⚠️
Volumes / Montagenslist_mounts, create_mount ⚠️
Portaslist_ports, create_port ⚠️
Composecreate_compose, inspect_compose, deploy_compose
Monitoramentoget_docker_stats, get_storage_stats, get_service_stats
Manutençãoprune_docker ⚠️, cleanup_docker_images
Servidor / Infralist_users, list_certificates, list_nodes, restart_panel ⚠️, reboot_server ⚠️
Acesso brutoeasypanel_raw ⚠️

⚠️ = requer confirm: "CONFIRMO". Para exec_in_container, create_mount, create_port e easypanel_raw a confirmação é condicional (apenas para comandos destrutivos, montagens de bind sensíveis de caminho do host, portas privilegiadas < 1024 e escritas, respectivamente).

Descrições completas das ferramentas com parâmetros estão em llms.txt. Para a API subjacente (todas as gerações), veja docs/easypanel-api.md.

easypanel_raw — alcançar qualquer uma das ~375 operações

Cobrir toda operação do Easypanel com uma ferramenta tipada não é prático, então qualquer coisa sem ferramenta dedicada é alcançável diretamente:

// read (default) — flat name, as documented in your panel's /api/openapi.json
{ "procedure": "listCertificates" }
{ "procedure": "getPanelDomain" }
{ "procedure": "listVolumeBackups", "input": { "projectName": "app", "serviceName": "api" } }

// the old dot notation still works and is translated
{ "procedure": "certificates.listCertificates" }

// write — requires isMutation:true AND confirm:"CONFIRMO"
{ "procedure": "setLogoSettings", "input": { /* ... */ },
  "isMutation": true, "confirm": "CONFIRMO" }

Áreas acessíveis apenas via easypanel_raw: Traefik, branding, Cloudflare Tunnel, Box, middlewares, notificações, backups de volume/banco de dados, WordPress, provedores de armazenamento, builders Docker, chaves Git, gerenciamento de cluster e atualizações. Para descobrir nomes, leia GET <your-panel>/api/openapi.json.

O cliente classifica cada operação contra a especificação OpenAPI do próprio painel, fail-closed: uma leitura só executa se a especificação disser que é uma leitura, então escritas não podem passar despercebidas pelo modo readonly ou pelo bloqueio de confirmação — e o inverso também é capturado (chamar uma leitura com isMutation:true é recusado com uma mensagem clara). Na 2.33+ essa classificação é exata, pois a API pública declara GET para leituras e POST para escritas. Na 2.31 é o método HTTP documentado; na 2.32, onde a especificação é somente POST e não carrega tal marcador, o cliente recorre à convenção de nomenclatura do painel (get/list/inspect/check/query/search = leitura, qualquer outra coisa = escrita), restrito a operações presentes na especificação.

Uma exceção deliberada: na 2.33+ o painel valida parâmetros de consulta sem coerção de tipo, então ?limit=5 chega como a string "5" e é rejeitado. Sempre que uma entrada carrega um valor não-string, o cliente roteia essa leitura pelo transporte interno /api/rpc (que envia JSON no corpo) e registra o motivo no stderr. A classificação leitura/escrita ainda vem da especificação primeiro, então a proteção não é afetada.


Recursos de segurança

Banner de contexto

Toda resposta que toca um projeto/serviço específico começa com:

[Contexto ativo: projeto="my-project" | serviço="my-api"]

O Claude sempre sabe o que está modificando antes de tomar qualquer ação.

Bloqueio de confirmação

Ações destrutivas ou que impactam produção retornam BLOQUEADO até receberem confirm: "CONFIRMO":

{
  "status": "BLOQUEADO",
  "acao": "stop_service",
  "alvo": "serviço \"api\" (usuários perderão acesso)",
  "instrucao": "Para confirmar, passe o parâmetro: confirm: \"CONFIRMO\"",
  "aviso": "⚠️  Esta ação pode ser IRREVERSÍVEL. Confirme apenas se tiver certeza."
}

Isso bloqueia exclusão de projeto/serviço, parar/renomear, remoção de env/domínio, destruição de banco de dados, operações globais de servidor (prune_docker, restart_panel, reboot_server) e — condicionalmente — comandos perigosos de contêiner, montagens de bind sensíveis, portas privilegiadas e mutações brutas.

Modo somente leitura

Defina MCP_ACCESS_MODE=readonly para bloquear toda escrita na origem (client.mutate), cobrindo tanto as ferramentas curadas quanto easypanel_raw. As leituras permanecem disponíveis — perfeito para um painel de produção que você só quer inspecionar.

Controles de escape bruto

easypanel_raw valida o nome da operação (plano ou namespace.procedure, sem injeção de caminho/consulta), exige que input seja um objeto (≤ 50KB) e exige CONFIRMO para qualquer mutação. Defina EASYPANEL_RAW_DISABLED=1 para desativá-lo completamente.

Ocultação de segredos

list_users remove apiToken, twoFactorSecret e campos de senha antes de retornar — apenas id, email, admin, twoFactorEnabled e createdAt chegam ao modelo.

Variáveis de ambiente seguras (ler-modificar-escrever)

set_env_var e delete_env_var leem o estado atual, aplicam apenas a alteração solicitada e gravam de volta. A API do Easypanel substitui toda a string de ambiente a cada atualização — sem essa proteção, é fácil apagar acidentalmente todas as variáveis de uma vez.

Mascaramento de valores sensíveis

get_env_vars mascara valores cuja chave corresponde a *SECRET*, *PASSWORD*, *TOKEN*, *KEY* por padrão. Passe include_values: true para revelar.

O token nunca vaza

Erros HTTP e falhas de WebSocket são registrados em stderr e apresentados ao modelo como uma mensagem genérica — o token de portador (enviado na string de consulta do WebSocket, como o Easypanel exige) nunca chega ao contexto do modelo.

Validação de entrada

projectName / serviceName são validados contra ^[a-z0-9][a-z0-9_-]*$ antes de serem usados para construir um nome de serviço Docker ou consulta WebSocket (defesa em profundidade contra confusão de alvo / injeção de parâmetros). As portas são validadas como inteiros 1–65535; os valores de recursos devem ser números positivos.


Habilidade complementar /ep

Instale a habilidade de fluxo de trabalho para operações de implantação guiadas no Claude Code:

mkdir -p ~/.claude/skills/ep
cp skill/SKILL.md ~/.claude/skills/ep/SKILL.md

Em seguida, use /ep para um fluxo de trabalho de implantação interativo sem precisar lembrar nomes de ferramentas.


Como funciona

O painel do Easypanel fala com seu backend via tRPC (/api/trpc/<router>.<procedure>), não uma API REST pública. Este servidor usa os mesmos endpoints:

  • Leituras são consultas tRPC; escritas são mutações tRPC — veja docs/easypanel-api.md.
  • Logs ao vivo, execução de contêineres e eventos Docker usam os canais WebSocket do painel (/ws/serviceLogs, /ws/containerShell, /ws/dockerEvents) — os mesmos que a interface usa — para que funcionem sem os Advanced Logs licenciados (Loki).
  • Alguns esquemas de entrada (montagens, portas, recursos) foram validados contra um Easypanel ativo e estão documentados na referência da API.

Limitações conhecidas

  • Tipos de serviço WordPress / Box — não expostos como ferramentas dedicadas; acesse-os via easypanel_raw (por exemplo, inspectWordPressService, createBoxService).
  • Leituras de easypanel_raw ignoram o modo somente leitura — somente leitura bloqueia apenas escritas. Uma leitura bruta pode retornar dados sensíveis; use EASYPANEL_RAW_DISABLED=1 em ambientes não confiáveis.
  • Ferramentas de cluster — list_nodes retorna apenas o nó local em configurações de servidor único (sem cluster Swarm).
  • Eventos Docker são apenas em tempo real (sem histórico) — um servidor ocioso pode retornar uma janela vazia.

Testando sem Claude

npx @modelcontextprotocol/inspector dist/index.js

Abre uma interface de navegador onde você pode chamar qualquer ferramenta manualmente e inspecionar a resposta.


Comparação com pacotes semelhantes

Recursoeasypanel-mcp-servereasypanel-mcp (sitp2k)
Ferramentas curadas57~15
Acesso bruto a todas as ~375 operações da API✅ (easypanel_raw)❌
Método de autenticaçãoBearer tokenEmail + senha
Proteção de confirmação✅❌
Modo somente leitura✅❌
Execução de contêiner + logs ao vivo (WebSocket)✅❌
Volumes / portas / compose / recursos✅❌
Manutenção do servidor (prune / reboot)✅❌
Atualização segura de ambiente (ler-modificar-escrever)✅❌
Ocultação de segredos e mascaramento de valores✅❌
Habilidade complementar do Claude✅❌
Limitações conhecidas documentadas✅❌

🤝 Contribuindo

Contribuições são bem-vindas! Veja CONTRIBUTING.md para saber como adicionar ferramentas, relatar bugs e abrir PRs.


👤 Autor

Criado por Helbert Paranhos da Strat Academy.

Instagram YouTube LinkedIn Buy Me A Coffee

Se este projeto foi útil, considere dar uma ⭐ e seguir a Strat Academy para mais conteúdo de automação com IA.


📄 Licença

MIT © Helbert Paranhos / Strat Academy

Veja LICENSE para detalhes.