hostinger-api-mcp 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +432 -0
- package/README.md +406 -406
- package/gemini-extension.json +1 -1
- package/package.json +4 -3
- package/server.json +2 -2
- package/skills/headless/SKILL.md +1 -1
- package/skills/headless/references/DATABASE.md +14 -14
- package/skills/headless/references/DEPLOYMENT.md +5 -5
- package/skills/headless/references/SETUP.md +8 -8
- package/skills/headless/references/STORE.md +4 -4
- package/skills/headless/references/WORDPRESS.md +5 -5
- package/src/core/instructions.js +1 -1
- package/src/core/instructions.ts +1 -1
- package/src/core/runtime.js +87 -12
- package/src/core/runtime.ts +93 -12
- package/src/core/skills.js +54 -0
- package/src/core/skills.ts +69 -0
- package/src/core/tools/agency-hosting.js +44 -44
- package/src/core/tools/agency-hosting.ts +44 -44
- package/src/core/tools/all.js +405 -405
- package/src/core/tools/all.ts +405 -405
- package/src/core/tools/billing.js +9 -9
- package/src/core/tools/billing.ts +9 -9
- package/src/core/tools/dns.js +8 -8
- package/src/core/tools/dns.ts +8 -8
- package/src/core/tools/domains.js +41 -41
- package/src/core/tools/domains.ts +41 -41
- package/src/core/tools/ecommerce.js +29 -29
- package/src/core/tools/ecommerce.ts +29 -29
- package/src/core/tools/horizons.js +6 -6
- package/src/core/tools/horizons.ts +6 -6
- package/src/core/tools/hosting.js +76 -76
- package/src/core/tools/hosting.ts +76 -76
- package/src/core/tools/mail.js +38 -38
- package/src/core/tools/mail.ts +38 -38
- package/src/core/tools/reach.js +52 -52
- package/src/core/tools/reach.ts +52 -52
- package/src/core/tools/vps.js +64 -64
- package/src/core/tools/vps.ts +64 -64
- package/src/core/tools/wordpress.js +38 -38
- package/src/core/tools/wordpress.ts +38 -38
- package/src/servers/agency-hosting.js +1 -1
- package/src/servers/agency-hosting.ts +1 -1
- package/src/servers/all.js +2 -1
- package/src/servers/all.ts +2 -1
- package/src/servers/billing.js +1 -1
- package/src/servers/billing.ts +1 -1
- package/src/servers/dns.js +1 -1
- package/src/servers/dns.ts +1 -1
- package/src/servers/domains.js +1 -1
- package/src/servers/domains.ts +1 -1
- package/src/servers/ecommerce.js +1 -1
- package/src/servers/ecommerce.ts +1 -1
- package/src/servers/horizons.js +1 -1
- package/src/servers/horizons.ts +1 -1
- package/src/servers/hosting.js +1 -1
- package/src/servers/hosting.ts +1 -1
- package/src/servers/mail.js +1 -1
- package/src/servers/mail.ts +1 -1
- package/src/servers/reach.js +1 -1
- package/src/servers/reach.ts +1 -1
- package/src/servers/vps.js +1 -1
- package/src/servers/vps.ts +1 -1
- package/src/servers/wordpress.js +1 -1
- package/src/servers/wordpress.ts +1 -1
- package/types.d.ts +405 -405
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Auto-generated agent skills served over the MCP Skills extension
|
|
2
|
+
export default [
|
|
3
|
+
{
|
|
4
|
+
"uri": "skill://hostinger-headless/SKILL.md",
|
|
5
|
+
"frontmatter": {
|
|
6
|
+
"name": "hostinger-headless",
|
|
7
|
+
"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."
|
|
8
|
+
},
|
|
9
|
+
"resources": [
|
|
10
|
+
{
|
|
11
|
+
"uri": "skill://hostinger-headless/SKILL.md",
|
|
12
|
+
"digest": "sha256:7ed8a33109f571b56646627d21ba58cf7cbf8c2818c9bfacf645a341a8847b1f",
|
|
13
|
+
"size": 7200,
|
|
14
|
+
"mimeType": "text/markdown",
|
|
15
|
+
"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"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"uri": "skill://hostinger-headless/references/DATABASE.md",
|
|
19
|
+
"digest": "sha256:e0800ac848244ead5b9a1bfb0a39d223b336c2a179ac13ece0089d135c418d76",
|
|
20
|
+
"size": 4299,
|
|
21
|
+
"mimeType": "text/markdown",
|
|
22
|
+
"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"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"uri": "skill://hostinger-headless/references/DEPLOYMENT.md",
|
|
26
|
+
"digest": "sha256:1369632f23a6934ca47ca942cba20882681bc679fe833757ce30099c51257ea2",
|
|
27
|
+
"size": 2170,
|
|
28
|
+
"mimeType": "text/markdown",
|
|
29
|
+
"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"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"uri": "skill://hostinger-headless/references/SETUP.md",
|
|
33
|
+
"digest": "sha256:52cc927dd67c4f4b6686dff55e1fd36b61350a1a41a3e5ced364a769dcd6f6fd",
|
|
34
|
+
"size": 2860,
|
|
35
|
+
"mimeType": "text/markdown",
|
|
36
|
+
"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"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"uri": "skill://hostinger-headless/references/STORE.md",
|
|
40
|
+
"digest": "sha256:ca5bf13b3968b49ae53717c0e52e16d301774b2ea166a687e246bd6089f155e2",
|
|
41
|
+
"size": 5470,
|
|
42
|
+
"mimeType": "text/markdown",
|
|
43
|
+
"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"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"uri": "skill://hostinger-headless/references/WORDPRESS.md",
|
|
47
|
+
"digest": "sha256:d9e80f800fbf4c53a95972762f9fe177430860715d849ea520ae5d47e0ef8f04",
|
|
48
|
+
"size": 4569,
|
|
49
|
+
"mimeType": "text/markdown",
|
|
50
|
+
"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"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
];
|
|
@@ -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;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Auto-generated tool list for group: agency-hosting
|
|
2
2
|
export default [
|
|
3
3
|
{
|
|
4
|
-
"name": "agency-
|
|
4
|
+
"name": "agency-hosting_deploy-node-static-website",
|
|
5
5
|
"title": "Deploy node-static website",
|
|
6
6
|
"annotations": {
|
|
7
7
|
"title": "Deploy node-static website",
|
|
@@ -9,7 +9,7 @@ export default [
|
|
|
9
9
|
"destructiveHint": true
|
|
10
10
|
},
|
|
11
11
|
"topic": "agency-hosting",
|
|
12
|
-
"description": "Deploy a node-static Agency Plan (h5g) website from an archive file. WARNING: this overwrites the website's existing contents and cannot be undone — always confirm with the user before proceeding. Use this for Agency Plan websites of type node-static (a Node.js-built static site that requires a build step or a plain simple static site). The tool resolves the website from its domain, uploads the archive to the website's file browser over TUS, and triggers the build-assets process which builds the site and deploys the result to public_html. This operation is synchronous: the build and deployment complete before the tool returns, so the website is live as soon as the tool finishes successfully — there is no separate asynchronous build to wait for or poll. Upload credentials are generated and used internally — do not call a separate upload-url endpoint or upload the archive yourself, this tool does it end-to-end. For plain PHP applications that should be extracted as-is, use
|
|
12
|
+
"description": "Deploy a node-static Agency Plan (h5g) website from an archive file. WARNING: this overwrites the website's existing contents and cannot be undone — always confirm with the user before proceeding. Use this for Agency Plan websites of type node-static (a Node.js-built static site that requires a build step or a plain simple static site). The tool resolves the website from its domain, uploads the archive to the website's file browser over TUS, and triggers the build-assets process which builds the site and deploys the result to public_html. This operation is synchronous: the build and deployment complete before the tool returns, so the website is live as soon as the tool finishes successfully — there is no separate asynchronous build to wait for or poll. Upload credentials are generated and used internally — do not call a separate upload-url endpoint or upload the archive yourself, this tool does it end-to-end. For plain PHP applications that should be extracted as-is, use agency-hosting_deploy-php-application instead. The website UID is automatically resolved from the domain.",
|
|
13
13
|
"method": "",
|
|
14
14
|
"path": "",
|
|
15
15
|
"inputSchema": {
|
|
@@ -41,7 +41,7 @@ export default [
|
|
|
41
41
|
"group": "agency-hosting"
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
|
-
"name": "agency-
|
|
44
|
+
"name": "agency-hosting_deploy-php-application",
|
|
45
45
|
"title": "Deploy PHP application",
|
|
46
46
|
"annotations": {
|
|
47
47
|
"title": "Deploy PHP application",
|
|
@@ -49,7 +49,7 @@ export default [
|
|
|
49
49
|
"destructiveHint": true
|
|
50
50
|
},
|
|
51
51
|
"topic": "agency-hosting",
|
|
52
|
-
"description": "Deploy a PHP (or other non-build) Agency Plan (h5g) website from an archive file. WARNING: this overwrites the website's existing contents and cannot be undone — always confirm with the user before proceeding. Use this for Agency Plan websites where the archive contents should be extracted and served as-is with no build step (e.g., PHP applications). The tool resolves the website from its domain, uploads the archive to the website's file browser over TUS, and triggers the import-archive process which overwrites the website contents with the archive contents. This operation is synchronous: the archive is extracted and deployed before the tool returns, so the website is live as soon as the tool finishes successfully — there is no separate asynchronous build to wait for or poll. Upload credentials are generated and used internally — do not call a separate upload-url endpoint or upload the archive yourself, this tool does it end-to-end. For node-static websites that require a build step, use
|
|
52
|
+
"description": "Deploy a PHP (or other non-build) Agency Plan (h5g) website from an archive file. WARNING: this overwrites the website's existing contents and cannot be undone — always confirm with the user before proceeding. Use this for Agency Plan websites where the archive contents should be extracted and served as-is with no build step (e.g., PHP applications). The tool resolves the website from its domain, uploads the archive to the website's file browser over TUS, and triggers the import-archive process which overwrites the website contents with the archive contents. This operation is synchronous: the archive is extracted and deployed before the tool returns, so the website is live as soon as the tool finishes successfully — there is no separate asynchronous build to wait for or poll. Upload credentials are generated and used internally — do not call a separate upload-url endpoint or upload the archive yourself, this tool does it end-to-end. For node-static websites that require a build step, use agency-hosting_deploy-node-static-website instead. The website UID is automatically resolved from the domain.",
|
|
53
53
|
"method": "",
|
|
54
54
|
"path": "",
|
|
55
55
|
"inputSchema": {
|
|
@@ -81,7 +81,7 @@ export default [
|
|
|
81
81
|
"group": "agency-hosting"
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
|
-
"name": "agency-
|
|
84
|
+
"name": "agency-hosting_datacenters_list",
|
|
85
85
|
"title": "List available datacenters",
|
|
86
86
|
"annotations": {
|
|
87
87
|
"title": "List available datacenters",
|
|
@@ -111,7 +111,7 @@ export default [
|
|
|
111
111
|
"group": "agency-hosting"
|
|
112
112
|
},
|
|
113
113
|
{
|
|
114
|
-
"name": "agency-
|
|
114
|
+
"name": "agency-hosting_domains_change-website",
|
|
115
115
|
"title": "Change website domain",
|
|
116
116
|
"annotations": {
|
|
117
117
|
"title": "Change website domain",
|
|
@@ -152,7 +152,7 @@ export default [
|
|
|
152
152
|
"group": "agency-hosting"
|
|
153
153
|
},
|
|
154
154
|
{
|
|
155
|
-
"name": "agency-
|
|
155
|
+
"name": "agency-hosting_domains_link-to-website",
|
|
156
156
|
"title": "Link domain to website",
|
|
157
157
|
"annotations": {
|
|
158
158
|
"title": "Link domain to website",
|
|
@@ -187,7 +187,7 @@ export default [
|
|
|
187
187
|
"group": "agency-hosting"
|
|
188
188
|
},
|
|
189
189
|
{
|
|
190
|
-
"name": "agency-
|
|
190
|
+
"name": "agency-hosting_domains_list",
|
|
191
191
|
"title": "List domains",
|
|
192
192
|
"annotations": {
|
|
193
193
|
"title": "List domains",
|
|
@@ -227,7 +227,7 @@ export default [
|
|
|
227
227
|
"group": "agency-hosting"
|
|
228
228
|
},
|
|
229
229
|
{
|
|
230
|
-
"name": "agency-
|
|
230
|
+
"name": "agency-hosting_domains_unlink-from-website",
|
|
231
231
|
"title": "Unlink domain from website",
|
|
232
232
|
"annotations": {
|
|
233
233
|
"title": "Unlink domain from website",
|
|
@@ -263,7 +263,7 @@ export default [
|
|
|
263
263
|
"group": "agency-hosting"
|
|
264
264
|
},
|
|
265
265
|
{
|
|
266
|
-
"name": "agency-
|
|
266
|
+
"name": "agency-hosting_files_generate-upload-url",
|
|
267
267
|
"title": "Generate upload URL",
|
|
268
268
|
"annotations": {
|
|
269
269
|
"title": "Generate upload URL",
|
|
@@ -293,7 +293,7 @@ export default [
|
|
|
293
293
|
"group": "agency-hosting"
|
|
294
294
|
},
|
|
295
295
|
{
|
|
296
|
-
"name": "agency-
|
|
296
|
+
"name": "agency-hosting_files_import-website-from-archive",
|
|
297
297
|
"title": "Import website from archive",
|
|
298
298
|
"annotations": {
|
|
299
299
|
"title": "Import website from archive",
|
|
@@ -328,7 +328,7 @@ export default [
|
|
|
328
328
|
"group": "agency-hosting"
|
|
329
329
|
},
|
|
330
330
|
{
|
|
331
|
-
"name": "agency-
|
|
331
|
+
"name": "agency-hosting_metrics_list-plan-order-disk-usage",
|
|
332
332
|
"title": "List Agency Plan order disk usage metrics",
|
|
333
333
|
"annotations": {
|
|
334
334
|
"title": "List Agency Plan order disk usage metrics",
|
|
@@ -368,7 +368,7 @@ export default [
|
|
|
368
368
|
"group": "agency-hosting"
|
|
369
369
|
},
|
|
370
370
|
{
|
|
371
|
-
"name": "agency-
|
|
371
|
+
"name": "agency-hosting_orders_list",
|
|
372
372
|
"title": "List orders",
|
|
373
373
|
"annotations": {
|
|
374
374
|
"title": "List orders",
|
|
@@ -400,7 +400,7 @@ export default [
|
|
|
400
400
|
"group": "agency-hosting"
|
|
401
401
|
},
|
|
402
402
|
{
|
|
403
|
-
"name": "agency-
|
|
403
|
+
"name": "agency-hosting_metrics_list-order-resource-usage",
|
|
404
404
|
"title": "List order resource usage metrics",
|
|
405
405
|
"annotations": {
|
|
406
406
|
"title": "List order resource usage metrics",
|
|
@@ -441,7 +441,7 @@ export default [
|
|
|
441
441
|
"group": "agency-hosting"
|
|
442
442
|
},
|
|
443
443
|
{
|
|
444
|
-
"name": "agency-
|
|
444
|
+
"name": "agency-hosting_php_list-extensions-for-website",
|
|
445
445
|
"title": "List PHP extensions for a website",
|
|
446
446
|
"annotations": {
|
|
447
447
|
"title": "List PHP extensions for a website",
|
|
@@ -471,7 +471,7 @@ export default [
|
|
|
471
471
|
"group": "agency-hosting"
|
|
472
472
|
},
|
|
473
473
|
{
|
|
474
|
-
"name": "agency-
|
|
474
|
+
"name": "agency-hosting_php_replace-website-extensions",
|
|
475
475
|
"title": "Replace website PHP extensions",
|
|
476
476
|
"annotations": {
|
|
477
477
|
"title": "Replace website PHP extensions",
|
|
@@ -511,7 +511,7 @@ export default [
|
|
|
511
511
|
"group": "agency-hosting"
|
|
512
512
|
},
|
|
513
513
|
{
|
|
514
|
-
"name": "agency-
|
|
514
|
+
"name": "agency-hosting_php_list-options-for-website",
|
|
515
515
|
"title": "List PHP options for a website",
|
|
516
516
|
"annotations": {
|
|
517
517
|
"title": "List PHP options for a website",
|
|
@@ -541,7 +541,7 @@ export default [
|
|
|
541
541
|
"group": "agency-hosting"
|
|
542
542
|
},
|
|
543
543
|
{
|
|
544
|
-
"name": "agency-
|
|
544
|
+
"name": "agency-hosting_php_replace-website-options",
|
|
545
545
|
"title": "Replace website PHP options",
|
|
546
546
|
"annotations": {
|
|
547
547
|
"title": "Replace website PHP options",
|
|
@@ -595,7 +595,7 @@ export default [
|
|
|
595
595
|
"group": "agency-hosting"
|
|
596
596
|
},
|
|
597
597
|
{
|
|
598
|
-
"name": "agency-
|
|
598
|
+
"name": "agency-hosting_php_list-versions-for-order",
|
|
599
599
|
"title": "List available PHP versions for an order",
|
|
600
600
|
"annotations": {
|
|
601
601
|
"title": "List available PHP versions for an order",
|
|
@@ -625,7 +625,7 @@ export default [
|
|
|
625
625
|
"group": "agency-hosting"
|
|
626
626
|
},
|
|
627
627
|
{
|
|
628
|
-
"name": "agency-
|
|
628
|
+
"name": "agency-hosting_php_list-versions-for-website",
|
|
629
629
|
"title": "List available PHP versions for a website",
|
|
630
630
|
"annotations": {
|
|
631
631
|
"title": "List available PHP versions for a website",
|
|
@@ -655,7 +655,7 @@ export default [
|
|
|
655
655
|
"group": "agency-hosting"
|
|
656
656
|
},
|
|
657
657
|
{
|
|
658
|
-
"name": "agency-
|
|
658
|
+
"name": "agency-hosting_php_update-website-version",
|
|
659
659
|
"title": "Update website PHP version",
|
|
660
660
|
"annotations": {
|
|
661
661
|
"title": "Update website PHP version",
|
|
@@ -691,7 +691,7 @@ export default [
|
|
|
691
691
|
"group": "agency-hosting"
|
|
692
692
|
},
|
|
693
693
|
{
|
|
694
|
-
"name": "agency-
|
|
694
|
+
"name": "agency-hosting_website-setups_create",
|
|
695
695
|
"title": "Create a new website",
|
|
696
696
|
"annotations": {
|
|
697
697
|
"title": "Create a new website",
|
|
@@ -807,7 +807,7 @@ export default [
|
|
|
807
807
|
"group": "agency-hosting"
|
|
808
808
|
},
|
|
809
809
|
{
|
|
810
|
-
"name": "agency-
|
|
810
|
+
"name": "agency-hosting_website-setups_status",
|
|
811
811
|
"title": "Get website setup status",
|
|
812
812
|
"annotations": {
|
|
813
813
|
"title": "Get website setup status",
|
|
@@ -842,7 +842,7 @@ export default [
|
|
|
842
842
|
"group": "agency-hosting"
|
|
843
843
|
},
|
|
844
844
|
{
|
|
845
|
-
"name": "agency-
|
|
845
|
+
"name": "agency-hosting_ssl_reinstall-website",
|
|
846
846
|
"title": "Reinstall website SSL",
|
|
847
847
|
"annotations": {
|
|
848
848
|
"title": "Reinstall website SSL",
|
|
@@ -877,7 +877,7 @@ export default [
|
|
|
877
877
|
"group": "agency-hosting"
|
|
878
878
|
},
|
|
879
879
|
{
|
|
880
|
-
"name": "agency-
|
|
880
|
+
"name": "agency-hosting_ssl_install-website",
|
|
881
881
|
"title": "Install website SSL",
|
|
882
882
|
"annotations": {
|
|
883
883
|
"title": "Install website SSL",
|
|
@@ -912,7 +912,7 @@ export default [
|
|
|
912
912
|
"group": "agency-hosting"
|
|
913
913
|
},
|
|
914
914
|
{
|
|
915
|
-
"name": "agency-
|
|
915
|
+
"name": "agency-hosting_ssl_website-status",
|
|
916
916
|
"title": "Get website SSL status",
|
|
917
917
|
"annotations": {
|
|
918
918
|
"title": "Get website SSL status",
|
|
@@ -947,7 +947,7 @@ export default [
|
|
|
947
947
|
"group": "agency-hosting"
|
|
948
948
|
},
|
|
949
949
|
{
|
|
950
|
-
"name": "agency-
|
|
950
|
+
"name": "agency-hosting_ssl_uninstall-website",
|
|
951
951
|
"title": "Uninstall website SSL",
|
|
952
952
|
"annotations": {
|
|
953
953
|
"title": "Uninstall website SSL",
|
|
@@ -983,7 +983,7 @@ export default [
|
|
|
983
983
|
"group": "agency-hosting"
|
|
984
984
|
},
|
|
985
985
|
{
|
|
986
|
-
"name": "agency-
|
|
986
|
+
"name": "agency-hosting_websites_build-nodejs-assets",
|
|
987
987
|
"title": "Build website NodeJS assets",
|
|
988
988
|
"annotations": {
|
|
989
989
|
"title": "Build website NodeJS assets",
|
|
@@ -1018,7 +1018,7 @@ export default [
|
|
|
1018
1018
|
"group": "agency-hosting"
|
|
1019
1019
|
},
|
|
1020
1020
|
{
|
|
1021
|
-
"name": "agency-
|
|
1021
|
+
"name": "agency-hosting_cache_clear-website",
|
|
1022
1022
|
"title": "Clear website cache",
|
|
1023
1023
|
"annotations": {
|
|
1024
1024
|
"title": "Clear website cache",
|
|
@@ -1049,7 +1049,7 @@ export default [
|
|
|
1049
1049
|
"group": "agency-hosting"
|
|
1050
1050
|
},
|
|
1051
1051
|
{
|
|
1052
|
-
"name": "agency-
|
|
1052
|
+
"name": "agency-hosting_cron-jobs_list-website",
|
|
1053
1053
|
"title": "List website cron jobs",
|
|
1054
1054
|
"annotations": {
|
|
1055
1055
|
"title": "List website cron jobs",
|
|
@@ -1087,7 +1087,7 @@ export default [
|
|
|
1087
1087
|
"group": "agency-hosting"
|
|
1088
1088
|
},
|
|
1089
1089
|
{
|
|
1090
|
-
"name": "agency-
|
|
1090
|
+
"name": "agency-hosting_cron-jobs_create-website",
|
|
1091
1091
|
"title": "Create website cron job",
|
|
1092
1092
|
"annotations": {
|
|
1093
1093
|
"title": "Create website cron job",
|
|
@@ -1127,7 +1127,7 @@ export default [
|
|
|
1127
1127
|
"group": "agency-hosting"
|
|
1128
1128
|
},
|
|
1129
1129
|
{
|
|
1130
|
-
"name": "agency-
|
|
1130
|
+
"name": "agency-hosting_cron-jobs_delete-website",
|
|
1131
1131
|
"title": "Delete website cron job",
|
|
1132
1132
|
"annotations": {
|
|
1133
1133
|
"title": "Delete website cron job",
|
|
@@ -1163,7 +1163,7 @@ export default [
|
|
|
1163
1163
|
"group": "agency-hosting"
|
|
1164
1164
|
},
|
|
1165
1165
|
{
|
|
1166
|
-
"name": "agency-
|
|
1166
|
+
"name": "agency-hosting_databases_list-website",
|
|
1167
1167
|
"title": "List website databases",
|
|
1168
1168
|
"annotations": {
|
|
1169
1169
|
"title": "List website databases",
|
|
@@ -1201,7 +1201,7 @@ export default [
|
|
|
1201
1201
|
"group": "agency-hosting"
|
|
1202
1202
|
},
|
|
1203
1203
|
{
|
|
1204
|
-
"name": "agency-
|
|
1204
|
+
"name": "agency-hosting_databases_create-website",
|
|
1205
1205
|
"title": "Create website database",
|
|
1206
1206
|
"annotations": {
|
|
1207
1207
|
"title": "Create website database",
|
|
@@ -1246,7 +1246,7 @@ export default [
|
|
|
1246
1246
|
"group": "agency-hosting"
|
|
1247
1247
|
},
|
|
1248
1248
|
{
|
|
1249
|
-
"name": "agency-
|
|
1249
|
+
"name": "agency-hosting_databases_delete-website",
|
|
1250
1250
|
"title": "Delete website database",
|
|
1251
1251
|
"annotations": {
|
|
1252
1252
|
"title": "Delete website database",
|
|
@@ -1282,7 +1282,7 @@ export default [
|
|
|
1282
1282
|
"group": "agency-hosting"
|
|
1283
1283
|
},
|
|
1284
1284
|
{
|
|
1285
|
-
"name": "agency-
|
|
1285
|
+
"name": "agency-hosting_databases_create-website-user",
|
|
1286
1286
|
"title": "Create website database user",
|
|
1287
1287
|
"annotations": {
|
|
1288
1288
|
"title": "Create website database user",
|
|
@@ -1331,7 +1331,7 @@ export default [
|
|
|
1331
1331
|
"group": "agency-hosting"
|
|
1332
1332
|
},
|
|
1333
1333
|
{
|
|
1334
|
-
"name": "agency-
|
|
1334
|
+
"name": "agency-hosting_databases_delete-website-user",
|
|
1335
1335
|
"title": "Delete website database user",
|
|
1336
1336
|
"annotations": {
|
|
1337
1337
|
"title": "Delete website database user",
|
|
@@ -1372,7 +1372,7 @@ export default [
|
|
|
1372
1372
|
"group": "agency-hosting"
|
|
1373
1373
|
},
|
|
1374
1374
|
{
|
|
1375
|
-
"name": "agency-
|
|
1375
|
+
"name": "agency-hosting_websites_get",
|
|
1376
1376
|
"title": "Get website details",
|
|
1377
1377
|
"annotations": {
|
|
1378
1378
|
"title": "Get website details",
|
|
@@ -1402,7 +1402,7 @@ export default [
|
|
|
1402
1402
|
"group": "agency-hosting"
|
|
1403
1403
|
},
|
|
1404
1404
|
{
|
|
1405
|
-
"name": "agency-
|
|
1405
|
+
"name": "agency-hosting_websites_delete",
|
|
1406
1406
|
"title": "Delete website",
|
|
1407
1407
|
"annotations": {
|
|
1408
1408
|
"title": "Delete website",
|
|
@@ -1433,7 +1433,7 @@ export default [
|
|
|
1433
1433
|
"group": "agency-hosting"
|
|
1434
1434
|
},
|
|
1435
1435
|
{
|
|
1436
|
-
"name": "agency-
|
|
1436
|
+
"name": "agency-hosting_websites_list-plan",
|
|
1437
1437
|
"title": "List Agency Plan websites",
|
|
1438
1438
|
"annotations": {
|
|
1439
1439
|
"title": "List Agency Plan websites",
|
|
@@ -1507,7 +1507,7 @@ export default [
|
|
|
1507
1507
|
"group": "agency-hosting"
|
|
1508
1508
|
},
|
|
1509
1509
|
{
|
|
1510
|
-
"name": "agency-
|
|
1510
|
+
"name": "agency-hosting_websites_list-processes",
|
|
1511
1511
|
"title": "List website processes",
|
|
1512
1512
|
"annotations": {
|
|
1513
1513
|
"title": "List website processes",
|
|
@@ -1537,7 +1537,7 @@ export default [
|
|
|
1537
1537
|
"group": "agency-hosting"
|
|
1538
1538
|
},
|
|
1539
1539
|
{
|
|
1540
|
-
"name": "agency-
|
|
1540
|
+
"name": "agency-hosting_wordpress_change-version",
|
|
1541
1541
|
"title": "Change WordPress version",
|
|
1542
1542
|
"annotations": {
|
|
1543
1543
|
"title": "Change WordPress version",
|
|
@@ -1573,7 +1573,7 @@ export default [
|
|
|
1573
1573
|
"group": "agency-hosting"
|
|
1574
1574
|
},
|
|
1575
1575
|
{
|
|
1576
|
-
"name": "agency-
|
|
1576
|
+
"name": "agency-hosting_wordpress_settings",
|
|
1577
1577
|
"title": "Get WordPress settings",
|
|
1578
1578
|
"annotations": {
|
|
1579
1579
|
"title": "Get WordPress settings",
|
|
@@ -1603,7 +1603,7 @@ export default [
|
|
|
1603
1603
|
"group": "agency-hosting"
|
|
1604
1604
|
},
|
|
1605
1605
|
{
|
|
1606
|
-
"name": "agency-
|
|
1606
|
+
"name": "agency-hosting_wordpress_list-versions",
|
|
1607
1607
|
"title": "List available WordPress versions",
|
|
1608
1608
|
"annotations": {
|
|
1609
1609
|
"title": "List available WordPress versions",
|