hostinger-api-mcp 3.15.1 → 3.16.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 CHANGED
@@ -4,6 +4,20 @@ Generated at release time from the diff between the previous and current
4
4
  build. Tool changes are listed individually; everything else is summarised
5
5
  by area.
6
6
 
7
+ ## v3.16.0 — 2026-10-27
8
+
9
+ ### Also in this release
10
+
11
+ - Bundled agent skills: `skills/headless/steps/02-refine/SKILL.md`, `skills/headless/steps/05-design/SKILL.md`, `skills/headless/steps/06-frontend/SKILL.md`
12
+ - Other files: `src/core/skills.js`, `src/core/skills.ts`
13
+
14
+ ## v3.15.2 — 2026-10-27
15
+
16
+ ### Also in this release
17
+
18
+ - Bundled agent skills: `skills/headless/steps/04-content-model/SKILL.md`
19
+ - Other files: `src/core/skills.js`, `src/core/skills.ts`
20
+
7
21
  ## v3.15.1 — 2026-10-27
8
22
 
9
23
  ### Also in this release
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hostinger-api-mcp",
3
- "version": "3.15.1",
3
+ "version": "3.16.0",
4
4
  "description": "Hostinger API — manage domains, DNS, hosting, VPS, billing and more from Gemini CLI.",
5
5
  "mcpServers": {
6
6
  "hostinger": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hostinger-api-mcp",
3
- "version": "3.15.1",
3
+ "version": "3.16.0",
4
4
  "mcpName": "io.github.hostinger/hostinger-api-mcp",
5
5
  "description": "MCP server for Hostinger API",
6
6
  "repository": {
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/hostinger/api-mcp-server",
7
7
  "source": "github"
8
8
  },
9
- "version": "3.15.1",
9
+ "version": "3.16.0",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "@hostinger/mcp",
14
- "version": "3.15.1",
14
+ "version": "3.16.0",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },
@@ -150,10 +150,15 @@ app's look:
150
150
  existing project in the current folder as the source**, collaborates on design/code at the user's
151
151
  direction, and wires it to the provisioned backend. There is **no agent-generated design** — the
152
152
  design step defers to the user (see the Build mode box at the top of the design step), and the
153
- frontend step builds on their project rather than scaffolding a new one. Write "Keep the look we
154
- have: the app in this folder" in **Design direction**.
155
- - **Agent designs and builds it — a new design** — the design step proposes directions and the
156
- frontend step scaffolds and implements them.
153
+ frontend step builds on their project rather than scaffolding a new one. Build mode is **Bring your
154
+ own frontend**; write "Keep the look we have: the app in this folder" in **Design direction**.
155
+ - **Agent rebuilds it — keep my app's look** — the design step reads the look (colours, fonts, logo)
156
+ from their project, and the frontend step starts from the project's source, keeping its screens and
157
+ features, and rebuilds its UI to that look. Build mode is **Agent designs and builds**; write "Keep
158
+ the look we have: the app in this folder" in **Design direction**.
159
+ - **Agent rebuilds it — a new design** — the design step proposes directions and the frontend step
160
+ rebuilds the app from them. Build mode is **Agent designs and builds**; take **Design direction**
161
+ from Round 3.
157
162
 
158
163
  A skipped tool result is not a pick: re-ask in plain text, and use the default only when the user
159
164
  says so (see *When you ask the user* in the top-level `SKILL.md`).
@@ -162,9 +167,10 @@ Otherwise don't ask: Build mode is **Agent designs and builds**. When the user s
162
167
  own code elsewhere, ask for its path, inspect it as in Step 2, and from then on treat it as a project
163
168
  found in the folder.
164
169
 
165
- Record the answer as the brief's **Build mode**. This is the one frontend/technology question you *do*
166
- put to the user; everything else about the stack (framework, SSR/SSG) is still inferred. The deliverable
167
- is the same either way — a working site on the backend; only *who drives the frontend* changes.
170
+ Record the Build mode the chosen option names in the brief's **Build mode**, and its look in **Design
171
+ direction**. This is the one frontend/technology question you *do* put to the user; everything else
172
+ about the stack (framework, SSR/SSG) is still inferred. The deliverable is the same either way — a working
173
+ site on the backend; only *who drives the frontend* changes.
168
174
 
169
175
  ## Step 4 — Decide the backend (your call, from the brief — not a question)
170
176
 
@@ -297,7 +303,8 @@ the app reads — names only, never values>
297
303
  ## Build mode
298
304
  **<Bring your own frontend | Agent designs and builds>** — <one line>. <When "Bring your own frontend":
299
305
  how they want to drive design/code; the project's path is under **Existing project**. When "Agent designs and builds": leave the design + frontend steps to run as
300
- normal.> The design step and the frontend step both read this: **Bring your own frontend** → design
306
+ normal; with **Existing project** filled, the frontend starts from that app's source and rebuilds its UI
307
+ to design.md.> The design step and the frontend step both read this: **Bring your own frontend** → design
301
308
  defers to the user and frontend builds on their project; **Agent designs and builds** → both run as normal.
302
309
 
303
310
  ## Rendering
@@ -96,7 +96,7 @@ not an answer, see *When you ask the user* in the top-level `SKILL.md`):
96
96
  | Option | Tool | Backends | Needs the live instance? |
97
97
  |---|---|---|---|
98
98
  | **A — Hostinger AI image generation** *(default for WordPress / WooCommerce)* | `wordpress_ai-content_generate-images` | WordPress, WordPress + WooCommerce | **yes** — runs at the instance barrier |
99
- | **B — Unsplash stock photos** *(default for Ecommerce / Webapp; the fallback everywhere)* | Unsplash API / web search | any | no — pure prepare work |
99
+ | **B — Unsplash stock photos** *(default for Ecommerce / Webapp; the fallback everywhere)* | Unsplash API, or web search + web fetch | any | no — pure prepare work |
100
100
 
101
101
  > **Do not silently fall back to stock on a WordPress site.** On WordPress / WooCommerce the default is
102
102
  > **Hostinger AI (Option A)** — on-brand, generated from `design.md`. Using Unsplash on a WordPress build
@@ -105,8 +105,9 @@ not an answer, see *When you ask the user* in the top-level `SKILL.md`):
105
105
  > shortcut: the async start → poll → upload-before-expiry flow (Option A below) is the expected work, not
106
106
  > an optional extra. If you are tempted to skip it "for speed", stop and offer the user the choice instead.
107
107
 
108
- If you can generate images yourself (some agents can), that's a third path: put the files in `media/`
109
- and record alt text — no tool needed. **Record alt text for every image whichever source you use.**
108
+ If you can generate images yourself (some agents can), offer that as a third option; only if the user
109
+ picks it, put the files in `media/` (no tool needed). **Record alt text for every image whichever source
110
+ you use.**
110
111
 
111
112
  **During the prepare wait, write an image brief for each image** into `content-model.md` no matter the
112
113
  option (subject, `image_type`, aspect, and the alt text you expect). Option B can also *fetch* the
@@ -171,14 +172,21 @@ and the push phase uploads them.
171
172
  - Without a key, use web search limited to `unsplash.com` (e.g. "unsplash photo Lisbon tram") and
172
173
  take the photo id from the result URL: the last segment of `unsplash.com/photos/<slug>-<id>`, or
173
174
  the whole segment for `unsplash.com/photos/<id>`.
174
- - Don't call `unsplash.com/napi/…`. It sits behind a bot challenge and returns 401.
175
- 2. **Resolve a direct file URL.** `GET https://unsplash.com/photos/<id>/download?force=true` (don't
176
- follow the redirect) answers `302` with `Location: https://images.unsplash.com/photo-<…>?…`. The
177
- `dl=` parameter in it also carries the photographer's name. Drop the query string and request a
178
- web size: `https://images.unsplash.com/photo-<…>?w=1600&q=80&fm=jpg&fit=max`. The upload ability
179
- needs this direct file URL, which returns 200 with `image/jpeg`. A photo *page* URL won't work.
180
- 3. **Look before you keep it.** Download a small preview (`?w=500`) and view it. Search snippets
181
- only show captions, and a photo often isn't quite what its title says. Reject anything off-topic.
175
+ 2. **Resolve a direct file URL.** With the API, the result's `urls.raw` is the file and `user.name`
176
+ the photographer; for each photo you keep, also `GET` its `links.download_location` (same header),
177
+ as the API terms require. Without a key, open the photo page (`https://unsplash.com/photos/<…>`)
178
+ with your **web-fetch tool** and ask it for the main photo's `images.unsplash.com/photo-<…>` URL,
179
+ quoted exactly, and the photographer's name. Either way, drop the query string and request a web
180
+ size: `https://images.unsplash.com/photo-<…>?w=1600&q=80&fm=jpg&fit=max`. Check that it returns
181
+ 200 with `image/jpeg`: the upload ability needs this direct file URL, not the photo page.
182
+ - Every other `unsplash.com` request (curl on the page, `/photos/<id>/download`, `/napi/…`,
183
+ `/oembed`) hits a bot challenge: a `307` to `/.within.website` (Anubis) or a 401. If your fetch
184
+ tool gets the challenge page too, stop: no user-agent spoofing or other workarounds. On a
185
+ WordPress backend where Option A hasn't already failed, offer it; otherwise ask the user for an
186
+ `UNSPLASH_ACCESS_KEY` or record the gap (step 5).
187
+ 3. **Look before you keep it.** Download a small preview (`?w=500`) and view it. Search snippets and
188
+ fetch summaries only describe the page, and can hand you a related photo's thumbnail instead of
189
+ the main one; a photo also often isn't quite what its title says. Reject anything off-topic.
182
190
  If nothing fits exactly, take the closest real photo and note the gap rather than mislabel it.
183
191
  4. **Write alt text from what the photo shows**, not from the article's image brief. For example,
184
192
  use "Shopfronts and parked scooters on a Hanoi street" even if the article is about rain.
@@ -191,6 +199,9 @@ and the push phase uploads them.
191
199
  Image file: <site>-<subject>.jpg
192
200
  ```
193
201
 
202
+ If you can't get a real photo, write `Image gap: <reason>` in place of these lines and tell the
203
+ user. Never substitute drawn or generated images without saying so.
204
+
194
205
  Unsplash photos are free to use under the Unsplash License. Still credit the photographer: the push
195
206
  phase stores "Photo by <Photographer> on Unsplash" as the image caption.
196
207
 
@@ -17,10 +17,12 @@ user gave. **Out:** `~/.hostinger/<domain>/design.md` and the logo files in
17
17
  > Read `brief.md` → **Build mode** first. When it is **Bring your own frontend**, the user drives the
18
18
  > design — **do not generate three directions or write a prescriptive `design.md` over their project.**
19
19
  > The frontend already exists (or the user vibe-codes it with you); your job is to follow *their*
20
- > direction, not impose one. Skip Steps 1–7 below: either write nothing, or capture only what the user
21
- > explicitly asks for (a short note of their stated colours/vibe) so the frontend step has it. The logo
22
- > and token work here apply only when **Build mode is "Agent designs and builds"**. (This mirrors the
23
- > frontend step's existing "existing app the user brought" handling, now generalised to any backend.)
20
+ > direction, not impose one. Skip Steps 1–7 below, *Keep the current look* included, even when
21
+ > **Design direction** keeps the look of the app in this folder: their own code already carries it.
22
+ > Either write nothing, or capture only what the user explicitly asks for (a short note of their
23
+ > stated colours/vibe) so the frontend step has it, then do Step 7's `state.json` update so the flow
24
+ > moves on to frontend. The logo and token work here apply only when **Build mode is "Agent designs
25
+ > and builds"**.
24
26
 
25
27
  This is **prepare work**: it runs while provision settles (see *Background provision & the instance
26
28
  barrier* in the top-level `SKILL.md`). Nothing here calls the Hostinger connector or the backend.
@@ -73,7 +75,19 @@ Read `brief.md`, `state.json`, and `content-model.md` if it exists.
73
75
  logo file as it is (the header `<img>` or inline `<svg>`, plus its favicon if it has one) and save
74
76
  it unchanged in `brand/`. Screenshots or a brand guide: read the colours and lettering from them;
75
77
  a logo seen only in a screenshot counts as no logo file, so list "logo file needed" under gaps in
76
- the final report. Files or exact colours and fonts the owner supplied win over anything you read.
78
+ the final report. The app in this folder (the path under `brief.md` → **Existing project**):
79
+ read its source; no build or browser needed.
80
+ - *Colours:* the theme tokens (Tailwind v4 `@theme`, v3 `tailwind.config.*` `theme`/`theme.extend`,
81
+ `:root` custom properties), ranked by how often the code uses them (class names, `var()`), with
82
+ the page background and body text taken from the root layout or `body`.
83
+ - *Fonts:* theme font tokens, `@fontsource` imports or dependencies, Google Fonts `<link>` or
84
+ `@import`, and the `font-family` on `body` and headings.
85
+ - *Logo:* files named `logo*` in `public/`, `static/`, `src/assets/` or `assets/`;
86
+ `favicon*`, `icon*` or `apple-icon*` in `public/`, `static/`, `app/` or `src/app/`; or the icon
87
+ declared by `<link rel="icon">` in `index.html` or the root layout's `metadata.icons`. Copy them
88
+ unchanged into `brand/`.
89
+
90
+ Files or exact colours and fonts the owner supplied win over anything you read.
77
91
  2. **Confirm in one question.** Describe the kept look in two plain sentences and ask: *keep it, or
78
92
  change something?* "Keep the look we have" still gets this question; skip it only when the brief
79
93
  says to change nothing at all ("keep it exactly as it is"). A skipped tool result is not Keep; see
@@ -28,7 +28,7 @@ workspace `~/.hostinger/<domain>/src/`.
28
28
  > API, or the MySQL database recorded in `site.json → database`). It comes in two shapes, decided back in
29
29
  > **refine**:
30
30
  >
31
- > - **An existing app the user brought to deploy** (refine routes "deploy my app" here). **Use their
31
+ > - **An existing app under Build mode "Bring your own frontend"** (refine routes "deploy my app" here). **Use their
32
32
  > project as the source** — copy/point `~/.hostinger/<domain>/src/` at it and keep its own framework and
33
33
  > UI. **Do not scaffold a new project, and do not re-implement `design.md` over it** (so **the design
34
34
  > step does not apply** to an app that brings its own UI). Your job is only to make it deployable: set
@@ -36,7 +36,10 @@ workspace `~/.hostinger/<domain>/src/`.
36
36
  > Step 2 design pass**, and ignore the `content-model.md` requirement in Step 3.
37
37
  > - **A new app built from the brief.** Scaffold and build it from `brief.md` (and `design.md` if the
38
38
  > design step produced one — design *does* run for a from-scratch app). Its data is owned by the app, so
39
- > there is still **no `content-model.md`** to bind against.
39
+ > there is still **no `content-model.md`** to bind against. An existing app under **Build mode "Agent
40
+ > designs and builds"** takes this shape too, but starts from its source: copy the project at
41
+ > `brief.md` → **Existing project** into `~/.hostinger/<domain>/src/`, keep its framework, screens,
42
+ > features and data wiring, and rebuild its UI to `design.md` instead of scaffolding a new project.
40
43
  >
41
44
  > Framework choice (Step 1), the build, and hand-off (Step 4) apply to both. The per-backend bullets in
42
45
  > Step 3 are **WordPress / WooCommerce / Ecommerce only** — for a webapp follow the Webapp bullet there.
@@ -50,7 +53,8 @@ it, and the backend constraint:
50
53
  Next.js is the default, not a requirement (Express, Nuxt, SvelteKit, etc. are all fine).
51
54
  - **WordPress + WooCommerce → SSR required** (same reason — cart/checkout need per-request rendering).
52
55
  - **WordPress → SSG (Astro)** when the brief says SSG, otherwise **SSR (Next.js default)**.
53
- - **Webapp → the app's own stack.** An **existing app** keeps its current framework (don't impose one); a
56
+ - **Webapp → the app's own stack.** An **existing app** keeps its current framework (don't impose one), including
57
+ one rebuilt under **Agent designs and builds**; a
54
58
  **new app** uses whatever fits the brief (SSR or SPA). Either way it deploys as a Node.js app (Step 8) —
55
59
  an SSR app runs a server, a SPA builds to static output.
56
60
  - Map rendering → framework: **`ssr` → Next.js**, **`ssg` → Astro** — unless the brief/prompt explicitly