AI Assistant (MCP)
Last updated
jabali-mcp is a stdio MCP server that wraps the panel’s REST API as 75+ tools an AI assistant can call. It reimplements no auth, no validation, no scoping — every call goes through the same ownership checks the panel enforces for any API client, using your API token as your identity.
Marketing overview: jabali-panel.com/mcp. Source: github.com/shukiv/jabali-mcp. Full tool reference: docs/TOOLS.md.
What it is
- Transport: stdio. The MCP client launches the binary on demand — nothing runs when no client is attached.
- Language / binary: single Go binary, AGPL-3.0.
- Auth: Bearer token (
JABALI_API_TOKEN) minted from the panel’s tenant shell → API Tokens → MCP tab. Sent only to the configured panel URL over TLS. - Panel URL:
JABALI_PANEL_URL, e.g.https://panel.example:8443/api/v1.
Safety model
The server ships with four layers of guardrails. All four are on by default.
- Read-only by default. Mutating tools are not registered unless
JABALI_MCP_ALLOW_WRITE=1is set. Without it, an assistant that tries to call a write tool sees the tool doesn’t exist. - Two-step destructive actions. Deletes, restores, and password rotations always return a preview first. The tool executes only when re-called with
confirm: true. An assistant cannot destroy anything in one call. - Dry-run.
JABALI_MCP_DRY_RUN=1(or per-calldry_run: true) shows the exact REST request that would be sent, without sending it. Useful when writes are enabled and you’re not sure what a prompt will do. - Token boundary. Ownership is enforced server-side by the panel on every endpoint. The MCP server can’t reach anything your token can’t. A tenant token is scoped to that tenant’s resources only.
Every tool call is a normal REST request in your panel’s audit trail.
Install
Prebuilt binaries: https://github.com/shukiv/jabali-mcp/releases/latest.
Or install from source:
go install github.com/shukiv/jabali-mcp/cmd/jabali-mcp@latest
Setup
1. Mint a token
Log in to the panel as the tenant whose resources the assistant should manage. Go to API Tokens → MCP. The wizard generates a client-config JSON block with your token pre-filled — entirely in the browser, no server round-trip after the token is issued.
Use a tenant token, not the admin token, whenever possible. Ownership scoping means the assistant sees only that tenant’s domains, mailboxes, databases, etc.
2. Run the wizard
jabali-mcp init
Prompts for panel URL + token, verifies the connection, writes the config file the client will read.
3. Register with your client
Claude Code:
claude mcp add jabali -- jabali-mcp
Claude Desktop / Cursor / Windsurf / any client using the standard mcpServers block:
{
"mcpServers": {
"jabali": {
"command": "jabali-mcp",
"env": {
"JABALI_PANEL_URL": "https://panel.example:8443/api/v1",
"JABALI_API_TOKEN": "jat_…"
}
}
}
}
Environment variables
| Variable | Required | Purpose |
|---|---|---|
JABALI_PANEL_URL | yes | Panel REST API base URL. Include /api/v1 suffix. TLS required — no http://. |
JABALI_API_TOKEN | yes | Bearer token minted from the panel’s tenant shell. |
JABALI_MCP_ALLOW_WRITE | no (default 0) | Set to 1 to register mutating tools. Without it the server is read-only. |
JABALI_MCP_DRY_RUN | no (default 0) | Set to 1 to make every mutating call return the planned REST request instead of sending it. |
JABALI_CA_FILE | no | Path to a CA bundle. Point at your CA when the panel uses a self-signed or private-CA cert. TLS verification is always on — there is no way to disable it. |
Tool surface
75+ tools grouped by resource area:
- Domains:
list_domains,get_domain,diagnose_domain,get_domain_bandwidth,get_domain_whois,tail_web_log. - DNS:
list_dns_recordsand (in write mode) DNS record CRUD gated by panel validation. - SSL:
get_ssl_statusper domain. - Mail:
list_mailboxes,get_mailbox,list_forwarders,get_autoresponder,list_mail_logs. - Databases:
list_databases,get_database,list_database_users. - Applications:
list_applications,get_application,list_app_catalog. - Backups:
list_backups,get_backup_manifest. - Cron:
list_cron_jobs,get_cron_job,get_cron_log. - Files:
list_files,preview_file. - PHP:
get_php_settings,list_php_versions. - Ops:
list_activity,list_api_tokens,list_ssh_keys,get_disk_usage,whoami. - Meta:
report_issue(drafts a GitHub bug report with live diagnostics for you to review before posting).
The authoritative, always-up-to-date list is generated from the code: docs/TOOLS.md.
diagnose_domain is worth highlighting: a single call gathers domain config, SSL status, DNS records, recent nginx errors, and bandwidth, so the assistant has everything it needs to explain “why is example.com down?” without a dozen follow-up tool calls.
Common tasks
Read-only checks the assistant can run in the default config:
- Explain an outage: “Why is example.com down?” — one
diagnose_domaincall, results explained. - SSL sweep: “Which of my domains don’t have SSL?” —
list_domains+get_ssl_statusper domain. - Mail audit: “List every mailbox with a forwarder set.” —
list_mailboxes+list_forwarders. - Backup verification: “Show me the newest manifest for user X.” —
list_backups+get_backup_manifest.
With JABALI_MCP_ALLOW_WRITE=1:
- Provisioning: “Create two mailboxes and a catch-all forwarder on my new domain.”
- DNS edits: “Add an A record for
vpnpointing at 203.0.113.5, TTL 300.” - Cert issuance sweep: “Enable Let’s Encrypt on every domain that doesn’t have it.”
- Database provisioning: “Create a database + user for the shop app, read-write.”
Client compatibility
Any MCP-capable client works. Documented as of jabali-mcp v0.4.0:
- Claude Code
- Claude Desktop
- Cursor
- Windsurf
- Cline
- OpenAI Codex
- OpenCode
- Gemini CLI
Troubleshooting
connect: connection refused— checkJABALI_PANEL_URLand that the panel is reachable from the machine running the MCP client, not just from the panel host itself.x509: certificate signed by unknown authority— panel uses a private CA. SetJABALI_CA_FILEto your CA bundle.401 unauthorized— token wrong, revoked, or from the wrong tenant. Re-mint in the panel’s API Tokens → MCP tab.- Assistant says “no such tool” for a write — writes are read-only unless
JABALI_MCP_ALLOW_WRITE=1is set in the client’senvblock. Restart the MCP client after changing env vars. - Assistant asks to confirm a destructive action — expected. Re-call the tool with
confirm: trueto actually execute.
Community
Roadmap and requests: github.com/shukiv/jabali-panel/discussions/963.