hostinger-api-mcp 2.0.0 → 2.1.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 (64) hide show
  1. package/CHANGELOG.md +423 -0
  2. package/README.md +406 -406
  3. package/gemini-extension.json +1 -1
  4. package/package.json +1 -1
  5. package/server.json +2 -2
  6. package/skills/headless/SKILL.md +1 -1
  7. package/skills/headless/references/DATABASE.md +14 -14
  8. package/skills/headless/references/DEPLOYMENT.md +5 -5
  9. package/skills/headless/references/SETUP.md +8 -8
  10. package/skills/headless/references/STORE.md +4 -4
  11. package/skills/headless/references/WORDPRESS.md +5 -5
  12. package/src/core/instructions.js +1 -1
  13. package/src/core/instructions.ts +1 -1
  14. package/src/core/runtime.js +9 -9
  15. package/src/core/runtime.ts +9 -9
  16. package/src/core/tools/agency-hosting.js +44 -44
  17. package/src/core/tools/agency-hosting.ts +44 -44
  18. package/src/core/tools/all.js +405 -405
  19. package/src/core/tools/all.ts +405 -405
  20. package/src/core/tools/billing.js +9 -9
  21. package/src/core/tools/billing.ts +9 -9
  22. package/src/core/tools/dns.js +8 -8
  23. package/src/core/tools/dns.ts +8 -8
  24. package/src/core/tools/domains.js +41 -41
  25. package/src/core/tools/domains.ts +41 -41
  26. package/src/core/tools/ecommerce.js +29 -29
  27. package/src/core/tools/ecommerce.ts +29 -29
  28. package/src/core/tools/horizons.js +6 -6
  29. package/src/core/tools/horizons.ts +6 -6
  30. package/src/core/tools/hosting.js +76 -76
  31. package/src/core/tools/hosting.ts +76 -76
  32. package/src/core/tools/mail.js +38 -38
  33. package/src/core/tools/mail.ts +38 -38
  34. package/src/core/tools/reach.js +52 -52
  35. package/src/core/tools/reach.ts +52 -52
  36. package/src/core/tools/vps.js +64 -64
  37. package/src/core/tools/vps.ts +64 -64
  38. package/src/core/tools/wordpress.js +38 -38
  39. package/src/core/tools/wordpress.ts +38 -38
  40. package/src/servers/agency-hosting.js +1 -1
  41. package/src/servers/agency-hosting.ts +1 -1
  42. package/src/servers/all.js +1 -1
  43. package/src/servers/all.ts +1 -1
  44. package/src/servers/billing.js +1 -1
  45. package/src/servers/billing.ts +1 -1
  46. package/src/servers/dns.js +1 -1
  47. package/src/servers/dns.ts +1 -1
  48. package/src/servers/domains.js +1 -1
  49. package/src/servers/domains.ts +1 -1
  50. package/src/servers/ecommerce.js +1 -1
  51. package/src/servers/ecommerce.ts +1 -1
  52. package/src/servers/horizons.js +1 -1
  53. package/src/servers/horizons.ts +1 -1
  54. package/src/servers/hosting.js +1 -1
  55. package/src/servers/hosting.ts +1 -1
  56. package/src/servers/mail.js +1 -1
  57. package/src/servers/mail.ts +1 -1
  58. package/src/servers/reach.js +1 -1
  59. package/src/servers/reach.ts +1 -1
  60. package/src/servers/vps.js +1 -1
  61. package/src/servers/vps.ts +1 -1
  62. package/src/servers/wordpress.js +1 -1
  63. package/src/servers/wordpress.ts +1 -1
  64. package/types.d.ts +405 -405
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hostinger-api-mcp",
3
- "version": "2.0.0",
3
+ "version": "2.1.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": "2.0.0",
3
+ "version": "2.1.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": "2.0.0",
9
+ "version": "2.1.0",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "@hostinger/mcp",
14
- "version": "2.0.0",
14
+ "version": "2.1.0",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },
@@ -52,5 +52,5 @@ Run non-interactively wherever possible. The exceptions that must involve the us
52
52
 
53
53
  The inputSchema returned by search is authoritative for request shapes — read it before calling. Two live sources supersede anything written here when they disagree:
54
54
 
55
- - The ecommerce operation `ecommerce_getCustomStorefrontSetupInstructionsV1` returns the current storefront integration guide from the server — execute it at the start of any store run.
55
+ - The ecommerce operation `ecommerce_miscellaneous_custom-storefront-setup-instructions` returns the current storefront integration guide from the server — execute it at the start of any store run.
56
56
  - The Hostinger API reference at https://developers.hostinger.com describes every endpoint behind the operations.
@@ -4,8 +4,8 @@ Use this when the app needs MySQL, or when a deploy "succeeded" but the app cann
4
4
 
5
5
  ## 1. Create the database
6
6
 
7
- 1. `hosting_createAccountDatabaseV1` on the site's `username` with a database name, a user and a password you generate — name and user are prefixed with the account username automatically.
8
- 2. Read the full, prefixed `name` and `user` back from `hosting_listAccountDatabasesV1`; every other database operation wants the full name.
7
+ 1. `hosting_databases_create` on the site's `username` with a database name, a user and a password you generate — name and user are prefixed with the account username automatically.
8
+ 2. Read the full, prefixed `name` and `user` back from `hosting_databases_list`; every other database operation wants the full name.
9
9
  3. Do not print the password to the user once it is stored, and never commit it.
10
10
 
11
11
  ## 2. Which host the app connects to
@@ -14,13 +14,13 @@ Use this when the app needs MySQL, or when a deploy "succeeded" but the app cann
14
14
  | --- | --- | --- | --- |
15
15
  | PHP on the website | `localhost` or `127.0.0.1` | 3306 | `localhost` uses the MySQL socket; both are granted |
16
16
  | Node.js on the website | `127.0.0.1` | 3306 | `localhost` may resolve to IPv6 `::1`, and not every database user has that grant |
17
- | Outside Hostinger (a laptop, another server) | the `host` from `hosting_listAccountDatabasesV1` (`srvNNNN.hstgr.io`) | 3306 | needs `hosting_createDatabaseRemoteConnectionV1` for that client's IP first — never `%`, it opens the database to every address on the internet |
17
+ | Outside Hostinger (a laptop, another server) | the `host` from `hosting_databases_list` (`srvNNNN.hstgr.io`) | 3306 | needs `hosting_databases_create-remote-connection` for that client's IP first — never `%`, it opens the database to every address on the internet |
18
18
 
19
19
  Do not put the remote `host` into the deployed app — it has no grant for connections that come from the server itself.
20
20
 
21
21
  ## 3. Hand credentials to the app
22
22
 
23
- - **Node.js:** environment variables via `hosting_replaceNode_jsEnvironmentVariablesV1`. Conventional keys: `DB_HOST=127.0.0.1`, `DB_PORT=3306`, `DB_NAME`, `DB_USER`, `DB_PASSWORD`, plus `DATABASE_URL=mysql://USER:PASSWORD@127.0.0.1:3306/NAME` for ORMs that want one string — URL-encode `USER` and `PASSWORD` there (`encodeURIComponent`), or a password containing `@`, `:`, `/` or `#` breaks the URL. The call is a **full replace**: list the current keys with `hosting_listNode_jsEnvironmentVariablesV1` (values come back masked as `********` — never copy those), then send the complete set with real values. Saving restarts the process; frameworks that bake variables into the build (Next.js, `NEXT_PUBLIC_*`) need a new `hosting_startNode_jsBuildV1` afterwards.
23
+ - **Node.js:** environment variables via `hosting_nodejs_replace-environment-variables`. Conventional keys: `DB_HOST=127.0.0.1`, `DB_PORT=3306`, `DB_NAME`, `DB_USER`, `DB_PASSWORD`, plus `DATABASE_URL=mysql://USER:PASSWORD@127.0.0.1:3306/NAME` for ORMs that want one string — URL-encode `USER` and `PASSWORD` there (`encodeURIComponent`), or a password containing `@`, `:`, `/` or `#` breaks the URL. The call is a **full replace**: list the current keys with `hosting_nodejs_list-environment-variables` (values come back masked as `********` — never copy those), then send the complete set with real values. Saving restarts the process; frameworks that bake variables into the build (Next.js, `NEXT_PUBLIC_*`) need a new `hosting_nodejs_start-build` afterwards.
24
24
  - **PHP:** a config file on the server that the app reads (its own `config.php`, WordPress's `wp-config.php`). Ship it with the deploy, keep it out of git.
25
25
  - **Never** in client-side JavaScript, in a committed `.env`, or in chat replies.
26
26
 
@@ -28,22 +28,22 @@ Do not put the remote `host` into the deployed app — it has no grant for conne
28
28
 
29
29
  | You called | Poll this until | Typical wait |
30
30
  | --- | --- | --- |
31
- | `hosting_createWebsiteV1` | `hosting_listWebsitesV1` lists the domain | up to a few minutes |
32
- | `hosting_deployJsApplication` | `hosting_listJsDeployments` shows the build finished | minutes |
33
- | `hosting_startNode_jsBuildV1` | `hosting_getNode_jsBuildDetailsV1` state is `completed` or `failed` | minutes |
34
- | `hosting_installWordPressV1`, plugin/theme/core jobs | `hosting_listWordPressInstallationsV1` lists the install | 1–2 minutes |
35
- | `hosting_repairDatabaseV1`, `hosting_deleteWebsiteV1` | nothing to poll — runs in the background | minutes |
36
- | `agency-hosting_createANewWebsiteV1` | `agency-hosting_getWebsiteSetupStatusV1` with `setup_uuid` is `completed` | minutes |
31
+ | `hosting_websites_create` | `hosting_websites_list` lists the domain | up to a few minutes |
32
+ | `hosting_deploy-js-application` | `hosting_list-js-deployments` shows the build finished | minutes |
33
+ | `hosting_nodejs_start-build` | `hosting_nodejs_build` state is `completed` or `failed` | minutes |
34
+ | `wordpress_installations_install`, plugin/theme/core jobs | `wordpress_installations_list` lists the install | 1–2 minutes |
35
+ | `hosting_databases_repair`, `hosting_websites_delete` | nothing to poll — runs in the background | minutes |
36
+ | `agency-hosting_website-setups_create` | `agency-hosting_website-setups_status` with `setup_uuid` is `completed` | minutes |
37
37
 
38
38
  Poll with backoff (a few seconds, then tens of seconds). A queued response is not a failure, and re-sending the write does not speed it up.
39
39
 
40
40
  ## 5. When the app is up but broken
41
41
 
42
- - Build failed: `hosting_getNodeJSBuildLogsV1` for the raw log, `hosting_analyseFailedNode_jsBuildV1` for a diagnosis.
43
- - Build passed, app errors: `hosting_getNode_jsRuntimeLogsV1` with a `period` such as `1h`; entries before `last_deployed_at` belong to the previous deploy.
42
+ - Build failed: `hosting_nodejs_build-logs` for the raw log, `hosting_nodejs_analyse-failed-build` for a diagnosis.
43
+ - Build passed, app errors: `hosting_nodejs_runtime-logs` with a `period` such as `1h`; entries before `last_deployed_at` belong to the previous deploy.
44
44
  - `Access denied for user 'x'@'::1'`: the app used `localhost` from Node.js — set `DB_HOST` to `127.0.0.1`.
45
- - PHP limits (memory, upload size): `hosting_getPHPDetailsV1`, then `hosting_updatePHPOptionsV1`.
45
+ - PHP limits (memory, upload size): `hosting_php_get`, then `hosting_php_update-options`.
46
46
 
47
47
  ## Agency Plan websites (`agency-hosting_*`)
48
48
 
49
- `agency-hosting_createWebsiteDatabaseV1` creates the database and its single user; the user is granted on `localhost`, so the PHP app connects to `localhost`. Deploys are synchronous there — `agency-hosting_deployPhpApplication` returns when the site is live. Other jobs (SSL, backups) show up in `agency-hosting_listWebsiteProcessesV1`.
49
+ `agency-hosting_databases_create-website` creates the database and its single user; the user is granted on `localhost`, so the PHP app connects to `localhost`. Deploys are synchronous there — `agency-hosting_deploy-php-application` returns when the site is live. Other jobs (SSL, backups) show up in `agency-hosting_websites_list-processes`.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Match the deploy method to what the project actually is — this is the single most common failure point.
4
4
 
5
- ## Static site → `hosting_deployStaticWebsite`
5
+ ## Static site → `hosting_deploy-static-website`
6
6
 
7
7
  For pre-built files only: plain HTML/CSS/JS, or the **build output** of a framework (run the build locally first).
8
8
 
@@ -10,15 +10,15 @@ For pre-built files only: plain HTML/CSS/JS, or the **build output** of a framew
10
10
  - Name it `name_YYYYMMDD_HHMMSS.zip`; pass `removeArchive: true` to clean up after upload.
11
11
  - Deployment is effectively immediate — verify right after.
12
12
 
13
- ## Node.js app → `hosting_deployJsApplication`
13
+ ## Node.js app → `hosting_deploy-js-application`
14
14
 
15
15
  For anything that needs a server or a server-side build (Express, Next.js, NestJS, SSR frameworks).
16
16
 
17
17
  - Archive the **source**, not the output: exclude `node_modules/`, `dist/`, `.next/`, `build/`, and everything matched by `.gitignore`. The install and build run on Hostinger.
18
18
  - Hard cap: **50 MB** archive.
19
- - The upload starts a build. Track it with `hosting_listJsDeployments`; on failure pull `hosting_showJsDeploymentLogs`, fix, and redeploy. Poll with backoff — builds take minutes, not seconds.
19
+ - The upload starts a build. Track it with `hosting_list-js-deployments`; on failure pull `hosting_show-js-deployment-logs`, fix, and redeploy. Poll with backoff — builds take minutes, not seconds.
20
20
 
21
- ## WordPress → `hosting_importWordpressWebsite` / plugin & theme operations
21
+ ## WordPress → `hosting_import-wordpress-website` / plugin & theme operations
22
22
 
23
23
  Only when the user explicitly wants a WordPress *site* migrated or themed. Site imports take an archive plus a `.sql` dump and can run for several minutes. (WordPress as a headless content backend behind an agent-built frontend is a different flow — that's `WORDPRESS.md`, installed fresh via the API, not imported here.)
24
24
 
@@ -29,6 +29,6 @@ curl -s -o /dev/null -w "%{http_code}\n" https://YOURDOMAIN/
29
29
  curl -s https://YOURDOMAIN/ | grep -o "SOME_REAL_HEADLINE_TEXT"
30
30
  ```
31
31
 
32
- Replace the grep target with copy you actually rendered — a 200 alone can be a placeholder page. A freshly created site may serve a default page for a short while; if content doesn't match, clear the cache (`hosting_clearWebsiteCacheV1`) and retry before assuming the deploy failed. For store runs, also run the checkout verification in `STORE.md`.
32
+ Replace the grep target with copy you actually rendered — a 200 alone can be a placeholder page. A freshly created site may serve a default page for a short while; if content doesn't match, clear the cache (`hosting_cache_clear-website`) and retry before assuming the deploy failed. For store runs, also run the checkout verification in `STORE.md`.
33
33
 
34
34
  When the site is live, report the URL and remind the user the site is managed from hPanel (https://hpanel.hostinger.com).
@@ -6,24 +6,24 @@ Everything here uses the **hosting** MCP operations. If they're missing, ask the
6
6
 
7
7
  A website can only be created on an active hosting plan.
8
8
 
9
- 1. `hosting_listWebsitesV1` — if it returns websites, the account has a working plan; note any existing `order_id` and `username` for step 2.
10
- 2. Otherwise `hosting_listOrdersV1` — look for an order in a usable state. A fresh order that has never hosted a website still works; note its `order_id`.
9
+ 1. `hosting_websites_list` — if it returns websites, the account has a working plan; note any existing `order_id` and `username` for step 2.
10
+ 2. Otherwise `hosting_orders_list` — look for an order in a usable state. A fresh order that has never hosted a website still works; note its `order_id`.
11
11
  3. If there is no usable order: **stop and tell the user** that an active Hostinger hosting plan is required to deploy, link https://www.hostinger.com/web-hosting, and offer to continue building the site locally in the meantime. When they confirm the purchase, re-run this check.
12
12
 
13
13
  Never purchase a plan, domain, or any paid item without the user explicitly approving that specific purchase.
14
14
 
15
15
  ## 2. Choose the domain
16
16
 
17
- - **Default: free subdomain.** `hosting_generateAFreeSubdomainV1` returns a `*.hostingersite.com` domain. No verification needed. Tell the user a custom domain can be connected later.
18
- - **User-owned domain:** `hosting_verifyDomainOwnershipV1` first. If not accessible, relay the TXT record it returns, remind them propagation can take ~10 minutes, and re-verify before continuing.
19
- - **New domain purchase:** only on explicit request — check availability with `domains_checkDomainAvailabilityV1`, state the price, and get an explicit yes before `domains_purchaseNewDomainV1` (needs the domains product group).
17
+ - **Default: free subdomain.** `hosting_domains_generate-free-subdomain` returns a `*.hostingersite.com` domain. No verification needed. Tell the user a custom domain can be connected later.
18
+ - **User-owned domain:** `hosting_domains_verify-ownership` first. If not accessible, relay the TXT record it returns, remind them propagation can take ~10 minutes, and re-verify before continuing.
19
+ - **New domain purchase:** only on explicit request — check availability with `domains_availability_check`, state the price, and get an explicit yes before `domains_portfolio_purchase` (needs the domains product group).
20
20
 
21
21
  ## 3. Create the website and wait for it
22
22
 
23
23
  Generating a subdomain does **not** create a website — deploying straight to it fails with `No website found for domain`. The working sequence:
24
24
 
25
- 1. `hosting_createWebsiteV1 { domain, order_id }` — `datacenter_code` is required only for the first website on a brand-new plan (pick the first entry from `hosting_listAvailableDatacentersV1`).
26
- 2. **Poll** `hosting_listWebsitesV1` filtered by the domain until the site appears. Creation takes up to a few minutes — poll with backoff, don't fail fast.
25
+ 1. `hosting_websites_create { domain, order_id }` — `datacenter_code` is required only for the first website on a brand-new plan (pick the first entry from `hosting_datacenters_list`).
26
+ 2. **Poll** `hosting_websites_list` filtered by the domain until the site appears. Creation takes up to a few minutes — poll with backoff, don't fail fast.
27
27
  3. Note the site's `username` — deployment and database operations are keyed on it.
28
28
 
29
29
  If the domain already has a website (an `iterate` run, or the user pointed at an existing site), skip creation entirely.
@@ -31,4 +31,4 @@ If the domain already has a website (an `iterate` run, or the user pointed at an
31
31
  ## 4. Optional extras (only when the run needs them)
32
32
 
33
33
  - **Database:** when the app needs MySQL, follow `DATABASE.md` — creating it, which host each runtime connects to (Node.js must use `127.0.0.1`), and handing the credentials to the app without hard-coding them.
34
- - **DNS records:** the DNS operations (`DNS_updateDNSRecordsV1` etc.) for custom-domain records; take a snapshot (`DNS_getDNSSnapshotListV1` context) before destructive changes.
34
+ - **DNS records:** the DNS operations (`dns_records_update` etc.) for custom-domain records; take a snapshot (`dns_snapshots_list` context) before destructive changes.
@@ -1,6 +1,6 @@
1
1
  # Store — Hostinger Ecommerce with a custom storefront
2
2
 
3
- **Primary source:** execute `ecommerce_getCustomStorefrontSetupInstructionsV1` at the start of every store run — it returns the current, server-maintained integration guide, and it supersedes this file wherever they disagree. This file carries the essentials so the run can be planned before that call, and a fallback when the ecommerce operations aren't enabled.
3
+ **Primary source:** execute `ecommerce_miscellaneous_custom-storefront-setup-instructions` at the start of every store run — it returns the current, server-maintained integration guide, and it supersedes this file wherever they disagree. This file carries the essentials so the run can be planned before that call, and a fallback when the ecommerce operations aren't enabled.
4
4
 
5
5
  ## Mental model
6
6
 
@@ -17,9 +17,9 @@ Two API surfaces — don't mix them:
17
17
 
18
18
  ## Backend setup (management tools)
19
19
 
20
- 1. Resolve the `custom` sales channel: `ecommerce_getStoresV1` → `ecommerce_listSalesChannelsV1`. If a `custom` channel already exists, confirm with the user that it's the one to use; otherwise add one to the existing store with `ecommerce_createCustomSalesChannelV1`, or create a store with `ecommerce_createStoreV1` (with a `custom` sales channel) when no suitable store exists. Set the channel `url` to the storefront's public domain at creation when it's already known.
21
- 2. For checkout to work the store needs all three: ≥ 1 product, ≥ 1 payment method, ≥ 1 shipping zone. Payment, shipping, and currency are store-level — check `ecommerce_getStoreMetadataV1` (`has_payment_methods` and `has_shipping` must be `true`; the same response carries `default_currency` with `code`, `decimal_digits`, `template` — read it here rather than guessing). Products are **per sales channel** — verify by listing products for the resolved channel on the Storefront API and confirming the list is non-empty. Seed what's missing with `ecommerce_createPhysicalProductV1` / `ecommerce_createDigitalProductV1`, `ecommerce_enableManualPaymentMethodV1`, and `ecommerce_setStoreShippingV1` (price `0` = free shipping) — confirming with the user before writing to a store that already has real data.
22
- 3. After deploy, point the channel at the live site: `ecommerce_updateSalesChannelV1 { store_id, sales_channel_id, url }`.
20
+ 1. Resolve the `custom` sales channel: `ecommerce_stores_list` → `ecommerce_sales-channels_list`. If a `custom` channel already exists, confirm with the user that it's the one to use; otherwise add one to the existing store with `ecommerce_sales-channels_create`, or create a store with `ecommerce_stores_create` (with a `custom` sales channel) when no suitable store exists. Set the channel `url` to the storefront's public domain at creation when it's already known.
21
+ 2. For checkout to work the store needs all three: ≥ 1 product, ≥ 1 payment method, ≥ 1 shipping zone. Payment, shipping, and currency are store-level — check `ecommerce_stores_metadata` (`has_payment_methods` and `has_shipping` must be `true`; the same response carries `default_currency` with `code`, `decimal_digits`, `template` — read it here rather than guessing). Products are **per sales channel** — verify by listing products for the resolved channel on the Storefront API and confirming the list is non-empty. Seed what's missing with `ecommerce_products_create-physical` / `ecommerce_products_create-digital`, `ecommerce_payments_enable-manual-method`, and `ecommerce_shipping_set-store` (price `0` = free shipping) — confirming with the user before writing to a store that already has real data.
22
+ 3. After deploy, point the channel at the live site: `ecommerce_sales-channels_update { store_id, sales_channel_id, url }`.
23
23
 
24
24
  If the ecommerce operations aren't available, ask the user to enable the Ecommerce product group in the Hostinger Connector — or to provide the `sales_channel_id` directly, after which the public endpoints suffice for the frontend work.
25
25
 
@@ -20,11 +20,11 @@ Two surfaces, like the store recipe:
20
20
 
21
21
  ## Setup (management tools)
22
22
 
23
- 1. **Check for an existing installation first**: `hosting_listWordPressInstallationsV1` filtered by the site's username/domain. Reuse a valid install when the user agrees — never overwrite one silently.
24
- 2. **Choose where WordPress lives.** Default: a dedicated subdomain of the site, e.g. `cms.<domain>` — create it with `hosting_createWebsiteSubdomainV1` so the main domain stays free for the frontend. A separate free-subdomain website (per `SETUP.md`) also works when the plan allows another website.
25
- 3. **Install**: `hosting_installWordPressV1` on that domain. The call only queues the job — **poll** `hosting_listWordPressInstallationsV1` until the installation appears (typically 1–2 minutes). Don't proceed on the queued response alone.
26
- 4. **Hand the owner their editor**: mint a one-click wp-admin link with `hosting_createLoginLinksV1` and show it to the user. Content authoring happens in wp-admin — the skill does not seed posts (there is no anonymous write path, by design). The fresh install ships with a sample post, which is enough to build and verify the frontend against.
27
- 5. **Caching** (recommended before finishing): enable the object cache with `hosting_toggleMemcachedObjectCacheV1`; after config changes, purge with `hosting_purgeLiteSpeedCacheV1`.
23
+ 1. **Check for an existing installation first**: `wordpress_installations_list` filtered by the site's username/domain. Reuse a valid install when the user agrees — never overwrite one silently.
24
+ 2. **Choose where WordPress lives.** Default: a dedicated subdomain of the site, e.g. `cms.<domain>` — create it with `hosting_domains_create-website-subdomain` so the main domain stays free for the frontend. A separate free-subdomain website (per `SETUP.md`) also works when the plan allows another website.
25
+ 3. **Install**: `wordpress_installations_install` on that domain. The call only queues the job — **poll** `wordpress_installations_list` until the installation appears (typically 1–2 minutes). Don't proceed on the queued response alone.
26
+ 4. **Hand the owner their editor**: mint a one-click wp-admin link with `wordpress_login_create-links` and show it to the user. Content authoring happens in wp-admin — the skill does not seed posts (there is no anonymous write path, by design). The fresh install ships with a sample post, which is enough to build and verify the frontend against.
27
+ 5. **Caching** (recommended before finishing): enable the object cache with `wordpress_object-cache_toggle-memcached`; after config changes, purge with `wordpress_litespeed-cache_purge-lite-speed`.
28
28
 
29
29
  ## Frontend contract
30
30
 
@@ -1,2 +1,2 @@
1
1
  // Auto-generated server instructions
2
- export default "Hostinger API notes for agents. Find operations with search; the inputSchema it returns is authoritative for request shapes. Run one with execute, or chain several with multi-execute.\n\nDatabases (web hosting, hosting_* operations)\n- MySQL runs on the same server as the website. From the deployed app connect to host 127.0.0.1, port 3306. PHP may also use localhost (Unix socket). Node.js should use 127.0.0.1: localhost can resolve to IPv6 (::1) and not every database user has that grant.\n- The `host` from hosting_listAccountDatabasesV1 (srvNNNN.hstgr.io) is only for connections from outside Hostinger, after hosting_createDatabaseRemoteConnectionV1. Never use it from the app.\n- Agency Plan (agency-hosting_* operations) database users are created for localhost; the PHP app connects there.\n\nAsynchronous operations\n- A success response often means \"queued\", not \"done\". Poll the matching read operation with backoff (seconds, then minutes). Never re-send the write.\n- hosting_createWebsiteV1 -> poll hosting_listWebsitesV1 until the domain appears (a few minutes).\n- hosting_startNode_jsBuildV1 -> hosting_getNode_jsBuildDetailsV1; logs via hosting_getNodeJSBuildLogsV1; on failure hosting_analyseFailedNode_jsBuildV1.\n- hosting_installWordPressV1 and WordPress plugin/theme/core jobs -> poll hosting_listWordPressInstallationsV1.\n- agency-hosting_createANewWebsiteV1 -> poll agency-hosting_getWebsiteSetupStatusV1 with setup_uuid; other Agency Plan jobs -> agency-hosting_listWebsiteProcessesV1.\n- Website deletion, database repair and domain contact changes finish in the background.\n\nCredentials\n- Never write database passwords or API tokens into source code, client-side JavaScript or committed .env files.\n- Node.js apps read them from environment variables: set the full set with hosting_replaceNode_jsEnvironmentVariablesV1 (full replace; values are masked on read). Build-time variables (Next.js) need a new build afterwards.\n- PHP apps read them from a config file on the server, outside the repository.\n- Generate strong passwords and do not echo them back once stored.\n\nFor end-to-end site builds install the headless skill: npx skills add hostinger/api-mcp-server";
2
+ export default "Hostinger API notes for agents. Find operations with search; the inputSchema it returns is authoritative for request shapes. Run one with execute, or chain several with multi-execute.\n\nDatabases (web hosting, hosting_* operations)\n- MySQL runs on the same server as the website. From the deployed app connect to host 127.0.0.1, port 3306. PHP may also use localhost (Unix socket). Node.js should use 127.0.0.1: localhost can resolve to IPv6 (::1) and not every database user has that grant.\n- The `host` from hosting_databases_list (srvNNNN.hstgr.io) is only for connections from outside Hostinger, after hosting_databases_create-remote-connection. Never use it from the app.\n- Agency Plan (agency-hosting_* operations) database users are created for localhost; the PHP app connects there.\n\nAsynchronous operations\n- A success response often means \"queued\", not \"done\". Poll the matching read operation with backoff (seconds, then minutes). Never re-send the write.\n- hosting_websites_create -> poll hosting_websites_list until the domain appears (a few minutes).\n- hosting_nodejs_start-build -> hosting_nodejs_build; logs via hosting_nodejs_build-logs; on failure hosting_nodejs_analyse-failed-build.\n- wordpress_installations_install and WordPress plugin/theme/core jobs -> poll wordpress_installations_list.\n- agency-hosting_website-setups_create -> poll agency-hosting_website-setups_status with setup_uuid; other Agency Plan jobs -> agency-hosting_websites_list-processes.\n- Website deletion, database repair and domain contact changes finish in the background.\n\nCredentials\n- Never write database passwords or API tokens into source code, client-side JavaScript or committed .env files.\n- Node.js apps read them from environment variables: set the full set with hosting_nodejs_replace-environment-variables (full replace; values are masked on read). Build-time variables (Next.js) need a new build afterwards.\n- PHP apps read them from a config file on the server, outside the repository.\n- Generate strong passwords and do not echo them back once stored.\n\nFor end-to-end site builds install the headless skill: npx skills add hostinger/api-mcp-server";
@@ -1,3 +1,3 @@
1
1
  // Auto-generated server instructions
2
- const instructions: string = "Hostinger API notes for agents. Find operations with search; the inputSchema it returns is authoritative for request shapes. Run one with execute, or chain several with multi-execute.\n\nDatabases (web hosting, hosting_* operations)\n- MySQL runs on the same server as the website. From the deployed app connect to host 127.0.0.1, port 3306. PHP may also use localhost (Unix socket). Node.js should use 127.0.0.1: localhost can resolve to IPv6 (::1) and not every database user has that grant.\n- The `host` from hosting_listAccountDatabasesV1 (srvNNNN.hstgr.io) is only for connections from outside Hostinger, after hosting_createDatabaseRemoteConnectionV1. Never use it from the app.\n- Agency Plan (agency-hosting_* operations) database users are created for localhost; the PHP app connects there.\n\nAsynchronous operations\n- A success response often means \"queued\", not \"done\". Poll the matching read operation with backoff (seconds, then minutes). Never re-send the write.\n- hosting_createWebsiteV1 -> poll hosting_listWebsitesV1 until the domain appears (a few minutes).\n- hosting_startNode_jsBuildV1 -> hosting_getNode_jsBuildDetailsV1; logs via hosting_getNodeJSBuildLogsV1; on failure hosting_analyseFailedNode_jsBuildV1.\n- hosting_installWordPressV1 and WordPress plugin/theme/core jobs -> poll hosting_listWordPressInstallationsV1.\n- agency-hosting_createANewWebsiteV1 -> poll agency-hosting_getWebsiteSetupStatusV1 with setup_uuid; other Agency Plan jobs -> agency-hosting_listWebsiteProcessesV1.\n- Website deletion, database repair and domain contact changes finish in the background.\n\nCredentials\n- Never write database passwords or API tokens into source code, client-side JavaScript or committed .env files.\n- Node.js apps read them from environment variables: set the full set with hosting_replaceNode_jsEnvironmentVariablesV1 (full replace; values are masked on read). Build-time variables (Next.js) need a new build afterwards.\n- PHP apps read them from a config file on the server, outside the repository.\n- Generate strong passwords and do not echo them back once stored.\n\nFor end-to-end site builds install the headless skill: npx skills add hostinger/api-mcp-server";
2
+ const instructions: string = "Hostinger API notes for agents. Find operations with search; the inputSchema it returns is authoritative for request shapes. Run one with execute, or chain several with multi-execute.\n\nDatabases (web hosting, hosting_* operations)\n- MySQL runs on the same server as the website. From the deployed app connect to host 127.0.0.1, port 3306. PHP may also use localhost (Unix socket). Node.js should use 127.0.0.1: localhost can resolve to IPv6 (::1) and not every database user has that grant.\n- The `host` from hosting_databases_list (srvNNNN.hstgr.io) is only for connections from outside Hostinger, after hosting_databases_create-remote-connection. Never use it from the app.\n- Agency Plan (agency-hosting_* operations) database users are created for localhost; the PHP app connects there.\n\nAsynchronous operations\n- A success response often means \"queued\", not \"done\". Poll the matching read operation with backoff (seconds, then minutes). Never re-send the write.\n- hosting_websites_create -> poll hosting_websites_list until the domain appears (a few minutes).\n- hosting_nodejs_start-build -> hosting_nodejs_build; logs via hosting_nodejs_build-logs; on failure hosting_nodejs_analyse-failed-build.\n- wordpress_installations_install and WordPress plugin/theme/core jobs -> poll wordpress_installations_list.\n- agency-hosting_website-setups_create -> poll agency-hosting_website-setups_status with setup_uuid; other Agency Plan jobs -> agency-hosting_websites_list-processes.\n- Website deletion, database repair and domain contact changes finish in the background.\n\nCredentials\n- Never write database passwords or API tokens into source code, client-side JavaScript or committed .env files.\n- Node.js apps read them from environment variables: set the full set with hosting_nodejs_replace-environment-variables (full replace; values are masked on read). Build-time variables (Next.js) need a new build afterwards.\n- PHP apps read them from a config file on the server, outside the repository.\n- Generate strong passwords and do not echo them back once stored.\n\nFor end-to-end site builds install the headless skill: npx skills add hostinger/api-mcp-server";
3
3
  export default instructions;
@@ -218,23 +218,23 @@ class MCPServer {
218
218
 
219
219
  async executeCustomTool(tool, params) {
220
220
  switch (tool.name) {
221
- case 'agency-hosting_deployNodeStaticWebsite':
221
+ case 'agency-hosting_deploy-node-static-website':
222
222
  return await this.handleNodeStaticDeploy(params);
223
- case 'agency-hosting_deployPhpApplication':
223
+ case 'agency-hosting_deploy-php-application':
224
224
  return await this.handlePhpAppDeploy(params);
225
- case 'hosting_importWordpressWebsite':
225
+ case 'hosting_import-wordpress-website':
226
226
  return await this.handleWordpressWebsiteImport(params);
227
- case 'hosting_deployWordpressPlugin':
227
+ case 'hosting_deploy-wordpress-plugin':
228
228
  return await this.handleWordpressPluginDeploy(params);
229
- case 'hosting_deployWordpressTheme':
229
+ case 'hosting_deploy-wordpress-theme':
230
230
  return await this.handleWordpressThemeDeploy(params);
231
- case 'hosting_deployJsApplication':
231
+ case 'hosting_deploy-js-application':
232
232
  return await this.handleJavascriptApplicationDeploy(params);
233
- case 'hosting_deployStaticWebsite':
233
+ case 'hosting_deploy-static-website':
234
234
  return await this.handleStaticWebsiteDeploy(params);
235
- case 'hosting_listJsDeployments':
235
+ case 'hosting_list-js-deployments':
236
236
  return await this.handleListJavascriptDeployments(params);
237
- case 'hosting_showJsDeploymentLogs':
237
+ case 'hosting_show-js-deployment-logs':
238
238
  return await this.handleShowJsDeploymentLogs(params);
239
239
  default:
240
240
  throw new Error(`Unknown custom tool: ${tool.name}`);
@@ -242,23 +242,23 @@ class MCPServer {
242
242
 
243
243
  private async executeCustomTool(tool: OpenApiTool, params: Record<string, any>): Promise<any> {
244
244
  switch (tool.name) {
245
- case 'agency-hosting_deployNodeStaticWebsite':
245
+ case 'agency-hosting_deploy-node-static-website':
246
246
  return await this.handleNodeStaticDeploy(params);
247
- case 'agency-hosting_deployPhpApplication':
247
+ case 'agency-hosting_deploy-php-application':
248
248
  return await this.handlePhpAppDeploy(params);
249
- case 'hosting_importWordpressWebsite':
249
+ case 'hosting_import-wordpress-website':
250
250
  return await this.handleWordpressWebsiteImport(params);
251
- case 'hosting_deployWordpressPlugin':
251
+ case 'hosting_deploy-wordpress-plugin':
252
252
  return await this.handleWordpressPluginDeploy(params);
253
- case 'hosting_deployWordpressTheme':
253
+ case 'hosting_deploy-wordpress-theme':
254
254
  return await this.handleWordpressThemeDeploy(params);
255
- case 'hosting_deployJsApplication':
255
+ case 'hosting_deploy-js-application':
256
256
  return await this.handleJavascriptApplicationDeploy(params);
257
- case 'hosting_deployStaticWebsite':
257
+ case 'hosting_deploy-static-website':
258
258
  return await this.handleStaticWebsiteDeploy(params);
259
- case 'hosting_listJsDeployments':
259
+ case 'hosting_list-js-deployments':
260
260
  return await this.handleListJavascriptDeployments(params);
261
- case 'hosting_showJsDeploymentLogs':
261
+ case 'hosting_show-js-deployment-logs':
262
262
  return await this.handleShowJsDeploymentLogs(params);
263
263
  default:
264
264
  throw new Error(`Unknown custom tool: ${tool.name}`);