easypanel-mcp-server Server
Claude Code、Cursor、Claude DesktopからEasypanelを完全に制御するためのMCPサーバー。
ドキュメント
easypanel-mcp-server
MCP Server for full Easypanel control via Claude Code, Cursor and Claude Desktop.
What is this
easypanel-mcp-server connects Claude Code, Cursor and Claude Desktop directly to your Easypanel instance — 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 to 57 typed tools across 15 categories, plus a single trpc_raw escape hatch that reaches any of Easypanel's ~350 procedures (40+ namespaces) for everything not covered by a dedicated tool. It speaks both API generations — the tRPC API of panels ≤ 2.30 and the new RPC layer introduced in Easypanel 2.31 — 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 43 namespaces, confirmed procedures mapped tool-by-tool, and how to discover new ones.
Compatibility
Easypanel 2.31 replaced its internal tRPC API with a new RPC layer (/api/rpc/*, OpenAPI at /api/openapi.json). On panels ≥ 2.31, every v1.x call that carries parameters fails with 400 Input validation failed.
| Your Easypanel version | Use |
|---|---|
| any (recommended) | easypanel-mcp-server@latest (v2.x) — auto-detects the panel's API generation, works on both |
| ≤ 2.30.x only, pinned | easypanel-mcp-server@legacy (v1.3.x) — frozen tRPC-only line, last validated against v2.30.1 |
v2.x detects the generation with a single probe request on first call (cached). To skip detection, set EASYPANEL_API_FLAVOR=trpc (≤ 2.30) or EASYPANEL_API_FLAVOR=rpc (≥ 2.31).
Prerequisites
- Easypanel instance running and accessible
- API token — generate at Easypanel → Settings → API → Generate Token
- Node.js ≥ 18 and Claude Code, Cursor or Claude Desktop
Quick start
Option A — npx (no install needed)
Add .mcp.json to your project root:
{
"mcpServers": {
"easypanel-mcp": {
"command": "npx",
"args": ["-y", "easypanel-mcp-server"],
"env": {
"EASYPANEL_URL": "https://your-panel.example.com",
"EASYPANEL_TOKEN": "your-api-token"
}
}
}
}
Option B — local build
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 — reuse env vars across projects
In Cursor Settings → Tools & MCPs → Environment Variables, set:
EASYPANEL_URL=https://your-panel.example.comEASYPANEL_TOKEN=your-api-token
Then your .cursor/mcp.json uses 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}"
}
}
}
}
Environment variables
| Variable | Required | Default | Description |
|---|---|---|---|
EASYPANEL_URL | ✅ | — | Panel URL, no trailing slash (e.g. https://panel.example.com) |
EASYPANEL_TOKEN | ✅ | — | API token (Easypanel → Settings → API → Generate Token) |
MCP_ACCESS_MODE | — | full | Set to readonly to block all writes (curated tools and trpc_raw). Reads stay available — ideal for connecting to a production panel for inspection only. |
EASYPANEL_API_FLAVOR | — | (auto) | Force the panel's API generation instead of auto-detecting: trpc (≤ 2.30) or rpc (≥ 2.31). Aliases: legacy / modern. |
EASYPANEL_RAW_DISABLED | — | (enabled) | Set to 1 to fully disable the trpc_raw escape hatch. Recommended when the MCP is exposed to untrusted content (prompt-injection risk), since trpc_raw reads can return secrets and are not covered by read-only mode. |
Adding context to a project
Place this in your project's CLAUDE.md so 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.
Use cases
"Deploy my app" — Claude lists projects, inspects the current service, triggers
deploy_service, then watcheslist_actionsuntil it completes.
"Why is my service down?" — Claude calls
get_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 with
get_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 calls
set_service_resources(reads current limits and merges your change) and reminds you to restart.
"Persist /app/data and expose port 5432" — Claude calls
create_mount(named volume) andcreate_port, both applied on the next deploy.
"My disk is full" — Claude runs
get_storage_stats, thencleanup_docker_imagesorprune_docker(with confirmation) to reclaim space.
"Show me the Traefik dashboard config" — for anything without a dedicated tool, Claude uses
trpc_rawto call the procedure directly.
Available tools (57)
| Category | Tools |
|---|---|
| Projects | list_projects, get_project, create_project, delete_project ⚠️ |
| Services | inspect_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 / GitHub | set_source_github, set_source_image, enable_github_deploy, disable_github_deploy, list_actions, get_action |
| Env Vars | get_env_vars, set_env_var, delete_env_var ⚠️ |
| Logs | get_service_logs, get_build_logs, get_system_stats |
| Containers | list_containers, exec_in_container ⚠️, get_docker_events |
| Domains | list_domains, add_domain, remove_domain ⚠️, set_primary_domain |
| Databases | create_database, inspect_database, destroy_database ⚠️ |
| Volumes / Mounts | list_mounts, create_mount ⚠️ |
| Ports | list_ports, create_port ⚠️ |
| Compose | create_compose, inspect_compose, deploy_compose |
| Monitoring | get_docker_stats, get_storage_stats, get_service_stats |
| Maintenance | prune_docker ⚠️, cleanup_docker_images |
| Server / Infra | list_users, list_certificates, list_nodes, restart_panel ⚠️, reboot_server ⚠️ |
| Raw access | trpc_raw ⚠️ |
⚠️ = requires confirm: "CONFIRMO". For exec_in_container, create_mount, create_port and trpc_raw the confirmation is conditional (only for destructive commands, sensitive host-path bind mounts, privileged ports < 1024, and write mutations respectively).
Full tool descriptions with parameters are in llms.txt. For the underlying API (both generations), see docs/easypanel-api.md.
trpc_raw — reach any of the ~350 procedures
Covering every Easypanel procedure with a typed tool isn't practical, so anything without a dedicated tool is reachable directly:
// read (default)
{ "procedure": "certificates.listCertificates" }
{ "procedure": "traefik.getDashboard" }
// write — requires isMutation:true AND confirm:"CONFIRMO"
{ "procedure": "branding.updateSettings", "input": { /* ... */ },
"isMutation": true, "confirm": "CONFIRMO" }
Useful namespaces only reachable via trpc_raw: traefik.*, branding.*, cloudflareTunnel.*, box.*, middlewares.*, notifications.*, volumeBackups.*, databaseBackups.*, wordpress.*, git.*, update.*.
Procedure names use dot notation on both API generations — the client translates to the right transport. On panels ≥ 2.31 the client also validates the procedure against the panel's own OpenAPI spec, fail-closed: a trpc_raw read only executes if the spec documents the procedure as a query, so writes can't sneak past the readonly mode or the confirmation gate.
Safety features
Context banner
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.
Confirmation guard
Destructive or production-impacting actions return BLOQUEADO until they receive 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."
}
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.
Read-only mode
Set MCP_ACCESS_MODE=readonly to block every write at the source (client.mutate), covering both curated tools and trpc_raw. Reads remain available — perfect for a production panel you only want to inspect.
Raw escape-hatch controls
trpc_raw validates the procedure name (namespace.procedure, no path/query injection), requires the input to be an object (≤ 50KB), and demands CONFIRMO for any mutation. Set EASYPANEL_RAW_DISABLED=1 to turn it off entirely.
Secret redaction
list_users strips apiToken, twoFactorSecret and password fields before returning — only id, email, admin, twoFactorEnabled and createdAt reach the model.
Safe env vars (read-modify-write)
set_env_var and delete_env_var read 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.
Sensitive value masking
get_env_vars masks values whose key matches *SECRET*, *PASSWORD*, *TOKEN*, *KEY* by default. Pass include_values: true to reveal.
Token never leaks
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.
Input validation
projectName / serviceName are 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 integers 1–65535; resource values must be positive numbers.
Companion skill /ep
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 /ep for an interactive deploy workflow without needing to remember tool names.
How it works
The Easypanel panel talks to its backend over tRPC (/api/trpc/<router>.<procedure>), not a public REST API. This server uses the same endpoints:
- Reads are tRPC queries; writes are tRPC mutations — see
docs/easypanel-api.md. - Live logs, container exec and Docker events use the panel's WebSocket channels (
/ws/serviceLogs,/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) were validated against a live Easypanel and are documented in the API reference.
Known limitations
- WordPress / Box service types — not exposed as dedicated tools; reach them via
trpc_raw(e.g.wordpress.inspectService,box.createService). trpc_rawreads bypass read-only mode — read-only blocks writes only. A raw read can return sensitive data; useEASYPANEL_RAW_DISABLED=1in untrusted environments.- Cluster tools —
list_nodesreturns the local node only on single-server setups (no Swarm cluster). - Docker events are real-time only (no history) — an idle server may return an empty window.
Testing without Claude
npx @modelcontextprotocol/inspector dist/index.js
Opens a browser UI where you can call any tool manually and inspect the response.
Comparison with similar packages
| Feature | easypanel-mcp-server | easypanel-mcp (sitp2k) |
|---|---|---|
| Curated tools | 57 | ~15 |
| Raw access to all ~347 procedures | ✅ (trpc_raw) | ❌ |
| Auth method | Bearer token | Email + password |
| Confirmation guard | ✅ | ❌ |
| Read-only mode | ✅ | ❌ |
| Container exec + live logs (WebSocket) | ✅ | ❌ |
| Volumes / ports / compose / resources | ✅ | ❌ |
| Server maintenance (prune / reboot) | ✅ | ❌ |
| Safe env update (read-modify-write) | ✅ | ❌ |
| Secret redaction & value masking | ✅ | ❌ |
| Companion Claude skill | ✅ | ❌ |
| Known limitations documented | ✅ | ❌ |
🤝 Contributing
Contributions are welcome! See CONTRIBUTING.md for how to add tools, report bugs and open PRs.
👤 Author
Created by Helbert Paranhos from Strat Academy.
If this project was useful, consider giving it a ⭐ and following Strat Academy for more AI automation content.
📄 License
MIT © Helbert Paranhos / Strat Academy
See LICENSE for details.