easypanel-mcp-server
About
MCP Server for full Easypanel control via Claude Code, Cursor and Claude Desktop.
Details
- Author
- helbertparanhos
- Categories
- Cloud Service, Other, AI, Infrastructure
Jump to
Setup
Install easypanel-mcp-server in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/helbertparanhos/easypanel-mcp-server
Follow the installation instructions in the repository README, then restart your MCP client.
MCP Server for full Easypanel control via Claude Code, Cursor and Claude Desktop.
easypanel-mcp-serverconnects Claude Code, Cursor and Claude Desktop directly to yourEasypanelinstance — a modern Docker-based server control panel — through the Model Context Protocol.
Instead of switching between your editor and the Easypanel dashboard, you control everything from inside Claude: deploy from GitHub, update env vars, read live logs, exec into containers, manage domains, databases, volumes and ports, set resource limits, run Docker maintenance and monitor your server — all in natural language.
It maps the Easypanel API to57 typed toolsacross 15 categories, plus a singleeasypanel_rawescape hatch that reachesanyof Easypanel's ~375 API operations for everything not covered by a dedicated tool. It speaksall three API generations— the tRPC API of panels ≤ 2.30, the RPC layer of 2.31–2.32, and thepublic API introduced in Easypanel 2.33— auto-detecting which one your panel uses. Every destructive action is gated behind an explicit confirmation, every response opens with a context banner so Claude always knows what it is touching, and an optional read-only mode lets you connect safely to a production panel.
📖 API reference:docs/easypanel-api.md— architecture, the API generations, confirmed operations mapped tool-by-tool, and how to discover new ones.
Easypanel changed its API twice in quick succession:
- 2.31replaced the internal tRPC API with an RPC layer (/api/rpc/). On panels ≥ 2.31, every v1.x call that carries parameters fails with400 Input validation failed.
- 2.33shipped adocumented public API(/api/<operation>, GET for reads, POST for writes) and stated that the old internal API"may change without notice and should not be relied upon". v3 targets the public API on those panels.
v3 detects the generation with a single probe request on first call (cached) and logs the panel version to stderr. To skip detection, setEASYPANEL_API_FLAVORtotrpc(≤ 2.30),rpc(2.31–2.32) orpublic(≥ 2.33).
Upgrading from v2?If you pinnedEASYPANEL_API_FLAVOR=rpcto work around the 2.32 issues,remove it— otherwise the client stays on the internal API that Easypanel now declares unstable.
This MCP vs. Easypanel's built-in MCP
Easypanel 2.33 also ships its own MCP endpoint (/api/mcp, connection details next to your API key). It's a thin wrapper over the public API. This server is a different trade-off:
Using both at once is fine — they don't conflict.
- Easypanel instance running and accessible
- API token — generate atEasypanel → Settings → API → Generate Token
- Node.js ≥ 18 and Claude Code, Cursor or Claude Desktop
{ "mcpServers": { "easypanel-mcp": { "command": "npx", "args": ["-y", "easypanel-mcp-server"], "env": { "EASYPANEL_URL": "https://your-panel.example.com", "EASYPANEL_TOKEN": "your-api-token" } } } }
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" } } } }
InCursor Settings → Tools & MCPs → Environment Variables, set:
- EASYPANEL_URL=https://your-panel.example.com
- EASYPANEL_TOKEN=your-api-token
Then your.cursor/mcp.jsonuses references that apply automatically to every project:
{ "mcpServers": { "easypanel-mcp": { "command": "npx", "args": ["-y", "easypanel-mcp-server"], "env": { "EASYPANEL_URL": "${EASYPANEL_URL}", "EASYPANEL_TOKEN": "${EASYPANEL_TOKEN}" } } } }
Place this in your project'sCLAUDE.mdso Claude knows which Easypanel project and service it should operate on by default:
## Easypanel Project: my-project | Service: my-api | Branch: main Repo: owner/repo`
No folder copying needed — one MCP install serves all your projects.
"Deploy my app"— Claude lists projects, inspects the current service, triggersdeploy_service, then watcheslist_actionsuntil it completes.
"Why is my service down?"— Claude callsget_service_error,get_service_logsandget_build_logs, and canexec_in_containerto inspect files/env live.
"Add DATABASE_URL to staging"— Claude reads current env vars withget_env_vars, adds only the new key withset_env_var(never wipes others), and reminds you to redeploy.
"Give this service 512MB and half a core"— Claude callsset_service_resources(reads current limits and merges your change) and reminds you to restart.
"Persist /app/data and expose port 5432"— Claude callscreate_mount(named volume) andcreate_port, both applied on the next deploy.
"My disk is full"— Claude runsget_storage_stats, thencleanup_docker_imagesorprune_docker(with confirmation) to reclaim space.
"Show me the Traefik dashboard config"— for anything without a dedicated tool, Claude useseasypanel_rawto call the procedure directly.
⚠️ = requiresconfirm: "CONFIRMO". Forexec_in_container,create_mount,create_portandeasypanel_rawthe confirmation isconditional(only for destructive commands, sensitive host-path bind mounts, privileged ports< 1024, and writes respectively).
Full tool descriptions with parameters are inllms.txt. For the underlying API (all generations), seedocs/easypanel-api.md.
easypanel_raw— reach any of the ~375 operations
Covering every Easypanel operation with a typed tool isn't practical, so anything without a dedicated tool is reachable directly:
// 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" }
Areas only reachable viaeasypanel_raw: Traefik, branding, Cloudflare Tunnel, Box, middlewares, notifications, volume/database backups, WordPress, storage providers, Docker builders, Git keys, cluster and update management. To discover names, readGET <your-panel>/api/openapi.json.
The client classifies each operation against the panel's own OpenAPI spec,fail-closed: a read only executes if the spec says it's a read, so writes can't sneak pastreadonlymode or the confirmation gate — and the reverse is caught too (calling a read withisMutation:trueis refused with a clear message). On2.33+ that classification is exact, since the public API declares GET for reads and POST for writes. On 2.31 it's the documented HTTP method; on 2.32, where the spec is POST-only and carries no such marker, the client falls back to the panel's naming convention (get/list/inspect/check/query/search= read, anything else = write), restricted to operations present in the spec.
One deliberate exception: on 2.33+ the panel validates query paramswithout type coercion, so?limit=5arrives as the string"5"and is rejected. Whenever an input carries a non-string value, the client routes that read through the internal/api/rpctransport (which sends JSON in the body) and logs the reason to stderr. The read/write classification still comes from the spec first, so the guard is unaffected.
Every response that touches a specific project/service starts with:
[Contexto ativo: projeto="my-project" | serviço="my-api"]
Claude always knows what it is modifying before taking any action.
Destructive or production-impacting actions returnBLOQUEADOuntil they receiveconfirm: "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." }
This gates project/service deletion, stop/rename, env/domain removal, database destruction, the global server ops (prune_docker,restart_panel,reboot_server), and — conditionally — dangerous container commands, sensitive bind mounts, privileged ports and raw mutations.
SetMCP_ACCESS_MODE=readonlyto blockeverywrite at the source (client.mutate), covering both curated tools andeasypanel_raw. Reads remain available — perfect for a production panel you only want to inspect.
easypanel_rawvalidates the operation name (flat ornamespace.procedure, no path/query injection), requires theinputto be an object (≤ 50KB), and demandsCONFIRMOfor any mutation. SetEASYPANEL_RAW_DISABLED=1to turn it off entirely.
list_usersstripsapiToken,twoFactorSecretand password fields before returning — onlyid,email,admin,twoFactorEnabledandcreatedAtreach the model.
set_env_varanddelete_env_varread the current state, apply only the requested change, and write back. The Easypanel API replaces the entire env string on every update — without this protection it is easy to accidentally wipe all variables at once.
get_env_varsmasks values whose key matchesSECRET,PASSWORD,TOKEN,KEYby default. Passinclude_values: trueto reveal.
HTTP errors and WebSocket failures are logged to stderr and surfaced to the model as a generic message — the bearer token (sent in the WebSocket query string, as Easypanel requires) never reaches the model context.
projectName/serviceNameare validated against^[a-z0-9][a-z0-9_-]$before being used to build a Docker service name or WebSocket query (defense-in-depth against target confusion / parameter injection). Ports are validated as integers1–65535; resource values must be positive numbers.
Install the workflow skill for guided deploy operations in Claude Code:
mkdir -p ~/.claude/skills/ep cp skill/SKILL.md ~/.claude/skills/ep/SKILL.md
Then use/epfor an interactive deploy workflow without needing to remember tool names.
The Easypanel panel talks to its backend overtRPC(/api/trpc/<router>.<procedure>), not a public REST API. This server uses the same endpoints:
- Readsare tRPC queries;writesare tRPC mutations — seedocs/easypanel-api.md./ws/serviceLogs
- Live logs, container exec and Docker eventsuse the panel's WebSocket channels (,/ws/containerShell,/ws/dockerEvents) — the same ones the UI uses — so they work without the licensed Advanced Logs (Loki).
- A few input schemas (mounts, ports, resources) werevalidated against a live Easypaneland are documented in the API reference.
- WordPress / Box service types— not exposed as dedicated tools; reach them viaeasypanel_raw(e.g.inspectWordPressService,createBoxService).easypanel_raw
- reads bypass read-only mode— read-only blocks writes only. A raw read can return sensitive data; useEASYPANEL_RAW_DISABLED=1in untrusted environments.list_nodes
- Cluster tools—returns the local node only on single-server setups (no Swarm cluster).
- Docker eventsare real-time only (no history) — an idle server may return an empty window.
npx @modelcontextprotocol/inspector dist/index.js`
Opens a browser UI where you can call any tool manually and inspect the response.
Contributions are welcome! SeeCONTRIBUTING.mdfor how to add tools, report bugs and open PRs.
Created byHelbert ParanhosfromStrat Academy.
If this project was useful, consider giving it a ⭐ and followingStrat Academyfor more AI automation content.
Competitive intelligence platform with 24 tools — monitor competitor pricing, content, positioning, tech stacks, and how ChatGPT, Claude, and Gemini rank your brand.
A Model Context Protocol (MCP) server for managing app publishing on Huawei AppGallery Connect. Integrates directly with Claude Desktop or any MCP-compatible client.
Interact with Infactory APIs using Claude and other large language models.
Connect your Shopify store to Claude, Cursor, or Windsurf and get 100+ pre-calculated ecommerce metrics like net profit, blended CAC, per-channel ROAS, and customer LTV segments.
Run Proxmox VE and Backup Server from Claude — 69 token-efficient, safety-gated tools with dry-run previews and a tamper-evident audit trail.
Create and publish websites from ChatGPT, Claude, Codex, Cline, and other AI agents with no account required and optional free custom domains.
A serverless Monzo → Claude connector on Cloudflare Workers
There are already a few Monzo MCP servers (partymola, BfdCampos, an npm one), and they're good — but they're all local stdio servers you run on your own machine. This is the first remote/serverless one I've found: it lives on a Cloudflare Worker, so you authenticate once and it follows you to every Claude surface, with nothing to keep running.
AI code reviews for GitHub, GitLab, Azure DevOps & Bitbucket PR/MR URLs from Cursor, Claude, or Copilot.
The DataFast MCP server lets MCP-compatible clients such as Codex, Claude Code, and Cursor query your analytics and manage your account through natural language.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





