Labsco
helbertparanhos logo

easypanel-mcp-server

from helbertparanhos

MCP Server for full Easypanel control via Claude Code, Cursor and Claude Desktop.

πŸ”₯πŸ”₯πŸ”₯βœ“ VerifiedAccount requiredNeeds API keys

easypanel-mcp-server

MCP Server for full Easypanel control via Claude Code, Cursor and Claude Desktop.

Glama Quality


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 versionUse
any (recommended)easypanel-mcp-server@latest (v2.x) β€” auto-detects the panel's API generation, works on both
≀ 2.30.x only, pinnedeasypanel-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).


Environment variables

VariableRequiredDefaultDescription
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β€”fullSet 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 watches list_actions until it completes.

"Why is my service down?" β€” Claude calls get_service_error, get_service_logs and get_build_logs, and can exec_in_container to inspect files/env live.

"Add DATABASE_URL to staging" β€” Claude reads current env vars with get_env_vars, adds only the new key with set_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) and create_port, both applied on the next deploy.

"My disk is full" β€” Claude runs get_storage_stats, then cleanup_docker_images or prune_docker (with confirmation) to reclaim space.

"Show me the Traefik dashboard config" β€” for anything without a dedicated tool, Claude uses trpc_raw to call the procedure directly.


Available tools (57)

CategoryTools
Projectslist_projects, get_project, create_project, delete_project ⚠️
Servicesinspect_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
Env Varsget_env_vars, set_env_var, delete_env_var ⚠️
Logsget_service_logs, get_build_logs, get_system_stats
Containerslist_containers, exec_in_container ⚠️, get_docker_events
Domainslist_domains, add_domain, remove_domain ⚠️, set_primary_domain
Databasescreate_database, inspect_database, destroy_database ⚠️
Volumes / Mountslist_mounts, create_mount ⚠️
Portslist_ports, create_port ⚠️
Composecreate_compose, inspect_compose, deploy_compose
Monitoringget_docker_stats, get_storage_stats, get_service_stats
Maintenanceprune_docker ⚠️, cleanup_docker_images
Server / Infralist_users, list_certificates, list_nodes, restart_panel ⚠️, reboot_server ⚠️
Raw accesstrpc_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.

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

Featureeasypanel-mcp-servereasypanel-mcp (sitp2k)
Curated tools57~15
Raw access to all ~347 proceduresβœ… (trpc_raw)❌
Auth methodBearer tokenEmail + 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.