MCP Server¶
Expose the StarkOne panel to AI agents (Claude Code, Claude Desktop, and any other MCP-compatible client) over the Model Context Protocol.
Access is granted through MCP keys: long-lived credentials bound to an existing panel user. A key can never do more than its owning user is permitted to do - it can only be narrowed further.
Enabling¶
Enable the MCP Server plugin from Plugins, then open MCP Server in the sidebar to issue keys. The screen requires the MCP Server permission (AI group in the user editor); superusers have it implicitly.
Security model¶
Every tool call is executed against the panel's own REST API using a short-lived
(2 minute) token minted for the key's owner. The request then passes through the
panel's normal pipeline - the same authentication and RequirePermission checks a
browser session goes through. Authorization is therefore never reimplemented.
Three layers apply, in order:
- Read-only - when set, the key may only issue
GETrequests. - Scopes - when one or more scopes are selected, the key may only reach paths in those categories. Selecting none means the key inherits everything the user has.
- User permissions - the panel's RBAC, always enforced, and always the ceiling.
Scope categories mirror the panel's permission slugs:
| Scope | Covers |
|---|---|
websites_management |
webapps, databases, DNS, SSL, cron, FTP, backups, aliases, Varnish, git |
websites_administration |
website administration operations |
administrative_operations |
server info, services, plugins, settings (default for unmapped paths) |
firewall_management |
firewall (CSF) |
booting_users_management |
panel users |
Keys can additionally be given an expiry, disabled without deletion, or revoked. The plaintext key is shown once at creation and stored only as a SHA-256 hash. Creation and deletion are written to the activity log.
Panel TLS certificate¶
MCP clients verify the panel's certificate before connecting. The panel is normally reached by IP, so the certificate must list that IP in its Subject Alternative Name extension - a certificate carrying only a Common Name is rejected outright by browsers, Go and Node.
The MCP screen shows the installed certificate, which addresses it covers, and
whether any of the server's own addresses are missing. Generate certificate &
restart panel issues a fresh self-signed certificate covering every local
address (plus any extra hostnames or IPs you list), backs up the previous pair
as panel.crt.bak / panel.key.bak, and restarts the panel to load it.
Fresh installs generate a SAN-bearing certificate automatically at first start.
Keeping verification enabled¶
Rather than disabling TLS checks in your client, download the certificate and pin it:
curl -k -o starkone-panel.crt https://panel.example.com:2087/api/mcp-keys/tls/download
export NODE_EXTRA_CA_CERTS=$PWD/starkone-panel.crt
Disabling verification (for example NODE_TLS_REJECT_UNAUTHORIZED=0) turns it
off for every host the client talks to, not just this panel - pinning does not.
Connecting a client¶
The endpoint is:
Authenticate with the key as a bearer token. For Claude Code:
claude mcp add --transport http starkone https://panel.example.com:2087/api/mcp \
--header "Authorization: Bearer mcp_..."
Or in an MCP client config file:
{
"mcpServers": {
"starkone": {
"type": "http",
"url": "https://panel.example.com:2087/api/mcp",
"headers": { "Authorization": "Bearer mcp_..." }
}
}
}
The management screen generates both snippets with the key filled in.
Transport¶
MCP Streamable HTTP over POST, carrying JSON-RPC 2.0. The transport is stateless:
no session id is issued, and each request carries its own credential. Supported
methods are initialize, ping, tools/list, and tools/call.
Tools¶
Convenience tools cover common operations:
list_websites, get_website, list_website_databases, get_dns_zone,
list_website_backups, website_ssl_status, list_website_crontab,
server_info, list_services, activity_log, list_users, firewall_status,
list_plugins, system_updates, service_action
Two generic tools give access to everything else:
list_endpoints- discover the REST API; accepts an optionalquerysubstring to filter (e.g.backup,dns).api_call- invoke any endpoint withmethod,path, and an optionalbody. Subject to the same read-only, scope, and permission checks.
This keeps the tool list small enough for models to use well while leaving the full API reachable.