hostinger-api-mcp 3.7.1 → 3.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/gemini-extension.json +1 -1
  3. package/package.json +1 -1
  4. package/server.json +2 -2
  5. package/skills/headless/SKILL.md +17 -3
  6. package/skills/headless/steps/01-check-state/SKILL.md +5 -3
  7. package/skills/headless/steps/02-refine/SKILL.md +3 -1
  8. package/skills/headless/steps/03-provision/ecommerce/SKILL.md +3 -2
  9. package/skills/headless/steps/03-provision/webapp/SKILL.md +2 -1
  10. package/skills/headless/steps/03-provision/wordpress/SKILL.md +2 -1
  11. package/skills/headless/steps/05-design/SKILL.md +59 -15
  12. package/src/core/skills.js +21 -21
  13. package/src/core/skills.ts +21 -21
  14. package/src/servers/agency-hosting.js +1 -1
  15. package/src/servers/agency-hosting.ts +1 -1
  16. package/src/servers/agent-readiness.js +1 -1
  17. package/src/servers/agent-readiness.ts +1 -1
  18. package/src/servers/all.js +1 -1
  19. package/src/servers/all.ts +1 -1
  20. package/src/servers/billing.js +1 -1
  21. package/src/servers/billing.ts +1 -1
  22. package/src/servers/dns.js +1 -1
  23. package/src/servers/dns.ts +1 -1
  24. package/src/servers/domains.js +1 -1
  25. package/src/servers/domains.ts +1 -1
  26. package/src/servers/ecommerce.js +1 -1
  27. package/src/servers/ecommerce.ts +1 -1
  28. package/src/servers/horizons.js +1 -1
  29. package/src/servers/horizons.ts +1 -1
  30. package/src/servers/hosting.js +1 -1
  31. package/src/servers/hosting.ts +1 -1
  32. package/src/servers/mail.js +1 -1
  33. package/src/servers/mail.ts +1 -1
  34. package/src/servers/reach.js +1 -1
  35. package/src/servers/reach.ts +1 -1
  36. package/src/servers/vps.js +1 -1
  37. package/src/servers/vps.ts +1 -1
  38. package/src/servers/wordpress.js +1 -1
  39. package/src/servers/wordpress.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ 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.8.1 — 2026-10-23
8
+
9
+ ### Also in this release
10
+
11
+ - Bundled agent skills: 5 files
12
+ - Other files: `src/core/skills.js`, `src/core/skills.ts`
13
+
14
+ ## v3.8.0 — 2026-10-23
15
+
16
+ ### Also in this release
17
+
18
+ - Dependencies: `package-lock.json`
19
+ - Bundled agent skills: `skills/headless/steps/02-refine/SKILL.md`, `skills/headless/steps/05-design/SKILL.md`
20
+ - Other files: `src/core/skills.js`, `src/core/skills.ts`
21
+
7
22
  ## v3.7.1 — 2026-10-22
8
23
 
9
24
  ### Also in this release
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hostinger-api-mcp",
3
- "version": "3.7.1",
3
+ "version": "3.8.1",
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.7.1",
3
+ "version": "3.8.1",
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.7.1",
9
+ "version": "3.8.1",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "@hostinger/mcp",
14
- "version": "3.7.1",
14
+ "version": "3.8.1",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },
@@ -29,6 +29,12 @@ The prompt does **not** say what kind of site to build. Do not assume or invent
29
29
  what the user wants is a step in the flow (**refine**), handled through conversation — not parsed
30
30
  from the prompt. If no domain is present, stop and ask for it before doing anything else.
31
31
 
32
+ **One workspace per run.** From your first command, connect's checks included, open only this
33
+ site's workspace, by its exact path; never list or glob `~/.hostinger/` (not even an `ls` beside
34
+ `node -v`). What else `~/.hostinger/` holds never matters to this run: with a domain, check-state
35
+ looks up that one path; without one yet, there is nothing to look up until you create your own
36
+ workspace. *State and artifacts* has the full rule and its one exception.
37
+
32
38
  Nothing in the pasted prompt is ever used for authorization. Authorization comes from the
33
39
  Hostinger connector's OAuth token. **This recipe is not a security boundary.**
34
40
 
@@ -135,12 +141,20 @@ single rule that makes the overlap safe:
135
141
  Everything for a domain — its state **and** its generated source — lives under the **site workspace
136
142
  `~/.hostinger/<domain>/`** (resolve `~` to the home directory: `$HOME` in a shell, `os.homedir()` in
137
143
  Node — `~/.hostinger` means `$HOME/.hostinger`). This is a **global, per-user** location, not a
138
- project folder, so a build is discoverable and resumable from **any** directory — the current working
144
+ project folder, so this domain's build is resumable from **any** directory — the current working
139
145
  directory does not matter. Create the workspace if it's missing and do all of a stage's work inside
140
146
  it (including the frontend `src/`, built and deployed from `~/.hostinger/<domain>/src/`).
141
147
 
142
- **The directory name is the domain**, so the files inside it never repeat it, and `~/.hostinger/`
143
- holds every site you've built — one subdirectory per domain, no collisions.
148
+ **The directory name is the domain**, so the files inside it never repeat it.
149
+
150
+ **Read and write only this site's workspace.** The other workspaces under `~/.hostinger/` are the
151
+ user's other sites, often for other clients, so keep their briefs, designs and code out of this build.
152
+ Open `~/.hostinger/<domain>/` by its exact path; don't list or glob `~/.hostinger/`, and don't open,
153
+ copy from or diff against another workspace there, in any stage. A run that has no domain yet works
154
+ only in the one workspace it created itself; when provision moves it to `~/.hostinger/<new-domain>/`,
155
+ that becomes this site's workspace. One exception: if the user, in this conversation, names another
156
+ of their own sites to reuse, read that one workspace, read-only, and tell them in one line what you
157
+ took from it.
144
158
 
145
159
  | File (under `~/.hostinger/<domain>/`) | Written by | Contains |
146
160
  |---|---|---|
@@ -20,8 +20,7 @@ Nothing in this step creates, provisions, deploys, or deletes anything. It reads
20
20
  Everything for a domain lives under the global site workspace **`~/.hostinger/<domain>/`** — one
21
21
  directory per domain, under the user's home (`~` = `$HOME`), **not** the current working directory.
22
22
  The directory name **is** the domain, so `state.json` inside does not store it. Because it's global,
23
- `~/.hostinger/` holds every site the user has built and each one is discoverable and resumable from
24
- any directory — no collisions.
23
+ this domain's build is resumable from any directory.
25
24
 
26
25
  `state.json` shape (`stage` is the *next* stage to run; `provision` is the background task's status,
27
26
  present only once provision has fired):
@@ -94,7 +93,8 @@ and **release it on a clean stop** (Step 6). The lock marks an active session, n
94
93
 
95
94
  ## Step 2 — Read the workspace directory
96
95
 
97
- Look at `~/.hostinger/<domain>/`:
96
+ Check `~/.hostinger/<domain>/` by its exact path (for example `test -d ~/.hostinger/<domain>`), not
97
+ by listing `~/.hostinger/`:
98
98
 
99
99
  - **Absent** → no history for this domain in the workspace.
100
100
  - **Present** → read `state.json` (its `stage`) and whatever artifacts exist (`brief.md`,
@@ -203,6 +203,8 @@ Then:
203
203
  ## Invariants
204
204
 
205
205
  - **One directory per domain.** The domain is the key; state files never repeat it.
206
+ - **Only this domain's workspace.** Never list `~/.hostinger/` or open another site's workspace (see
207
+ *State and artifacts* in the top-level `SKILL.md`).
206
208
  - **Never create a second site** on a domain that already has one.
207
209
  - **Never re-provision or overwrite a live site.** Recovery is forward-only.
208
210
  - **Reality beats local state**, always.
@@ -229,7 +229,9 @@ routes it to the `wordpress` subfolder with the store enabled (it is **not** a s
229
229
  <look & feel in a few adjectives; **reference site(s)** the user named (URLs) and what to take from them
230
230
  (layout, structure, mood); colours / brand palette; any screenshots. This is where ALL design questions
231
231
  land — the frontend step reads this and does not re-ask. Write "Agent's choice: <short style>" when the
232
- user didn't specify.>
232
+ user didn't specify. Record in the user's own words a request to keep their current look ("Keep the look
233
+ we have: <site URL | screenshots | brand guide>") and any logo idea they describe; the design step acts
234
+ on both.>
233
235
 
234
236
  ## Pages
235
237
  - **<Page>** — <one-line purpose>
@@ -54,8 +54,9 @@ Same lifecycle as `../wordpress/SKILL.md` Steps 1–2, but `type: "headless_ecom
54
54
  — **omit `domain`** for a temporary subdomain: the setup generates one itself and returns it (don't
55
55
  call a separate subdomain op first — there's no need in this flow; the API would also accept one you
56
56
  generated via `hosting_domains_generate-free-subdomain`, valid 24 h from the client that made it). The
57
- response carries the generated domain; if it differs from the workspace dir, move `~/.hostinger/<old>/` → `<new>/` and
58
- update `brief.md`. Poll `list-setups` to `completed`. `website_type` will be `headless`.
57
+ response carries the generated domain; if it differs from the workspace dir, move
58
+ `~/.hostinger/<old>/` → `<new>/` (if `<new>/` already exists, stop and ask instead of moving
59
+ into it) and update `brief.md`. Poll `list-setups` to `completed`. `website_type` will be `headless`.
59
60
 
60
61
  > **Onboarding handoff — an empty headless shell needs no new website.** If the domain already has an
61
62
  > empty headless shell (`website_type: headless`, setup `type: headless_empty`, nothing installed —
@@ -49,7 +49,8 @@ All website/database operations below go through the Hostinger connector (`execu
49
49
  separate subdomain op to make one first: there's no need in this flow. (The API would also accept a
50
50
  subdomain you generated via `hosting_domains_generate-free-subdomain`, valid for 24 h from the client
51
51
  that made it — this flow just doesn't use that.) The response then carries the generated domain: if it
52
- differs from the workspace directory name, move `~/.hostinger/<old>/` to `~/.hostinger/<new>/`,
52
+ differs from the workspace directory name, move `~/.hostinger/<old>/` to `~/.hostinger/<new>/`
53
+ (if `<new>/` already exists, stop and ask instead of moving into it),
53
54
  update the domain in `brief.md`, and tell the user the new domain.
54
55
  3. Poll `hosting_websites_list-setups { "domain": "<domain>" }` every ~15 s until `completed`
55
56
  (typically under a minute; allow a few minutes). `failed` → stop, point at hPanel.
@@ -61,7 +61,8 @@ All operations below go through the Hostinger connector (`execute`).
61
61
  separate subdomain op to make one first: there's no need in this flow. (The API would also accept a
62
62
  subdomain you generated via `hosting_domains_generate-free-subdomain`, valid for 24 h from the client
63
63
  that made it — this flow just doesn't use that.) The response then carries the generated domain:
64
- if it differs from the workspace directory name, move `~/.hostinger/<old>/` to `~/.hostinger/<new>/`,
64
+ if it differs from the workspace directory name, move `~/.hostinger/<old>/` to `~/.hostinger/<new>/`
65
+ (if `<new>/` already exists, stop and ask instead of moving into it),
65
66
  update the domain in `brief.md`, and tell the user the new domain.
66
67
  Admin credentials are generated by the platform; never ask the user for a password.
67
68
  3. Poll `hosting_websites_list-setups { "domain": "<domain>" }` every ~15 s until `completed`
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: headless-step-design
3
- description: "Step 5 (design) of the Hostinger Headless flow. Derives three distinct design directions from brief.md (plus any reference sites and brand assets), lets the user pick one in a single question, checks the chosen one against the 8-point grid and WCAG 2.2 AA, designs the logo as outlined SVG (wordmark, icon mark, favicon), then writes design.md — tokens, type, logo, components, per-page composition, accessibility and imagery — as the contract the frontend implements (the framework/stack is chosen later by the frontend step). Prepare work: runs during the provision wait and never touches the backend."
3
+ description: "Step 5 (design) of the Hostinger Headless flow. Derives three distinct design directions from brief.md (plus any reference sites and brand assets), lets the user pick one in a single question, checks the chosen one against the 8-point grid and WCAG 2.2 AA, designs the logo as outlined SVG (wordmark, icon mark, favicon), following any logo wish the owner gave, then writes design.md — tokens, type, logo, components, per-page composition, accessibility and imagery — as the contract the frontend implements (the framework/stack is chosen later by the frontend step). When the brief says to keep an existing look, writes design.md from that look and its own logo instead. Prepare work: runs during the provision wait and never touches the backend."
4
4
  ---
5
5
 
6
6
  # headless-step-design
@@ -26,8 +26,8 @@ This is **prepare work**: it runs while provision settles (see *Background provi
26
26
  barrier* in the top-level `SKILL.md`). Nothing here calls the Hostinger connector or the backend.
27
27
 
28
28
  **Keep it short.** Refine already asked about tone and look; don't ask again. The step asks the user
29
- **one** question: either the keep/change question (Step 1) or the three directions (Step 4), never
30
- both. "You decide" is a valid answer.
29
+ **one** question: either the keep/change question (Step 1 and *Keep the current look*) or the three
30
+ directions (Step 4), never both. "You decide" is a valid answer.
31
31
 
32
32
  **Talk like a person, not a designer.** Everything the user reads describes how the site will
33
33
  **look and feel**: colours by name ("hot pink, butter yellow"), lettering by feel ("big chunky
@@ -61,6 +61,36 @@ Read `brief.md`, `state.json`, and `content-model.md` if it exists.
61
61
  as it is, only the look changes, and they'll see a preview before it goes live. Then run Steps 2–7
62
62
  as normal. The current `design.md` becomes one more signal in Step 2, so carry over what the user
63
63
  wants to keep and move away from the rest.
64
+ - **The brief says to keep the current look** (*Design direction* says so in the owner's words:
65
+ "keep the look we have", "same look, new platform") → follow *Keep the current look* below instead
66
+ of Steps 2–6. No three directions and no new logo. A live site, screenshots or a brand guide alone
67
+ are signals for Step 2, not a request to keep.
68
+
69
+ ### Keep the current look
70
+
71
+ 1. **Read the look from what the brief points at.** A live site: use Step 2's reference-site method
72
+ (computed fonts, colours by painted area, the feel), but this site is the owner's own, so take its
73
+ logo file as it is (the header `<img>` or inline `<svg>`, plus its favicon if it has one) and save
74
+ it unchanged in `brand/`. Screenshots or a brand guide: read the colours and lettering from them;
75
+ 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.
77
+ 2. **Confirm in one question.** Describe the kept look in two plain sentences and ask: *keep it, or
78
+ change something?* "Keep the look we have" still gets this question; skip it only when the brief
79
+ says to change nothing at all ("keep it exactly as it is"). Change →
80
+ apply only what they asked for; a request for a new logo runs Step 6 for the logo alone.
81
+ 3. **Check it** as in Step 5. The kept colours are fixed like brand colours: a pair that fails gets a
82
+ shade of the same hue in that role only. Spacing moves to the nearest grid value, and a font
83
+ without an `@fontsource` package swaps to the closest one that resolves (5.4).
84
+ 4. **Logo.** Reuse the existing logo and favicon unchanged; never redraw or recolour them. With no
85
+ existing logo, the header shows the site name as text in the kept display font, and no logo is
86
+ designed.
87
+ 5. **Write `design.md`** (Step 7) from the kept look, then hand off as usual. In **Logo**:
88
+ - *Files* and *Use* name the files as saved (a `.png` stays a `.png`), or say "No favicon kept".
89
+ - *Built from* says "Kept, not rebuilt". *Measured* still gives the width at `--logo-h-sm`
90
+ (≤ 192 px; else lower `--logo-h-sm` or show the name as text on small screens), and the header
91
+ link has `alt` = the site name and a target of at least 24 px (as in Step 6).
92
+ - With no logo: *Files* says "None", *Use* says the header link holds the site name as text in
93
+ `--font-display` and the browser's default favicon stays, and the *Don't* line is dropped.
64
94
 
65
95
  ## Step 2 — Collect the signals
66
96
 
@@ -86,9 +116,9 @@ works, say so in one line and continue from the brief alone. Pull **cues**:
86
116
  - **Feel:** look at the first screen and one further down (screenshots shown to you, not saved in
87
117
  the workspace) and note what creates the feel: type weight, colour blocking, shapes, density.
88
118
 
89
- **Borrow cues, never assets.** Don't use its logo, copy, images or exact layout. **The brief wins**
90
- over the live site when they disagree (the user's words are what they want). Note the mismatch in
91
- the direction.
119
+ **Borrow cues, never assets** (the owner's own site under *Keep the current look* is the exception).
120
+ Don't use its logo, copy, images or exact layout. **The brief wins** over the live site when they
121
+ disagree (the user's words are what they want). Note the mismatch in the direction.
92
122
 
93
123
  **Brand colours that fail contrast** are still fixed, but only in roles where they pass. A pale brand
94
124
  yellow can be a background band or a large decorative shape, never body text. Say so in the
@@ -117,7 +147,9 @@ Each direction carries exactly this:
117
147
  - **Signature element** — the one memorable move (a scrolling marquee, stickers, oversized numerals,
118
148
  a duotone photo treatment). If it moves on its own, it gets a pause control (5.3).
119
149
  - **Logo idea** — one line on how the name becomes a logo, using a move from Step 6 ("letters
120
- bounce in different colours and the O is a smiley").
150
+ bounce in different colours and the O is a smiley"). When the brief carries a logo wish (*Design
151
+ direction* or *Assets*), every direction's logo idea is that wish in its own style. A wish is words
152
+ describing a logo; a logo file in *Assets* is a supplied logo and wins (Step 6).
121
153
 
122
154
  **Only offer what can pass.** Before asking, run two quick gates on **all three**:
123
155
 
@@ -144,7 +176,8 @@ option as one line in the same shape.
144
176
 
145
177
  The description says what the site would feel like, the main colours by name, what the lettering
146
178
  is like, the logo idea, and the one detail they'll remember. Hex codes and font names stay in your
147
- notes.
179
+ notes. The question may end with one plain clause saying they can add a logo idea to their pick, but
180
+ never suggest one or give an example: that idea would end up in the logo.
148
181
 
149
182
  > **Sticker-book maximal** — Loud and playful, like a scrapbook: candy pink, butter yellow and lilac,
150
183
  > chunky headlines, tilted sticker photos and a bouncy logo with a smiley O.
@@ -154,12 +187,19 @@ notes.
154
187
 
155
188
  Then:
156
189
 
157
- - **Pick** → use it as written.
190
+ - **Pick** → use it as written, and confirm the look in one line.
158
191
  - **"You decide" / skipped** → use A, and tell them in one line which look you went with.
159
192
  - **A mix** ("A's colours with C's fonts") → merge them. Don't ask again.
160
193
  - **Something else** → build a direction from what they said, run Step 5, and use it. Don't send
161
194
  three new options.
162
195
 
196
+ **Logo wish.** An answer can carry a logo idea next to the pick ("A, and make the logo a little
197
+ teapot"); it replaces the chosen direction's logo idea, and wins over a wish from the brief.
198
+ Whenever the logo follows a wish, from the answer or the brief, add it once to the line that confirms
199
+ the pick: *"The logo follows your idea: a little teapot."* If the kit can't draw it as said (a
200
+ detailed illustration, a photo), build its closest kit version and name what you simplified in that
201
+ same line. Don't ask a follow-up.
202
+
163
203
  Don't ask about anything else in this step.
164
204
 
165
205
  ## Step 5 — Check the chosen direction
@@ -246,8 +286,8 @@ read; the variable ones ship only `.woff2`.
246
286
  skip the rest of this step. Never redraw or recolour it.
247
287
 
248
288
  Otherwise, turn the name into a **designed** logo: shaped, coloured and composed. Typing the name in
249
- the display font with an emoji or symbol next to it doesn't count. Build the **logo idea** from the
250
- chosen direction with one or two of these moves:
289
+ the display font with an emoji or symbol next to it doesn't count. Build the chosen direction's **logo
290
+ idea** (as replaced by any logo wish, Step 4) with one or two of these moves:
251
291
 
252
292
  | Move | What it is | Suits |
253
293
  |---|---|---|
@@ -347,7 +387,8 @@ If content prepare hasn't sourced images yet, it now follows `design.md` → **I
347
387
 
348
388
  > Direction **<name>**, selected on <YYYY-MM-DD> from three options (others offered: <B name>,
349
389
  > <C name>). <"Picked by the user." | "User said 'you decide'; recommendation A used." |
350
- > "Merged by the user: <what>.">
390
+ > "Merged by the user: <what>."> — or, when kept: "Kept the owner's current look from <site URL |
391
+ > screenshots | brand guide>, confirmed on <YYYY-MM-DD>."
351
392
 
352
393
  ## Direction
353
394
  <2–3 sentences: the mood, what it borrows from the references (and any brief/reference mismatch),
@@ -401,7 +442,9 @@ confirms the framework (default Next.js SSR; ecommerce must be SSR) and records
401
442
  - **Body:** <family> (`@fontsource-variable/<slug>@<version>`); `--text-body` / `--leading-body`, measure ≤ 68ch
402
443
 
403
444
  ## Logo
404
- - **Concept:** <the move(s), and what any swapped letter or symbol stands for | "Supplied by the user">
445
+ - **Concept:** <the move(s), and what any swapped letter or symbol stands for, plus "From the owner:
446
+ '<their words>'" only when it follows their wish | "Supplied by the user" | "Kept from <source>" |
447
+ "No logo: owner kept the current look" (header shows the site name as text in `--font-display`)>
405
448
  - **Built from:** `@fontsource/<display-slug>@<version>`, weight(s)/style(s) …
406
449
  - **Files:** `brand/logo.svg` (header, `--logo-h` desktop / `--logo-h-sm` small screens),
407
450
  `brand/logo-mark.svg`, `brand/favicon.svg`<, `brand/logo-seal.svg`>; source `brand/logo-build.mjs`
@@ -449,14 +492,15 @@ duotone…); alt text written from what the photo shows.>
449
492
  ## Invariants
450
493
 
451
494
  - **One question.** Refine owns discovery; this step only chooses among directions (or keeps the
452
- existing one).
495
+ existing look).
453
496
  - **8-point grid, always.** No spacing, size, radius or breakpoint off the grid except the listed
454
497
  exemptions.
455
498
  - **WCAG 2.2 AA is the floor.** No direction is offered, chosen or written that fails it. Brand
456
499
  colours keep their hue but only appear in roles where they pass.
457
500
  - **Brand assets are fixed.** A supplied logo, colour or font appears in every direction, unchanged.
458
501
  - **A logo is designed, not typed.** Outlined SVG paths built with the logo kit, never live text,
459
- emoji or clip-art, and always readable at its smallest use.
502
+ emoji or clip-art, and always readable at its smallest use. The one exception: a kept look with no
503
+ logo shows the site name as text and gets no new logo.
460
504
  - **Self-hosted fonts only** (`@fontsource`). No Google Fonts or other font CDN links in the output.
461
505
  - **The tokens block is the only source of values** (breakpoints excepted). Components and pages
462
506
  reference tokens, never raw hex codes, pixel values or font names.