hostinger-api-mcp 3.17.4 → 3.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +36 -137
  3. package/gemini-extension.json +1 -1
  4. package/package.json +1 -1
  5. package/server.json +2 -2
  6. package/skills/audit-hosting/SKILL.md +1 -1
  7. package/skills/connect-domain/SKILL.md +1 -1
  8. package/skills/deploy-to-hosting/SKILL.md +1 -1
  9. package/skills/troubleshoot-website/SKILL.md +5 -5
  10. package/src/core/runtime.js +152 -2
  11. package/src/core/runtime.ts +152 -2
  12. package/src/core/skills.js +12 -12
  13. package/src/core/skills.ts +12 -12
  14. package/src/core/tools/all.js +182 -12
  15. package/src/core/tools/all.ts +182 -12
  16. package/src/core/tools/hosting.js +145 -10
  17. package/src/core/tools/hosting.ts +145 -10
  18. package/src/core/tools/reach.js +37 -2
  19. package/src/core/tools/reach.ts +37 -2
  20. package/src/servers/agency-hosting.js +1 -1
  21. package/src/servers/agency-hosting.ts +1 -1
  22. package/src/servers/agent-readiness.js +1 -1
  23. package/src/servers/agent-readiness.ts +1 -1
  24. package/src/servers/all.js +1 -1
  25. package/src/servers/all.ts +1 -1
  26. package/src/servers/billing.js +1 -1
  27. package/src/servers/billing.ts +1 -1
  28. package/src/servers/dns.js +1 -1
  29. package/src/servers/dns.ts +1 -1
  30. package/src/servers/domains.js +1 -1
  31. package/src/servers/domains.ts +1 -1
  32. package/src/servers/ecommerce.js +1 -1
  33. package/src/servers/ecommerce.ts +1 -1
  34. package/src/servers/horizons.js +1 -1
  35. package/src/servers/horizons.ts +1 -1
  36. package/src/servers/hosting.js +1 -1
  37. package/src/servers/hosting.ts +1 -1
  38. package/src/servers/mail.js +1 -1
  39. package/src/servers/mail.ts +1 -1
  40. package/src/servers/reach.js +1 -1
  41. package/src/servers/reach.ts +1 -1
  42. package/src/servers/vps.js +1 -1
  43. package/src/servers/vps.ts +1 -1
  44. package/src/servers/wordpress.js +1 -1
  45. package/src/servers/wordpress.ts +1 -1
  46. package/types.d.ts +92 -4
package/CHANGELOG.md CHANGED
@@ -4,6 +4,26 @@ Generated at release time from the diff between the previous and current
4
4
  build. Tool changes are listed individually; everything else is summarised
5
5
  by area.
6
6
 
7
+ ## v3.18.0 — 2026-10-28
8
+
9
+ ### Operations
10
+
11
+ - Added `hosting_websites_get-settings` — Get website SSL, CDN and cache settings
12
+ - Added `hosting_websites_update-settings` — Update website HTTPS redirect, CDN and cache settings
13
+ - Added `hosting_cache_clear` — Clear website cache
14
+ - Added `reach_integrations_connect-ecommerce-store` — Connect Ecommerce store
15
+ - Hid 10 operations from search (they still run through `execute`): `hosting_cache_clear-website`, `hosting_cache_status`, `hosting_cache_toggle-cacheless`, `hosting_cache_toggle-website`, `hosting_cdn_disable`, `hosting_cdn_enable`, `hosting_cdn_purge-cache`, `hosting_cdn_status`, `hosting_ssl_status`, `hosting_ssl_toggle-https-redirect`
16
+ - Changed the description of `reach_integrations_disconnect-ecommerce-store`
17
+ - Changed the description of `reach_integrations_list-ecommerce-stores`
18
+
19
+ ### Also in this release
20
+
21
+ - Documentation: `README.md`
22
+ - Bundled agent skills: 4 files
23
+ - Request handling and authentication: `src/core/runtime.js`, `src/core/runtime.ts`
24
+ - Other files: `src/core/skills.js`, `src/core/skills.ts`
25
+ - Build and packaging: `types.d.ts`
26
+
7
27
  ## v3.17.4 — 2026-10-28
8
28
 
9
29
  ### Also in this release
package/README.md CHANGED
@@ -69,7 +69,7 @@ pnpm update -g @hostinger/mcp
69
69
 
70
70
  This package installs the following MCP server commands:
71
71
 
72
- - `hostinger-api-mcp` — unified server over every operation (418 total)
72
+ - `hostinger-api-mcp` — unified server over every operation (412 total)
73
73
  - `hostinger-agency-hosting-mcp` — 42 operations for agency-hosting
74
74
  - `hostinger-agent-readiness-mcp` — 3 operations for agent-readiness
75
75
  - `hostinger-billing-mcp` — 9 operations for billing
@@ -77,9 +77,9 @@ This package installs the following MCP server commands:
77
77
  - `hostinger-domains-mcp` — 42 operations for domains
78
78
  - `hostinger-ecommerce-mcp` — 29 operations for ecommerce
79
79
  - `hostinger-horizons-mcp` — 6 operations for horizons
80
- - `hostinger-hosting-mcp` — 68 operations for hosting
80
+ - `hostinger-hosting-mcp` — 61 operations for hosting
81
81
  - `hostinger-mail-mcp` — 38 operations for mail
82
- - `hostinger-reach-mcp` — 69 operations for reach
82
+ - `hostinger-reach-mcp` — 70 operations for reach
83
83
  - `hostinger-vps-mcp` — 67 operations for vps
84
84
  - `hostinger-wordpress-mcp` — 40 operations for wordpress
85
85
 
@@ -1828,123 +1828,33 @@ Check deployment status, build status, build logs and why a build failed (failur
1828
1828
  - **Method**: `custom`
1829
1829
  - **Path**: `custom`
1830
1830
 
1831
- #### hosting_websites_trigger-event
1831
+ #### hosting_websites_get-settings
1832
1832
 
1833
- Tell Hostinger that something happened on this website, so Hostinger services such as hPanel can react to it. `event.name` picks the event and decides which `event.params` it takes. The call changes nothing on the website.
1833
+ Read a website's SSL certificate, HTTPS redirect, CDN and server cache settings in one call. ssl is the SSL status as hosting_ssl_status returns it: the certificate status (active, installing, waiting_for_retry, failed, expired or not_installed) and provider, whether it is a lifetime certificate, whether HTTP is redirected to HTTPS, when it expires and the last installation error. cdn.is_enabled says whether the Hostinger CDN serves the website. cache.is_enabled says whether server-side caching is on, and cache.is_cacheless_mode_enabled whether development (cacheless) mode bypasses it. Use it before hosting_websites_update-settings, and to follow an SSL installation started by hosting_ssl_install: poll until ssl.status is active or failed, with growing pauses. A section that cannot be read comes back as { error } and the others are still returned; cache is null with a cacheNote when cache status is not available. To install or remove a certificate use hosting_ssl_install or hosting_ssl_uninstall. Works for Shared and Cloud hosting websites.
1834
1834
 
1835
1835
  - **Method**: `custom`
1836
1836
  - **Path**: `custom`
1837
1837
 
1838
- #### hosting_cache_clear-website
1839
-
1840
- Permanently clears all server-side cache for the website at once. Use it when content was
1841
- updated and needs to be visible immediately, or after making major changes.
1842
-
1843
- Also purges the Hostinger CDN cache when CDN is enabled on the website. To purge only the CDN
1844
- cache and leave the server cache untouched, use `Purge CDN cache`. For a WordPress
1845
- installation living in a subdirectory, pass the directory query parameter to clear its cache.
1846
-
1847
- - **Method**: `DELETE`
1848
- - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cache/clear`
1849
-
1850
- #### hosting_cache_status
1851
-
1852
- Returns the caching state of the website: whether server-side caching is enabled and whether
1853
- development (cacheless) mode is on. Works for the main domain, addon websites, parked domains
1854
- and subdomains of the account; each reports its own settings and does not inherit them from
1855
- its parent website.
1856
-
1857
- `is_enabled` is the setting changed by `Toggle website cache` and reflects a toggle
1858
- immediately. `is_cacheless_mode_enabled` is true while development mode is on; caching is then
1859
- bypassed even when `is_enabled` is true. `Toggle cacheless mode` is applied in the background,
1860
- so this flag can take a few minutes to follow it.
1861
-
1862
- The domain must be the exact website name as listed on the account, without a `www.` prefix.
1863
- Returns 404 when the domain is not a website on the account.
1864
-
1865
- - **Method**: `GET`
1866
- - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cache/status`
1867
-
1868
- #### hosting_cache_toggle-cacheless
1869
-
1870
- Turns development (cacheless) mode on or off, based on the enabled flag. When enabled, nothing
1871
- is cached, effectively turning off all caching for the website; use it while actively developing,
1872
- testing changes, debugging issues, or when real-time updates must be visible. Disable it after
1873
- finishing development work to restore the performance benefits of caching.
1874
-
1875
- The change is applied in the background and can take a few minutes. Use `Get cache status` to
1876
- check the current state.
1877
-
1878
- - **Method**: `PATCH`
1879
- - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cacheless-mode/toggle`
1880
-
1881
- #### hosting_cache_toggle-website
1882
-
1883
- Turns server-side caching for the website on or off, based on the enabled flag. Enable it for
1884
- faster page loads, reduced server load, and improved user experience; recommended for production
1885
- websites. Disabling may impact performance; to temporarily bypass caching while developing or
1886
- debugging, prefer toggling cacheless mode instead.
1887
-
1888
- Does nothing if caching is already in the requested state. Use `Get cache status` to check the
1889
- current state.
1890
-
1891
- - **Method**: `PATCH`
1892
- - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cache/toggle`
1893
-
1894
- #### hosting_cdn_disable
1895
-
1896
- Turns off the Hostinger CDN for the website domain. Once DNS propagation completes, the
1897
- website content is served directly from the origin server. Repeating the call is safe; when
1898
- CDN is already disabled, it applies the DNS change again.
1899
-
1900
- Returns 422 for platform-managed domains (for example `*.hostingersite.com` and
1901
- `*.app-preview.com`), where CDN cannot be disabled, even when CDN is already off. Also returns
1902
- 422 while the account is being moved to another server (retry after the move finishes), or
1903
- when the CDN provider rejects the change. Returns 404 when the domain is not a website on the
1904
- account.
1905
-
1906
- - **Method**: `POST`
1907
- - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cdn/disable`
1908
-
1909
- #### hosting_cdn_enable
1910
-
1911
- Turns on the Hostinger CDN for the website domain, which speeds up page loads and reduces the
1912
- load on the server. Works for the main domain, parked domains and subdomains of the account.
1913
-
1914
- Enabling changes the domain's DNS records and usually takes a few seconds. After that, DNS
1915
- propagation can take a few more minutes before visitors are served through the CDN.
1838
+ #### hosting_websites_update-settings
1916
1839
 
1917
- Repeating the call is safe, for example after a timeout. When CDN is already enabled, it
1918
- applies the DNS change again and refreshes the CDN SSL certificate.
1840
+ Change a website's HTTPS redirect, CDN and server cache settings in one call. Pass only the settings to change, at least one. Settings are applied in the order cache, cachelessMode, cdn, httpsRedirect, and the call stops at the first failure. applied lists the settings that were changed. When a setting fails, the call returns an error whose text is the same JSON: failed names the setting and why, and skipped lists the ones not attempted; a multi-execute batch stops there too. Turning httpsRedirect on needs an active SSL certificate: the call checks it first and changes nothing when there is none. Install one with hosting_ssl_install and wait until hosting_websites_get-settings shows ssl.status active. cachelessMode is applied in the background and takes effect within a few minutes; enabling the CDN changes DNS records, so visitors are served through it after a few minutes of propagation. Certificates are not installed or removed here: use hosting_ssl_install and hosting_ssl_uninstall. Read the current values with hosting_websites_get-settings. Works for Shared and Cloud hosting websites.
1919
1841
 
1920
- Returns 422 when the account is disabled, while the account is being moved to another
1921
- server (retry after the move finishes), or when the CDN provider rejects the change.
1922
- Returns 404 when the domain is not a website on the account.
1923
-
1924
- - **Method**: `POST`
1925
- - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cdn/enable`
1926
-
1927
- #### hosting_cdn_purge-cache
1928
-
1929
- Purges the website's content from the Hostinger CDN edge cache only. The origin server cache
1930
- is not touched; to clear both, use `Clear website cache`.
1842
+ - **Method**: `custom`
1843
+ - **Path**: `custom`
1931
1844
 
1932
- Returns 422 when CDN is not enabled on the website. Returns 404 when the domain is not a
1933
- website on the account.
1845
+ #### hosting_cache_clear
1934
1846
 
1935
- - **Method**: `DELETE`
1936
- - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cdn/purge`
1847
+ Clear a website's server cache (the hosting server's page cache) and Hostinger CDN cache, so updated content shows at once. By default (scope: all) it clears the server cache and, when the CDN is on, purges the CDN too. scope: cdn purges only the CDN edge cache and leaves the server cache alone; that fails with 422 when the CDN is off. For a WordPress site installed in a subdirectory, pass directory to clear that installation's cache (only with scope all). This does not purge the WordPress LiteSpeed Cache plugin: that is a separate WordPress operation (wordpress_litespeed-cache_purge-lite-speed). To turn caching or the CDN on or off use hosting_websites_update-settings. Works for Shared and Cloud hosting websites.
1937
1848
 
1938
- #### hosting_cdn_status
1849
+ - **Method**: `custom`
1850
+ - **Path**: `custom`
1939
1851
 
1940
- Returns whether the Hostinger CDN is enabled for the website domain. Works for the main
1941
- domain, parked domains and subdomains of the account.
1852
+ #### hosting_websites_trigger-event
1942
1853
 
1943
- The domain must be the exact website name as listed on the account, without a `www.` prefix.
1944
- Returns 404 when the domain is not a website on the account.
1854
+ Tell Hostinger that something happened on this website, so Hostinger services such as hPanel can react to it. `event.name` picks the event and decides which `event.params` it takes. The call changes nothing on the website.
1945
1855
 
1946
- - **Method**: `GET`
1947
- - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/cdn/status`
1856
+ - **Method**: `custom`
1857
+ - **Path**: `custom`
1948
1858
 
1949
1859
  #### hosting_cron-jobs_list
1950
1860
 
@@ -2562,32 +2472,6 @@ one has to be uninstalled first.
2562
2472
  - **Method**: `POST`
2563
2473
  - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/ssl/setup`
2564
2474
 
2565
- #### hosting_ssl_status
2566
-
2567
- Returns the SSL state of the website: the certificate `status` and `provider`, whether the
2568
- certificate is a lifetime one managed by the platform, whether HTTP requests are redirected to
2569
- HTTPS, when the certificate stops being valid and the last installation error.
2570
-
2571
- `installing` and `waiting_for_retry` mean an installation is in progress. `failed` means the
2572
- last installation gave up, or the website was not updated for 60 minutes while `installing`;
2573
- `last_error` holds the reason when it is a known message, otherwise it is null. `expired`
2574
- means the assigned certificate's validity has ended. `not_installed` means no certificate is
2575
- assigned. Free subdomains use a platform-managed certificate: with no installation recorded
2576
- they report `active` with `provider` and `expires_at` null.
2577
-
2578
- - **Method**: `GET`
2579
- - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/ssl/status`
2580
-
2581
- #### hosting_ssl_toggle-https-redirect
2582
-
2583
- Turns the HTTP to HTTPS redirect of the website on or off, based on `is_enabled`. Does
2584
- nothing when the redirect is already in the requested state. Turning it on requires an
2585
- installed certificate (`status` `active` or `expired` on `Get SSL status`) and returns 422
2586
- when there is none; turning it off is always accepted.
2587
-
2588
- - **Method**: `PATCH`
2589
- - **Path**: `/api/hosting/v1/accounts/{username}/websites/{domain}/ssl/https-redirect/toggle`
2590
-
2591
2475
  #### hosting_ssl_uninstall
2592
2476
 
2593
2477
  Removes the SSL certificate assigned to the website, turns the HTTPS redirect off and cancels
@@ -3720,6 +3604,21 @@ a connected domain cannot be changed here. Returns the settings after the change
3720
3604
  - **Method**: `PATCH`
3721
3605
  - **Path**: `/api/reach/v1/profiles/{profileUuid}/settings`
3722
3606
 
3607
+ #### reach_integrations_connect-ecommerce-store
3608
+
3609
+ Connect one of the customer's eCommerce stores to the profile, so Reach receives its
3610
+ customers and orders.
3611
+
3612
+ Take `store_id` from the list eCommerce stores endpoint. Fails with not found
3613
+ (`ECOMMERCE_STORE_NOT_FOUND`) when the store is not one of the customer's own stores, also
3614
+ when the eCommerce service cannot be reached. Fails with a conflict
3615
+ (`ECOMMERCE_CONNECTION_ALREADY_EXISTS`) when the store is connected to any profile or this
3616
+ profile already has a store - to move a store to another plan, disconnect it from the
3617
+ profile that holds it first.
3618
+
3619
+ - **Method**: `POST`
3620
+ - **Path**: `/api/reach/v1/profiles/{profileUuid}/ecommerce/stores/{storeId}`
3621
+
3723
3622
  #### reach_integrations_disconnect-ecommerce-store
3724
3623
 
3725
3624
  Disconnect an eCommerce store from the profile.
@@ -3728,8 +3627,8 @@ Reach stops receiving the store's customers and orders, and its products and cou
3728
3627
  removed from Reach; contacts and past orders stay. Take `store_id` from the list eCommerce
3729
3628
  stores endpoint; for a store that is `connected_to_other_profile`, call this with that
3730
3629
  profile. Also succeeds when the store is not connected to this profile, so success is not
3731
- proof that anything was disconnected. Confirm the store and the plan with the customer
3732
- before calling.
3630
+ proof that anything was disconnected. To move the store to another plan, connect it to the
3631
+ new profile afterwards. Confirm the store and the plan with the customer before calling.
3733
3632
 
3734
3633
  - **Method**: `DELETE`
3735
3634
  - **Path**: `/api/reach/v1/profiles/{profileUuid}/ecommerce/stores/{storeId}`
@@ -3741,8 +3640,8 @@ Get all of the customer's Hostinger eCommerce stores, each with its `store_id` a
3741
3640
 
3742
3641
  A store is connected to at most one profile. `connected_to_other_profile` does not name that
3743
3642
  profile - call this for each profile to find it. The list is empty, not an error, when the
3744
- eCommerce service cannot be reached. Pass `store_id` to the disconnect eCommerce store
3745
- endpoint. Connecting an AI Website Builder site connects the store selling on it.
3643
+ eCommerce service cannot be reached. Pass `store_id` to the connect or disconnect eCommerce
3644
+ store endpoint.
3746
3645
 
3747
3646
  - **Method**: `GET`
3748
3647
  - **Path**: `/api/reach/v1/profiles/{profileUuid}/ecommerce/stores`
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hostinger-api-mcp",
3
- "version": "3.17.4",
3
+ "version": "3.18.0",
4
4
  "description": "Hostinger API — manage domains, DNS, hosting, VPS, billing and more from Gemini CLI.",
5
5
  "mcpServers": {
6
6
  "hostinger": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hostinger-api-mcp",
3
- "version": "3.17.4",
3
+ "version": "3.18.0",
4
4
  "mcpName": "io.github.hostinger/hostinger-api-mcp",
5
5
  "description": "MCP server for Hostinger API",
6
6
  "repository": {
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/hostinger/api-mcp-server",
7
7
  "source": "github"
8
8
  },
9
- "version": "3.17.4",
9
+ "version": "3.18.0",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "@hostinger/mcp",
14
- "version": "3.17.4",
14
+ "version": "3.18.0",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },
@@ -29,7 +29,7 @@ Tell the user the size (plans, websites, WordPress installs) before the checks.
29
29
 
30
30
  Per Shared and Cloud website (skip `builder` and `horizons`):
31
31
 
32
- - `hosting_ssl_status` — flag `failed` (with `last_error`), `expired`, `not_installed` on a custom domain, `is_https_redirect_enabled: false`, and `expires_at` within 30 days when `is_lifetime` is false. Lifetime certificates renew on their own.
32
+ - `hosting_websites_get-settings` — in `ssl`, flag `failed` (with `last_error`), `expired`, `not_installed` on a custom domain, `is_https_redirect_enabled: false`, and `expires_at` within 30 days when `is_lifetime` is false; lifetime certificates renew on their own. In `cache`, flag `is_cacheless_mode_enabled: true` (development mode left on) and `is_enabled: false`.
33
33
  - Node.js sites: `hosting_get-deployment` (latest build failed? `build.state`) and `hosting_nodejs_list-vulnerabilities` with `severities: ["critical", "high"]`.
34
34
 
35
35
  Per hosting account (`username`): `hosting_databases_list` — flag `disk_usage_mb` above 80% of `max_size_mb`.
@@ -53,7 +53,7 @@ Agency Plan:
53
53
 
54
54
  Start only once `dig` shows the domain resolving to Hostinger — the certificate authority checks the domain against the server.
55
55
 
56
- - Shared and Cloud: `hosting_ssl_status`. When it is not `active`, call `hosting_ssl_install` and poll the status until `active` (or `failed` with `last_error`), then `hosting_ssl_toggle-https-redirect` with `is_enabled: true` (it returns 422 until a certificate exists).
56
+ - Shared and Cloud: `ssl` in `hosting_websites_get-settings`. When `ssl.status` is not `active`, call `hosting_ssl_install` and poll `hosting_websites_get-settings` until it is `active` (or `failed` with `last_error`), then `hosting_websites_update-settings` with `httpsRedirect: true` (it changes nothing until the certificate is `active`).
57
57
  - Agency: `agency-hosting_ssl_install-website` for each domain, then poll `agency-hosting_ssl_website-status`. A domain allows three setups per seven days and one request a minute — install once DNS is right and never loop.
58
58
  - A `CAA` record at the apex that does not allow `letsencrypt.org` blocks issuance; the user adds `0 issue "letsencrypt.org"` beside the existing ones.
59
59
 
@@ -130,6 +130,6 @@ curl -s -o /dev/null -w "%{http_code}\n" https://DOMAIN/
130
130
  curl -s https://DOMAIN/ | grep -o "TEXT THE PROJECT RENDERS"
131
131
  ```
132
132
 
133
- A `200` alone can be a placeholder page; match real copy. A new site may serve a default page briefly — clear it with `hosting_cache_clear-website` and retry before calling the deploy failed.
133
+ A `200` alone can be a placeholder page; match real copy. A new site may serve a default page briefly — clear it with `hosting_cache_clear` and retry before calling the deploy failed.
134
134
 
135
135
  Write `.hostinger/site.json` in the project so later runs reuse the target: `{ "domain", "username" or "website_uid", "type": "static" | "nodejs" | "php" }`, keeping any fields already there.
@@ -35,7 +35,7 @@ dig +short NS DOMAIN; dig +short A DOMAIN; dig +short CAA DOMAIN
35
35
  - Hostinger responses carry `platform: hostinger` and `panel: hpanel`. Without them, or with DNS pointing elsewhere, traffic is not reaching this hosting — hand over to the `connect-domain` skill.
36
36
  - Certificate or TLS errors → [SSL](#ssl).
37
37
  - `5xx`, a blank page or an error page → [By website type](#3-by-website-type).
38
- - `200` with old content → cache: `hosting_cache_clear-website` (also purges the Hostinger CDN; pass `directory` for WordPress in a subfolder), plus `wordpress_litespeed-cache_purge-lite-speed` for WordPress; Agency: `agency-hosting_cache_clear-website`.
38
+ - `200` with old content → cache: `hosting_cache_clear` (also purges the Hostinger CDN; pass `directory` for WordPress in a subfolder), plus `wordpress_litespeed-cache_purge-lite-speed` for WordPress; Agency: `agency-hosting_cache_clear-website`.
39
39
  - Slow first byte → [Slow site](#slow-site). Behind the Hostinger CDN, `x-hcdn-upstream-rt` is the origin's own response time in seconds; a small value there means the server is not the bottleneck.
40
40
 
41
41
  ## 3. By website type
@@ -76,19 +76,19 @@ Batch `hosting_get-deployment` (the latest build with its log, failure analysis
76
76
 
77
77
  ## SSL
78
78
 
79
- Shared and Cloud, `hosting_ssl_status`:
79
+ Shared and Cloud, `ssl` in `hosting_websites_get-settings`:
80
80
 
81
- - `not_installed` or `failed` (`last_error` says why): the domain must resolve to Hostinger, and any CAA record must allow `letsencrypt.org`, before `hosting_ssl_install` can succeed. Poll the status until `active` or `failed`.
81
+ - `not_installed` or `failed` (`last_error` says why): the domain must resolve to Hostinger, and any CAA record must allow `letsencrypt.org`, before `hosting_ssl_install` can succeed. Poll `hosting_websites_get-settings` until `ssl.status` is `active` or `failed`.
82
82
  - `installing` or `waiting_for_retry`: wait — another install request returns 422.
83
83
  - Free `*.hostingersite.com` subdomains use a platform certificate; installing returns 422 by design.
84
- - Browser still warns while the certificate is `active`: turn on the redirect with `hosting_ssl_toggle-https-redirect` when `is_https_redirect_enabled` is false, otherwise the page loads `http://` assets (mixed content) that the app has to change.
84
+ - Browser still warns while the certificate is `active`: turn on the redirect with `hosting_websites_update-settings` (`httpsRedirect: true`) when `is_https_redirect_enabled` is false, otherwise the page loads `http://` assets (mixed content) that the app has to change.
85
85
 
86
86
  Agency, `agency-hosting_ssl_website-status` for each domain: every domain allows three certificate setups per seven days and one request a minute. Check `agency-hosting_websites_list-processes` before `agency-hosting_ssl_install-website` or `agency-hosting_ssl_reinstall-website`, and never retry in a loop.
87
87
 
88
88
  ## Slow site
89
89
 
90
90
  - WordPress: `wordpress_litespeed-cache_show-lite-speed-status` and `wordpress_object-cache_show-memcached-status`. Turning on Memcached with `wordpress_object-cache_toggle-memcached` is the usual quick win.
91
- - Other sites: server caching may be off or development mode left on, and neither has a read operation. `hosting_cache_toggle-website` with `enabled: true` does nothing when caching is already on; `hosting_cache_toggle-cacheless` with `enabled: false` turns development mode off.
91
+ - Other sites: server caching may be off or development mode left on. `hosting_websites_get-settings` shows both in `cache` (`is_enabled`, `is_cacheless_mode_enabled`); fix them with `hosting_websites_update-settings` (`cache: true`, `cachelessMode: false`). Development mode takes a few minutes to turn off.
92
92
  - PHP 7.x runs markedly slower than 8.x; propose a supported 8.x version from `hosting_php_get` when the app allows it.
93
93
  - Agency: `agency-hosting_metrics_list-order-resource-usage` with `time_frame_hours: 24` shows CPU, memory and processes per website against the plan quota.
94
94
  - Shared and Cloud have no CPU or memory metrics in the API. When the evidence points at resource limits, send the user to hPanel's resource usage page.
@@ -66,7 +66,7 @@ const GetSkillRequestSchema = z.object({
66
66
 
67
67
  /**
68
68
  * MCP Server for Hostinger API
69
- * Generated from OpenAPI spec version 2.4.4
69
+ * Generated from OpenAPI spec version 2.5.0
70
70
  */
71
71
  class MCPServer {
72
72
  constructor({ name, version, tools, instructions, skills = [] }) {
@@ -302,6 +302,12 @@ class MCPServer {
302
302
  return await this.handleHostingDeploy(params);
303
303
  case 'hosting_get-deployment':
304
304
  return await this.handleHostingGetDeployment(params);
305
+ case 'hosting_websites_get-settings':
306
+ return await this.handleHostingWebsitesGetSettings(params);
307
+ case 'hosting_websites_update-settings':
308
+ return await this.handleHostingWebsitesUpdateSettings(params);
309
+ case 'hosting_cache_clear':
310
+ return await this.handleHostingCacheClear(params);
305
311
  case 'hosting_import-wordpress-website':
306
312
  return await this.handleWordpressWebsiteImport(params);
307
313
  case 'hosting_deploy-wordpress-plugin':
@@ -559,7 +565,7 @@ class MCPServer {
559
565
  // Agency Plan (U4S) websites come back without a username, and every later call would fail with
560
566
  // an unclear API error.
561
567
  if (typeof site.username !== 'string') {
562
- throw new Error(site.domain + ' is an Agency Plan website: Git deploys and build status here work only for Shared and Cloud hosting websites. Use the agency-hosting operations for it.');
568
+ throw new Error(site.domain + ' is an Agency Plan website: this tool works only for Shared and Cloud hosting websites. Use the agency-hosting operations for it.');
563
569
  }
564
570
  return site;
565
571
  }
@@ -1330,6 +1336,150 @@ class MCPServer {
1330
1336
  };
1331
1337
  }
1332
1338
 
1339
+ // A 404 means the domain is not a website on the account, which fails the whole call; any other
1340
+ // failure only fails its own section.
1341
+ async hosting_websitesGetSettings_section(request, pick) {
1342
+ try {
1343
+ return pick(await request);
1344
+ } catch (error) {
1345
+ if (error instanceof ApiExecutionError && error.status === 404) {
1346
+ throw error;
1347
+ }
1348
+ return { error: this.formatToolError(error) };
1349
+ }
1350
+ }
1351
+
1352
+ async handleHostingWebsitesGetSettings(params) {
1353
+ const { domain: requestedDomain } = params;
1354
+
1355
+ if (!requestedDomain || typeof requestedDomain !== 'string') {
1356
+ throw new Error('domain is required and must be a string');
1357
+ }
1358
+
1359
+ const { username, domain } = await this.findWebsite(requestedDomain);
1360
+ const target = { username, domain };
1361
+ // hosting_cache_status joined the spec after this tool: a catalog without it gets cache: null.
1362
+ // Once every catalog has it, make this true (and drop cacheNote).
1363
+ const cacheAvailable = this.operations.has('hosting_cache_status');
1364
+
1365
+ const [ssl, cdn, cache] = await Promise.all([
1366
+ this.hosting_websitesGetSettings_section(this.callOperation('hosting_ssl_status', target), (response) => response),
1367
+ this.hosting_websitesGetSettings_section(this.callOperation('hosting_cdn_status', target), (response) => ({ is_enabled: response.is_enabled })),
1368
+ cacheAvailable
1369
+ ? this.hosting_websitesGetSettings_section(this.callOperation('hosting_cache_status', target), (response) => ({
1370
+ is_enabled: response.is_enabled,
1371
+ is_cacheless_mode_enabled: response.is_cacheless_mode_enabled,
1372
+ }))
1373
+ : Promise.resolve(null),
1374
+ ]);
1375
+
1376
+ return {
1377
+ domain,
1378
+ ssl,
1379
+ cdn,
1380
+ cache,
1381
+ ...(cacheAvailable ? {} : { cacheNote: 'cache status not available yet' }),
1382
+ };
1383
+ }
1384
+
1385
+ // Application order, and how each setting maps to its operation.
1386
+ hosting_websitesUpdateSettings_steps = [
1387
+ { setting: 'cache', run: (target, value) => this.callOperation('hosting_cache_toggle-website', { ...target, enabled: value }) },
1388
+ { setting: 'cachelessMode', run: (target, value) => this.callOperation('hosting_cache_toggle-cacheless', { ...target, enabled: value }) },
1389
+ { setting: 'cdn', run: (target, value) => this.callOperation(value ? 'hosting_cdn_enable' : 'hosting_cdn_disable', target) },
1390
+ { setting: 'httpsRedirect', run: (target, value) => this.callOperation('hosting_ssl_toggle-https-redirect', { ...target, is_enabled: value }) },
1391
+ ];
1392
+
1393
+ async handleHostingWebsitesUpdateSettings(params) {
1394
+ const { domain: requestedDomain } = params;
1395
+
1396
+ // Models send null for settings they leave unset.
1397
+ const requested = this.hosting_websitesUpdateSettings_steps.filter(step => params[step.setting] !== undefined && params[step.setting] !== null);
1398
+ for (const step of requested) {
1399
+ if (typeof params[step.setting] !== 'boolean') {
1400
+ throw new Error(step.setting + ' must be a boolean when provided');
1401
+ }
1402
+ }
1403
+ if (requested.length === 0) {
1404
+ throw new Error('Pass at least one of cache, cachelessMode, cdn, httpsRedirect');
1405
+ }
1406
+ if (!requestedDomain || typeof requestedDomain !== 'string') {
1407
+ throw new Error('domain is required and must be a string');
1408
+ }
1409
+
1410
+ const { username, domain } = await this.findWebsite(requestedDomain);
1411
+ const target = { username, domain };
1412
+
1413
+ // The redirect needs an installed certificate: check it before changing anything, so a
1414
+ // missing certificate does not leave the other settings half applied.
1415
+ if (params.httpsRedirect === true) {
1416
+ const ssl = await this.callOperation('hosting_ssl_status', target);
1417
+ const status = ssl ? ssl.status : undefined;
1418
+ if (status !== 'active') {
1419
+ const shown = ['string', 'number', 'boolean'].includes(typeof status) ? String(status) : 'unknown';
1420
+ throw new Error('HTTPS redirect needs an active SSL certificate, but the SSL status of ' + domain + ' is ' + shown + '. Install SSL first with hosting_ssl_install and wait until hosting_websites_get-settings shows ssl.status active; no settings were changed.');
1421
+ }
1422
+ }
1423
+
1424
+ const applied = {};
1425
+ let failed = null;
1426
+ const skipped = [];
1427
+ for (const step of requested) {
1428
+ const value = params[step.setting];
1429
+ if (failed) {
1430
+ skipped.push(step.setting);
1431
+ continue;
1432
+ }
1433
+ try {
1434
+ await step.run(target, value);
1435
+ applied[step.setting] = value;
1436
+ } catch (error) {
1437
+ failed = { setting: step.setting, error: this.formatToolError(error) };
1438
+ }
1439
+ }
1440
+
1441
+ const result = {
1442
+ domain,
1443
+ applied,
1444
+ failed,
1445
+ skipped,
1446
+ ...('cachelessMode' in applied ? { note: 'cachelessMode takes effect in the background within a few minutes; hosting_websites_get-settings shows it once applied.' } : {}),
1447
+ };
1448
+ // A failed setting is a tool error carrying the same JSON, so execute reports it and a
1449
+ // multi-execute batch stops at this step.
1450
+ if (failed) {
1451
+ throw new Error(JSON.stringify(result));
1452
+ }
1453
+ return result;
1454
+ }
1455
+
1456
+ async handleHostingCacheClear(params) {
1457
+ const { domain: requestedDomain } = params;
1458
+ // Models send null for fields they leave unset.
1459
+ const scope = params.scope ?? 'all';
1460
+ const directory = params.directory ?? null;
1461
+
1462
+ if (scope !== 'all' && scope !== 'cdn') {
1463
+ throw new Error('scope must be one of: all, cdn');
1464
+ }
1465
+ if (directory !== null && (typeof directory !== 'string' || directory === '')) {
1466
+ throw new Error('directory must be a non-empty string when provided');
1467
+ }
1468
+ if (scope === 'cdn' && directory !== null) {
1469
+ throw new Error('directory applies only when scope is all: the CDN purge clears the whole website');
1470
+ }
1471
+ if (!requestedDomain || typeof requestedDomain !== 'string') {
1472
+ throw new Error('domain is required and must be a string');
1473
+ }
1474
+
1475
+ const { username, domain } = await this.findWebsite(requestedDomain);
1476
+
1477
+ const response = scope === 'cdn'
1478
+ ? await this.callOperation('hosting_cdn_purge-cache', { username, domain })
1479
+ : await this.callOperation('hosting_cache_clear-website', { username, domain, ...(directory !== null ? { directory } : {}) });
1480
+ return { domain, cleared: scope, directory, response };
1481
+ }
1482
+
1333
1483
  hosting_importWordpressWebsite_validateArchiveFormat(filePath) {
1334
1484
  const validExtensions = ['zip', 'tar', 'tar.gz', 'tgz', '7z', 'gz', 'gzip'];
1335
1485
  const fileName = path.basename(filePath).toLowerCase();