hostinger-api-mcp 2.1.0 → 2.3.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.
@@ -0,0 +1,69 @@
1
+ // Auto-generated agent skills served over the MCP Skills extension
2
+ export interface SkillFile {
3
+ uri: string;
4
+ digest: string;
5
+ size: number;
6
+ mimeType: string;
7
+ text: string;
8
+ }
9
+
10
+ export interface Skill {
11
+ uri: string;
12
+ frontmatter: Record<string, unknown>;
13
+ resources: SkillFile[];
14
+ }
15
+
16
+ const skills: Skill[] = [
17
+ {
18
+ "uri": "skill://hostinger-headless/SKILL.md",
19
+ "frontmatter": {
20
+ "name": "hostinger-headless",
21
+ "description": "Build, connect, or iterate on a website hosted on Hostinger — provision hosting and a domain, optionally seed an ecommerce store with a real hosted checkout or a WordPress content backend (headless CMS/blog), build the frontend, deploy, and verify. Requires an authenticated Hostinger MCP session (see entry/skill.md). Triggers: build me a site on Hostinger, deploy this to Hostinger, connect this project to Hostinger, add a store to my Hostinger site, add a blog to my Hostinger site, update my Hostinger site."
22
+ },
23
+ "resources": [
24
+ {
25
+ "uri": "skill://hostinger-headless/SKILL.md",
26
+ "digest": "sha256:7ed8a33109f571b56646627d21ba58cf7cbf8c2818c9bfacf645a341a8847b1f",
27
+ "size": 7200,
28
+ "mimeType": "text/markdown",
29
+ "text": "---\nname: hostinger-headless\ndescription: \"Build, connect, or iterate on a website hosted on Hostinger — provision hosting and a domain, optionally seed an ecommerce store with a real hosted checkout or a WordPress content backend (headless CMS/blog), build the frontend, deploy, and verify. Requires an authenticated Hostinger MCP session (see entry/skill.md). Triggers: build me a site on Hostinger, deploy this to Hostinger, connect this project to Hostinger, add a store to my Hostinger site, add a blog to my Hostinger site, update my Hostinger site.\"\n---\n\n# Hostinger Headless\n\nThis skill turns a prompt into a live website on Hostinger. Its job is to own the full run: check the account, provision hosting and a domain, seed the backend (an ecommerce store when the intent calls for selling), build the frontend, deploy it, and verify the result.\n\nThe frontend is built ad-hoc to the user's intent — there is no template library. The backend pieces are real Hostinger products: web hosting (static or Node.js), domains and DNS, Hostinger Ecommerce with its public Storefront API and hosted checkout, and WordPress as a headless CMS/blog backend read through the public WP REST API.\n\n## Preconditions\n\n1. An authenticated Hostinger MCP session — the entry skill's bootstrap handled this. If MCP tools fail with auth errors, send the user back through `entry/skill.md`.\n2. The Hostinger MCP operations for **hosting** (plus **ecommerce** when the run involves a store, and **wordpress** when it involves a content backend). Operation availability varies per user — product groups can be toggled in the Hostinger Connector. When search cannot find a needed operation, ask the user to enable that product group (or configure the scoped binary, e.g. `hostinger-hosting-mcp`) rather than improvising around it.\n3. An active hosting plan (checked in Setup §1). Hostinger hosting is a paid product: if the account has no usable plan, inform the user plainly that a subscription is required, link them to https://www.hostinger.com/web-hosting, and pause until they confirm the purchase. Do not treat this as an error — it is a normal step for new accounts. Everything that doesn't need hosting (planning, building the frontend locally) can proceed while they decide.\n\n## Resolving the operation\n\nResolve by intent first, disk second — never let an empty directory override what the user is asking for. Check `iterate` first (it's decided by an unambiguous on-disk signal):\n\n- `iterate` — a `.hostinger/site.json` is present in the project: the site is already deployed through this skill and the user wants changes. Reuse the recorded domain/site details; apply only the delta the new intent needs (edit frontend → redeploy; add a store → run `references/STORE.md` then redeploy). Never re-provision an existing site.\n- `connect` — a frontend project already on disk (or brought in as a zip/export/URL) that is not yet on Hostinger, with language like \"deploy this / host this on Hostinger / connect this project\". Emptiness of the CWD at trigger time is not a create signal when a design is brought in from elsewhere.\n- `create` — a new site from a prompt with nothing brought in: \"build me a store / portfolio / site…\".\n\nIf signals conflict, ask the user — don't guess.\n\n## The run\n\n1. **Discovery** — from the prompt (and the project on disk for connect/iterate), infer: does this run need a store (any buy/sell/product intent → yes)? Does it need owner-managed content — a blog, news, or anything the owner edits without a redeploy (→ WordPress backend; static copy that rarely changes does not qualify)? What brand, copy, and structure does the site need? What stack fits — plain static HTML/CSS/JS for simple sites (default), a static-output framework build, or a Node.js app when SSR or server code is genuinely required? Prefer static: it deploys fastest and has no build-failure surface. Ask the user only what you cannot infer.\n2. **Setup** (`references/SETUP.md`) — plan check, then provision the website on a free subdomain (or the user's own domain) and wait until it's ready.\n3. **Store** (`references/STORE.md`, only when commerce is needed) — resolve or create the store and its `custom` sales channel, seed products/shipping/payment, and note the `sales_channel_id` for the frontend.\n4. **Content backend** (`references/WORDPRESS.md`, only when owner-managed content is needed) — install WordPress on a dedicated subdomain, wait until it's ready, and hand the owner a wp-admin login link. The frontend reads it through the public WP REST API.\n5. **Build** — create or wire the frontend. For store runs, follow the frontend contract in `references/STORE.md` (catalog fetched at runtime from the public Storefront API, cart in `localStorage`, client-side checkout — never embed an API token in the site). For content runs, follow the frontend contract in `references/WORDPRESS.md` (posts fetched at runtime from the WP REST API, rendered HTML bodies, graceful empty states). When the app needs MySQL, follow `references/DATABASE.md` (which host each runtime connects to, credentials via env vars or a server-side config file, never in the frontend).\n6. **Deploy** (`references/DEPLOYMENT.md`) — archive and deploy via the matching hosting operation, polling build logs for Node.js runs.\n7. **Verify** — curl the live URL for a 200 and a piece of real page copy; for store runs, confirm a checkout POST returns a redirect URL; for content runs, confirm the WP REST API returns 200 and the frontend renders posts. Show the user the live URL and where to manage things (hPanel: https://hpanel.hostinger.com, the store dashboard for commerce, wp-admin for content).\n8. **Record** — write `.hostinger/site.json` into the project: `{ \"domain\", \"username\", \"type\": \"static\"|\"nodejs\", \"sales_channel_id\"?, \"store_id\"?, \"cms_domain\"? }`. This is what makes future runs resolve as `iterate`.\n\nRun non-interactively wherever possible. The exceptions that must involve the user: the paid-plan confirmation, anything that costs money (a domain purchase, a new subscription), and picking between genuinely equal options the prompt doesn't decide.\n\n## Paths\n\n| What | Path |\n| --- | --- |\n| Plan check + website/domain provisioning | `references/SETUP.md` |\n| Store: seed the backend + the frontend API contract | `references/STORE.md` |\n| WordPress: headless CMS/blog backend + the frontend read contract | `references/WORDPRESS.md` |\n| Deploy: static vs Node.js, archive rules, logs, verify | `references/DEPLOYMENT.md` |\n| Database + runtime: MySQL host per runtime, env vars, what to poll, runtime logs | `references/DATABASE.md` |\n\n## Where the how comes from\n\nThe inputSchema returned by search is authoritative for request shapes — read it before calling. Two live sources supersede anything written here when they disagree:\n\n- 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.\n- The Hostinger API reference at https://developers.hostinger.com describes every endpoint behind the operations.\n"
30
+ },
31
+ {
32
+ "uri": "skill://hostinger-headless/references/DATABASE.md",
33
+ "digest": "sha256:e0800ac848244ead5b9a1bfb0a39d223b336c2a179ac13ece0089d135c418d76",
34
+ "size": 4299,
35
+ "mimeType": "text/markdown",
36
+ "text": "# Database and runtime — MySQL hosts, env vars, and what to poll\n\nUse this when the app needs MySQL, or when a deploy \"succeeded\" but the app cannot reach its database. Everything here uses the **hosting** MCP operations; Agency Plan differences are at the end.\n\n## 1. Create the database\n\n1. `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.\n2. Read the full, prefixed `name` and `user` back from `hosting_databases_list`; every other database operation wants the full name.\n3. Do not print the password to the user once it is stored, and never commit it.\n\n## 2. Which host the app connects to\n\n| Where the code runs | Host | Port | Why |\n| --- | --- | --- | --- |\n| PHP on the website | `localhost` or `127.0.0.1` | 3306 | `localhost` uses the MySQL socket; both are granted |\n| Node.js on the website | `127.0.0.1` | 3306 | `localhost` may resolve to IPv6 `::1`, and not every database user has that grant |\n| 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 |\n\nDo not put the remote `host` into the deployed app — it has no grant for connections that come from the server itself.\n\n## 3. Hand credentials to the app\n\n- **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.\n- **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.\n- **Never** in client-side JavaScript, in a committed `.env`, or in chat replies.\n\n## 4. What is asynchronous, and what to poll\n\n| You called | Poll this until | Typical wait |\n| --- | --- | --- |\n| `hosting_websites_create` | `hosting_websites_list` lists the domain | up to a few minutes |\n| `hosting_deploy-js-application` | `hosting_list-js-deployments` shows the build finished | minutes |\n| `hosting_nodejs_start-build` | `hosting_nodejs_build` state is `completed` or `failed` | minutes |\n| `wordpress_installations_install`, plugin/theme/core jobs | `wordpress_installations_list` lists the install | 1–2 minutes |\n| `hosting_databases_repair`, `hosting_websites_delete` | nothing to poll — runs in the background | minutes |\n| `agency-hosting_website-setups_create` | `agency-hosting_website-setups_status` with `setup_uuid` is `completed` | minutes |\n\nPoll 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.\n\n## 5. When the app is up but broken\n\n- Build failed: `hosting_nodejs_build-logs` for the raw log, `hosting_nodejs_analyse-failed-build` for a diagnosis.\n- Build passed, app errors: `hosting_nodejs_runtime-logs` with a `period` such as `1h`; entries before `last_deployed_at` belong to the previous deploy.\n- `Access denied for user 'x'@'::1'`: the app used `localhost` from Node.js — set `DB_HOST` to `127.0.0.1`.\n- PHP limits (memory, upload size): `hosting_php_get`, then `hosting_php_update-options`.\n\n## Agency Plan websites (`agency-hosting_*`)\n\n`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`.\n"
37
+ },
38
+ {
39
+ "uri": "skill://hostinger-headless/references/DEPLOYMENT.md",
40
+ "digest": "sha256:1369632f23a6934ca47ca942cba20882681bc679fe833757ce30099c51257ea2",
41
+ "size": 2170,
42
+ "mimeType": "text/markdown",
43
+ "text": "# Deployment — getting the build live\n\nMatch the deploy method to what the project actually is — this is the single most common failure point.\n\n## Static site → `hosting_deploy-static-website`\n\nFor pre-built files only: plain HTML/CSS/JS, or the **build output** of a framework (run the build locally first).\n\n- The archive (zip/tar) must have `index.html` at its **root** — not nested inside a folder.\n- Name it `name_YYYYMMDD_HHMMSS.zip`; pass `removeArchive: true` to clean up after upload.\n- Deployment is effectively immediate — verify right after.\n\n## Node.js app → `hosting_deploy-js-application`\n\nFor anything that needs a server or a server-side build (Express, Next.js, NestJS, SSR frameworks).\n\n- Archive the **source**, not the output: exclude `node_modules/`, `dist/`, `.next/`, `build/`, and everything matched by `.gitignore`. The install and build run on Hostinger.\n- Hard cap: **50 MB** archive.\n- 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.\n\n## WordPress → `hosting_import-wordpress-website` / plugin & theme operations\n\nOnly 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.)\n\n## Verify (every deploy)\n\n```bash\ncurl -s -o /dev/null -w \"%{http_code}\\n\" https://YOURDOMAIN/\ncurl -s https://YOURDOMAIN/ | grep -o \"SOME_REAL_HEADLINE_TEXT\"\n```\n\nReplace 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`.\n\nWhen the site is live, report the URL and remind the user the site is managed from hPanel (https://hpanel.hostinger.com).\n"
44
+ },
45
+ {
46
+ "uri": "skill://hostinger-headless/references/SETUP.md",
47
+ "digest": "sha256:52cc927dd67c4f4b6686dff55e1fd36b61350a1a41a3e5ced364a769dcd6f6fd",
48
+ "size": 2860,
49
+ "mimeType": "text/markdown",
50
+ "text": "# Setup — plan check and website provisioning\n\nEverything here uses the **hosting** MCP operations. If they're missing, ask the user to enable the Websites product group in the Hostinger Connector (or use the `hostinger-hosting-mcp` scoped binary).\n\n## 1. Plan check (gate — run this first)\n\nA website can only be created on an active hosting plan.\n\n1. `hosting_websites_list` — if it returns websites, the account has a working plan; note any existing `order_id` and `username` for step 2.\n2. 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`.\n3. 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.\n\nNever purchase a plan, domain, or any paid item without the user explicitly approving that specific purchase.\n\n## 2. Choose the domain\n\n- **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.\n- **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.\n- **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).\n\n## 3. Create the website and wait for it\n\nGenerating a subdomain does **not** create a website — deploying straight to it fails with `No website found for domain`. The working sequence:\n\n1. `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`).\n2. **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.\n3. Note the site's `username` — deployment and database operations are keyed on it.\n\nIf the domain already has a website (an `iterate` run, or the user pointed at an existing site), skip creation entirely.\n\n## 4. Optional extras (only when the run needs them)\n\n- **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.\n- **DNS records:** the DNS operations (`dns_records_update` etc.) for custom-domain records; take a snapshot (`dns_snapshots_list` context) before destructive changes.\n"
51
+ },
52
+ {
53
+ "uri": "skill://hostinger-headless/references/STORE.md",
54
+ "digest": "sha256:ca5bf13b3968b49ae53717c0e52e16d301774b2ea166a687e246bd6089f155e2",
55
+ "size": 5470,
56
+ "mimeType": "text/markdown",
57
+ "text": "# Store — Hostinger Ecommerce with a custom storefront\n\n**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.\n\n## Mental model\n\nTwo API surfaces — don't mix them:\n\n| Surface | Base URL | Auth | Use for |\n| --- | --- | --- | --- |\n| Storefront Core V2 | `https://api-ecommerce.hostinger.com/v2` | none (public, open CORS) | read products/variants, checkout — called from the browser |\n| Management (MCP tools) | Hostinger API | authenticated | create stores/products/shipping/payments |\n\n- A **store** (`store_*`) has **sales channels** (`scha_*`). The Storefront API is keyed on the **`sales_channel_id`** of a `custom`-type channel — not the store id. Managed channels (e.g. `quick-link`) cannot be used here, and only `custom` channels are API-creatable.\n- **Prices are integers in minor units** (`2900` = €29.00 → divide by `10^decimal_digits`) and live on **variants**, not products.\n- **Security boundary:** storefront reads and checkout are public and run client-side — **never embed a Hostinger API token in the storefront**. Only the management/hosting side (MCP tools) is authenticated.\n\n## Backend setup (management tools)\n\n1. 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.\n2. 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.\n3. After deploy, point the channel at the live site: `ecommerce_sales-channels_update { store_id, sales_channel_id, url }`.\n\nIf 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.\n\n## Frontend contract\n\nThe OpenAPI schema for the Storefront API is at `https://api-ecommerce.hostinger.com/v2/docs.json` — fetch it for exact endpoint shapes. Non-obvious rules the schema won't spell out:\n\n- **Fetch the catalog at runtime, not build time** — client-side fetch on page load (CORS is open). Baking products into a static build makes the site stale on the first catalog edit. (SSR / Node.js hosting may fetch it server-side per request.)\n- Each variant has a **`prices[]` array** (one entry per currency) — read `prices[0].amount` / `prices[0].sale_amount` (minor units) and `prices[0].currency` (which carries `decimal_digits` and the `template` whose `$1` placeholder you replace when formatting). There is **no** top-level `amount` on a variant.\n- Product detail resolves by **product id** only; a slug returns 404 (map slug→id from the list endpoint). `limit` max is 100 on list endpoints (else 400).\n- Filter variants with `product_ids[]=...`; the unfiltered variant list is eventually-consistent right after catalog edits.\n- Cart lives in the site (e.g. `localStorage`): persist only `variant_id` + `quantity`, resolve display data from the live catalog — never a saved copy — then send everything in one checkout call:\n\n```\nPOST /channels/{sales_channel_id}/checkout\n{ \"items\":[{ \"variant_id\":\"variant_01...\", \"quantity\":1 }],\n \"success_url\":\"https://YOURDOMAIN/checkout/success/\",\n \"cancel_url\":\"https://YOURDOMAIN/checkout/cancel/\",\n \"locale\":\"en\" }\n```\n\n`success_url`/`cancel_url` are required — build them from `window.location.origin` and make sure both pages exist. The response is `{ url, cart_token }`; redirect the browser to `url` (Hostinger's hosted checkout).\n\nA multi-step cart alternative exists (`POST /channels/{sales_channel_id}/carts`, `PATCH /carts/{cart_id}`, `POST /carts/{cart_id}/line-items`, `PUT /carts/{cart_id}/shipping-method`, `POST /carts/{cart_id}/complete`) — the single checkout call suffices for a simple buy flow.\n\n## Verify\n\n- A `POST` to the checkout endpoint returns a `url` — test it directly with curl before calling the run done.\n- The `success_url`/`cancel_url` pages return 200 (`curl -s -o /dev/null -w \"%{http_code}\" https://YOURDOMAIN/checkout/success/`).\n- Open the live site, add to cart, and confirm the redirect to `https://checkout.hostinger.com`.\n"
58
+ },
59
+ {
60
+ "uri": "skill://hostinger-headless/references/WORDPRESS.md",
61
+ "digest": "sha256:d9e80f800fbf4c53a95972762f9fe177430860715d849ea520ae5d47e0ef8f04",
62
+ "size": 4569,
63
+ "mimeType": "text/markdown",
64
+ "text": "# WordPress — headless CMS and blog backend\n\nUse WordPress when the site has **owner-managed content**: a blog, news, articles, or any content the owner must edit without a developer or a redeploy. The frontend stays agent-built and is deployed like any other run; WordPress runs separately as the content backend, and the owner writes in wp-admin.\n\n**When NOT to use this:** static copy that rarely changes (an about page, a services list, a brochure site) — bake that into the frontend. Installing WordPress for content the owner will never edit adds a moving part for nothing. Any buy/sell intent is `STORE.md`, not this file.\n\nEverything in Setup uses the **hosting** and **wordpress** MCP operation groups; ask the user to enable them in the Hostinger Connector if operations are missing.\n\n## Mental model\n\nTwo surfaces, like the store recipe:\n\n| Surface | Base URL | Auth | Use for |\n| --- | --- | --- | --- |\n| WP REST API | `https://CMS_DOMAIN/wp-json/wp/v2` | none for published content (open CORS) | frontend reads: posts, pages, media, categories |\n| Management (MCP tools + wp-admin) | Hostinger API / wp-admin | authenticated | install WP, plugins, cache; the owner writes content |\n\n- Published content is publicly readable and the REST API allows cross-origin browser reads — a static frontend on another domain fetches it directly at runtime.\n- Drafts, previews, and **writes need authentication** (WP application passwords). Never put credentials of any kind in the frontend; a public site only needs the anonymous read path.\n\n## Setup (management tools)\n\n1. **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.\n2. **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.\n3. **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.\n4. **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.\n5. **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`.\n\n## Frontend contract\n\nAll paths relative to `https://CMS_DOMAIN/wp-json/wp/v2`. Non-obvious rules:\n\n- **Fetch at runtime, not build time** — content changes whenever the owner publishes; baking it into a static build defeats the purpose. Client-side fetch on page load is fine (CORS is open).\n- List posts with `/posts?per_page=10&_embed` — `_embed` inlines featured images (`_embedded['wp:featuredmedia'][0].source_url`), authors, and terms; without it you get IDs that need extra requests.\n- Post bodies are **rendered HTML**: use `title.rendered` / `content.rendered` / `excerpt.rendered` and render them as HTML — do not treat them as plain text and do not try to restyle their inner markup beyond CSS.\n- Single post by slug: `/posts?slug=my-post` — returns an **array** (take the first element); there is no direct slug path.\n- Pagination comes from the `X-WP-Total` / `X-WP-TotalPages` response headers, not the body.\n- Only **published** content is returned anonymously. An empty list is a normal state — the frontend must render it gracefully, not error.\n- SEO is the frontend's job: page titles, meta tags, and the sitemap come from the frontend build, not from WordPress plugins.\n\n## Verify\n\n```bash\ncurl -s -o /dev/null -w \"%{http_code}\\n\" \"https://CMS_DOMAIN/wp-json/wp/v2/posts?per_page=1\"\n```\n\nExpect 200 with a JSON array. Then confirm the deployed frontend renders the sample post (or a clean empty state), and show the user two links: the live site and the wp-admin login for writing content.\n\n## Record\n\nAdd `\"cms_domain\"` to `.hostinger/site.json` (see `SKILL.md` §Record) so iterate runs know a WordPress backend exists and reuse it instead of installing again.\n"
65
+ }
66
+ ]
67
+ }
68
+ ];
69
+ export default skills;
@@ -6208,7 +6208,7 @@ export default [
6208
6208
  "readOnlyHint": false,
6209
6209
  "destructiveHint": false
6210
6210
  },
6211
- "description": "Allows a remote host to connect to the specified database.\n\nProvide an IPv4/IPv6 address, or \"%\" to allow any host. The database name must be\nthe full name returned by the list databases endpoint.",
6211
+ "description": "Allows a remote host to connect to the specified database.\n\nProvide an IPv4/IPv6 address, or \"%\" to allow any host. The database name must be\nthe full name returned by the list databases endpoint. Database creation is synchronous,\nso a 404 here means no database with that name exists under the username, not that it\nis still being created.",
6212
6212
  "method": "POST",
6213
6213
  "path": "/api/hosting/v1/accounts/{username}/databases/{name}/remote-connections",
6214
6214
  "inputSchema": {
@@ -6760,7 +6760,7 @@ export default [
6760
6760
  "readOnlyHint": false,
6761
6761
  "destructiveHint": false
6762
6762
  },
6763
- "description": "Generate a file browser upload URL with authentication credentials\nfor uploading files directly to a website's file storage.\n\nReturns `url`, `auth_key` and `rest_auth_key`. Use these to upload a file to the\nwebsite's `public_html` directory via the TUS resumable upload protocol (TUS 1.0.0).\nSend `X-Auth: {auth_key}` and `X-Auth-Rest: {rest_auth_key}` headers on every request\nbelow.\n\n1. Create the upload: `POST` to `{url}/{relative_file_path}?override=true` with headers\n `upload-length: {file size in bytes}` and `upload-offset: 0`. Expect `201 Created`.\n2. Upload the file: send the file bytes to the same location (any TUS 1.0.0 client, or\n `PATCH` requests with an `upload-offset` header tracking progress) until complete.\n\n`relative_file_path` is the destination path inside `public_html`, e.g. `app.zip`.\n\nInstead of a TUS client, plain `curl` also works:\n```\nFILE=app.zip\nSIZE=$(stat -f%z \"$FILE\") # stat -c%s on Linux\n\ncurl -i -X POST \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Upload-Length: ${SIZE}\" \\\n -H \"Upload-Offset: 0\"\n# -> 201 Created\n\ncurl -i -X PATCH \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Content-Type: application/offset+octet-stream\" \\\n -H \"Upload-Offset: 0\" \\\n --data-binary \"@${FILE}\"\n# -> 204 No Content, Upload-Offset response header equals SIZE when done\n```",
6763
+ "description": "Generate a file browser upload URL with authentication credentials\nfor uploading files directly to a website's file storage.\n\nWhile the website is still being set up (`status: running` on the list website setups\nendpoint) this endpoint returns 409 with a `Retry-After` header: wait that many\nseconds and retry, or poll the website setups until the status is `completed`.\n\nReturns `url`, `auth_key` and `rest_auth_key`. Use these to upload a file to the\nwebsite's `public_html` directory via the TUS resumable upload protocol (TUS 1.0.0).\nSend `X-Auth: {auth_key}` and `X-Auth-Rest: {rest_auth_key}` headers on every request\nbelow.\n\n1. Create the upload: `POST` to `{url}/{relative_file_path}?override=true` with headers\n `upload-length: {file size in bytes}` and `upload-offset: 0`. Expect `201 Created`.\n2. Upload the file: send the file bytes to the same location (any TUS 1.0.0 client, or\n `PATCH` requests with an `upload-offset` header tracking progress) until complete.\n\n`relative_file_path` is the destination path inside `public_html`, e.g. `app.zip`.\n\nInstead of a TUS client, plain `curl` also works:\n```\nFILE=app.zip\nSIZE=$(stat -f%z \"$FILE\") # stat -c%s on Linux\n\ncurl -i -X POST \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Upload-Length: ${SIZE}\" \\\n -H \"Upload-Offset: 0\"\n# -> 201 Created\n\ncurl -i -X PATCH \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Content-Type: application/offset+octet-stream\" \\\n -H \"Upload-Offset: 0\" \\\n --data-binary \"@${FILE}\"\n# -> 204 No Content, Upload-Offset response header equals SIZE when done\n```",
6764
6764
  "method": "POST",
6765
6765
  "path": "/api/hosting/v1/files/upload-urls",
6766
6766
  "inputSchema": {
@@ -7924,6 +7924,34 @@ export default [
7924
7924
  ],
7925
7925
  "group": "hosting"
7926
7926
  },
7927
+ {
7928
+ "name": "hosting_websites_list-setups",
7929
+ "title": "List website setups",
7930
+ "annotations": {
7931
+ "title": "List website setups",
7932
+ "readOnlyHint": true,
7933
+ "destructiveHint": false
7934
+ },
7935
+ "description": "Returns the website setups started in the last 24 hours for the hosting accounts\naccessible to the authenticated client, newest first.\n\nMeant for polling right after creating a website: the website shows up in the\nwebsites list before its server-side setup has finished, and while the setup is\n`running` endpoints that operate on that website may respond with `404` or `409`.\nPoll this endpoint with the `domain` filter every 10 to 15 seconds and wait for\n`status: completed` before uploading files, deploying or creating databases.\n`failed` means the setup stopped before finishing or has not reported progress for\nover an hour. Setups older than 24 hours are not listed.",
7936
+ "method": "GET",
7937
+ "path": "/api/hosting/v1/onboardings",
7938
+ "inputSchema": {
7939
+ "type": "object",
7940
+ "properties": {
7941
+ "domain": {
7942
+ "type": "string",
7943
+ "description": "Filter by domain name (exact match)"
7944
+ }
7945
+ },
7946
+ "required": []
7947
+ },
7948
+ "security": [
7949
+ {
7950
+ "apiToken": []
7951
+ }
7952
+ ],
7953
+ "group": "hosting"
7954
+ },
7927
7955
  {
7928
7956
  "name": "hosting_orders_list",
7929
7957
  "title": "List orders",
@@ -8503,7 +8531,7 @@ export default [
8503
8531
  "readOnlyHint": true,
8504
8532
  "destructiveHint": false
8505
8533
  },
8506
- "description": "Retrieve a paginated list of websites (CloudLinux, Builder, and Horizons) accessible to the\nauthenticated client.\n\nThis endpoint returns websites from your hosting accounts as well as\nwebsites from other client hosting accounts that have shared access\nwith you.\n\nEach website includes a `website_type` field describing the type of\nwebsite detected on the underlying platform (`wordpress`, `builder`,\n`horizons`, `nodejs`, or `other`). Some fields, such as\n`vhost_type`, `username`, and `root_directory`, only apply to\nCloudLinux websites and are null for other platforms.\n\nUse `website_types` to list only websites of a given detected type, e.g. only\nWordPress websites (`website_types=wordpress`) or only Node.js websites\n(`website_types=nodejs`). Combine with the other available query parameters to\nfilter by username, order ID, enabled status, or domain name for more targeted\nresults.",
8534
+ "description": "Retrieve a paginated list of websites (CloudLinux, Builder, and Horizons) accessible to the\nauthenticated client.\n\nThis endpoint returns websites from your hosting accounts as well as\nwebsites from other client hosting accounts that have shared access\nwith you.\n\nEach website includes a `website_type` field describing the type of\nwebsite detected on the underlying platform (`wordpress`, `builder`,\n`horizons`, `nodejs`, or `other`). Some fields, such as\n`vhost_type`, `username`, and `root_directory`, only apply to\nCloudLinux websites and are null for other platforms.\n\nUse `website_types` to list only websites of a given detected type, e.g. only\nWordPress websites (`website_types=wordpress`) or only Node.js websites\n(`website_types=nodejs`). Combine with the other available query parameters to\nfilter by username, order ID, enabled status, or domain name for more targeted\nresults.\n\nA website appears in this list before its server-side setup has finished, and\n`is_enabled` reflects suspension, not readiness. To know when a newly created website\nis ready for file, deploy or database operations, poll the list website setups\nendpoint instead.",
8507
8535
  "method": "GET",
8508
8536
  "path": "/api/hosting/v1/websites",
8509
8537
  "inputSchema": {
@@ -8566,7 +8594,7 @@ export default [
8566
8594
  "readOnlyHint": false,
8567
8595
  "destructiveHint": false
8568
8596
  },
8569
- "description": "Create a new website for the authenticated client.\n\nYou must choose which hosting order to create this website on. Pass that\norder as `order_id` together with the domain name. List orders to see\navailable IDs; the website is provisioned on that order's hosting plan.\n\nThe datacenter_code parameter is required when creating the first website\non a new hosting plan - this will set up and configure new hosting account\nin the selected datacenter.\n\nSubsequent websites will be hosted on the same datacenter automatically.\n\nWebsite creation takes up to a few minutes to complete. Check the\nwebsites list endpoint to see when your new website becomes available.",
8597
+ "description": "Create a new website for the authenticated client.\n\nYou must choose which hosting order to create this website on. Pass that\norder as `order_id` together with the domain name. List orders to see\navailable IDs; the website is provisioned on that order's hosting plan.\n\nThe datacenter_code parameter is required when creating the first website\non a new hosting plan - this will set up and configure new hosting account\nin the selected datacenter.\n\nSubsequent websites will be hosted on the same datacenter automatically.\n\nWebsite creation is asynchronous and takes up to a few minutes. Poll the list website\nsetups endpoint with the `domain` filter every 10 to 15 seconds and wait for `status:\ncompleted` before uploading files, deploying or creating databases. While the setup is\n`running`, endpoints that operate on the website may respond with `404` or `409`.\n`is_enabled` on the websites list reflects suspension, not readiness.",
8570
8598
  "method": "POST",
8571
8599
  "path": "/api/hosting/v1/websites",
8572
8600
  "inputSchema": {
@@ -6222,7 +6222,7 @@ const tools: OpenApiTool[] = [
6222
6222
  "readOnlyHint": false,
6223
6223
  "destructiveHint": false
6224
6224
  },
6225
- "description": "Allows a remote host to connect to the specified database.\n\nProvide an IPv4/IPv6 address, or \"%\" to allow any host. The database name must be\nthe full name returned by the list databases endpoint.",
6225
+ "description": "Allows a remote host to connect to the specified database.\n\nProvide an IPv4/IPv6 address, or \"%\" to allow any host. The database name must be\nthe full name returned by the list databases endpoint. Database creation is synchronous,\nso a 404 here means no database with that name exists under the username, not that it\nis still being created.",
6226
6226
  "method": "POST",
6227
6227
  "path": "/api/hosting/v1/accounts/{username}/databases/{name}/remote-connections",
6228
6228
  "inputSchema": {
@@ -6774,7 +6774,7 @@ const tools: OpenApiTool[] = [
6774
6774
  "readOnlyHint": false,
6775
6775
  "destructiveHint": false
6776
6776
  },
6777
- "description": "Generate a file browser upload URL with authentication credentials\nfor uploading files directly to a website's file storage.\n\nReturns `url`, `auth_key` and `rest_auth_key`. Use these to upload a file to the\nwebsite's `public_html` directory via the TUS resumable upload protocol (TUS 1.0.0).\nSend `X-Auth: {auth_key}` and `X-Auth-Rest: {rest_auth_key}` headers on every request\nbelow.\n\n1. Create the upload: `POST` to `{url}/{relative_file_path}?override=true` with headers\n `upload-length: {file size in bytes}` and `upload-offset: 0`. Expect `201 Created`.\n2. Upload the file: send the file bytes to the same location (any TUS 1.0.0 client, or\n `PATCH` requests with an `upload-offset` header tracking progress) until complete.\n\n`relative_file_path` is the destination path inside `public_html`, e.g. `app.zip`.\n\nInstead of a TUS client, plain `curl` also works:\n```\nFILE=app.zip\nSIZE=$(stat -f%z \"$FILE\") # stat -c%s on Linux\n\ncurl -i -X POST \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Upload-Length: ${SIZE}\" \\\n -H \"Upload-Offset: 0\"\n# -> 201 Created\n\ncurl -i -X PATCH \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Content-Type: application/offset+octet-stream\" \\\n -H \"Upload-Offset: 0\" \\\n --data-binary \"@${FILE}\"\n# -> 204 No Content, Upload-Offset response header equals SIZE when done\n```",
6777
+ "description": "Generate a file browser upload URL with authentication credentials\nfor uploading files directly to a website's file storage.\n\nWhile the website is still being set up (`status: running` on the list website setups\nendpoint) this endpoint returns 409 with a `Retry-After` header: wait that many\nseconds and retry, or poll the website setups until the status is `completed`.\n\nReturns `url`, `auth_key` and `rest_auth_key`. Use these to upload a file to the\nwebsite's `public_html` directory via the TUS resumable upload protocol (TUS 1.0.0).\nSend `X-Auth: {auth_key}` and `X-Auth-Rest: {rest_auth_key}` headers on every request\nbelow.\n\n1. Create the upload: `POST` to `{url}/{relative_file_path}?override=true` with headers\n `upload-length: {file size in bytes}` and `upload-offset: 0`. Expect `201 Created`.\n2. Upload the file: send the file bytes to the same location (any TUS 1.0.0 client, or\n `PATCH` requests with an `upload-offset` header tracking progress) until complete.\n\n`relative_file_path` is the destination path inside `public_html`, e.g. `app.zip`.\n\nInstead of a TUS client, plain `curl` also works:\n```\nFILE=app.zip\nSIZE=$(stat -f%z \"$FILE\") # stat -c%s on Linux\n\ncurl -i -X POST \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Upload-Length: ${SIZE}\" \\\n -H \"Upload-Offset: 0\"\n# -> 201 Created\n\ncurl -i -X PATCH \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Content-Type: application/offset+octet-stream\" \\\n -H \"Upload-Offset: 0\" \\\n --data-binary \"@${FILE}\"\n# -> 204 No Content, Upload-Offset response header equals SIZE when done\n```",
6778
6778
  "method": "POST",
6779
6779
  "path": "/api/hosting/v1/files/upload-urls",
6780
6780
  "inputSchema": {
@@ -7938,6 +7938,34 @@ const tools: OpenApiTool[] = [
7938
7938
  ],
7939
7939
  "group": "hosting"
7940
7940
  },
7941
+ {
7942
+ "name": "hosting_websites_list-setups",
7943
+ "title": "List website setups",
7944
+ "annotations": {
7945
+ "title": "List website setups",
7946
+ "readOnlyHint": true,
7947
+ "destructiveHint": false
7948
+ },
7949
+ "description": "Returns the website setups started in the last 24 hours for the hosting accounts\naccessible to the authenticated client, newest first.\n\nMeant for polling right after creating a website: the website shows up in the\nwebsites list before its server-side setup has finished, and while the setup is\n`running` endpoints that operate on that website may respond with `404` or `409`.\nPoll this endpoint with the `domain` filter every 10 to 15 seconds and wait for\n`status: completed` before uploading files, deploying or creating databases.\n`failed` means the setup stopped before finishing or has not reported progress for\nover an hour. Setups older than 24 hours are not listed.",
7950
+ "method": "GET",
7951
+ "path": "/api/hosting/v1/onboardings",
7952
+ "inputSchema": {
7953
+ "type": "object",
7954
+ "properties": {
7955
+ "domain": {
7956
+ "type": "string",
7957
+ "description": "Filter by domain name (exact match)"
7958
+ }
7959
+ },
7960
+ "required": []
7961
+ },
7962
+ "security": [
7963
+ {
7964
+ "apiToken": []
7965
+ }
7966
+ ],
7967
+ "group": "hosting"
7968
+ },
7941
7969
  {
7942
7970
  "name": "hosting_orders_list",
7943
7971
  "title": "List orders",
@@ -8517,7 +8545,7 @@ const tools: OpenApiTool[] = [
8517
8545
  "readOnlyHint": true,
8518
8546
  "destructiveHint": false
8519
8547
  },
8520
- "description": "Retrieve a paginated list of websites (CloudLinux, Builder, and Horizons) accessible to the\nauthenticated client.\n\nThis endpoint returns websites from your hosting accounts as well as\nwebsites from other client hosting accounts that have shared access\nwith you.\n\nEach website includes a `website_type` field describing the type of\nwebsite detected on the underlying platform (`wordpress`, `builder`,\n`horizons`, `nodejs`, or `other`). Some fields, such as\n`vhost_type`, `username`, and `root_directory`, only apply to\nCloudLinux websites and are null for other platforms.\n\nUse `website_types` to list only websites of a given detected type, e.g. only\nWordPress websites (`website_types=wordpress`) or only Node.js websites\n(`website_types=nodejs`). Combine with the other available query parameters to\nfilter by username, order ID, enabled status, or domain name for more targeted\nresults.",
8548
+ "description": "Retrieve a paginated list of websites (CloudLinux, Builder, and Horizons) accessible to the\nauthenticated client.\n\nThis endpoint returns websites from your hosting accounts as well as\nwebsites from other client hosting accounts that have shared access\nwith you.\n\nEach website includes a `website_type` field describing the type of\nwebsite detected on the underlying platform (`wordpress`, `builder`,\n`horizons`, `nodejs`, or `other`). Some fields, such as\n`vhost_type`, `username`, and `root_directory`, only apply to\nCloudLinux websites and are null for other platforms.\n\nUse `website_types` to list only websites of a given detected type, e.g. only\nWordPress websites (`website_types=wordpress`) or only Node.js websites\n(`website_types=nodejs`). Combine with the other available query parameters to\nfilter by username, order ID, enabled status, or domain name for more targeted\nresults.\n\nA website appears in this list before its server-side setup has finished, and\n`is_enabled` reflects suspension, not readiness. To know when a newly created website\nis ready for file, deploy or database operations, poll the list website setups\nendpoint instead.",
8521
8549
  "method": "GET",
8522
8550
  "path": "/api/hosting/v1/websites",
8523
8551
  "inputSchema": {
@@ -8580,7 +8608,7 @@ const tools: OpenApiTool[] = [
8580
8608
  "readOnlyHint": false,
8581
8609
  "destructiveHint": false
8582
8610
  },
8583
- "description": "Create a new website for the authenticated client.\n\nYou must choose which hosting order to create this website on. Pass that\norder as `order_id` together with the domain name. List orders to see\navailable IDs; the website is provisioned on that order's hosting plan.\n\nThe datacenter_code parameter is required when creating the first website\non a new hosting plan - this will set up and configure new hosting account\nin the selected datacenter.\n\nSubsequent websites will be hosted on the same datacenter automatically.\n\nWebsite creation takes up to a few minutes to complete. Check the\nwebsites list endpoint to see when your new website becomes available.",
8611
+ "description": "Create a new website for the authenticated client.\n\nYou must choose which hosting order to create this website on. Pass that\norder as `order_id` together with the domain name. List orders to see\navailable IDs; the website is provisioned on that order's hosting plan.\n\nThe datacenter_code parameter is required when creating the first website\non a new hosting plan - this will set up and configure new hosting account\nin the selected datacenter.\n\nSubsequent websites will be hosted on the same datacenter automatically.\n\nWebsite creation is asynchronous and takes up to a few minutes. Poll the list website\nsetups endpoint with the `domain` filter every 10 to 15 seconds and wait for `status:\ncompleted` before uploading files, deploying or creating databases. While the setup is\n`running`, endpoints that operate on the website may respond with `404` or `409`.\n`is_enabled` on the websites list reflects suspension, not readiness.",
8584
8612
  "method": "POST",
8585
8613
  "path": "/api/hosting/v1/websites",
8586
8614
  "inputSchema": {
@@ -747,7 +747,7 @@ export default [
747
747
  "readOnlyHint": false,
748
748
  "destructiveHint": false
749
749
  },
750
- "description": "Allows a remote host to connect to the specified database.\n\nProvide an IPv4/IPv6 address, or \"%\" to allow any host. The database name must be\nthe full name returned by the list databases endpoint.",
750
+ "description": "Allows a remote host to connect to the specified database.\n\nProvide an IPv4/IPv6 address, or \"%\" to allow any host. The database name must be\nthe full name returned by the list databases endpoint. Database creation is synchronous,\nso a 404 here means no database with that name exists under the username, not that it\nis still being created.",
751
751
  "method": "POST",
752
752
  "path": "/api/hosting/v1/accounts/{username}/databases/{name}/remote-connections",
753
753
  "inputSchema": {
@@ -1299,7 +1299,7 @@ export default [
1299
1299
  "readOnlyHint": false,
1300
1300
  "destructiveHint": false
1301
1301
  },
1302
- "description": "Generate a file browser upload URL with authentication credentials\nfor uploading files directly to a website's file storage.\n\nReturns `url`, `auth_key` and `rest_auth_key`. Use these to upload a file to the\nwebsite's `public_html` directory via the TUS resumable upload protocol (TUS 1.0.0).\nSend `X-Auth: {auth_key}` and `X-Auth-Rest: {rest_auth_key}` headers on every request\nbelow.\n\n1. Create the upload: `POST` to `{url}/{relative_file_path}?override=true` with headers\n `upload-length: {file size in bytes}` and `upload-offset: 0`. Expect `201 Created`.\n2. Upload the file: send the file bytes to the same location (any TUS 1.0.0 client, or\n `PATCH` requests with an `upload-offset` header tracking progress) until complete.\n\n`relative_file_path` is the destination path inside `public_html`, e.g. `app.zip`.\n\nInstead of a TUS client, plain `curl` also works:\n```\nFILE=app.zip\nSIZE=$(stat -f%z \"$FILE\") # stat -c%s on Linux\n\ncurl -i -X POST \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Upload-Length: ${SIZE}\" \\\n -H \"Upload-Offset: 0\"\n# -> 201 Created\n\ncurl -i -X PATCH \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Content-Type: application/offset+octet-stream\" \\\n -H \"Upload-Offset: 0\" \\\n --data-binary \"@${FILE}\"\n# -> 204 No Content, Upload-Offset response header equals SIZE when done\n```",
1302
+ "description": "Generate a file browser upload URL with authentication credentials\nfor uploading files directly to a website's file storage.\n\nWhile the website is still being set up (`status: running` on the list website setups\nendpoint) this endpoint returns 409 with a `Retry-After` header: wait that many\nseconds and retry, or poll the website setups until the status is `completed`.\n\nReturns `url`, `auth_key` and `rest_auth_key`. Use these to upload a file to the\nwebsite's `public_html` directory via the TUS resumable upload protocol (TUS 1.0.0).\nSend `X-Auth: {auth_key}` and `X-Auth-Rest: {rest_auth_key}` headers on every request\nbelow.\n\n1. Create the upload: `POST` to `{url}/{relative_file_path}?override=true` with headers\n `upload-length: {file size in bytes}` and `upload-offset: 0`. Expect `201 Created`.\n2. Upload the file: send the file bytes to the same location (any TUS 1.0.0 client, or\n `PATCH` requests with an `upload-offset` header tracking progress) until complete.\n\n`relative_file_path` is the destination path inside `public_html`, e.g. `app.zip`.\n\nInstead of a TUS client, plain `curl` also works:\n```\nFILE=app.zip\nSIZE=$(stat -f%z \"$FILE\") # stat -c%s on Linux\n\ncurl -i -X POST \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Upload-Length: ${SIZE}\" \\\n -H \"Upload-Offset: 0\"\n# -> 201 Created\n\ncurl -i -X PATCH \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Content-Type: application/offset+octet-stream\" \\\n -H \"Upload-Offset: 0\" \\\n --data-binary \"@${FILE}\"\n# -> 204 No Content, Upload-Offset response header equals SIZE when done\n```",
1303
1303
  "method": "POST",
1304
1304
  "path": "/api/hosting/v1/files/upload-urls",
1305
1305
  "inputSchema": {
@@ -2463,6 +2463,34 @@ export default [
2463
2463
  ],
2464
2464
  "group": "hosting"
2465
2465
  },
2466
+ {
2467
+ "name": "hosting_websites_list-setups",
2468
+ "title": "List website setups",
2469
+ "annotations": {
2470
+ "title": "List website setups",
2471
+ "readOnlyHint": true,
2472
+ "destructiveHint": false
2473
+ },
2474
+ "description": "Returns the website setups started in the last 24 hours for the hosting accounts\naccessible to the authenticated client, newest first.\n\nMeant for polling right after creating a website: the website shows up in the\nwebsites list before its server-side setup has finished, and while the setup is\n`running` endpoints that operate on that website may respond with `404` or `409`.\nPoll this endpoint with the `domain` filter every 10 to 15 seconds and wait for\n`status: completed` before uploading files, deploying or creating databases.\n`failed` means the setup stopped before finishing or has not reported progress for\nover an hour. Setups older than 24 hours are not listed.",
2475
+ "method": "GET",
2476
+ "path": "/api/hosting/v1/onboardings",
2477
+ "inputSchema": {
2478
+ "type": "object",
2479
+ "properties": {
2480
+ "domain": {
2481
+ "type": "string",
2482
+ "description": "Filter by domain name (exact match)"
2483
+ }
2484
+ },
2485
+ "required": []
2486
+ },
2487
+ "security": [
2488
+ {
2489
+ "apiToken": []
2490
+ }
2491
+ ],
2492
+ "group": "hosting"
2493
+ },
2466
2494
  {
2467
2495
  "name": "hosting_orders_list",
2468
2496
  "title": "List orders",
@@ -3042,7 +3070,7 @@ export default [
3042
3070
  "readOnlyHint": true,
3043
3071
  "destructiveHint": false
3044
3072
  },
3045
- "description": "Retrieve a paginated list of websites (CloudLinux, Builder, and Horizons) accessible to the\nauthenticated client.\n\nThis endpoint returns websites from your hosting accounts as well as\nwebsites from other client hosting accounts that have shared access\nwith you.\n\nEach website includes a `website_type` field describing the type of\nwebsite detected on the underlying platform (`wordpress`, `builder`,\n`horizons`, `nodejs`, or `other`). Some fields, such as\n`vhost_type`, `username`, and `root_directory`, only apply to\nCloudLinux websites and are null for other platforms.\n\nUse `website_types` to list only websites of a given detected type, e.g. only\nWordPress websites (`website_types=wordpress`) or only Node.js websites\n(`website_types=nodejs`). Combine with the other available query parameters to\nfilter by username, order ID, enabled status, or domain name for more targeted\nresults.",
3073
+ "description": "Retrieve a paginated list of websites (CloudLinux, Builder, and Horizons) accessible to the\nauthenticated client.\n\nThis endpoint returns websites from your hosting accounts as well as\nwebsites from other client hosting accounts that have shared access\nwith you.\n\nEach website includes a `website_type` field describing the type of\nwebsite detected on the underlying platform (`wordpress`, `builder`,\n`horizons`, `nodejs`, or `other`). Some fields, such as\n`vhost_type`, `username`, and `root_directory`, only apply to\nCloudLinux websites and are null for other platforms.\n\nUse `website_types` to list only websites of a given detected type, e.g. only\nWordPress websites (`website_types=wordpress`) or only Node.js websites\n(`website_types=nodejs`). Combine with the other available query parameters to\nfilter by username, order ID, enabled status, or domain name for more targeted\nresults.\n\nA website appears in this list before its server-side setup has finished, and\n`is_enabled` reflects suspension, not readiness. To know when a newly created website\nis ready for file, deploy or database operations, poll the list website setups\nendpoint instead.",
3046
3074
  "method": "GET",
3047
3075
  "path": "/api/hosting/v1/websites",
3048
3076
  "inputSchema": {
@@ -3105,7 +3133,7 @@ export default [
3105
3133
  "readOnlyHint": false,
3106
3134
  "destructiveHint": false
3107
3135
  },
3108
- "description": "Create a new website for the authenticated client.\n\nYou must choose which hosting order to create this website on. Pass that\norder as `order_id` together with the domain name. List orders to see\navailable IDs; the website is provisioned on that order's hosting plan.\n\nThe datacenter_code parameter is required when creating the first website\non a new hosting plan - this will set up and configure new hosting account\nin the selected datacenter.\n\nSubsequent websites will be hosted on the same datacenter automatically.\n\nWebsite creation takes up to a few minutes to complete. Check the\nwebsites list endpoint to see when your new website becomes available.",
3136
+ "description": "Create a new website for the authenticated client.\n\nYou must choose which hosting order to create this website on. Pass that\norder as `order_id` together with the domain name. List orders to see\navailable IDs; the website is provisioned on that order's hosting plan.\n\nThe datacenter_code parameter is required when creating the first website\non a new hosting plan - this will set up and configure new hosting account\nin the selected datacenter.\n\nSubsequent websites will be hosted on the same datacenter automatically.\n\nWebsite creation is asynchronous and takes up to a few minutes. Poll the list website\nsetups endpoint with the `domain` filter every 10 to 15 seconds and wait for `status:\ncompleted` before uploading files, deploying or creating databases. While the setup is\n`running`, endpoints that operate on the website may respond with `404` or `409`.\n`is_enabled` on the websites list reflects suspension, not readiness.",
3109
3137
  "method": "POST",
3110
3138
  "path": "/api/hosting/v1/websites",
3111
3139
  "inputSchema": {
@@ -761,7 +761,7 @@ const tools: OpenApiTool[] = [
761
761
  "readOnlyHint": false,
762
762
  "destructiveHint": false
763
763
  },
764
- "description": "Allows a remote host to connect to the specified database.\n\nProvide an IPv4/IPv6 address, or \"%\" to allow any host. The database name must be\nthe full name returned by the list databases endpoint.",
764
+ "description": "Allows a remote host to connect to the specified database.\n\nProvide an IPv4/IPv6 address, or \"%\" to allow any host. The database name must be\nthe full name returned by the list databases endpoint. Database creation is synchronous,\nso a 404 here means no database with that name exists under the username, not that it\nis still being created.",
765
765
  "method": "POST",
766
766
  "path": "/api/hosting/v1/accounts/{username}/databases/{name}/remote-connections",
767
767
  "inputSchema": {
@@ -1313,7 +1313,7 @@ const tools: OpenApiTool[] = [
1313
1313
  "readOnlyHint": false,
1314
1314
  "destructiveHint": false
1315
1315
  },
1316
- "description": "Generate a file browser upload URL with authentication credentials\nfor uploading files directly to a website's file storage.\n\nReturns `url`, `auth_key` and `rest_auth_key`. Use these to upload a file to the\nwebsite's `public_html` directory via the TUS resumable upload protocol (TUS 1.0.0).\nSend `X-Auth: {auth_key}` and `X-Auth-Rest: {rest_auth_key}` headers on every request\nbelow.\n\n1. Create the upload: `POST` to `{url}/{relative_file_path}?override=true` with headers\n `upload-length: {file size in bytes}` and `upload-offset: 0`. Expect `201 Created`.\n2. Upload the file: send the file bytes to the same location (any TUS 1.0.0 client, or\n `PATCH` requests with an `upload-offset` header tracking progress) until complete.\n\n`relative_file_path` is the destination path inside `public_html`, e.g. `app.zip`.\n\nInstead of a TUS client, plain `curl` also works:\n```\nFILE=app.zip\nSIZE=$(stat -f%z \"$FILE\") # stat -c%s on Linux\n\ncurl -i -X POST \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Upload-Length: ${SIZE}\" \\\n -H \"Upload-Offset: 0\"\n# -> 201 Created\n\ncurl -i -X PATCH \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Content-Type: application/offset+octet-stream\" \\\n -H \"Upload-Offset: 0\" \\\n --data-binary \"@${FILE}\"\n# -> 204 No Content, Upload-Offset response header equals SIZE when done\n```",
1316
+ "description": "Generate a file browser upload URL with authentication credentials\nfor uploading files directly to a website's file storage.\n\nWhile the website is still being set up (`status: running` on the list website setups\nendpoint) this endpoint returns 409 with a `Retry-After` header: wait that many\nseconds and retry, or poll the website setups until the status is `completed`.\n\nReturns `url`, `auth_key` and `rest_auth_key`. Use these to upload a file to the\nwebsite's `public_html` directory via the TUS resumable upload protocol (TUS 1.0.0).\nSend `X-Auth: {auth_key}` and `X-Auth-Rest: {rest_auth_key}` headers on every request\nbelow.\n\n1. Create the upload: `POST` to `{url}/{relative_file_path}?override=true` with headers\n `upload-length: {file size in bytes}` and `upload-offset: 0`. Expect `201 Created`.\n2. Upload the file: send the file bytes to the same location (any TUS 1.0.0 client, or\n `PATCH` requests with an `upload-offset` header tracking progress) until complete.\n\n`relative_file_path` is the destination path inside `public_html`, e.g. `app.zip`.\n\nInstead of a TUS client, plain `curl` also works:\n```\nFILE=app.zip\nSIZE=$(stat -f%z \"$FILE\") # stat -c%s on Linux\n\ncurl -i -X POST \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Upload-Length: ${SIZE}\" \\\n -H \"Upload-Offset: 0\"\n# -> 201 Created\n\ncurl -i -X PATCH \"{url}/${FILE}?override=true\" \\\n -H \"X-Auth: {auth_key}\" \\\n -H \"X-Auth-Rest: {rest_auth_key}\" \\\n -H \"Tus-Resumable: 1.0.0\" \\\n -H \"Content-Type: application/offset+octet-stream\" \\\n -H \"Upload-Offset: 0\" \\\n --data-binary \"@${FILE}\"\n# -> 204 No Content, Upload-Offset response header equals SIZE when done\n```",
1317
1317
  "method": "POST",
1318
1318
  "path": "/api/hosting/v1/files/upload-urls",
1319
1319
  "inputSchema": {
@@ -2477,6 +2477,34 @@ const tools: OpenApiTool[] = [
2477
2477
  ],
2478
2478
  "group": "hosting"
2479
2479
  },
2480
+ {
2481
+ "name": "hosting_websites_list-setups",
2482
+ "title": "List website setups",
2483
+ "annotations": {
2484
+ "title": "List website setups",
2485
+ "readOnlyHint": true,
2486
+ "destructiveHint": false
2487
+ },
2488
+ "description": "Returns the website setups started in the last 24 hours for the hosting accounts\naccessible to the authenticated client, newest first.\n\nMeant for polling right after creating a website: the website shows up in the\nwebsites list before its server-side setup has finished, and while the setup is\n`running` endpoints that operate on that website may respond with `404` or `409`.\nPoll this endpoint with the `domain` filter every 10 to 15 seconds and wait for\n`status: completed` before uploading files, deploying or creating databases.\n`failed` means the setup stopped before finishing or has not reported progress for\nover an hour. Setups older than 24 hours are not listed.",
2489
+ "method": "GET",
2490
+ "path": "/api/hosting/v1/onboardings",
2491
+ "inputSchema": {
2492
+ "type": "object",
2493
+ "properties": {
2494
+ "domain": {
2495
+ "type": "string",
2496
+ "description": "Filter by domain name (exact match)"
2497
+ }
2498
+ },
2499
+ "required": []
2500
+ },
2501
+ "security": [
2502
+ {
2503
+ "apiToken": []
2504
+ }
2505
+ ],
2506
+ "group": "hosting"
2507
+ },
2480
2508
  {
2481
2509
  "name": "hosting_orders_list",
2482
2510
  "title": "List orders",
@@ -3056,7 +3084,7 @@ const tools: OpenApiTool[] = [
3056
3084
  "readOnlyHint": true,
3057
3085
  "destructiveHint": false
3058
3086
  },
3059
- "description": "Retrieve a paginated list of websites (CloudLinux, Builder, and Horizons) accessible to the\nauthenticated client.\n\nThis endpoint returns websites from your hosting accounts as well as\nwebsites from other client hosting accounts that have shared access\nwith you.\n\nEach website includes a `website_type` field describing the type of\nwebsite detected on the underlying platform (`wordpress`, `builder`,\n`horizons`, `nodejs`, or `other`). Some fields, such as\n`vhost_type`, `username`, and `root_directory`, only apply to\nCloudLinux websites and are null for other platforms.\n\nUse `website_types` to list only websites of a given detected type, e.g. only\nWordPress websites (`website_types=wordpress`) or only Node.js websites\n(`website_types=nodejs`). Combine with the other available query parameters to\nfilter by username, order ID, enabled status, or domain name for more targeted\nresults.",
3087
+ "description": "Retrieve a paginated list of websites (CloudLinux, Builder, and Horizons) accessible to the\nauthenticated client.\n\nThis endpoint returns websites from your hosting accounts as well as\nwebsites from other client hosting accounts that have shared access\nwith you.\n\nEach website includes a `website_type` field describing the type of\nwebsite detected on the underlying platform (`wordpress`, `builder`,\n`horizons`, `nodejs`, or `other`). Some fields, such as\n`vhost_type`, `username`, and `root_directory`, only apply to\nCloudLinux websites and are null for other platforms.\n\nUse `website_types` to list only websites of a given detected type, e.g. only\nWordPress websites (`website_types=wordpress`) or only Node.js websites\n(`website_types=nodejs`). Combine with the other available query parameters to\nfilter by username, order ID, enabled status, or domain name for more targeted\nresults.\n\nA website appears in this list before its server-side setup has finished, and\n`is_enabled` reflects suspension, not readiness. To know when a newly created website\nis ready for file, deploy or database operations, poll the list website setups\nendpoint instead.",
3060
3088
  "method": "GET",
3061
3089
  "path": "/api/hosting/v1/websites",
3062
3090
  "inputSchema": {
@@ -3119,7 +3147,7 @@ const tools: OpenApiTool[] = [
3119
3147
  "readOnlyHint": false,
3120
3148
  "destructiveHint": false
3121
3149
  },
3122
- "description": "Create a new website for the authenticated client.\n\nYou must choose which hosting order to create this website on. Pass that\norder as `order_id` together with the domain name. List orders to see\navailable IDs; the website is provisioned on that order's hosting plan.\n\nThe datacenter_code parameter is required when creating the first website\non a new hosting plan - this will set up and configure new hosting account\nin the selected datacenter.\n\nSubsequent websites will be hosted on the same datacenter automatically.\n\nWebsite creation takes up to a few minutes to complete. Check the\nwebsites list endpoint to see when your new website becomes available.",
3150
+ "description": "Create a new website for the authenticated client.\n\nYou must choose which hosting order to create this website on. Pass that\norder as `order_id` together with the domain name. List orders to see\navailable IDs; the website is provisioned on that order's hosting plan.\n\nThe datacenter_code parameter is required when creating the first website\non a new hosting plan - this will set up and configure new hosting account\nin the selected datacenter.\n\nSubsequent websites will be hosted on the same datacenter automatically.\n\nWebsite creation is asynchronous and takes up to a few minutes. Poll the list website\nsetups endpoint with the `domain` filter every 10 to 15 seconds and wait for `status:\ncompleted` before uploading files, deploying or creating databases. While the setup is\n`running`, endpoints that operate on the website may respond with `404` or `409`.\n`is_enabled` on the websites list reflects suspension, not readiness.",
3123
3151
  "method": "POST",
3124
3152
  "path": "/api/hosting/v1/websites",
3125
3153
  "inputSchema": {
@@ -4,4 +4,4 @@ import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/agency-hosting.js';
5
5
  import instructions from '../core/instructions.js';
6
6
 
7
- startServer({ name: 'hostinger-agency-hosting-mcp', version: '2.1.0', tools, instructions });
7
+ startServer({ name: 'hostinger-agency-hosting-mcp', version: '2.3.0', tools, instructions });
@@ -4,4 +4,4 @@ import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/agency-hosting.js';
5
5
  import instructions from '../core/instructions.js';
6
6
 
7
- startServer({ name: 'hostinger-agency-hosting-mcp', version: '2.1.0', tools, instructions });
7
+ startServer({ name: 'hostinger-agency-hosting-mcp', version: '2.3.0', tools, instructions });
@@ -3,5 +3,6 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/all.js';
5
5
  import instructions from '../core/instructions.js';
6
+ import skills from '../core/skills.js';
6
7
 
7
- startServer({ name: 'hostinger-api-mcp', version: '2.1.0', tools, instructions });
8
+ startServer({ name: 'hostinger-api-mcp', version: '2.3.0', tools, instructions, skills });
@@ -3,5 +3,6 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/all.js';
5
5
  import instructions from '../core/instructions.js';
6
+ import skills from '../core/skills.js';
6
7
 
7
- startServer({ name: 'hostinger-api-mcp', version: '2.1.0', tools, instructions });
8
+ startServer({ name: 'hostinger-api-mcp', version: '2.3.0', tools, instructions, skills });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/billing.js';
5
5
 
6
- startServer({ name: 'hostinger-billing-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-billing-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/billing.js';
5
5
 
6
- startServer({ name: 'hostinger-billing-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-billing-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/dns.js';
5
5
 
6
- startServer({ name: 'hostinger-dns-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-dns-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/dns.js';
5
5
 
6
- startServer({ name: 'hostinger-dns-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-dns-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/domains.js';
5
5
 
6
- startServer({ name: 'hostinger-domains-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-domains-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/domains.js';
5
5
 
6
- startServer({ name: 'hostinger-domains-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-domains-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/ecommerce.js';
5
5
 
6
- startServer({ name: 'hostinger-ecommerce-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-ecommerce-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/ecommerce.js';
5
5
 
6
- startServer({ name: 'hostinger-ecommerce-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-ecommerce-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/horizons.js';
5
5
 
6
- startServer({ name: 'hostinger-horizons-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-horizons-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/horizons.js';
5
5
 
6
- startServer({ name: 'hostinger-horizons-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-horizons-mcp', version: '2.3.0', tools });
@@ -4,4 +4,4 @@ import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/hosting.js';
5
5
  import instructions from '../core/instructions.js';
6
6
 
7
- startServer({ name: 'hostinger-hosting-mcp', version: '2.1.0', tools, instructions });
7
+ startServer({ name: 'hostinger-hosting-mcp', version: '2.3.0', tools, instructions });
@@ -4,4 +4,4 @@ import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/hosting.js';
5
5
  import instructions from '../core/instructions.js';
6
6
 
7
- startServer({ name: 'hostinger-hosting-mcp', version: '2.1.0', tools, instructions });
7
+ startServer({ name: 'hostinger-hosting-mcp', version: '2.3.0', tools, instructions });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/mail.js';
5
5
 
6
- startServer({ name: 'hostinger-mail-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-mail-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/mail.js';
5
5
 
6
- startServer({ name: 'hostinger-mail-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-mail-mcp', version: '2.3.0', tools });
@@ -3,4 +3,4 @@
3
3
  import { startServer } from '../core/runtime.js';
4
4
  import tools from '../core/tools/reach.js';
5
5
 
6
- startServer({ name: 'hostinger-reach-mcp', version: '2.1.0', tools });
6
+ startServer({ name: 'hostinger-reach-mcp', version: '2.3.0', tools });