MCP server
Connect any Model Context Protocol AI agent (ChatGPT, Claude, Cursor, VS Code, custom clients) to your panel account so it can manage your servers, files, backups, databases, tickets and billing for you.
Overview
Connect an AI assistant to your StormPanel account to manage your game servers through Model Context Protocol (MCP). You can ask it to list servers, start or stop them, send console commands, edit files, manage backups, and use the other tools listed below.
Your AI uses your account permissions. It cannot access servers or perform actions that your account cannot access. Tool calls are recorded in your account activity log.
ChatGPT connects through a sign-in and authorization page. Clients that support custom headers can connect with a dedicated panel API key. Both methods give the AI the same access as your account.
Server URL
Use the following URL when adding StormPanel to your AI client. Select Streamable HTTP if the client asks for a transport type.
Opening this URL directly in a browser displays a method-not-allowed message. Add it in your AI client instead.
Server URL: https://stormnodes.xyz/api/mcp
Transport: Streamable HTTPConnecting with an API key
For clients that support an Authorization header, create a dedicated key under Account → API keys. Give it a recognizable name, such as "claude-desktop", so you can disconnect that client without affecting your other integrations.
Copy the full token shown when you create the key. It contains a public and private part joined with a dot. Store it in your client's credential settings and treat it like a password. Do not share it or include it in public repositories.
Add the token as a Bearer credential using the header below. Your panel login cookie cannot be used as an MCP credential. ChatGPT users should follow the ChatGPT setup section instead.
Authorization: Bearer <public_key>.<private_key>Good to know
To disconnect a client or replace a leaked key, delete or regenerate its key under Account → API keys.Setup: Claude Desktop
Claude Desktop connects to remote HTTP MCP servers natively. Open Settings → Connectors (or Developer settings, depending on version), choose to add a remote MCP server, and point it at the panel endpoint with your bearer token. Claude will perform the MCP handshake and list your tools automatically.
On versions without native remote support, install the mcp-remote adapter (npx mcp-remote) in the desktop configuration file (claude_desktop_config.json) and restart the app.
// Native remote connector
Server URL: https://stormnodes.xyz/api/mcp
Custom header: Authorization: Bearer fp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.fp_yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
// Via mcp-remote (claude_desktop_config.json)
{
"mcpServers": {
"stormpanel": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://stormnodes.xyz/api/mcp",
"--header", "Authorization: Bearer fp_PUBLIC.fp_PRIVATE"]
}
}
}Setup: Claude Code
Claude Code manages remote MCP servers through its CLI. The command below registers the panel as an HTTP MCP server for your user scope; adjust --scope project to store it in a project instead. After adding it, run /mcp inside a session to verify the server connects and shows its tools.
claude mcp add --transport http --scope user stormpanel \
https://stormnodes.xyz/api/mcp \
--header "Authorization: Bearer fp_PUBLIC.fp_PRIVATE"
# verify
claude mcp listSetup: Cursor
Cursor reads MCP servers from ~/.cursor/mcp.json (or .cursor/mcp.json inside a project). Add the panel as an HTTP server with your Authorization header, then enable the "stormpanel" server in Cursor settings → MCP. The tool list appears after the first successful handshake.
{
"mcpServers": {
"stormpanel": {
"url": "https://stormnodes.xyz/api/mcp",
"headers": {
"Authorization": "Bearer fp_PUBLIC.fp_PRIVATE"
}
}
}
}Setup: VS Code and other clients
VS Code (Copilot Chat agent mode) configures MCP servers in .vscode/mcp.json or user settings; other MCP-capable clients (Windsurf, Cline, Zed, custom SDK clients) accept the same shape. Any client that supports the Streamable HTTP transport with custom headers works: point it at the endpoint, attach the Authorization header, and the handshake negotiates the protocol version automatically.
{
"servers": {
"stormpanel": {
"type": "http",
"url": "https://stormnodes.xyz/api/mcp",
"headers": {
"Authorization": "Bearer fp_PUBLIC.fp_PRIVATE"
}
}
}
}Setup: ChatGPT
Open ChatGPT Settings → Apps or Connectors and choose to create a custom MCP server. Enter a name, such as "StormPanel", and use https://stormnodes.xyz/api/mcp as the Server URL.
Select OAuth or no authentication. In Advanced OAuth settings, use Dynamic Client Registration (DCR) and the mcp scope. You do not need to enter a client ID, client secret, or tunnel ID. The notice that CIMD is unavailable is expected when using DCR.
Create the connection. In the authorization page, sign in with your StormPanel account, review the requested access, and click Authorize. Complete two-factor authentication if your account requires it.
Return to ChatGPT, enable the connection for your conversation, and try a read-only request such as "list my game servers". Review changes the AI proposes before letting it modify your server.
To disconnect ChatGPT, delete its MCP OAuth key under Account → API keys. If the connection expires or is revoked, reconnect from ChatGPT and authorize it again.
Name: StormPanel
Server URL: https://stormnodes.xyz/api/mcp
Authentication: OAuth or no authentication
Client registration: Dynamic Client Registration (DCR)
Scope: mcpGood to know
If discovery or registration fails, check the Server URL and contact StormNodes support with the error message. If authorization stalls, close the authorization page and start the connection again from ChatGPT. Check that your browser allows the login popup. If tools are missing, enable the connection in the conversation's tools menu.Protocol and raw request examples
The endpoint speaks JSON-RPC 2.0. A minimal conversation is three calls: initialize (handshake), tools/list (discover tools), and tools/call (execute one). Notifications such as notifications/initialized are accepted with HTTP 202 and no body. Batching (JSON arrays) is not supported and returns a 400 error.
These curl examples are handy for smoke-testing a token or wiring custom clients. Note that tools/call arguments are always a JSON object, and errors inside a tool come back as a result with "isError": true rather than as an HTTP error.
# 1) Handshake
curl -s https://stormnodes.xyz/api/mcp \
-H "Authorization: Bearer fp_PUBLIC.fp_PRIVATE" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2025-06-18",
"clientInfo":{"name":"curl","version":"1.0"}}}'
# 2) Discover tools
curl -s https://stormnodes.xyz/api/mcp \
-H "Authorization: Bearer fp_PUBLIC.fp_PRIVATE" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
# 3) Call a tool
curl -s https://stormnodes.xyz/api/mcp \
-H "Authorization: Bearer fp_PUBLIC.fp_PRIVATE" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
"params":{"name":"list_servers","arguments":{"limit":20}}}'
# 4) Ping
curl -s https://stormnodes.xyz/api/mcp \
-H "Authorization: Bearer fp_PUBLIC.fp_PRIVATE" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":4,"method":"ping"}'Tool catalog
The 137 tools below are exposed to your AI. Every server-scoped tool takes the server short UUID (uuidShort) that list_servers returns, plus the arguments shown. Tools marked DESTRUCTIVE in their description permanently change or delete data. The AI is instructed to confirm with you before calling them.
Calling a tool your account lacks permission for (for example a subuser without file delete rights) returns the same permission error the panel UI would show. That is the permission model working: the AI is bound to your account rights, never above them.
ACCOUNT & PLATFORM
get_account account profile, 2FA state, preferences
list_user_activities (page,limit) recent account activity
list_notifications (page,limit) account notifications
dismiss_notification (id) mark a notification read
get_node_status infrastructure node health
list_kb_categories / search_kb_articles / get_kb_article
SERVERS
list_servers (page,limit,search) your servers + short UUIDs (start here)
get_server (uuidShort) full details, SFTP, variables, limits
update_server (name,description,image,spell_id,variables,startup,wipe_files)
reinstall_server (uuidShort,wipe_files) DESTRUCTIVE
delete_server (uuidShort) DESTRUCTIVE
get_server_jwt (uuidShort) short-lived console websocket token
list_server_splits / create_server_split
POWER & CONSOLE
power_action (uuidShort,action) action: start | stop | restart | kill
send_console_command (uuidShort,command)
get_server_logs (uuidShort) read console output after commands
get_install_logs (uuidShort)
FILES
list_files (uuidShort,path) directory listing with sizes
read_file (uuidShort,path) file contents (text)
write_file (uuidShort,path,content) create/overwrite text file
upload_file (uuidShort,filename,content_base64,path)
rename_files (uuidShort,root,files[{from,to}])
copy_files (uuidShort,location,files[])
delete_files (uuidShort,root,files[]) DESTRUCTIVE
create_directory (uuidShort,path,name)
compress_files (uuidShort,root,files[],name,extension)
decompress_archive (uuidShort,root,file)
change_file_permissions (uuidShort,root,files[{name,mode}])
pull_file (uuidShort,url,root,fileName,foreground) download URL onto server
download_file (uuidShort,path) signed download URL
get_folder_size (uuidShort,path)
list_pull_processes (uuidShort) background transfers
wipe_all_files (uuidShort) DESTRUCTIVE
BACKUPS
list_backups / create_backup (name) / get_backup (backupUuid)
delete_backup (backupUuid) DESTRUCTIVE
restore_backup (backupUuid) DESTRUCTIVE
get_backup_download_url (backupUuid)
lock_backup / unlock_backup (backupUuid)
get_restore_status (uuidShort)
DATABASES
list_databases / create_database (database,remote)
get_database / update_database / delete_database (databaseId)
list_database_hosts
export_database_dump (databaseId)
import_database_dump (databaseId,content) raw SQL
list_database_backups / create_database_backup (databaseId)
restore_database_backup / delete_database_backup (backupUuid)
SCHEDULES & TASKS
list_schedules / create_schedule (name,minute,hour,day_of_week,day_of_month,is_active)
get_schedule / update_schedule / delete_schedule / toggle_schedule (scheduleId)
list_schedule_tasks (scheduleId)
create_schedule_task (scheduleId,action,payload,time_offset,sequence)
update_schedule_task / delete_schedule_task (scheduleId,taskId)
SUBUSERS & PORTS
list_subusers / create_subuser (email,permissions[])
get_subuser / update_subuser / delete_subuser (subuserId)
list_subuser_permissions valid permission keys
list_allocations / list_available_allocations / auto_allocate
set_primary_allocation / delete_allocation (allocationId)
STARTUP
list_startup_command_reviews / submit_startup_command_review (command,reason)
PLAYERS (Minecraft)
list_players (page,limit,search) / list_online_players
get_player_details / get_player_chat_history (identifier)
run_player_action (identifier,action,reason,value) kick/ban/op/gamemode...
get_player_list (listType) whitelist | banlist | operators
add_player_list_entry / remove_player_list_entry (listType,identifier)
PLUGINS, PACKAGES, VERSIONS, TEMPLATES, WORLDS
search_plugins (search,page,limit) / list_plugin_versions (resourceId)
install_plugin (resourceId,version) / uninstall_plugin (resourceId)
get_plugin_install_status
search_packages (runtime,search) / list_installed_packages (runtime)
install_package / uninstall_package (runtime,package,version)
list_software / list_software_versions (type)
install_software_version (type,version)
list_templates (page,limit) / install_template (templateId) DESTRUCTIVE
rollback_template
list_worlds / get_world_info / get_world_properties (worldName)
update_world_properties (worldName,properties)
delete_world (worldName) DESTRUCTIVE
NETWORK
list_subdomains / create_subdomain (subdomain,domain) / delete_subdomain (uuid)
list_firewall_rules / create_firewall_rule (port,protocol,source,note)
update_firewall_rule / delete_firewall_rule (ruleId)
TICKETS
list_tickets (page,limit,status) / list_ticket_categories
create_ticket (subject,message,category,priority,server)
get_ticket (uuid) / reply_to_ticket (uuid,message)
BILLING (read + subscription lifecycle)
get_billing_summary / get_billing_workspace
list_receipts / list_invoices / get_invoice (invoiceId)
renew_subscription (subscriptionId)
set_subscription_auto_renew (subscriptionId,enabled)
cancel_subscription (subscriptionId)
get_wallet_status / get_referral_summary
ALERTS, SSH KEYS, LOGS
list_alert_incidents / acknowledge_alert_incident / resolve_alert_incident (incidentId)
list_ssh_keys / create_ssh_key (name,public_key) / delete_ssh_key (id)
get_server_activities (uuidShort,page,limit)Permissions and account access
Connecting an AI gives it access to the actions available to your account. Server ownership, subuser permissions, suspensions, and server locks still apply.
Review your account activity log to see which tools the AI has called. Disconnect clients you no longer use by deleting their keys under Account → API keys.
MCP does not expose panel administration, API key creation, or payment checkout. Some tools can delete files, change settings, cancel subscriptions, or spend an existing wallet balance. Read the tool descriptions and review consequential actions before approving them.
Good to know
Use a separate key for each client. Keep credentials private and remove access when you stop using a client.Rate limits and file sizes
The MCP endpoint allows up to 120 requests per minute per client IP by default. Individual tools also follow the panel's limits for the action being performed. If you receive a rate-limit error, wait before trying again and reduce how many actions your AI sends at once.
Request bodies are limited to 8 MiB and tool output to 512 KiB by default. Large results may be shortened. Binary files are returned as download links rather than displayed as text.
Default request limit: 120 requests/minute/IP
Default request size: 8 MiB
Default output size: 512 KiBErrors and troubleshooting
MCP protocol problems come back as JSON-RPC error objects; tool-level problems come back as tool results with "isError": true whose text contains the panel error code (SERVER_NOT_FOUND, ACCESS_DENIED, RATE_LIMITED, and so on). Use the table to diagnose what you are seeing.
HTTP 401 Invalid API key, a session cookie was sent instead of a Bearer key,
or an OAuth connection (ChatGPT) was revoked/expired. Reconnect it.
HTTP 403 Opaque origin (Origin: null) refused, or the account is banned.
HTTP 400 Malformed JSON-RPC (parse error, batching, wrong version, bad id),
or an unsupported pinned MCP-Protocol-Version header.
HTTP 405 GET/DELETE on /api/mcp. Use POST.
HTTP 413 Request body over 8 MiB.
HTTP 429 Rate limited, slow down; per-route limits apply per account.
JSON-RPC -32700 Body is not valid JSON.
JSON-RPC -32600 Invalid request envelope (batching, wrong jsonrpc, params not an object).
JSON-RPC -32601 Unknown method (only initialize, ping, tools/list, tools/call).
JSON-RPC -32602 Bad tool arguments: unknown tool name, missing required argument,
invalid uuidShort/action/world name, invalid base64, oversized content.
JSON-RPC -32603 Unexpected server error (logged server-side with request context).
Tool result isError:true The panel API rejected the operation. Read error_code in
the returned JSON (permissions, server state, validation).
OAuth endpoints (token/revoke) speak RFC 6749 §5.2 errors instead:
invalid_client / invalid_grant / invalid_request / invalid_scope /
unsupported_grant_type / temporarily_unavailable.Good to know
Claude/Cursor showing no tools? Verify the key works with the curl ping example, then check that your client sends the Authorization header on every request (some clients require it explicitly in the server entry rather than an OAuth flow).