
Jabali Panel
io.github.shukiv由 GitHub 账号 shukiv 发布v0.6.1更新于 Nov 1, 2026
Manage domains, DNS, mail, databases and backups on a Jabali Panel hosting server.
概览
本地 MCP 服务器,让助手通过 Jabali Panel 的 REST API 管理托管服务器上的域名、DNS、邮件、应用、数据库和备份。
- 可以做什么
- 列出并查看域名、DNS 记录、邮箱、转发、应用、数据库、备份、定时任务、SSH 密钥、PHP 设置、SSL 状态、日志和磁盘用量
- 执行综合域名诊断,汇总配置、SSL、DNS、近期错误和带宽,并可查询官方面板文档
- 创建和更新域名、DNS 记录、邮箱、转发、备份、应用、数据库、定时任务、SSH 密钥和 PHP 设置(仅写入模式)
- 删除、恢复、撤销或轮换资源,均先返回预览,需带 confirm 再次调用才执行
- 可选开放用户、服务器设置和面板更新的管理工具,并可在多面板模式下指定某一台面板
- 适用场景
- 适合运行 Jabali Panel 托管服务器、希望用自然语言让助手查看或修改托管配置而不必手动操作面板的人。建议先以只读模式做诊断和巡检,确需改动时再开启写入模式。
- 运行要求
- 本地二进制程序(预编译版本、go install 或用 Go 1.25+ 从源码构建),由 MCP 客户端通过 stdio 启动。需要可访问的面板 API 地址(JABALI_PANEL_URL)和 jat_ API 令牌(JABALI_API_TOKEN),或由 init 命令生成的 panels.json。可选:JABALI_CA_FILE、JABALI_MCP_ALLOW_WRITE、JABALI_MCP_DRY_RUN、JABALI_MCP_ADMIN、JABALI_PANELS_FILE。
安装
在 SourceWeft 中
- 打开 控制台中的 Jabali Panel,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
jabali-mcp
A Model Context Protocol server for Jabali Panel.
Install | Set up | Tools | Safety | Generation
[Working MVP] [Go 1.25] [MCP stdio] [AGPL-3.0]
Lets an AI assistant drive panel operations — domains, DNS, mail, applications, databases, backups — through natural language. It's a thin, generated wrapper over the panel's existing REST API: it reimplements no auth, validation, or scoping, it rides them.
Status: working MVP. Read tools + gated write/destructive tools + a fleet registry, generated from the panel's OpenAPI spec (a golden test fails if the checked-in code drifts from the spec).
Install
Prerequisites: Go 1.25+ and a reachable Jabali Panel with an API token (see Set up). The server speaks MCP over stdio — an MCP client (Claude Code, Claude Desktop, …) launches it; you don't run it as a daemon.
Prebuilt binaries
Grab the binary for your platform from the latest release (linux/darwin × amd64/arm64, with SHA256SUMS), then:
With go install
The binary lands in $(go env GOBIN) (or $(go env GOPATH)/bin).
From source
Update
Self-update runs go install, so it needs Go on the PATH. Restart your MCP
client afterward to pick up the new binary. (Installed from a checkout instead?
git pull && make build. Installed a prebuilt binary? Download the new release.)
Verify
It reads config from the environment, prints a one-line status to stderr,
then serves MCP on stdin/stdout (it exits on EOF, which is why the < /dev/null
smoke test returns immediately).
Set up
Quickest: the guided walkthrough
It prompts for each panel (name, URL, token), verifies the token against the
panel, and writes a 0600 panels.json to your config dir
(~/.config/jabali-mcp/panels.json). Add as many panels as you like — one for a
single instance, several for a fleet. Because that path is the default, the
server finds it with no env vars, so registering with a client is just:
Re-run init any time to reconfigure. The manual steps below are the same thing
by hand.
Manual
1. Mint an API token. In the panel, go to the tenant shell → API Tokens
and create one. The plaintext jat_… is shown once — copy it. Use a non-admin
(tenant) token so the server is confined to that one account.
2. Point the server at your panel with these environment variables:
3. Register it with your MCP client. In every example below jabali-mcp is
assumed on your PATH (else use its full path), and the two required env vars
are shown inline. It's a stdio MCP server, so any MCP-capable client can launch
it.
Claude Code (CLI — writes .mcp.json / your Claude config):
Claude Desktop — claude_desktop_config.json:
OpenAI Codex (CLI — writes ~/.codex/config.toml):
or edit ~/.codex/config.toml by hand — note it's TOML, and the key is
mcp_servers (underscore), not the JSON mcpServers:
OpenCode — opencode.json:
Kimi Code CLI (writes ~/.kimi/mcp.json):
Cursor, Windsurf, Cline, Gemini CLI, and other clients that use the standard
mcpServers JSON take the same entry as Claude Desktop above — a
{ "command": "jabali-mcp", "env": { … } } block under mcpServers in that
client's config file.
Start read-only. When you want mutations, add JABALI_MCP_ALLOW_WRITE=1 to the
env (and, at first, JABALI_MCP_DRY_RUN=1 to watch what it would do).
Run it on a remote box over SSH
Because it speaks stdio, any of the above can launch it on a remote host over
SSH instead of locally — the tool stream tunnels through the SSH pipe. Set the
client's command to ssh and pass the remote invocation as its argument, e.g.
for Claude Desktop:
On the box the panel API is reachable at localhost, and the token still scopes
everything to its user. Nothing to install client-side beyond an SSH key.
Fleet (multiple panels)
The easiest path is jabali-mcp init — add several panels when it asks "Add
another panel?". It writes them to the default panels.json, which the server
loads automatically.
Equivalently, point JABALI_PANELS_FILE at a JSON array (this overrides the
single-panel vars), or write that array yourself:
Config resolution order: JABALI_PANELS_FILE → single-panel env
(JABALI_PANEL_URL + JABALI_API_TOKEN) → the default panels.json. In a
fleet, every tool takes an optional panel argument to pick one; omit it for the
first (default) panel.
Admin tools (same binary, separate opt-in)
The admin operator surface (list/create users, read/update server settings,
run panel updates and read their status) lives in the same binary but a separate registration
group, exposed only with JABALI_MCP_ADMIN=1. It fronts whole-box operations —
a far larger blast radius than the tenant tools — so it is deliberately opt-in and
requires an admin token (the panel's RequireAdmin rejects a non-admin token
with 403 regardless of the flag). Admin write tools still need ALLOW_WRITE, and
admin_run_updates is confirm-gated. admin_renew_ssl and admin_retry_ssl
also live here: their paths look tenant-scoped, but the panel registers them
behind RequireAdmin. Give the admin server its own admin token;
use tenant tokens for everything else.
Auth model — inherits the panel's tenant isolation
Tools authenticate with the per-user Bearer token. The token acts as its owning user and the panel enforces ownership on every endpoint, so the server can only ever reach the resources that token's user owns — a tenant token is confined to that tenant. That is why a non-admin token is the safe default.
Safety
This fronts a hosting control plane, so mutation is fenced in four layers:
- Read-only by default. Write tools register only with
JABALI_MCP_ALLOW_WRITE=1. - Destructive tools require
confirm: true. Everydelete_*/revoke_*/rotate_*_passwordtool (plusrestore_backup,disable_ssl) returns a preview and acts only when re-called withconfirm: true. A model cannot destroy state in one step — the guard against a prompt-injected tool call. - Tool hints. Read tools carry
readOnlyHint; destructive tools carrydestructiveHintso clients can surface the risk. - Dry-run. Any write tool accepts
dry_run: trueto return the exact request it would send without acting;JABALI_MCP_DRY_RUN=1forces that globally.
TLS verification is always on. To trust a self-hosted panel's private CA, point
JABALI_CA_FILE at its bundle — that adds the CA, it never disables
verification.
Tools
Full per-tool reference with arguments and constraints: docs/TOOLS.md
(generated — make docs).
Read (always on): list_domains, get_domain, list_dns_records,
list_mailboxes, list_forwarders, list_applications, list_databases,
list_backups, list_api_tokens, list_mail_logs, tail_web_log,
get_ssl_status, get_domain_whois, get_domain_bandwidth, whoami,
get_disk_usage, list_activity, list_cron_jobs, get_cron_job,
get_cron_log, list_app_catalog, get_application, get_database,
list_database_users, get_mailbox, get_autoresponder,
get_backup_manifest, list_ssh_keys, get_php_settings,
list_php_versions, list_files, preview_file — plus the composite
diagnose_domain (config + SSL + DNS + recent errors + bandwidth in one
answer; a failed probe is reported without failing the rest) and
report_issue (draft a bug report / feature request for the jabali-panel or
jabali-mcp GitHub repo as a prefilled link; in write mode it can also file it
directly via gh, gated by confirm: true) and search_docs (look up the
official panel documentation from jabali-panel.com mid-task — anonymous,
origin-restricted fetches; override the source with JABALI_DOCS_URL).
preview_filereads file contents (up to 1 MiB) into the conversation — that can include secrets such aswp-config.php.create_database_userand therotate_*_passwordtools return the plaintext secret once, by panel design.
Write (needs JABALI_MCP_ALLOW_WRITE=1): create_domain, update_domain,
create_dns_record, update_dns_record, create_mailbox, create_forwarder,
create_backup, install_application, create_database, enable_ssl,
create_cron_job, update_cron_job, run_cron_job, create_database_user,
grant_database_access, update_mailbox, set_autoresponder, add_ssh_key,
update_php_settings — plus the confirm-gated destructive set: delete_domain,
delete_dns_record, delete_mailbox, restore_backup,
disable_ssl, delete_cron_job, delete_application, delete_database,
delete_database_user, revoke_database_access, rotate_database_password,
delete_autoresponder, rotate_mailbox_password, delete_backup,
delete_ssh_key.
Tool generation
Tools are generated, not hand-written, so the surface can't drift from the API:
openapi/openapi.yaml— vendored copy of the panel's spec.openapi/tools.yaml— curation: which operations are exposed, their tool names,read/writegroup, anddestructive/paginatedflags. An operation absent here is not exposed (that keepsadmin/*andnic/updateout).internal/genjoins the two and emitsinternal/tools/generated.go; run it withmake genorgo generate ./....- A curation entry naming an operation the spec lacks is a hard error (drift
guard), and
TestGeneratedIsUpToDatefails if the committed file is stale. openapi/panel-routes.txtpins the routes the panel really serves, read from the panel's embedded spec (panel-api/internal/api/openapi.yaml, which the panel's own tests hold to its registered routes).TestCuratedOpsArePanelRoutesfails for any curated operation missing from it: that tool would 404. The vendored spec is a hand-edited copy and cannot catch this on its own.
To refresh after the panel API changes: run make panel-routes (reads
origin/main of ../jabali2; override with PANEL_REPO= / PANEL_REF=),
merge the changed operations into openapi.yaml by hand (a wholesale copy
loses the request bodies written here), adjust tools.yaml, run make gen,
review the diff.
Development
Layout
Roadmap
- M1 — read-only MVP ✅ Bearer client, MCP stdio server, read tools, tests.
- M2 — gated mutations ✅ write tools behind an opt-in flag; destructive ops confirm-gated.
- M3 — fleet ✅ multi-panel registry +
paneltool argument. - Generator ✅ tools generated from the spec + curation, golden-tested.
- Dry-run ✅ per-call
dry_run+ globalJABALI_MCP_DRY_RUN. - Input validation ✅ generated per-tool checks for the spec's value constraints (enum, minLength, min/max) — fail fast before any request.
- Admin tools ✅
/admin/*surface behindJABALI_MCP_ADMIN=1+ an admin token, same binary. - Logs ✅
list_mail_logs+tail_web_log(panel gainedGET /logs/tail). - Next: richer InputSchema (constraints visible to clients), composite
diagnostics (
diagnose_domain), CLI mode.
License
GNU Affero General Public License v3.0 — see LICENSE. Same license as Jabali Panel.
来源:README.md,提交 ce869cd
工具
0版本历史
1- v0.6.1最新Nov 1, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分