easypanel-mcp-server is an MCP server for Easypanel, created by Helbert Paranhos / Strat Academy. Through the Model Context Protocol, it connects Claude Code, Cursor, and Claude Desktop directly to an Easypanel instance—a modern Docker-based server control panel. The goal is to free users from switching back and forth between the editor and the Easypanel dashboard, and instead let them complete all control within Claude using natural language.
Purpose and Positioning It maps the Easypanel API into 57 typed tools across 15 categories, and provides an easypanel_raw escape hatch that can reach the parts of Easypanel's roughly 375 API operations not covered by dedicated tools. It supports all three generations of the API: the tRPC API of Panel 2.30 and below, the RPC layer of 2.31–2.32, and the public API introduced in Easypanel 2.33, and automatically detects which generation the panel belongs to.
Main Capabilities Natural language can be used to: deploy from GitHub, update environment variables, read live logs, exec into containers, manage domains, databases, volumes, and ports, set resource limits, run Docker maintenance, and monitor the server. Specific examples include: having Claude list projects, check the current service, trigger deploy_service and watch list_actions until completion; calling get_service_error, get_service_logs, and get_build_logs to troubleshoot service failures, and using exec_in_container to inspect files or the environment in real time; using get_env_vars to read existing environment variables, using set_env_var to add only a new key (without clearing other variables) and reminding to redeploy; using set_service_resources to read the current limits and merge changes; using create_mount to create a named volume and create_port to expose a port; using get_storage_stats followed by cleanup_docker_images or prune_docker to reclaim space; for features without dedicated tools, use easypanel_raw to call procedures directly.
How to Use Prerequisites: a running and reachable Easypanel instance; generate an API token in Easypanel → Settings → API → Generate Token; Node.js ≥ 18 and Claude Code, Cursor, or Claude Desktop. There are two installation methods: Method A uses npx (no installation required), adding .mcp.json at the project root; Method B builds locally. In Cursor, EASYPANEL_URL and EASYPANEL_TOKEN can be set in Settings → Tools & MCPs → Environment Variables to reuse environment variables across projects. Default projects and services can be written into the project's CLAUDE.md so Claude knows the default target of operations. No need to copy folders; one MCP installation can serve all projects. A companion skill /ep is also provided; once installed, /ep can be used for an interactive deployment workflow.
API Versions and Compatibility Easypanel changed its API twice in a short period. 2.31 replaced the internal tRPC API with an RPC layer (/api/rpc/*), and on panels ≥ 2.31, all v1.x calls with parameters fail with 400 Input validation failed. 2.33 released a documented public API (/api/<operation>, GET for reads, POST for writes), and stated that the old internal API may change at any time and should not be relied upon. v3 targets the public API on these panels. On the first call, v3 detects the generation with a single probe request (cached) and records the panel version to stderr. Detection can be skipped by setting EASYPANEL_API_FLAVOR to trpc, rpc, or public. When upgrading from v2, if EASYPANEL_API_FLAVOR=rpc was pinned to bypass the 2.32 issue, it should be removed.
Comparison with Easypanel's Built-in MCP Easypanel 2.33 also ships with an MCP endpoint (/api/mcp), which is public A thin wrapper around the API. This project takes a different trade-off. Using both at the same time is fine and they will not conflict.
Security features Every response involving a specific project or service begins with a context banner; destructive or production-affecting operations return BLOQUEADO until confirm: "CONFIRMO" is received; setting MCP_ACCESS_MODE=readonly blocks all writes at the source (client.mutate), covering curated tools and easypanel_raw, while reads remain available; easypanel_raw validates the operation name (flat or namespace.procedure, no path or query injection), requires the input to be an object (≤ 50KB), and requires CONFIRMO for any change, and setting EASYPANEL_RAW_DISABLED=1 disables it completely; list_users strips the apiToken, twoFactorSecret, and password fields; set_env_var and delete_env_var use read-modify-write to prevent accidentally clearing all variables because the Easypanel API replaces the entire env string on every update; get_env_vars masks keys matching SECRET, PASSWORD, TOKEN, KEY by default, and include_values: true can be used to show them; HTTP errors and WebSocket failures are logged to stderr, generic messages are exposed to the model, and bearer tokens do not enter the model context; projectName and serviceName are validated against ^[a-z0-9][a-z0-9_-]*$ before being used to build Docker service names or WebSocket queries, ports are validated as integers from 1–65535, and resource values must be positive numbers.
Implementation notes The Easypanel panel communicates with its backend via tRPC (/api/trpc/<router>.<procedure>), not a public REST API, and this server uses the same endpoints. Reads are tRPC queries, writes are tRPC mutations. Live logs, container exec, and Docker events use the panel's WebSocket channels (/ws/serviceLogs, /ws/containerShell, /ws/dockerEvents), the same ones used by the UI, so it works without the licensed Advanced Logs (Loki). Some input schemas (mounts, ports, resources) have been verified against real Easypanel and written into the API reference.
Known limitations WordPress / Box service types are not exposed as dedicated tools and must be accessed via easypanel_raw (such as inspectWordPressService, createBoxService). easypanel_raw reads bypass read-only mode; read-only mode only blocks writes; raw reads may return sensitive data, so EASYPANEL_RAW_DISABLED=1 should be used in untrusted environments. Among cluster tools, list_nodes returns only the local node in a single-server setup (no Swarm cluster). Docker events are live only (no history), and an idle server may return an empty window.
Testing and contributing How to test without Claude: open the browser UI, manually call any tool, and inspect the response. Contributions are welcome; see CONTRIBUTING.md for how to add tools, report bugs, and submit PRs. The project is licensed under MIT.