# JetHost MCP API > Model Context Protocol server for JetHost MCP hosting accounts. Endpoint: https://mcp.jethost.com/mcp (JSON-RPC over streamable HTTP). Auth: OAuth 2.1 + Dynamic Client Registration + PKCE. > Last updated: 2026-10-15 - [Authentication & registration](https://mcp.jethost.com/docs/authentication.html): how to connect, endpoints, scopes - [Advanced Token Manager](https://mcp.jethost.com/docs/security.html): opt-in credentials — named, expiring keys scoped per account, service, tool, and cPanel module - [Rate limits](https://mcp.jethost.com/docs/limits.html): per-connection and per-account request limits, RateLimit-* headers, 429 + Retry-After ## Services - [list_services](https://mcp.jethost.com/docs/list_services.html): List the caller's active and suspended hosting services. Requires the read:services scope. - [get_service](https://mcp.jethost.com/docs/get_service.html): Get a single hosting service by ID, including status, billing cycle, disk/bandwidth usage, server, and default nameservers. Requires the read:services scope. - [get_service_usage](https://mcp.jethost.com/docs/get_service_usage.html): Get CPU usage for one of the caller's hosting services by ID: current, today, and month-to-date CPU-minutes (UTC). Pass month=YYYY-MM to also get a per-day series. Data may be up to ~60s stale. Requires the read:services scope. ## VPS - [list_vps_operations](https://mcp.jethost.com/docs/list_vps_operations.html): List the VPS operations ONE of the customer's VPS services supports, by service_id (from list_services, where service_kind is "vps" or "managed_vps"). Only the operations that service's plan includes are listed — a Managed VPS is typically limited to details — each with a one-line summary and its parameters (name, type, required, allowed values, pattern, bounds). `listing` is the same menu as text: one line per operation, "name(params)" with optional parameters marked "?", behind a two-character flag column: "!" in the first column means the operation changes the VPS and vps_manage refuses it without confirm:true; "x" in the second means it is not available through the assistant (reinstall and snapshot restore answer "Not implemented, contact support"). `notes` carries the rules to follow. Root credentials and password resets are never available here. A service that is not the customer's, or not a VPS, returns error="not_found"; a suspended or cancelled one returns error="service_not_active". Call this first, then vps_manage. Requires read access to services. - [vps_manage](https://mcp.jethost.com/docs/vps_manage.html): Run one operation on the customer's own VPS and return { ok, data, errors[], warnings[] }: details and status, power (start, stop, reboot), IPs and reverse DNS, null-routing, firewall rules, traffic, snapshots, rescue ISOs, notification settings and the console. Call list_vps_operations(service_id) first for the operations this VPS supports and their parameters; pass service_id, operation and params (a flat object, {} when none). Operations that change the VPS answer error="confirm_required" until you pass confirm:true: tell the customer exactly what will change, get their agreement, then repeat the call. Power and snapshot operations run in the background: data {accepted:true, async:true} only means accepted — poll operation="status" (or list_snapshots) before reporting the result. An attached or detached rescue ISO takes effect on the next boot. operation="console" returns console_url, a JetHost link that works ONCE and expires after 10 minutes — give it to the customer as is; logging in on the console needs the VPS root password, which is never available here (the customer finds or resets it in the client area). No credentials or password resets are offered; reinstall and snapshot restore answer error="not_implemented" ("Not implemented, contact support"). Other errors: "feature_not_enabled" (not in this plan), "invalid_params" (param names the culprit), "upstream_error" (detail says why), "rate_limited" (too many console links), "not_found" (not the customer's VPS). Reads need read access to services; changes and the console also need the hosting-management scope the customer already granted. ## Invoices - [list_invoices](https://mcp.jethost.com/docs/list_invoices.html): List the caller's invoices, optionally filtered by status (Unpaid, Paid, Cancelled, Refunded, Collections, Draft, Payment Pending, Overdue). Requires the read:invoices scope. - [get_invoice](https://mcp.jethost.com/docs/get_invoice.html): Get a single invoice by ID, including line items. Requires the read:invoices scope. - [search_invoices](https://mcp.jethost.com/docs/search_invoices.html): Search the caller's invoices for line items whose description matches a substring (case-insensitive). Returns up to 50 matching invoices, newest first. Requires the read:invoices scope. - [find_invoices_by_relation](https://mcp.jethost.com/docs/find_invoices_by_relation.html): Find the caller's invoices that include a charge for a specific hosting service (rel_type=Hosting) or domain (rel_type=Domain). rel_id is the integer service id or domain id. Returns up to 50 matching invoices, newest first. Requires the read:invoices scope. ## Domains - [list_domains](https://mcp.jethost.com/docs/list_domains.html): List the caller's registered domains with expiry dates. Requires the read:domains scope. - [get_domain](https://mcp.jethost.com/docs/get_domain.html): Get a single domain by ID, including status and expiry date. Requires the read:domains scope. - [get_domain_nameservers](https://mcp.jethost.com/docs/get_domain_nameservers.html): Get the registrar nameservers currently set for one of the caller's domains, by domain ID. Performs a live lookup at the registrar. Requires the read:domains scope. - [get_domain_whois](https://mcp.jethost.com/docs/get_domain_whois.html): Get the WHOIS contact records (registrant, admin, tech) for one of the caller's domains, by domain ID. Contains personal contact details; performs a live lookup at the registrar. Requires the read:domains scope. ## Tickets - [list_tickets](https://mcp.jethost.com/docs/list_tickets.html): List the caller's support tickets, optionally filtered by status. Requires the read:tickets scope. - [get_ticket](https://mcp.jethost.com/docs/get_ticket.html): Get a single support ticket by ID, including customer-visible replies only. Requires the read:tickets scope. ## Catalog - [check_domain_availability](https://mcp.jethost.com/docs/check_domain_availability.html): Check availability and USD pricing for one or more explicit domain names (up to 10). Each result gives status, 1-year register and transfer prices, and free_with_hosting / free_with_products — whether the TLD is free when ordered with a JetHost hosting plan and which plans (and billing cycles) qualify. When a domain is available and sellable, follow up with list_hosting_plans to show the customer which plans to pair it with; free_with_products already names the plans that include that TLD as a free domain. Data may be up to 60 seconds stale. Requires the read:domain_catalog scope. - [suggest_domains](https://mcp.jethost.com/docs/suggest_domains.html): Suggest available domains from a keyword stem. Pass the keyword in the "stem" argument (e.g. stem="bakery"). Returns up to 15 JetHost-sellable suggestions, each with USD pricing and free_with_hosting / free_with_products — whether the TLD is free when ordered with a JetHost hosting plan and which plans (and billing cycles) qualify. Data may be up to 60 seconds stale. Requires the read:domain_catalog scope. - [list_hosting_plans](https://mcp.jethost.com/docs/list_hosting_plans.html): List all active JetHost hosting plans with USD pricing per billing cycle (enabled cycles only) and the discounted new-order price. Returns a lean list without config options — call get_hosting_plan(pid) to drill into a single plan's configurable options. Data may be up to 60 seconds stale. Requires the read:product_catalog scope. - [get_hosting_plan](https://mcp.jethost.com/docs/get_hosting_plan.html): Get a single hosting plan by its WHMCS product id (pid), including its pricing and normalized configurable options (e.g. server location). Config-option prices are list price. Call list_hosting_plans first to find the pid. Data may be up to 60 seconds stale. Requires the read:product_catalog scope. ## Websites - [get_website_logs](https://mcp.jethost.com/docs/get_website_logs.html): Get raw log lines for one domain on one of the caller's hosting services, within a time window: log_type=access for the HTTPS web-server access log (falls back to the plain HTTP log when the site has no SSL log), log_type=http_access for the plain HTTP access log specifically, log_type=php_error for PHP error_log files and WordPress debug.log. Results are tail-first (most recent matching lines first) and hard-capped at 500 lines / 256 KB — if truncated=true, narrow the time window or add a fixed-string search filter instead of paging. from/to must be ISO 8601 with an explicit offset (e.g. 2026-06-10T08:00:00+03:00 or ...Z); the effective window applied is echoed back in UTC. status=log_not_available means no such log file exists for that domain (do NOT report it as "no errors") — distinct from status=ok with zero lines, which means the log exists but nothing matched. status=unavailable_on_server means log access is not rolled out on that hosting server yet. Requires the read:logs scope. - [list_website_domains](https://mcp.jethost.com/docs/list_website_domains.html): List the domains hosted on one of the caller's hosting services, by service ID: the main domain plus any addon domains, subdomains, and parked (alias) domains, each with its document root. The result is the complete set for that account. Use it to discover which domain to pass to get_website_logs or to map a site to its directory on the server. Requires the read:websites scope. - [get_website_statistics](https://mcp.jethost.com/docs/get_website_statistics.html): Get pre-aggregated AWStats traffic statistics for one domain on one of the caller's hosting services, for the CURRENT month. HTTP and HTTPS are reported as separate blocks (never summed). Each block has a status: ok (data parsed), statistics_not_available (no data file for that protocol this month — do NOT report as "no visitors"), or unavailable_on_server (the stats module is not rolled out on that hosting server yet). Sections cover summary, by_hour, by_day, top_pages, not_found_404, referrers, search_engines, search_keywords, origin, countries, os, browsers, robots, http_errors, file_types — pass "sections" to narrow the payload (omitted: list sections return a bounded top-N, small sections are complete). Bandwidth is raw bytes; individual visitor IPs are not exposed. Data is rebuilt nightly, so figures reflect through roughly yesterday and the current month is partial. Requires the read:analytics scope. ## Deploy - [deploy_site_from_url](https://mcp.jethost.com/docs/deploy_site_from_url.html): Deploy a Git repository to one domain on one of the caller's hosting services. Source repositories are restricted to a server-side host allowlist. NO build step runs (no npm/composer install, no compilation) — the repository must contain ready-to-serve files. For Node.js apps this is the PREBUILT-deploy path: since nothing is built or installed on the server, the repository must already contain the built/bundled output (a bundled production build is self-contained, so `node_modules` does not need to be uploaded). Deploys are contained: the module refuses to overwrite a target that is not a clean scaffold (status=target_not_empty), so an established site is never clobbered. Rollback is by ref — re-deploy a previous ref from get_deploy_status history to restore an earlier state. status=ok means the deploy landed (commit_sha/file_count describe it); status=quota_exceeded means the account disk quota would be exceeded and nothing was deployed; status=target_not_empty is the containment refusal; status=unavailable_on_server means the deploy module is not rolled out on that hosting server yet. This is a state-changing, destructive, non-idempotent write — it requires the write:deploy scope. - [deploy_private_repo](https://mcp.jethost.com/docs/deploy_private_repo.html): Deploy a private SSH Git repository to one domain on a caller's hosting service using a pre-installed per-repo deploy key. The repo MUST contain a .cpanel.yml at its root; without one, returns no_cpanel_yml. Call generate_deploy_key first (service_id — obtain via list_services) to provision the key, then add the returned public key to the repository's deploy keys on GitHub/GitLab/Bitbucket. Omitted branch deploys the repository default branch (HEAD). This destructive, non-idempotent write requires the write:deploy scope and is distinct from get_deploy_status (the URL-deploy lineage). - [get_deploy_status](https://mcp.jethost.com/docs/get_deploy_status.html): Get the current deploy marker and deploy history for one domain on one of the caller's hosting services: current = the repo_url, ref, commit_sha, and deployed_at currently live at the target (null when nothing has been deployed there); history = past deploys, each with the same fields. Pass a ref from history back to deploy_site_from_url to roll back. Requires the read:deploy scope. - [get_private_repo_deploy_status](https://mcp.jethost.com/docs/get_private_repo_deploy_status.html): Get the current deployment status for a private-repo (.cpanel.yml-managed) deploy on one domain on one of the caller's hosting services. This is the read-status companion to deploy_private_repo (cPanel VersionControl lineage) — distinct from get_deploy_status, which covers the URL-deploy lineage. Returns repository_root, branch, current_ref, commit_sha, last_deploy_outcome, and last_deployed_at for the active deployment. Requires the read:deploy scope. ## cPanel - [generate_deploy_key](https://mcp.jethost.com/docs/generate_deploy_key.html): Generate an ed25519 SSH deploy key (public key) for a Git repository on one of the caller's hosting services. BOTH inputs are REQUIRED: service_id (the hosting service the key is for — obtain it via list_services) and repo_url (the repository URL). Returns the public key and provider-specific instructions for pasting it as a deploy key in GitHub, GitLab, or Bitbucket. Generation is idempotent — re-calling for the same (service_id, repo_url) pair returns the existing public key without creating a duplicate. The private key is never returned; it is installed directly on the server. Requires the cpanel:uapi scope. TIP — add the returned public key to the repository's DEPLOY KEYS (not your account-wide SSH keys); a given deploy key is unique to ONE repo across the whole provider, so "key already in use" means it is attached elsewhere. If a later clone fails with "Permission denied (publickey)", the deploy may reference an SSH IdentityFile that does not match this installed key — verify ~/.ssh/config IdentityFile lines point at the key this tool installed. - [list_cpanel_operations](https://mcp.jethost.com/docs/list_cpanel_operations.html): List the cPanel MODULES the caller may currently use — a compact, category-grouped index (NOT the full operation catalog, which is too large to return at once). By default `listing` is a plain-text block: one category header (email, dns, files, databases, security, ssl, deploy, account, stats, misc) per line, then an indented "Name (count) — description" line per module. Pass `search` (e.g. "forwarder" or "ssl certificate") to instead get a token-matched result list of "Module::function(params) — summary" lines; a query naming something cPanel has no module for (e.g. "mailing list") explains that instead of returning nothing. The index reflects exactly which cPanel modules JetHost has enabled on the credential's role right now — toggling a module in the admin UI changes this on the next call, with no deploy. Use this first to find the right module, then call get_cpanel_module to fetch that module's functions and parameters, then cpanel_uapi to run one. discovery="live" means the index came from the role grants; "unavailable" means role introspection is temporarily unreachable. Requires the cpanel:uapi scope. - [list_cpanel_accounts](https://mcp.jethost.com/docs/list_cpanel_accounts.html): List the cPanel accounts on one of the caller's Managed VPS (cPanel) services, by service ID: user, domain, plan, suspended flag, and disk used/limit. System accounts (root, nobody, the WHM user) are never listed. Pass a returned user as cpanel_user to cpanel_uapi. A service that is not an active managed cPanel VPS, or not the caller's, returns error="not_found". Requires the cpanel:uapi scope. - [get_cpanel_module](https://mcp.jethost.com/docs/get_cpanel_module.html): Describe ONE cPanel module. Pass module (e.g. "DNS", "Email", "Mysql") — call list_cpanel_operations first to see the available module names; the name is matched case-insensitively (an ambiguous case-only match, e.g. both "SSH" and "ssh", returns error="module_ambiguous" with the candidates). By default returns a compact `listing`: one line per function, "name(params) — summary", where a leading "!" marks a MUTATING function (confirm with the user before running one via cpanel_uapi) and a leading space marks a read-only one. Pass `function` (one name, or an array of names, e.g. "list_pops" or ["list_pops","add_pop"]) to instead get the full parameter schema (method, summary, description, params: name/type/required/description) for just those functions. If the module is not enabled, the result lists the available module names so you can correct it. Use this after list_cpanel_operations and before cpanel_uapi to discover a module's exact functions and parameters. Requires the cpanel:uapi scope. - [cpanel_uapi](https://mcp.jethost.com/docs/cpanel_uapi.html): Run one cPanel operation against the cPanel account behind one of the caller's hosting services and return a normalized result { ok, data, errors[], warnings[] }. Discovery flow: list_cpanel_operations (optionally with `search`) to find the module, then get_cpanel_module to see its functions and parameters, then this tool to execute one. module is a cPanel UAPI module (e.g. "Email"); function is an operation in that module (e.g. "list_pops"); params is a JSON object of that operation's parameters. Only modules JetHost has enabled are available — an unknown or disabled module returns an error. A module the caller's key does not grant returns error="module_not_granted" together with granted_modules, the modules that key MAY use on that service. get_cpanel_module's listing marks each function with a leading "!" for mutating (write/delete) functions or a leading space for read-only ones — check that marker and confirm with the user before running a mutating call. The cPanel account is resolved from the owned service; a service the caller does not own returns error=not_found. Managed VPS services host several cPanel accounts: call list_cpanel_accounts and pass the chosen `user` as cpanel_user (error="cpanel_user_required" otherwise); there a "!" function refuses with error="confirm_required" until you pass confirm:true after the customer agreed. Requires the cpanel:uapi scope. data is the UAPI payload; cPanel base64-encoded fields (e.g. DNS::parse_zone dname_b64/data_b64/text_b64) are decoded to readable values under the same key without the _b64 suffix. TIP — writing PHP source: a WAF on the request path rejects any params carrying the literal "