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.
- package/CHANGELOG.md +20 -0
- package/README.md +36 -137
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/skills/audit-hosting/SKILL.md +1 -1
- package/skills/connect-domain/SKILL.md +1 -1
- package/skills/deploy-to-hosting/SKILL.md +1 -1
- package/skills/troubleshoot-website/SKILL.md +5 -5
- package/src/core/runtime.js +152 -2
- package/src/core/runtime.ts +152 -2
- package/src/core/skills.js +12 -12
- package/src/core/skills.ts +12 -12
- package/src/core/tools/all.js +182 -12
- package/src/core/tools/all.ts +182 -12
- package/src/core/tools/hosting.js +145 -10
- package/src/core/tools/hosting.ts +145 -10
- package/src/core/tools/reach.js +37 -2
- package/src/core/tools/reach.ts +37 -2
- package/src/servers/agency-hosting.js +1 -1
- package/src/servers/agency-hosting.ts +1 -1
- package/src/servers/agent-readiness.js +1 -1
- package/src/servers/agent-readiness.ts +1 -1
- package/src/servers/all.js +1 -1
- package/src/servers/all.ts +1 -1
- package/src/servers/billing.js +1 -1
- package/src/servers/billing.ts +1 -1
- package/src/servers/dns.js +1 -1
- package/src/servers/dns.ts +1 -1
- package/src/servers/domains.js +1 -1
- package/src/servers/domains.ts +1 -1
- package/src/servers/ecommerce.js +1 -1
- package/src/servers/ecommerce.ts +1 -1
- package/src/servers/horizons.js +1 -1
- package/src/servers/horizons.ts +1 -1
- package/src/servers/hosting.js +1 -1
- package/src/servers/hosting.ts +1 -1
- package/src/servers/mail.js +1 -1
- package/src/servers/mail.ts +1 -1
- package/src/servers/reach.js +1 -1
- package/src/servers/reach.ts +1 -1
- package/src/servers/vps.js +1 -1
- package/src/servers/vps.ts +1 -1
- package/src/servers/wordpress.js +1 -1
- package/src/servers/wordpress.ts +1 -1
- 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 (
|
|
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` —
|
|
80
|
+
- `hostinger-hosting-mcp` — 61 operations for hosting
|
|
81
81
|
- `hostinger-mail-mcp` — 38 operations for mail
|
|
82
|
-
- `hostinger-reach-mcp` —
|
|
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
|
-
####
|
|
1831
|
+
#### hosting_websites_get-settings
|
|
1832
1832
|
|
|
1833
|
-
|
|
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
|
-
####
|
|
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
|
-
|
|
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
|
-
|
|
1921
|
-
|
|
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
|
-
|
|
1933
|
-
website on the account.
|
|
1845
|
+
#### hosting_cache_clear
|
|
1934
1846
|
|
|
1935
|
-
-
|
|
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
|
-
|
|
1849
|
+
- **Method**: `custom`
|
|
1850
|
+
- **Path**: `custom`
|
|
1939
1851
|
|
|
1940
|
-
|
|
1941
|
-
domain, parked domains and subdomains of the account.
|
|
1852
|
+
#### hosting_websites_trigger-event
|
|
1942
1853
|
|
|
1943
|
-
|
|
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**: `
|
|
1947
|
-
- **Path**:
|
|
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.
|
|
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
|
|
3745
|
-
|
|
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`
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
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.
|
|
9
|
+
"version": "3.18.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@hostinger/mcp",
|
|
14
|
-
"version": "3.
|
|
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
|
-
- `
|
|
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: `
|
|
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
|
|
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
|
|
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, `
|
|
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
|
|
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 `
|
|
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
|
|
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.
|
package/src/core/runtime.js
CHANGED
|
@@ -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.
|
|
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:
|
|
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();
|