Manage a CloudPanel v2 server from Claude Code: sites, databases, certificates and nginx vhosts, with backups, config validation and automatic rollback.
CloudPanel has no HTTP API, its PHP source is obfuscated, and its CLI can create
and delete sites but not change them. There is no site:update, and not even a
site:list. This plugin closes that gap. It reads state from CloudPanel's own
SQLite database, uses clpctl where a command exists, and writes vhost
configuration itself where none does.
Every write is backed up first, validated with nginx -t, and rolled back
automatically if nginx rejects the result.
- A CloudPanel v2 server (developed against 2.5.4)
- Root access
- Claude Code
sqlite3,jq,openssl,python3,nginx,curl, andgitfor the clone path
/clp-doctor verifies all of these at runtime, and ./install.sh --check does
it before installing anything.
Claude Code can load the marketplace straight from GitHub. Nothing to clone:
/plugin marketplace add HashfoxGmbH/cloudpanel-claude-plugin
/plugin install cloudpanel@hashfox
Or from a shell:
claude plugin marketplace add HashfoxGmbH/cloudpanel-claude-plugin
claude plugin install cloudpanel@hashfox --yesStart a new Claude Code session afterwards, then run /clp-doctor first. That
also covers the requirement check, which this path otherwise skips.
To update:
claude plugin marketplace update hashfoxUse this when you want the requirements verified before anything is installed, when the server has no access to GitHub, or when you plan to modify the plugin.
git clone https://github.com/HashfoxGmbH/cloudpanel-claude-plugin /opt/cloudpanel-claude-plugin
cd /opt/cloudpanel-claude-plugin
./install.sh./install.sh --check # verify requirements only, change nothing
./install.sh --uninstall # remove plugin and marketplace entryinstall.sh is plain bash and needs only git and claude. It checks every
requirement, refuses to run rather than leaving a half-installed plugin behind,
and verifies afterwards that the plugin actually loads. To update this way:
git pull && ./install.sh.
Two notes for the clone path. Do not clone into /tmp, since hardened servers
mount it noexec and ./install.sh then fails with "Permission denied"
despite the executable bit. And do not move or delete the clone afterwards,
because the marketplace entry points at it. After a move, run ./install.sh
again at the new location.
The repository also ships install.js and a package.json for npm. That path
is the weakest one here: CloudPanel servers usually get Node through nvm per
site user, and npm is often not installed system-wide at all.
claude plugin uninstall cloudpanel@hashfox
claude plugin marketplace remove hashfoxBackups under /var/backups/clp-plugin/ and generated passwords under
/root/.clp-secrets/ are left in place on purpose.
Start a new Claude Code session after installing.
| Command | What it does |
|---|---|
/clp-doctor |
Host profile. Run this first on a server you do not know. |
/clp-sites |
List all sites with type, user, runtime and Varnish status |
/clp-site <domain> |
Everything about one site |
/clp-health |
Services, nginx config, disk, certificates |
/clp-vhost <domain> |
Inspect and edit a vhost |
/clp-site-add <domain> |
Create a site |
/clp-db [domain] |
List or create databases |
One rule the plugin holds Claude to: inside /home/<site-user>/ it works as
that site user, never as root. A file created by root there is owned by root
and the application can no longer write it.
The scripts also run standalone, without Claude Code:
plugins/cloudpanel/scripts/clp-doctor.sh
plugins/cloudpanel/scripts/clp-query.sh sites
plugins/cloudpanel/scripts/clp-vhost.sh check example.comSupported:
- Read sites, databases, users, certificates, cron jobs and vhost templates
- Create PHP, Node.js, Python, reverse proxy and static sites
- Create databases, request Let's Encrypt certificates, install your own
- Edit vhost configuration, with backup and rollback
- Delete sites, behind an explicit confirmation flag
Not supported, with reasons:
- Changing PHP version, Varnish, basic auth or PHP limits per site. CloudPanel exposes none of this on the CLI. Only the web UI can do it.
- Managing Node.js or Python processes. CloudPanel sets up the site and the reverse proxy, but the process itself is pm2 for Node (as the site user) or uWSGI for Python (a system service running under the site user's uid). The skill documents both setups; the plugin does not wrap either.
- Per-site settings that live only in the UI: basic auth, blocked IPs and bots, Cloudflare-only traffic, PHP limits, PageSpeed. The plugin reads and reports them so they do not get mistaken for a fault, but cannot change them.
| Script | Tier | Purpose |
|---|---|---|
clp-doctor.sh |
read | Host profile: requirements, DNS, certificates, drift |
clp-query.sh |
read | Opens the database read-only and changes nothing |
clp-site.sh |
create | Wraps clpctl for sites, databases, certificates |
clp-vhost.sh |
modify | Writes vhosts directly, with backup and rollback |
CloudPanel keeps a template with placeholders in site.vhost_template and
renders it to /etc/nginx/sites-enabled/<domain>.conf. The substitution rules
live in the obfuscated PHP source.
Rather than reimplementing them, clp_vhost_render.py derives them. It matches
the current template against the current rendered file as a regular expression,
turning each placeholder into a capture group. That yields exactly the values
CloudPanel itself substituted, including multi-line ones such as
{{php_settings}}.
Verified against 20 production sites: template, render, compare to file is byte-identical for all 20.
clp-vhost.sh check <domain> reports whether this holds for a given site. If it
does not, the file was edited by hand and only set-file is available, which a
later save in the web UI will discard.
Which clpctl commands exist depends on who runs them.
| Caller | Commands |
|---|---|
/usr/bin/clpctl as root |
site:add:*, site deletion, db:add, user:*, lets-encrypt:*, vhost-template:* |
a site user, or clp |
db:export, db:import, db:backup, varnish-cache:purge, system:permissions:reset |
A su - clp before the call yields the wrong set and reports
Command "site:add:php" is not defined for a command that does exist. This
costs hours to diagnose, so the plugin handles it. clp_ctl calls directly as
root, clp_ctl_as <user> covers the other set.
- Every write creates a backup under
/var/backups/clp-plugin/first nginx -truns after each change; a failure triggers an automatic rollback of both the file and the database recordnginxis only ever reloaded, never restarted, so a bad config cannot take all sites offline- Deleting a site requires an explicit
--i-know-what-i-doflag, and a PreToolUse hook blocks the rawclpctlcall - A PostToolUse hook validates nginx after any edit under
/etc/nginx - Generated passwords are written to
/root/.clp-secrets/with mode 0600 instead of being printed
One caveat that cannot be fixed from outside CloudPanel: clpctl accepts
passwords only as command line arguments, so sudo logs them in cleartext to
/var/log/auth.log, readable by group adm. The scripts point this out after
creating a site. Change the password in the web UI if that matters to you.
The plugin holds no facts about any particular server. Which PHP versions are in
use, which domains no longer resolve to this host, where a vhost template and
its rendered file have diverged: /clp-doctor determines all of that at
runtime.
If your server has lasting quirks worth remembering, put them in your project
memory or a CLAUDE.md, not into the plugin.
The clpctl options were decoded from the obfuscated source of CloudPanel
2.5.4. clp-site.sh and /clp-doctor warn when a different version is running.
After a CloudPanel update, verify the options before running write commands.
.claude-plugin/marketplace.json marketplace manifest
install.sh installer (bash, no node required)
install.js installer for npm/npx
plugins/cloudpanel/
.claude-plugin/plugin.json plugin manifest
commands/ slash commands
hooks/ PreToolUse and PostToolUse guards
scripts/ the actual implementation
skills/cloudpanel/SKILL.md what Claude needs to know about CloudPanel
Shell code is checked with shellcheck -x, Python with python3 -m py_compile.
Both are clean.
MIT, see LICENSE.