hostinger-api-mcp 3.21.2 → 3.22.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.
- package/CHANGELOG.md +13 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/core/oauth.js +22 -17
- package/src/core/oauth.ts +21 -17
- package/src/core/runtime.js +1 -1
- package/src/core/runtime.ts +1 -1
- 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/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,19 @@ 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.22.1 — 2026-10-29
|
|
8
|
+
|
|
9
|
+
### Also in this release
|
|
10
|
+
|
|
11
|
+
- OAuth sign-in flow: `src/core/oauth.js`, `src/core/oauth.ts`
|
|
12
|
+
|
|
13
|
+
## v3.22.0 — 2026-10-29
|
|
14
|
+
|
|
15
|
+
### Also in this release
|
|
16
|
+
|
|
17
|
+
- Dependencies: `package-lock.json`
|
|
18
|
+
- Request handling and authentication: `src/core/runtime.js`, `src/core/runtime.ts`
|
|
19
|
+
|
|
7
20
|
## v3.21.2 — 2026-10-28
|
|
8
21
|
|
|
9
22
|
### Operations
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
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.
|
|
9
|
+
"version": "3.22.1",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@hostinger/mcp",
|
|
14
|
-
"version": "3.
|
|
14
|
+
"version": "3.22.1",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|
package/src/core/oauth.js
CHANGED
|
@@ -12,16 +12,6 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
12
12
|
const SUCCESS_HTML = readFileSync(path.join(__dirname, "oauth-success.html"), "utf8");
|
|
13
13
|
const ERROR_HTML_TEMPLATE = readFileSync(path.join(__dirname, "oauth-error.html"), "utf8");
|
|
14
14
|
|
|
15
|
-
function escapeHtml(s) {
|
|
16
|
-
return String(s).replace(/[&<>"']/g, (ch) => ({
|
|
17
|
-
"&": "&",
|
|
18
|
-
"<": "<",
|
|
19
|
-
">": ">",
|
|
20
|
-
'"': """,
|
|
21
|
-
"'": "'",
|
|
22
|
-
})[ch]);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
15
|
const DEFAULT_ISSUER = "https://auth.hostinger.com";
|
|
26
16
|
const REGISTER_PATH = "/api/external/v1/oauth-server/register";
|
|
27
17
|
const AUTHORIZE_PATH = "/api/external/v1/oauth-server/authorize";
|
|
@@ -29,6 +19,16 @@ const TOKEN_PATH = "/api/external/v1/oauth-server/token";
|
|
|
29
19
|
const REVOKE_PATH = "/api/external/v1/oauth-server/token/revoke";
|
|
30
20
|
const CLIENT_NAME = "hostinger-mcp";
|
|
31
21
|
const CALLBACK_PATH = "/oauth/callback";
|
|
22
|
+
// RFC 6749 §4.1.2.1 — anything else in ?error= is reported as unknown_error
|
|
23
|
+
const OAUTH_ERROR_CODES = new Set([
|
|
24
|
+
"invalid_request",
|
|
25
|
+
"unauthorized_client",
|
|
26
|
+
"access_denied",
|
|
27
|
+
"unsupported_response_type",
|
|
28
|
+
"invalid_scope",
|
|
29
|
+
"server_error",
|
|
30
|
+
"temporarily_unavailable",
|
|
31
|
+
]);
|
|
32
32
|
const CREDENTIALS_DIR_NAME = "hostinger-mcp";
|
|
33
33
|
const CREDENTIALS_FILE_NAME = "credentials.json";
|
|
34
34
|
const EXPIRY_BUFFER_SECONDS = 60;
|
|
@@ -349,22 +349,27 @@ export class OAuthProvider {
|
|
|
349
349
|
const state = url.searchParams.get("state");
|
|
350
350
|
const error = url.searchParams.get("error");
|
|
351
351
|
|
|
352
|
-
|
|
353
|
-
|
|
352
|
+
if (state !== expectedState) {
|
|
353
|
+
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
354
|
+
res.end(ERROR_HTML_TEMPLATE.replace("{{error}}", "invalid_state"));
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const oauthError =
|
|
359
|
+
error && (OAUTH_ERROR_CODES.has(error) ? error : "unknown_error");
|
|
360
|
+
const body = oauthError
|
|
361
|
+
? ERROR_HTML_TEMPLATE.replace("{{error}}", oauthError)
|
|
354
362
|
: SUCCESS_HTML;
|
|
355
363
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
356
364
|
res.end(body);
|
|
357
365
|
|
|
358
366
|
setImmediate(() => server.close());
|
|
359
367
|
|
|
360
|
-
if (
|
|
368
|
+
if (oauthError) {
|
|
361
369
|
return reject(
|
|
362
|
-
new Error(`OAuth error from authorization server: ${
|
|
370
|
+
new Error(`OAuth error from authorization server: ${oauthError}`),
|
|
363
371
|
);
|
|
364
372
|
}
|
|
365
|
-
if (!state || state !== expectedState) {
|
|
366
|
-
return reject(new Error("OAuth state mismatch"));
|
|
367
|
-
}
|
|
368
373
|
if (!code) {
|
|
369
374
|
return reject(new Error("No authorization code received"));
|
|
370
375
|
}
|
package/src/core/oauth.ts
CHANGED
|
@@ -12,16 +12,6 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
12
12
|
const SUCCESS_HTML: string = readFileSync(path.join(__dirname, 'oauth-success.html'), 'utf8');
|
|
13
13
|
const ERROR_HTML_TEMPLATE: string = readFileSync(path.join(__dirname, 'oauth-error.html'), 'utf8');
|
|
14
14
|
|
|
15
|
-
function escapeHtml(s: string): string {
|
|
16
|
-
return String(s).replace(/[&<>"']/g, (ch) => ({
|
|
17
|
-
'&': '&',
|
|
18
|
-
'<': '<',
|
|
19
|
-
'>': '>',
|
|
20
|
-
'"': '"',
|
|
21
|
-
"'": ''',
|
|
22
|
-
})[ch] as string);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
15
|
const DEFAULT_ISSUER = 'https://auth.hostinger.com';
|
|
26
16
|
const REGISTER_PATH = '/api/external/v1/oauth-server/register';
|
|
27
17
|
const AUTHORIZE_PATH = '/api/external/v1/oauth-server/authorize';
|
|
@@ -29,6 +19,16 @@ const TOKEN_PATH = '/api/external/v1/oauth-server/token';
|
|
|
29
19
|
const REVOKE_PATH = '/api/external/v1/oauth-server/token/revoke';
|
|
30
20
|
const CLIENT_NAME = 'hostinger-mcp';
|
|
31
21
|
const CALLBACK_PATH = '/oauth/callback';
|
|
22
|
+
// RFC 6749 §4.1.2.1 — anything else in ?error= is reported as unknown_error
|
|
23
|
+
const OAUTH_ERROR_CODES = new Set([
|
|
24
|
+
'invalid_request',
|
|
25
|
+
'unauthorized_client',
|
|
26
|
+
'access_denied',
|
|
27
|
+
'unsupported_response_type',
|
|
28
|
+
'invalid_scope',
|
|
29
|
+
'server_error',
|
|
30
|
+
'temporarily_unavailable',
|
|
31
|
+
]);
|
|
32
32
|
const CREDENTIALS_DIR_NAME = 'hostinger-mcp';
|
|
33
33
|
const CREDENTIALS_FILE_NAME = 'credentials.json';
|
|
34
34
|
const EXPIRY_BUFFER_SECONDS = 60;
|
|
@@ -321,19 +321,23 @@ export class OAuthProvider {
|
|
|
321
321
|
const state = url.searchParams.get('state');
|
|
322
322
|
const error = url.searchParams.get('error');
|
|
323
323
|
|
|
324
|
-
|
|
325
|
-
|
|
324
|
+
if (state !== expectedState) {
|
|
325
|
+
res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
326
|
+
res.end(ERROR_HTML_TEMPLATE.replace('{{error}}', 'invalid_state'));
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const oauthError = error && (OAUTH_ERROR_CODES.has(error) ? error : 'unknown_error');
|
|
331
|
+
const body = oauthError
|
|
332
|
+
? ERROR_HTML_TEMPLATE.replace('{{error}}', oauthError)
|
|
326
333
|
: SUCCESS_HTML;
|
|
327
334
|
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
328
335
|
res.end(body);
|
|
329
336
|
|
|
330
337
|
setImmediate(() => server.close());
|
|
331
338
|
|
|
332
|
-
if (
|
|
333
|
-
return reject(new Error(`OAuth error from authorization server: ${
|
|
334
|
-
}
|
|
335
|
-
if (!state || state !== expectedState) {
|
|
336
|
-
return reject(new Error('OAuth state mismatch'));
|
|
339
|
+
if (oauthError) {
|
|
340
|
+
return reject(new Error(`OAuth error from authorization server: ${oauthError}`));
|
|
337
341
|
}
|
|
338
342
|
if (!code) {
|
|
339
343
|
return reject(new Error('No authorization code received'));
|
package/src/core/runtime.js
CHANGED
|
@@ -62,7 +62,7 @@ const GetSkillRequestSchema = z.object({
|
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* MCP Server for Hostinger API
|
|
65
|
-
* Generated from OpenAPI spec version 2.
|
|
65
|
+
* Generated from OpenAPI spec version 2.6.0
|
|
66
66
|
*/
|
|
67
67
|
class MCPServer {
|
|
68
68
|
constructor({ name, version, tools, instructions, skills = [] }) {
|
package/src/core/runtime.ts
CHANGED
|
@@ -94,7 +94,7 @@ interface Skill { uri: string; frontmatter: Record<string, unknown>; resources:
|
|
|
94
94
|
|
|
95
95
|
/**
|
|
96
96
|
* MCP Server for Hostinger API
|
|
97
|
-
* Generated from OpenAPI spec version 2.
|
|
97
|
+
* Generated from OpenAPI spec version 2.6.0
|
|
98
98
|
*/
|
|
99
99
|
class MCPServer {
|
|
100
100
|
private readonly name: string;
|
|
@@ -4,4 +4,4 @@ import { startServer } from '../core/runtime.js';
|
|
|
4
4
|
import tools from '../core/tools/agency-hosting.js';
|
|
5
5
|
import instructions from '../core/instructions.agency-hosting.js';
|
|
6
6
|
|
|
7
|
-
startServer({ name: 'hostinger-agency-hosting-mcp', version: '3.
|
|
7
|
+
startServer({ name: 'hostinger-agency-hosting-mcp', version: '3.22.1', tools, instructions });
|
|
@@ -4,4 +4,4 @@ import { startServer } from '../core/runtime.js';
|
|
|
4
4
|
import tools from '../core/tools/agency-hosting.js';
|
|
5
5
|
import instructions from '../core/instructions.agency-hosting.js';
|
|
6
6
|
|
|
7
|
-
startServer({ name: 'hostinger-agency-hosting-mcp', version: '3.
|
|
7
|
+
startServer({ name: 'hostinger-agency-hosting-mcp', version: '3.22.1', tools, instructions });
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
import { startServer } from '../core/runtime.js';
|
|
4
4
|
import tools from '../core/tools/agent-readiness.js';
|
|
5
5
|
|
|
6
|
-
startServer({ name: 'hostinger-agent-readiness-mcp', version: '3.
|
|
6
|
+
startServer({ name: 'hostinger-agent-readiness-mcp', version: '3.22.1', tools });
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
import { startServer } from '../core/runtime.js';
|
|
4
4
|
import tools from '../core/tools/agent-readiness.js';
|
|
5
5
|
|
|
6
|
-
startServer({ name: 'hostinger-agent-readiness-mcp', version: '3.
|
|
6
|
+
startServer({ name: 'hostinger-agent-readiness-mcp', version: '3.22.1', tools });
|
package/src/servers/all.js
CHANGED
|
@@ -5,4 +5,4 @@ import tools from '../core/tools/all.js';
|
|
|
5
5
|
import instructions from '../core/instructions.js';
|
|
6
6
|
import skills from '../core/skills.js';
|
|
7
7
|
|
|
8
|
-
startServer({ name: 'hostinger-api-mcp', version: '3.
|
|
8
|
+
startServer({ name: 'hostinger-api-mcp', version: '3.22.1', tools, instructions, skills });
|
package/src/servers/all.ts
CHANGED
|
@@ -5,4 +5,4 @@ import tools from '../core/tools/all.js';
|
|
|
5
5
|
import instructions from '../core/instructions.js';
|
|
6
6
|
import skills from '../core/skills.js';
|
|
7
7
|
|
|
8
|
-
startServer({ name: 'hostinger-api-mcp', version: '3.
|
|
8
|
+
startServer({ name: 'hostinger-api-mcp', version: '3.22.1', tools, instructions, skills });
|
package/src/servers/billing.js
CHANGED
package/src/servers/billing.ts
CHANGED
package/src/servers/dns.js
CHANGED
package/src/servers/dns.ts
CHANGED
package/src/servers/domains.js
CHANGED
package/src/servers/domains.ts
CHANGED
package/src/servers/ecommerce.js
CHANGED
package/src/servers/ecommerce.ts
CHANGED
package/src/servers/horizons.js
CHANGED
package/src/servers/horizons.ts
CHANGED
package/src/servers/hosting.js
CHANGED
|
@@ -4,4 +4,4 @@ import { startServer } from '../core/runtime.js';
|
|
|
4
4
|
import tools from '../core/tools/hosting.js';
|
|
5
5
|
import instructions from '../core/instructions.js';
|
|
6
6
|
|
|
7
|
-
startServer({ name: 'hostinger-hosting-mcp', version: '3.
|
|
7
|
+
startServer({ name: 'hostinger-hosting-mcp', version: '3.22.1', tools, instructions });
|
package/src/servers/hosting.ts
CHANGED
|
@@ -4,4 +4,4 @@ import { startServer } from '../core/runtime.js';
|
|
|
4
4
|
import tools from '../core/tools/hosting.js';
|
|
5
5
|
import instructions from '../core/instructions.js';
|
|
6
6
|
|
|
7
|
-
startServer({ name: 'hostinger-hosting-mcp', version: '3.
|
|
7
|
+
startServer({ name: 'hostinger-hosting-mcp', version: '3.22.1', tools, instructions });
|
package/src/servers/mail.js
CHANGED
package/src/servers/mail.ts
CHANGED
package/src/servers/reach.js
CHANGED
package/src/servers/reach.ts
CHANGED
package/src/servers/vps.js
CHANGED
package/src/servers/vps.ts
CHANGED
package/src/servers/wordpress.js
CHANGED
package/src/servers/wordpress.ts
CHANGED