hostinger-api-mcp 3.30.1 → 3.30.2
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 +11 -0
- package/README.md +4 -1
- package/gemini-extension.json +2 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/skills/headless/SKILL.md +7 -5
- package/skills/headless/VERSION +3 -3
- package/skills/headless/connect/SKILL.md +33 -16
- package/skills/headless/connect/bootstrap.mjs +25 -14
- package/skills/headless/connect/launch.mjs +42 -0
- package/skills/headless/connect/launch.sh +23 -0
- package/skills/headless/connect/tools/antigravity.md +5 -5
- package/skills/headless/connect/tools/claude-code.md +3 -3
- package/skills/headless/connect/tools/codex.md +7 -7
- package/skills/headless/connect/tools/cursor.md +9 -9
- package/skills/headless/connect/tools/devin.md +5 -5
- package/skills/headless/connect/tools/vscode.md +7 -7
- package/skills/headless/hostinger-mcp.mjs +4 -9
- package/skills/headless/steps/03-provision/ecommerce/SKILL.md +2 -2
- package/skills/headless/steps/03-provision/webapp/SKILL.md +1 -1
- package/skills/headless/steps/03-provision/wordpress/SKILL.md +2 -2
- package/skills/headless/steps/04-content-model/wordpress/SKILL.md +1 -1
- package/skills/headless/steps/08-deploy/SKILL.md +3 -3
- package/src/core/oauth.js +14 -4
- package/src/core/oauth.ts +14 -4
- package/src/core/runtime.js +6 -0
- package/src/core/runtime.ts +6 -0
- package/src/core/skills.js +59 -45
- package/src/core/skills.ts +59 -45
- 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,17 @@ 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.30.2 — 2026-11-06
|
|
8
|
+
|
|
9
|
+
### Also in this release
|
|
10
|
+
|
|
11
|
+
- Documentation: `README.md`
|
|
12
|
+
- Distribution manifests: `gemini-extension.json`
|
|
13
|
+
- Bundled agent skills: 18 files
|
|
14
|
+
- OAuth sign-in flow: `src/core/oauth.js`, `src/core/oauth.ts`
|
|
15
|
+
- Request handling and authentication: `src/core/runtime.js`, `src/core/runtime.ts`
|
|
16
|
+
- Other files: `src/core/skills.js`, `src/core/skills.ts`
|
|
17
|
+
|
|
7
18
|
## v3.30.1 — 2026-11-05
|
|
8
19
|
|
|
9
20
|
### Also in this release
|
package/README.md
CHANGED
|
@@ -133,11 +133,14 @@ hostinger-api-mcp --logout
|
|
|
133
133
|
|
|
134
134
|
### JSON configuration for Claude, Cursor, etc.
|
|
135
135
|
|
|
136
|
+
Register Node and the server script by absolute path, never `npx` or a bare `node`/`hostinger-api-mcp`: tools start the server in your project, where `npx` puts the project's `node_modules/.bin` first on `PATH`, a version manager (asdf, mise) runs whatever Node the project's `.tool-versions` names, and Windows looks a bare name up in the project folder first. Any of these lets a cloned repository run its own code with your Hostinger credentials. After the global install, `node -p process.execPath` prints the Node path and `npm root -g` the folder that holds `@hostinger/mcp`. Run both from your home folder.
|
|
137
|
+
|
|
136
138
|
```json
|
|
137
139
|
{
|
|
138
140
|
"mcpServers": {
|
|
139
141
|
"hostinger-api": {
|
|
140
|
-
"command": "
|
|
142
|
+
"command": "/absolute/path/to/node",
|
|
143
|
+
"args": ["/absolute/path/to/global/node_modules/@hostinger/mcp/src/servers/all.js"],
|
|
141
144
|
"env": {
|
|
142
145
|
"DEBUG": "false",
|
|
143
146
|
"HOSTINGER_API_TOKEN": "YOUR API TOKEN"
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hostinger-api-mcp",
|
|
3
|
-
"version": "3.30.
|
|
3
|
+
"version": "3.30.2",
|
|
4
4
|
"description": "Hostinger API — manage domains, DNS, hosting, VPS, billing and more from Gemini CLI.",
|
|
5
5
|
"mcpServers": {
|
|
6
6
|
"hostinger": {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"-y",
|
|
10
10
|
"@hostinger/mcp"
|
|
11
11
|
],
|
|
12
|
+
"cwd": "${extensionPath}",
|
|
12
13
|
"env": {
|
|
13
14
|
"HOSTINGER_API_TOKEN": "${HOSTINGER_API_TOKEN}"
|
|
14
15
|
}
|
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.30.
|
|
20
|
+
"version": "3.30.2",
|
|
21
21
|
"packages": [
|
|
22
22
|
{
|
|
23
23
|
"registryType": "npm",
|
|
24
24
|
"identifier": "@hostinger/mcp",
|
|
25
|
-
"version": "3.30.
|
|
25
|
+
"version": "3.30.2",
|
|
26
26
|
"transport": {
|
|
27
27
|
"type": "stdio"
|
|
28
28
|
},
|
package/skills/headless/SKILL.md
CHANGED
|
@@ -192,13 +192,15 @@ has usually outlasted the job, so it returns at once. The single rule that makes
|
|
|
192
192
|
### Waiting on Hostinger: `wait.mjs`
|
|
193
193
|
|
|
194
194
|
`wait.mjs` (next to this file) waits for a slow Hostinger job in one command, so you don't spend a turn
|
|
195
|
-
on every check:
|
|
195
|
+
on every check. Run it, like `push-content.mjs`, from the home folder (`cd "$HOME" && …`): both
|
|
196
|
+
start the Hostinger MCP server with the user's sign-in, and a version manager's `node` (asdf, mise)
|
|
197
|
+
runs whatever Node the current project's `.tool-versions` names:
|
|
196
198
|
|
|
197
199
|
```bash
|
|
198
|
-
node <skill>/wait.mjs setup <domain> # a fresh site's setup → completed
|
|
199
|
-
node <skill>/wait.mjs cms <domain> <username> # a shell swap's WordPress install at /cms → valid
|
|
200
|
-
node <skill>/wait.mjs build <domain> <buildUuid> # the deploy build → completed, then the root serves 200
|
|
201
|
-
node <skill>/wait.mjs live <domain> # the root serves 200
|
|
200
|
+
cd "$HOME" && node <skill>/wait.mjs setup <domain> # a fresh site's setup → completed
|
|
201
|
+
cd "$HOME" && node <skill>/wait.mjs cms <domain> <username> # a shell swap's WordPress install at /cms → valid
|
|
202
|
+
cd "$HOME" && node <skill>/wait.mjs build <domain> <buildUuid> # the deploy build → completed, then the root serves 200
|
|
203
|
+
cd "$HOME" && node <skill>/wait.mjs live <domain> # the root serves 200
|
|
202
204
|
```
|
|
203
205
|
|
|
204
206
|
Run it in the foreground, with a `--timeout` just under your tool's command limit (e.g. `--timeout 9m`
|
package/skills/headless/VERSION
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
version=3.30.
|
|
2
|
-
commit=
|
|
3
|
-
built=2026-11-
|
|
1
|
+
version=3.30.2
|
|
2
|
+
commit=27fa03d3cce1
|
|
3
|
+
built=2026-11-06
|
|
@@ -77,10 +77,10 @@ Read `<skill>/VERSION`: its line 1 is the skills version this run uses, which go
|
|
|
77
77
|
Run the bundled script. It verifies the MCP server and handles sign-in, emitting one JSON event per line on stdout. Run it as a background/streaming process. Show the user only the sign-in URL (`awaiting_user`) or a
|
|
78
78
|
failure's `detail`, and handle the other events silently (table below).
|
|
79
79
|
|
|
80
|
-
The script is safe and inspectable: it
|
|
80
|
+
The script is safe and inspectable: it copies the launcher to `~/.hostinger/mcp/launch.mjs`, checks the MCP server through it and drives the OAuth sign-in (a browser flow with a localhost callback) — no other network calls, no other filesystem writes.
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
node <skill>/connect/bootstrap.mjs
|
|
83
|
+
cd "$HOME" && node <skill>/connect/bootstrap.mjs
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
### Relay these events
|
|
@@ -89,11 +89,12 @@ The script emits one JSON object per line:
|
|
|
89
89
|
|
|
90
90
|
| Event | What to do |
|
|
91
91
|
| --- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
92
|
+
| `launcher` (`command`, `args`) | How to start the MCP server: use these for every registration (Phase 2). |
|
|
92
93
|
| `mcp_ok` | MCP server reachable — continue. |
|
|
93
94
|
| `logged_in` | Already authenticated (env token or a previous sign-in) — continue. |
|
|
94
95
|
| `awaiting_user` (`verificationUri`) | A browser window should have opened on the user's machine. Show the URL in plain prose and wait for the user to finish signing in. The OAuth callback lands on a localhost port, so the sign-in must be completed on this same machine. |
|
|
95
96
|
| `success` | Bootstrap done — continue to Phase 2. |
|
|
96
|
-
| `mcp_unreachable` / `login_failed` (with `detail`) | Stop and show the user the `detail`. Do not improvise a parallel setup by hand. |
|
|
97
|
+
| `launcher_failed` / `mcp_unreachable` / `login_failed` (with `detail`) | Stop and show the user the `detail`. Do not improvise a parallel setup by hand. |
|
|
97
98
|
|
|
98
99
|
If the environment has a `HOSTINGER_API_TOKEN` set (for example CI), the bootstrap reports `logged_in` immediately — no browser needed.
|
|
99
100
|
|
|
@@ -107,8 +108,8 @@ hostinger-api-mcp --login
|
|
|
107
108
|
hostinger-api-mcp --logout
|
|
108
109
|
|
|
109
110
|
# Without a global install:
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
cd "$HOME" && node "$HOME/.hostinger/mcp/launch.mjs" --login
|
|
112
|
+
cd "$HOME" && node "$HOME/.hostinger/mcp/launch.mjs" --logout
|
|
112
113
|
```
|
|
113
114
|
|
|
114
115
|
Credentials live in `~/.config/hostinger-mcp/credentials.json` (macOS/Linux) or `%APPDATA%\hostinger-mcp\credentials.json` (Windows) and are shared by every Hostinger MCP binary. OAuth works only when the tool runs the server over its default local (stdio) transport, which is what every registration below uses; `--http` needs `HOSTINGER_API_TOKEN`.
|
|
@@ -127,8 +128,8 @@ one group says nothing about the other:
|
|
|
127
128
|
|
|
128
129
|
| Group | Operations | Comes from | Needed by |
|
|
129
130
|
|---|---|---|---|
|
|
130
|
-
| **Hosting** | `hosting_*` (websites, deploy, build report), `wordpress_*` | `hostinger` (
|
|
131
|
-
| **Ecommerce** | `ecommerce_*` (stores, products, shipping, payments) | **only** `hostinger-ecommerce` (
|
|
131
|
+
| **Hosting** | `hosting_*` (websites, deploy, build report), `wordpress_*` | `hostinger` (`<command> <launcher>`), or the scoped servers such as `hostinger-hosting` + `hostinger-wordpress` | every build |
|
|
132
|
+
| **Ecommerce** | `ecommerce_*` (stores, products, shipping, payments) | **only** `hostinger-ecommerce` (`<command> <launcher> hostinger-ecommerce-mcp`), or the Ecommerce MCP in the Hostinger Connector. Neither `hostinger` nor the scoped hosting servers include it | Ecommerce backends (chosen later, in refine) |
|
|
132
133
|
|
|
133
134
|
Check each group on its own, right here at connect, before anything else:
|
|
134
135
|
|
|
@@ -148,8 +149,8 @@ Most coding tools load MCP servers only when they start, so a server registered
|
|
|
148
149
|
until the tool restarts. When either tool group above is missing:
|
|
149
150
|
|
|
150
151
|
1. **Register the missing servers** in the tool's MCP config, as the tool route below shows: `hostinger`
|
|
151
|
-
(
|
|
152
|
-
(
|
|
152
|
+
(`<command> <launcher>`) if the hosting group is missing, and `hostinger-ecommerce`
|
|
153
|
+
(`<command> <launcher> hostinger-ecommerce-mcp`) if the ecommerce group is missing.
|
|
153
154
|
Skip a server that is already registered under its name. When neither group is there, register
|
|
154
155
|
both: the backend isn't chosen until refine, and one restart then covers every backend.
|
|
155
156
|
2. **Write `connect.json`** (Phase 3) before you stop. The skill folder from Phase 1 stays in place,
|
|
@@ -163,12 +164,28 @@ until the tool restarts. When either tool group above is missing:
|
|
|
163
164
|
|
|
164
165
|
If a tool loads new servers without a restart (VS Code), use them right away and skip steps 3–4.
|
|
165
166
|
|
|
166
|
-
**Every
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
167
|
+
**Every registration and every command that starts the MCP server goes through the launcher**
|
|
168
|
+
(`~/.hostinger/mcp/launch.sh` and `launch.mjs`, which the bootstrap writes): never `npx` directly, with or without
|
|
169
|
+
`--prefix`. The tool starts the server, and you run commands, in the user's project, often a cloned
|
|
170
|
+
repository or template. npx run there puts the project's `node_modules/.bin` first on PATH and reads
|
|
171
|
+
its `.npmrc`, so whoever wrote the project runs their own `node` with the user's Hostinger sign-in.
|
|
172
|
+
The launcher runs npx from the home folder instead. A registration runs exactly the bootstrap's
|
|
173
|
+
`launcher` event, never a bare `node`: a version manager (asdf, mise) picks the Node that the project's
|
|
174
|
+
own `.tool-versions` names. On macOS and Linux the event is `/bin/sh` with `launch.sh`, which finds
|
|
175
|
+
Node only after moving to the home folder, so Node upgrades don't break it; on Windows it is the
|
|
176
|
+
absolute path of `node.exe` with `launch.mjs`. Replace `<command>` and `<launcher>` with that event's
|
|
177
|
+
`command` and `args[0]`, in shell commands and in JSON or TOML configs alike, and never leave a
|
|
178
|
+
placeholder in place. In JSON and TOML configs, double every backslash of a Windows path
|
|
179
|
+
(`C:\\Program Files\\nodejs\\node.exe`); a single one is an escape there (`\n` in `\nodejs` becomes a
|
|
180
|
+
newline). Commands you run yourself start in the home folder
|
|
181
|
+
(`cd "$HOME" && node …`) for the same reason.
|
|
182
|
+
|
|
183
|
+
**An existing Hostinger registration is "already registered" only when it runs exactly the
|
|
184
|
+
bootstrap's `launcher` event** (same `command`, `args[0]` the launcher, plus `hostinger-ecommerce-mcp`
|
|
185
|
+
for that server). Before you trust one (both groups present, or a name the tool lists), check its
|
|
186
|
+
command (Claude Code: `claude mcp get <name>`; otherwise the tool's MCP config). Anything else, such as
|
|
187
|
+
`npx`, a bare `node` or `hostinger-api-mcp`, or any other command or path than the event's:
|
|
188
|
+
remove it and register it again through the launcher, then follow *register, restart, resume*.
|
|
172
189
|
|
|
173
190
|
| Tool | Route |
|
|
174
191
|
|-------------|---------------------------------|
|
|
@@ -180,7 +197,7 @@ it when you register). In JSON or TOML configs replace `<home>` with the home fo
|
|
|
180
197
|
| Devin | `connect/tools/devin.md` |
|
|
181
198
|
|
|
182
199
|
If the user's tool isn't listed yet, connect it the generic way: register both Hostinger MCP servers
|
|
183
|
-
in that tool's MCP config (command
|
|
200
|
+
in that tool's MCP config (command `<command>`, args `<launcher>` as above), then follow *register, restart, resume*.
|
|
184
201
|
|
|
185
202
|
### The skills come from Phase 1 only
|
|
186
203
|
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// Hostinger Headless — bootstrap.
|
|
3
3
|
// Verifies the Hostinger MCP server is reachable and drives the OAuth sign-in,
|
|
4
4
|
// emitting one JSON event per line on stdout so a coding agent can relay
|
|
5
|
-
// progress to the user.
|
|
6
|
-
// stores (OAuth credentials); no network calls of its own.
|
|
5
|
+
// progress to the user. Its only writes are the launcher (~/.hostinger/mcp/launch.mjs, which
|
|
6
|
+
// coding tools register) and what the MCP itself stores (OAuth credentials); no network calls of its own.
|
|
7
7
|
import { spawn, spawnSync } from 'node:child_process';
|
|
8
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
8
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
9
9
|
import path from 'node:path';
|
|
10
10
|
import os from 'node:os';
|
|
11
11
|
|
|
@@ -17,19 +17,30 @@ const fail = (event, extra = {}) => {
|
|
|
17
17
|
process.exit(1);
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
// ──
|
|
20
|
+
// ── the MCP server, always through the launcher ──────────────────────────────
|
|
21
|
+
// launch.mjs runs the latest published package via npx from the home folder (see its header for why
|
|
22
|
+
// npx must never run in the project). Coding tools register the home copy, which every run refreshes,
|
|
23
|
+
// so a registration keeps working when the skill folder moves to a new version.
|
|
21
24
|
const isWin = process.platform === 'win32';
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const LAUNCHER = path.join(os.homedir(), '.hostinger', 'mcp', 'launch.mjs');
|
|
26
|
+
try {
|
|
27
|
+
mkdirSync(path.dirname(LAUNCHER), { recursive: true });
|
|
28
|
+
copyFileSync(new URL('./launch.mjs', import.meta.url), LAUNCHER);
|
|
29
|
+
copyFileSync(new URL('./launch.sh', import.meta.url), LAUNCHER.replace(/\.mjs$/, '.sh'));
|
|
30
|
+
} catch (e) {
|
|
31
|
+
fail('launcher_failed', { detail: String(e) });
|
|
32
|
+
}
|
|
33
|
+
const MCP = [process.execPath, LAUNCHER];
|
|
34
|
+
// A registration never names a bare `node`: Windows looks it up in the working directory (the project)
|
|
35
|
+
// first, and a version manager's shim (asdf, mise) runs the Node the project's .tool-versions names.
|
|
36
|
+
// macOS/Linux register /bin/sh with launch.sh, which finds node only after moving to home, so Node
|
|
37
|
+
// upgrades keep working. Windows names this Node by absolute path (this script runs from home).
|
|
38
|
+
emit('launcher', isWin
|
|
39
|
+
? { command: process.execPath, args: [LAUNCHER] }
|
|
40
|
+
: { command: '/bin/sh', args: [LAUNCHER.replace(/\.mjs$/, '.sh')] });
|
|
30
41
|
|
|
31
42
|
function capture(cmd, args) {
|
|
32
|
-
const r = spawnSync(cmd, args, { encoding: 'utf8',
|
|
43
|
+
const r = spawnSync(cmd, args, { encoding: 'utf8', cwd: os.homedir() });
|
|
33
44
|
return { status: r.status ?? 1, out: `${r.stdout || ''}${r.stderr || ''}`, error: r.error };
|
|
34
45
|
}
|
|
35
46
|
|
|
@@ -72,7 +83,7 @@ function existingAuth() {
|
|
|
72
83
|
// prefix — forward it so the agent can show it if the browser didn't open.
|
|
73
84
|
function login() {
|
|
74
85
|
return new Promise((resolve) => {
|
|
75
|
-
const child = spawn(MCP[0], [...MCP.slice(1), '--login'], {
|
|
86
|
+
const child = spawn(MCP[0], [...MCP.slice(1), '--login'], { cwd: os.homedir() });
|
|
76
87
|
let diag = '';
|
|
77
88
|
let urlSent = false;
|
|
78
89
|
const collect = (chunk) => {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Hostinger Headless — starts the latest Hostinger MCP server for a coding tool or a script.
|
|
3
|
+
// node launch.mjs [hostinger-<group>-mcp] [--login | --logout | --version]
|
|
4
|
+
//
|
|
5
|
+
// Coding tools start stdio servers in the user's project, often a cloned repository or template.
|
|
6
|
+
// npx run there puts <project>/node_modules/.bin, and the same folder of every parent, first on PATH
|
|
7
|
+
// (no npm flag turns that off) and reads the project's .npmrc, so the project's own `node` would run
|
|
8
|
+
// the server with the user's Hostinger credentials. This launcher runs npx from the home folder, with
|
|
9
|
+
// no relative or node_modules entries left on PATH, so nothing in the project is ever looked up.
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
|
|
14
|
+
const [PACKAGE, DEFAULT_BIN] = ['--package=@hostinger/mcp@latest', 'hostinger-api-mcp'];
|
|
15
|
+
const isWin = process.platform === 'win32';
|
|
16
|
+
const home = homedir();
|
|
17
|
+
|
|
18
|
+
const args = process.argv.slice(2);
|
|
19
|
+
// npx.cmd needs a shell on Windows (CVE-2024-27980), so every argument must be shell-inert.
|
|
20
|
+
if (args.some((a) => !/^[\w@.=:/-]+$/.test(a))) {
|
|
21
|
+
process.stderr.write(`launch.mjs: unexpected argument in ${JSON.stringify(args)}\n`);
|
|
22
|
+
process.exit(2);
|
|
23
|
+
}
|
|
24
|
+
const bin = /^[a-z0-9-]+-mcp$/.test(args[0] ?? '') ? args.shift() : DEFAULT_BIN;
|
|
25
|
+
|
|
26
|
+
// Windows may spell it Path; a relative entry or a node_modules folder can come from the project.
|
|
27
|
+
// The server returns to the project once started, so relative paths in tool arguments still work
|
|
28
|
+
// (launch.sh has already moved to home and names the project itself).
|
|
29
|
+
const env = { ...process.env, MCP_PROJECT_DIR: process.env.MCP_PROJECT_DIR || process.cwd() };
|
|
30
|
+
for (const key of Object.keys(env).filter((k) => k.toUpperCase() === 'PATH')) {
|
|
31
|
+
env[key] = env[key].split(path.delimiter)
|
|
32
|
+
.filter((p) => path.isAbsolute(p) && !p.split(/[\\/]/).includes('node_modules'))
|
|
33
|
+
.join(path.delimiter);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const child = spawn(isWin ? 'npx.cmd' : 'npx', ['-y', PACKAGE, bin, ...args], { cwd: home, env, stdio: 'inherit', shell: isWin });
|
|
37
|
+
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) process.on(signal, () => child.kill(signal));
|
|
38
|
+
child.on('error', (e) => {
|
|
39
|
+
process.stderr.write(`launch.mjs: could not start npx: ${e.message}\n`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|
|
42
|
+
child.on('exit', (code, signal) => process.exit(code ?? (signal ? 1 : 0)));
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Hostinger Headless — what coding tools register on macOS and Linux: /bin/sh <home>/.hostinger/mcp/launch.sh
|
|
3
|
+
# /bin/sh never moves, and node is looked up only here, after moving to the home folder, so a Node
|
|
4
|
+
# upgrade (Homebrew, nvm, asdf) keeps the registration working, and a version manager's shim picks the
|
|
5
|
+
# user's own Node, never the one a project's .tool-versions names. Relative and node_modules entries
|
|
6
|
+
# are dropped from PATH first: either could hold a node the project put there.
|
|
7
|
+
# The server returns to the project once started (relative paths in tool arguments), so name it first.
|
|
8
|
+
MCP_PROJECT_DIR=$(pwd)
|
|
9
|
+
export MCP_PROJECT_DIR
|
|
10
|
+
cd || exit 1
|
|
11
|
+
set -f
|
|
12
|
+
safe=
|
|
13
|
+
IFS=:
|
|
14
|
+
for dir in $PATH; do
|
|
15
|
+
case $dir in
|
|
16
|
+
/*node_modules*) ;;
|
|
17
|
+
/*) safe=${safe:+$safe:}$dir ;;
|
|
18
|
+
esac
|
|
19
|
+
done
|
|
20
|
+
unset IFS
|
|
21
|
+
PATH=$safe
|
|
22
|
+
export PATH
|
|
23
|
+
exec node "${0%/*}/launch.mjs" "$@"
|
|
@@ -12,7 +12,7 @@ description: "Specific Antigravity Hostinger MCP Server connection instructions
|
|
|
12
12
|
|
|
13
13
|
The later stages drive the Hostinger connector through Antigravity's native MCP tools. Check **both** tool groups (hosting and ecommerce), as *Check both tool groups* in `connect/SKILL.md`
|
|
14
14
|
says: other Hostinger tools responding doesn't mean the `hostinger-ecommerce` ones are there. Both
|
|
15
|
-
respond → use them and move on.
|
|
15
|
+
respond and both registrations run the launcher (*An existing Hostinger registration* in `connect/SKILL.md`) → use them and move on.
|
|
16
16
|
|
|
17
17
|
If either is missing, add the missing server(s) to `~/.gemini/antigravity/mcp_config.json` (Windows:
|
|
18
18
|
`C:\Users\<USERNAME>\.gemini\antigravity\mcp_config.json`), which you can reach from the Agent panel's
|
|
@@ -25,12 +25,12 @@ no tokens to handle:
|
|
|
25
25
|
{
|
|
26
26
|
"mcpServers": {
|
|
27
27
|
"hostinger": {
|
|
28
|
-
"command": "
|
|
29
|
-
"args": ["
|
|
28
|
+
"command": "<command>",
|
|
29
|
+
"args": ["<launcher>"]
|
|
30
30
|
},
|
|
31
31
|
"hostinger-ecommerce": {
|
|
32
|
-
"command": "
|
|
33
|
-
"args": ["
|
|
32
|
+
"command": "<command>",
|
|
33
|
+
"args": ["<launcher>", "hostinger-ecommerce-mcp"]
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -19,14 +19,14 @@ groups as *Check both tool groups* in `connect/SKILL.md` says:
|
|
|
19
19
|
`hostinger-wordpress`, `hostinger-domains`, …) never include it, so a session full of
|
|
20
20
|
`mcp__hostinger-*__*` tools can still be missing it.
|
|
21
21
|
|
|
22
|
-
Both present → use them and move on. Either missing → register the missing server(s) at user scope
|
|
22
|
+
Both present and both registrations run the launcher (*An existing Hostinger registration* in `connect/SKILL.md`) → use them and move on. Either missing → register the missing server(s) at user scope
|
|
23
23
|
now (`claude mcp list` shows what's already registered; skip those). The bootstrap already signed you
|
|
24
24
|
in, so they reuse the cached sign-in (`~/.config/hostinger-mcp/credentials.json`, or
|
|
25
25
|
`HOSTINGER_API_TOKEN`) and there are no tokens to handle:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
claude mcp add hostinger --scope user --
|
|
29
|
-
claude mcp add hostinger-ecommerce --scope user --
|
|
28
|
+
claude mcp add hostinger --scope user -- "<command>" "<launcher>" # hosting group missing
|
|
29
|
+
claude mcp add hostinger-ecommerce --scope user -- "<command>" "<launcher>" hostinger-ecommerce-mcp # ecommerce group missing
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
Claude Code loads MCP servers only at startup, so follow *register, restart, resume* in
|
|
@@ -12,27 +12,27 @@ description: "Specific Codex Hostinger MCP Server connection instructions for th
|
|
|
12
12
|
|
|
13
13
|
The later stages drive the Hostinger connector through Codex's native MCP tools. Check **both** tool groups (hosting and ecommerce), as *Check both tool groups* in `connect/SKILL.md`
|
|
14
14
|
says: other Hostinger tools responding doesn't mean the `hostinger-ecommerce` ones are there. Both
|
|
15
|
-
respond → use them and move on.
|
|
15
|
+
respond and both registrations run the launcher (*An existing Hostinger registration* in `connect/SKILL.md`) → use them and move on.
|
|
16
16
|
|
|
17
17
|
If either is missing, register the missing server(s); skip one already registered. The bootstrap already signed you in, so they reuse the cached
|
|
18
18
|
sign-in (`~/.config/hostinger-mcp/credentials.json`, or `HOSTINGER_API_TOKEN`) and there are no tokens
|
|
19
19
|
to handle:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
codex mcp add hostinger --
|
|
23
|
-
codex mcp add hostinger-ecommerce --
|
|
22
|
+
codex mcp add hostinger -- "<command>" "<launcher>"
|
|
23
|
+
codex mcp add hostinger-ecommerce -- "<command>" "<launcher>" hostinger-ecommerce-mcp
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
or add them to `~/.codex/config.toml`:
|
|
27
27
|
|
|
28
28
|
```toml
|
|
29
29
|
[mcp_servers.hostinger]
|
|
30
|
-
command = "
|
|
31
|
-
args = ["
|
|
30
|
+
command = "<command>"
|
|
31
|
+
args = ["<launcher>"]
|
|
32
32
|
|
|
33
33
|
[mcp_servers.hostinger-ecommerce]
|
|
34
|
-
command = "
|
|
35
|
-
args = ["
|
|
34
|
+
command = "<command>"
|
|
35
|
+
args = ["<launcher>", "hostinger-ecommerce-mcp"]
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
Codex loads MCP servers only when it starts, so follow *register, restart, resume* in
|
|
@@ -13,13 +13,13 @@ description: "Specific Cursor Hostinger MCP Server connection instructions for t
|
|
|
13
13
|
|
|
14
14
|
**Prerequisite:** Node.js 20 or newer on `PATH` (`node -v`). The published package engines require `>=20`; use Node 24 if you follow the package README.
|
|
15
15
|
|
|
16
|
-
The Hostinger MCP is the npm package `@hostinger/mcp`. You do **not** need a global install — Cursor (and this session)
|
|
16
|
+
The Hostinger MCP is the npm package `@hostinger/mcp`. You do **not** need a global install — Cursor (and this session) run it through the launcher (`~/.hostinger/mcp/`, written by the connect bootstrap), which starts the latest release with `npx` from your home folder. Never run `npx` for it directly: from the project, npx would run the project's own `node`. `<command>` and `<launcher>` below come from the bootstrap's `launcher` event (see `connect/SKILL.md`). Prefer the unified binary `hostinger-api-mcp` (every operation). Scoped binaries such as `hostinger-hosting-mcp` are optional.
|
|
17
17
|
|
|
18
18
|
### Option A — no global install (recommended)
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
# Verify the package/binary is reachable
|
|
22
|
-
|
|
22
|
+
cd "$HOME" && node "$HOME/.hostinger/mcp/launch.mjs" --version
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
### Option B — global install
|
|
@@ -37,7 +37,7 @@ hostinger-api-mcp --version
|
|
|
37
37
|
Check **both** tool groups, as *Check both tool groups* in `connect/SKILL.md` says: hosting
|
|
38
38
|
(`mcp__hostinger__*` or `mcp__hostinger-hosting__*`) **and** ecommerce (`mcp__hostinger-ecommerce__*`).
|
|
39
39
|
The scoped `mcp__hostinger-*__*` servers never include ecommerce, so they alone don't count. Both
|
|
40
|
-
present → skip registration: go to Step 2 only if you still need sign-in, otherwise go to Step 3.
|
|
40
|
+
present and both registrations run the launcher (*An existing Hostinger registration* in `connect/SKILL.md`) → skip registration: go to Step 2 only if you still need sign-in, otherwise go to Step 3.
|
|
41
41
|
|
|
42
42
|
If either is missing, register the missing server(s) in `~/.cursor/mcp.json` (global, so every project and every
|
|
43
43
|
later run has them). Merge them into any existing `mcpServers` rather than replacing the file.
|
|
@@ -48,12 +48,12 @@ OAuth can run:
|
|
|
48
48
|
{
|
|
49
49
|
"mcpServers": {
|
|
50
50
|
"hostinger": {
|
|
51
|
-
"command": "
|
|
52
|
-
"args": ["
|
|
51
|
+
"command": "<command>",
|
|
52
|
+
"args": ["<launcher>"]
|
|
53
53
|
},
|
|
54
54
|
"hostinger-ecommerce": {
|
|
55
|
-
"command": "
|
|
56
|
-
"args": ["
|
|
55
|
+
"command": "<command>",
|
|
56
|
+
"args": ["<launcher>", "hostinger-ecommerce-mcp"]
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -74,7 +74,7 @@ If the connect bootstrap already emitted `logged_in` / `success`, credentials ar
|
|
|
74
74
|
Otherwise run the login command. It registers a dynamic OAuth client (once per machine), **opens the user's browser** to Hostinger's authorization page, listens on a localhost callback, stores tokens, and exits:
|
|
75
75
|
|
|
76
76
|
```bash
|
|
77
|
-
|
|
77
|
+
cd "$HOME" && node "$HOME/.hostinger/mcp/launch.mjs" --login
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
(With a global install: `hostinger-api-mcp --login`.)
|
|
@@ -95,7 +95,7 @@ They are shared across every Hostinger MCP binary. Expired access tokens refresh
|
|
|
95
95
|
To sign out later:
|
|
96
96
|
|
|
97
97
|
```bash
|
|
98
|
-
|
|
98
|
+
cd "$HOME" && node "$HOME/.hostinger/mcp/launch.mjs" --logout
|
|
99
99
|
```
|
|
100
100
|
|
|
101
101
|
**API token (optional, CI / scripts):** set `HOSTINGER_API_TOKEN` in the environment before launching Cursor. When present it always wins and no OAuth code runs. Do not commit the token.
|
|
@@ -12,7 +12,7 @@ description: "Specific Devin Hostinger MCP Server connection instructions for th
|
|
|
12
12
|
|
|
13
13
|
The later stages drive the Hostinger connector through Devin's native MCP tools. Check **both** tool groups (hosting and ecommerce), as *Check both tool groups* in `connect/SKILL.md`
|
|
14
14
|
says: other Hostinger tools responding doesn't mean the `hostinger-ecommerce` ones are there. Both
|
|
15
|
-
respond → use them and move on.
|
|
15
|
+
respond and both registrations run the launcher (*An existing Hostinger registration* in `connect/SKILL.md`) → use them and move on.
|
|
16
16
|
|
|
17
17
|
If either is missing, register the missing server(s) for Devin; skip one already registered. The bootstrap already signed you in, so they reuse the
|
|
18
18
|
cached sign-in (`~/.config/hostinger-mcp/credentials.json`, or `HOSTINGER_API_TOKEN`) and there are no
|
|
@@ -21,18 +21,18 @@ tokens to handle.
|
|
|
21
21
|
- **Devin CLI:**
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
devin mcp add hostinger --
|
|
25
|
-
devin mcp add hostinger-ecommerce --
|
|
24
|
+
devin mcp add hostinger -- "<command>" "<launcher>"
|
|
25
|
+
devin mcp add hostinger-ecommerce -- "<command>" "<launcher>" hostinger-ecommerce-mcp
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
- **Devin app:** Settings → MCP Marketplace → **Add Your Own**, transport **STDIO**, once per server:
|
|
29
29
|
|
|
30
30
|
```json
|
|
31
|
-
{ "command": "
|
|
31
|
+
{ "command": "<command>", "args": ["<launcher>"] }
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
```json
|
|
35
|
-
{ "command": "
|
|
35
|
+
{ "command": "<command>", "args": ["<launcher>", "hostinger-ecommerce-mcp"] }
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
If the tools still aren't in this session, follow *register, restart, resume* in `connect/SKILL.md`:
|
|
@@ -12,7 +12,7 @@ description: "Specific VS Code Hostinger MCP Server connection instructions for
|
|
|
12
12
|
|
|
13
13
|
The later stages drive the Hostinger connector through VS Code's native MCP tools. Check **both** tool groups (hosting and ecommerce), as *Check both tool groups* in `connect/SKILL.md`
|
|
14
14
|
says: other Hostinger tools responding doesn't mean the `hostinger-ecommerce` ones are there. Both
|
|
15
|
-
respond → use them and move on.
|
|
15
|
+
respond and both registrations run the launcher (*An existing Hostinger registration* in `connect/SKILL.md`) → use them and move on.
|
|
16
16
|
|
|
17
17
|
If either is missing, register the missing server(s) for VS Code; skip one already registered. The bootstrap already signed you in, so they reuse
|
|
18
18
|
the cached sign-in (`~/.config/hostinger-mcp/credentials.json`, or `HOSTINGER_API_TOKEN`) and there are
|
|
@@ -25,13 +25,13 @@ no tokens to handle. Add them to `.vscode/mcp.json` (workspace) or your user `se
|
|
|
25
25
|
"servers": {
|
|
26
26
|
"hostinger": {
|
|
27
27
|
"type": "stdio",
|
|
28
|
-
"command": "
|
|
29
|
-
"args": ["
|
|
28
|
+
"command": "<command>",
|
|
29
|
+
"args": ["<launcher>"]
|
|
30
30
|
},
|
|
31
31
|
"hostinger-ecommerce": {
|
|
32
32
|
"type": "stdio",
|
|
33
|
-
"command": "
|
|
34
|
-
"args": ["
|
|
33
|
+
"command": "<command>",
|
|
34
|
+
"args": ["<launcher>", "hostinger-ecommerce-mcp"]
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -40,8 +40,8 @@ no tokens to handle. Add them to `.vscode/mcp.json` (workspace) or your user `se
|
|
|
40
40
|
Or add them in two commands:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
code --add-mcp '{"name":"hostinger","command":"
|
|
44
|
-
code --add-mcp '{"name":"hostinger-ecommerce","command":"
|
|
43
|
+
code --add-mcp '{"name":"hostinger","command":"<command>","args":["<launcher>"]}'
|
|
44
|
+
code --add-mcp '{"name":"hostinger-ecommerce","command":"<command>","args":["<launcher>","hostinger-ecommerce-mcp"]}'
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
VS Code picks up new servers and their tools become available right away, with no editor restart.
|
|
@@ -3,20 +3,15 @@
|
|
|
3
3
|
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
5
|
import { homedir } from 'node:os';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
6
7
|
|
|
7
|
-
// ──
|
|
8
|
-
const
|
|
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;
|
|
8
|
+
// ── always through the launcher, which runs npx from the home folder, never in the project ─────────
|
|
9
|
+
const MCP = [process.execPath, fileURLToPath(new URL('./connect/launch.mjs', import.meta.url))];
|
|
15
10
|
|
|
16
11
|
// One server per script run. Once it dies every pending and later call rejects, so the caller ends with
|
|
17
12
|
// exit 2 rather than hanging.
|
|
18
13
|
export function connect(clientName) {
|
|
19
|
-
const child = spawn(MCP[0], MCP.slice(1), { stdio: ['pipe', 'pipe', 'pipe'],
|
|
14
|
+
const child = spawn(MCP[0], MCP.slice(1), { stdio: ['pipe', 'pipe', 'pipe'], cwd: homedir() });
|
|
20
15
|
const pending = new Map();
|
|
21
16
|
let buffer = '';
|
|
22
17
|
let diag = '';
|
|
@@ -22,7 +22,7 @@ Provision a **Hostinger Ecommerce** backend for `<domain>` and prove it is ready
|
|
|
22
22
|
> aren't (for example, a tool connected before connect registered both servers), register it now. The
|
|
23
23
|
> command for each tool is in its `connect/tools/<tool>.md`; for Claude Code:
|
|
24
24
|
> ```bash
|
|
25
|
-
> claude mcp add hostinger-ecommerce --scope user --
|
|
25
|
+
> claude mcp add hostinger-ecommerce --scope user -- "<command>" "<launcher>" hostinger-ecommerce-mcp
|
|
26
26
|
> ```
|
|
27
27
|
> (Or enable the **Ecommerce** MCP in the Hostinger Connector.) A newly added MCP server only loads
|
|
28
28
|
> after a restart, so pause the run with *register, restart, resume* from `connect/SKILL.md`: save
|
|
@@ -49,7 +49,7 @@ Same lifecycle as `../wordpress/SKILL.md` Steps 1–2, but `type: "headless_ecom
|
|
|
49
49
|
call a separate subdomain op first — there's no need in this flow). The response carries the
|
|
50
50
|
generated domain; if it differs from the workspace dir, move
|
|
51
51
|
`~/.hostinger/<old>/` → `<new>/` (if `<new>/` already exists, stop and ask instead of moving
|
|
52
|
-
into it) and update `brief.md`. Don't wait here. At the join, `node <skill>/wait.mjs setup <domain>`
|
|
52
|
+
into it) and update `brief.md`. Don't wait here. At the join, `cd "$HOME" && node <skill>/wait.mjs setup <domain>`
|
|
53
53
|
returns once the setup is `completed` (see *Waiting on Hostinger* in the top-level `SKILL.md`).
|
|
54
54
|
`website_type` will be `headless`.
|
|
55
55
|
|
|
@@ -57,7 +57,7 @@ All website/database operations below go through the Hostinger connector (`execu
|
|
|
57
57
|
`~/.hostinger/<new>/`
|
|
58
58
|
(if `<new>/` already exists, stop and ask instead of moving into it),
|
|
59
59
|
update the domain in `brief.md`, and tell the user the new domain.
|
|
60
|
-
3. Don't wait here. At the join, `node <skill>/wait.mjs setup <domain>` (see *Waiting on Hostinger* in
|
|
60
|
+
3. Don't wait here. At the join, `cd "$HOME" && node <skill>/wait.mjs setup <domain>` (see *Waiting on Hostinger* in
|
|
61
61
|
the top-level `SKILL.md`) returns once the setup is `completed`, usually at once by then. A `failed`
|
|
62
62
|
setup → stop, point at hPanel.
|
|
63
63
|
|