hostinger-api-mcp 3.28.6 → 3.29.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 +7 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/skills/headless/SKILL.md +1 -0
- package/skills/headless/VERSION +2 -2
- package/skills/headless/hostinger-mcp.mjs +88 -0
- package/skills/headless/push-content.mjs +530 -0
- package/skills/headless/steps/04-content-model/SKILL.md +9 -9
- package/skills/headless/steps/04-content-model/wordpress/SKILL.md +83 -252
- package/skills/headless/steps/04-content-model/wordpress/by-hand.md +31 -0
- package/skills/headless/steps/04-content-model/wordpress/custom-plugins.md +2 -2
- package/skills/headless/steps/04-content-model/wordpress/woocommerce.md +21 -49
- package/skills/headless/steps/05-design/SKILL.md +1 -1
- package/skills/headless/wait.mjs +15 -95
- package/skills/headless/wp-mcp.mjs +125 -0
- package/src/core/skills.js +49 -21
- package/src/core/skills.ts +49 -21
- package/src/servers/agency-hosting.js +1 -1
- package/src/servers/agency-hosting.ts +1 -1
- package/src/servers/agent-readiness.js +1 -1
- package/src/servers/agent-readiness.ts +1 -1
- package/src/servers/all.js +1 -1
- package/src/servers/all.ts +1 -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/gpu.js +1 -1
- package/src/servers/gpu.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/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ 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.29.0 — 2026-11-05
|
|
8
|
+
|
|
9
|
+
### Also in this release
|
|
10
|
+
|
|
11
|
+
- Bundled agent skills: 12 files
|
|
12
|
+
- Other files: `src/core/skills.js`, `src/core/skills.ts`
|
|
13
|
+
|
|
7
14
|
## v3.28.6 — 2026-11-05
|
|
8
15
|
|
|
9
16
|
### Also in this release
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
"url": "https://github.com/hostinger/api-mcp-server",
|
|
18
18
|
"source": "github"
|
|
19
19
|
},
|
|
20
|
-
"version": "3.
|
|
20
|
+
"version": "3.29.0",
|
|
21
21
|
"packages": [
|
|
22
22
|
{
|
|
23
23
|
"registryType": "npm",
|
|
24
24
|
"identifier": "@hostinger/mcp",
|
|
25
|
-
"version": "3.
|
|
25
|
+
"version": "3.29.0",
|
|
26
26
|
"transport": {
|
|
27
27
|
"type": "stdio"
|
|
28
28
|
},
|
package/skills/headless/SKILL.md
CHANGED
|
@@ -239,6 +239,7 @@ took from it.
|
|
|
239
239
|
| `brief.md` | refine | refined brief, audience, tone, pages, must-haves |
|
|
240
240
|
| `site.json` | provision | chosen backend, username, install id, all URLs |
|
|
241
241
|
| `content-model.md` | content model | entities, fields, pages, navigation |
|
|
242
|
+
| `content.json` | content model (WordPress) | the drafted content `push-content.mjs` pushes |
|
|
242
243
|
| `design.md` (+ `brand/` logo files) | design | chosen design direction: tokens, type, logo, components, per-page composition, accessibility |
|
|
243
244
|
| `src/` | frontend | the website source implementing `design.md`; framework choice is recorded in `state.json → frontend` |
|
|
244
245
|
| `deploy.json` | deploy | build id, deployed at, live URLs |
|
package/skills/headless/VERSION
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
version=3.
|
|
2
|
-
commit=
|
|
1
|
+
version=3.29.0
|
|
2
|
+
commit=c4c3f98adbe2
|
|
3
3
|
built=2026-11-05
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// The local Hostinger MCP server (the management API), spoken to over newline-delimited JSON-RPC on
|
|
2
|
+
// stdio. It reuses the sign-in from the connect step. Shared by wait.mjs and push-content.mjs.
|
|
3
|
+
|
|
4
|
+
import { spawn } from 'node:child_process';
|
|
5
|
+
import { homedir } from 'node:os';
|
|
6
|
+
|
|
7
|
+
// ── platform-safe binary names (npm/npx are .cmd on Windows), as in connect/bootstrap.mjs ──────────
|
|
8
|
+
const isWin = process.platform === 'win32';
|
|
9
|
+
const bin = (name) => (isWin ? `${name}.cmd` : name);
|
|
10
|
+
const MCP = [bin('npx'), '-y', '--package=@hostinger/mcp@latest', 'hostinger-api-mcp'];
|
|
11
|
+
// Node >= 18.20.2 / 20.12.2 refuses to spawn a .cmd/.bat without a shell
|
|
12
|
+
// (CVE-2024-27980), so npx.cmd needs shell:true on Windows. Our args are all
|
|
13
|
+
// fixed literals, so enabling the shell introduces no injection risk.
|
|
14
|
+
const spawnShell = isWin;
|
|
15
|
+
|
|
16
|
+
// One server per script run. Once it dies every pending and later call rejects, so the caller ends with
|
|
17
|
+
// exit 2 rather than hanging.
|
|
18
|
+
export function connect(clientName) {
|
|
19
|
+
const child = spawn(MCP[0], MCP.slice(1), { stdio: ['pipe', 'pipe', 'pipe'], shell: spawnShell, cwd: homedir() });
|
|
20
|
+
const pending = new Map();
|
|
21
|
+
let buffer = '';
|
|
22
|
+
let diag = '';
|
|
23
|
+
let dead = null;
|
|
24
|
+
let nextId = 0;
|
|
25
|
+
const die = (reason) => {
|
|
26
|
+
dead ??= new Error(`the Hostinger MCP server stopped (${reason}): ${diag.trim().slice(-500)}`);
|
|
27
|
+
for (const { reject } of pending.values()) reject(dead);
|
|
28
|
+
pending.clear();
|
|
29
|
+
};
|
|
30
|
+
child.on('error', (e) => die(e.message));
|
|
31
|
+
// 'close' comes after stderr is drained, so the reason is in diag. A write to a dying server fails
|
|
32
|
+
// with EPIPE before that; 'close' still follows, so the EPIPE itself is ignored.
|
|
33
|
+
child.on('close', (code) => die(`exit code ${code}`));
|
|
34
|
+
child.stdin.on('error', () => {});
|
|
35
|
+
child.stderr.on('data', (chunk) => (diag = (diag + chunk).slice(-2000)));
|
|
36
|
+
child.stdout.on('data', (chunk) => {
|
|
37
|
+
buffer += chunk;
|
|
38
|
+
let i;
|
|
39
|
+
while ((i = buffer.indexOf('\n')) >= 0) {
|
|
40
|
+
const line = buffer.slice(0, i);
|
|
41
|
+
buffer = buffer.slice(i + 1);
|
|
42
|
+
try {
|
|
43
|
+
const message = JSON.parse(line);
|
|
44
|
+
pending.get(message.id)?.resolve(message);
|
|
45
|
+
pending.delete(message.id);
|
|
46
|
+
} catch {
|
|
47
|
+
/* not a JSON-RPC line */
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
// A call can stall on a live server (a stuck upstream request), so each one has its own deadline; past
|
|
52
|
+
// it, it answers like an error reply. A stalled start ends the run. The start gets longer: a cold `npx`
|
|
53
|
+
// fetch of the server takes 13-40 s on an idle machine and over 60 s on a busy one.
|
|
54
|
+
const rpc = (method, params, seconds = 60) =>
|
|
55
|
+
new Promise((resolve, reject) => {
|
|
56
|
+
if (dead) return reject(dead);
|
|
57
|
+
const id = (nextId += 1);
|
|
58
|
+
const timer = setTimeout(() => {
|
|
59
|
+
pending.delete(id);
|
|
60
|
+
resolve({ error: { message: `no reply to ${method} in ${seconds} s` } });
|
|
61
|
+
}, seconds * 1000);
|
|
62
|
+
const settle = (fn) => (value) => {
|
|
63
|
+
clearTimeout(timer);
|
|
64
|
+
fn(value);
|
|
65
|
+
};
|
|
66
|
+
pending.set(id, { resolve: settle(resolve), reject: settle(reject) });
|
|
67
|
+
child.stdin.write(`${JSON.stringify({ jsonrpc: '2.0', id, method, params })}\n`);
|
|
68
|
+
});
|
|
69
|
+
const ready = rpc('initialize', { protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: clientName, version: '1' } }, 180)
|
|
70
|
+
.then((reply) => {
|
|
71
|
+
if (reply.error) throw new Error(`the Hostinger MCP server didn't start: ${reply.error.message}`);
|
|
72
|
+
child.stdin.write(`${JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' })}\n`);
|
|
73
|
+
});
|
|
74
|
+
// Runs one API operation: { data } on success, else { error, status } with the HTTP status the server
|
|
75
|
+
// keeps in its error text (NaN when there is none).
|
|
76
|
+
const execute = async (operation, params) => {
|
|
77
|
+
await ready;
|
|
78
|
+
const reply = await rpc('tools/call', { name: 'execute', arguments: { operation, params } });
|
|
79
|
+
const text = reply.result?.content?.[0]?.text ?? reply.error?.message ?? 'unknown error';
|
|
80
|
+
if (reply.error || reply.result?.isError) return { error: text.slice(0, 300), status: Number(text.match(/HTTP (\d{3})/)?.[1]) };
|
|
81
|
+
try {
|
|
82
|
+
return { data: JSON.parse(text) };
|
|
83
|
+
} catch {
|
|
84
|
+
return { error: text.slice(0, 300), status: NaN };
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
return { execute, close: () => child.kill() };
|
|
88
|
+
}
|