hostinger-api-mcp 0.0.30 → 0.0.32

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/README.md CHANGED
@@ -66,7 +66,7 @@ The following environment variables can be configured when running the server:
66
66
  "command": "hostinger-api-mcp",
67
67
  "env": {
68
68
  "DEBUG": "false",
69
- "APITOKEN": "YOUR API TOKEN"
69
+ "API_TOKEN": "YOUR API TOKEN"
70
70
  }
71
71
  }
72
72
  }
@@ -862,18 +862,6 @@ This endpoint retrieves a list of public keys attached to a specified virtual ma
862
862
  - `virtualMachineId`: Virtual Machine ID (required)
863
863
  - `page`: Page number
864
864
 
865
- ### VPS_deleteBackupV1
866
-
867
- This endpoint deletes a specified backup for a virtual machine.
868
-
869
- - **Method**: `DELETE`
870
- - **Path**: `/api/vps/v1/virtual-machines/{virtualMachineId}/backups/{backupId}`
871
-
872
- **Parameters**:
873
-
874
- - `virtualMachineId`: Virtual Machine ID (required)
875
- - `backupId`: Backup ID (required)
876
-
877
865
  ### VPS_getBackupListV1
878
866
 
879
867
  This endpoint retrieves a list of backups for a specified virtual machine.
@@ -1038,6 +1026,7 @@ Be aware, that improper nameserver configuration can lead to the virtual machine
1038
1026
  - `virtualMachineId`: Virtual Machine ID (required)
1039
1027
  - `ns1`: ns1 parameter (required)
1040
1028
  - `ns2`: ns2 parameter
1029
+ - `ns3`: ns3 parameter
1041
1030
 
1042
1031
  ### VPS_createPTRRecordV1
1043
1032
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hostinger-api-mcp",
3
- "version": "0.0.30",
3
+ "version": "0.0.32",
4
4
  "description": "MCP server for Hostinger API",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,17 +25,21 @@
25
25
  "start:ts": "npx tsc && node dist/server.js"
26
26
  },
27
27
  "dependencies": {
28
- "@modelcontextprotocol/sdk": "^1.0.0",
28
+ "@modelcontextprotocol/sdk": "^1.0.6",
29
29
  "minimist": "^1.2.8",
30
- "express": "^5.1.0",
30
+ "express": "^4.21.2",
31
31
  "axios": "^1.8.0",
32
- "dotenv": "^16.0.0"
32
+ "dotenv": "^16.4.7",
33
+ "cors": "^2.8.5"
33
34
  },
34
35
  "devDependencies": {
35
- "@types/node": "^20.11.0",
36
- "typescript": "^5.3.3"
36
+ "@types/node": "^24.0.0",
37
+ "@types/express": "^5.0.0",
38
+ "@types/cors": "^2.8.17",
39
+ "@types/minimist": "^1.2.5",
40
+ "typescript": "^5.7.2"
37
41
  },
38
42
  "engines": {
39
- "node": ">=20.0.0"
43
+ "node": ">=24.0.0"
40
44
  }
41
45
  }
package/server.js CHANGED
@@ -2,8 +2,9 @@
2
2
 
3
3
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
- import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
5
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
6
6
  import minimist from 'minimist';
7
+ import cors from "cors";
7
8
  import express from "express";
8
9
  import axios from "axios";
9
10
  import { config as dotenvConfig } from "dotenv";
@@ -1729,34 +1730,6 @@ const TOOLS = [
1729
1730
  }
1730
1731
  ]
1731
1732
  },
1732
- {
1733
- "name": "VPS_deleteBackupV1",
1734
- "description": "This endpoint deletes a specified backup for a virtual machine.",
1735
- "method": "DELETE",
1736
- "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/backups/{backupId}",
1737
- "inputSchema": {
1738
- "type": "object",
1739
- "properties": {
1740
- "virtualMachineId": {
1741
- "type": "integer",
1742
- "description": "Virtual Machine ID"
1743
- },
1744
- "backupId": {
1745
- "type": "integer",
1746
- "description": "Backup ID"
1747
- }
1748
- },
1749
- "required": [
1750
- "virtualMachineId",
1751
- "backupId"
1752
- ]
1753
- },
1754
- "security": [
1755
- {
1756
- "apiToken": []
1757
- }
1758
- ]
1759
- },
1760
1733
  {
1761
1734
  "name": "VPS_getBackupListV1",
1762
1735
  "description": "This endpoint retrieves a list of backups for a specified virtual machine.",
@@ -2063,6 +2036,10 @@ const TOOLS = [
2063
2036
  "ns2": {
2064
2037
  "type": "string",
2065
2038
  "description": "ns2 parameter"
2039
+ },
2040
+ "ns3": {
2041
+ "type": "string",
2042
+ "description": "ns3 parameter"
2066
2043
  }
2067
2044
  },
2068
2045
  "required": [
@@ -2512,7 +2489,7 @@ const SECURITY_SCHEMES = {
2512
2489
 
2513
2490
  /**
2514
2491
  * MCP Server for Hostinger API
2515
- * Generated from OpenAPI spec version 0.0.81
2492
+ * Generated from OpenAPI spec version 0.0.86
2516
2493
  */
2517
2494
  class MCPServer {
2518
2495
  constructor() {
@@ -2530,7 +2507,7 @@ class MCPServer {
2530
2507
  this.server = new Server(
2531
2508
  {
2532
2509
  name: "hostinger-api-mcp",
2533
- version: "0.0.30",
2510
+ version: "0.0.32",
2534
2511
  },
2535
2512
  {
2536
2513
  capabilities: {
@@ -2555,7 +2532,7 @@ class MCPServer {
2555
2532
  });
2556
2533
  }
2557
2534
 
2558
- headers['User-Agent'] = 'hostinger-mcp-server/0.0.30';
2535
+ headers['User-Agent'] = 'hostinger-mcp-server/0.0.32';
2559
2536
 
2560
2537
  return headers;
2561
2538
  }
@@ -2683,59 +2660,12 @@ class MCPServer {
2683
2660
  return status < 500; // Resolve only if the status code is less than 500
2684
2661
  }
2685
2662
  };
2686
-
2687
- // Apply security headers based on tool security requirements
2688
- if (tool.security && Array.isArray(tool.security)) {
2689
- for (const requirement of tool.security) {
2690
- for (const securitySchemeName of Object.keys(requirement)) {
2691
- const securityDefinition = SECURITY_SCHEMES[securitySchemeName];
2692
-
2693
- if (securityDefinition) {
2694
- const authType = securityDefinition.type;
2695
-
2696
- // Handle API key
2697
- if (authType === 'apiKey') {
2698
- const apiKeyName = securityDefinition.name;
2699
- const envVarName = `${securitySchemeName.toUpperCase()}_${apiKeyName.toUpperCase()}`;
2700
- const apiKeyValue = process.env[envVarName];
2701
-
2702
- if (apiKeyValue) {
2703
- if (securityDefinition.in === 'header') {
2704
- config.headers[apiKeyName] = apiKeyValue;
2705
- } else if (securityDefinition.in === 'query') {
2706
- config.params = config.params || {};
2707
- config.params[apiKeyName] = apiKeyValue;
2708
- }
2709
- } else {
2710
- this.log('warning', `API Key environment variable not found: ${envVarName}`);
2711
- }
2712
- }
2713
- // Handle bearer token
2714
- else if (authType === 'http' && securityDefinition.scheme === 'bearer') {
2715
- const envVarName = `${securitySchemeName.toUpperCase()}`;
2716
- const bearerToken = process.env[envVarName];
2717
-
2718
- if (bearerToken) {
2719
- config.headers['Authorization'] = `Bearer ${bearerToken}`;
2720
- } else {
2721
- this.log('warning', `Bearer Token environment variable not found: ${envVarName}`);
2722
- }
2723
- }
2724
- // Handle basic auth
2725
- else if (authType === 'http' && securityDefinition.scheme === 'basic') {
2726
- const username = process.env[`${securitySchemeName.toUpperCase()}_USERNAME`];
2727
- const password = process.env[`${securitySchemeName.toUpperCase()}_PASSWORD`];
2728
-
2729
- if (username && password) {
2730
- const auth = Buffer.from(`${username}:${password}`).toString('base64');
2731
- config.headers['Authorization'] = `Basic ${auth}`;
2732
- } else {
2733
- this.log('warning', `Basic auth credentials not found for ${securitySchemeName}`);
2734
- }
2735
- }
2736
- }
2737
- }
2738
- }
2663
+
2664
+ const bearerToken = process.env['API_TOKEN'] || process.env['APITOKEN']; // APITOKEN for backwards compatibility
2665
+ if (bearerToken) {
2666
+ config.headers['Authorization'] = `Bearer ${bearerToken}`;
2667
+ } else {
2668
+ this.log('error', `Bearer Token environment variable not found: API_TOKEN`);
2739
2669
  }
2740
2670
 
2741
2671
  // Add parameters based on request method
@@ -2810,46 +2740,65 @@ class MCPServer {
2810
2740
  }
2811
2741
 
2812
2742
  /**
2813
- * Start the sse server
2743
+ * Create and configure Express app with shared middleware
2814
2744
  */
2815
- async startSse(host, port) {
2745
+ createApp() {
2746
+ const app = express();
2747
+ app.use(express.json());
2748
+ app.use(cors());
2749
+ return app;
2750
+ }
2751
+
2752
+ /**
2753
+ * Start the server with HTTP streaming transport
2754
+ */
2755
+ async startHttp(host, port) {
2816
2756
  try {
2817
- // Create sse transport
2818
- const app = express();
2819
- app.use(express.json());
2757
+ const app = this.createApp();
2820
2758
 
2821
- let transport = null;
2822
- const sessions = {};
2759
+ // Create HTTP transport with session management
2760
+ const httpTransport = new StreamableHTTPServerTransport({
2761
+ sessionIdGenerator: () => {
2762
+ // Generate a simple session ID
2763
+ return `session-${Date.now()}-${Math.random().toString(36).substring(7)}`;
2764
+ },
2765
+ });
2823
2766
 
2824
- app.get('/sse', (req, res) => {
2825
- transport = new SSEServerTransport('/messages', res);
2826
- sessions[transport.sessionId] = transport;
2827
-
2828
- res.on('close', () => {
2829
- delete sessions[transport.sessionId];
2830
- });
2831
-
2832
- this.server.connect(transport);
2767
+ // Set up CORS for all routes
2768
+ app.options("*", (req, res) => {
2769
+ res.header("Access-Control-Allow-Origin", "*");
2770
+ res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
2771
+ res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, x-session-id");
2772
+ res.sendStatus(200);
2833
2773
  });
2834
2774
 
2835
- app.post('/messages', (req, res) => {
2836
- const sessionId = req.query.sessionId;
2837
- const transport = sessions[sessionId];
2838
- if (transport) {
2839
- transport.handlePostMessage(req, res);
2840
- } else {
2841
- res.status(400).send('No transport found for sessionId');
2842
- }
2775
+ // Health check endpoint
2776
+ app.get("/health", (req, res) => {
2777
+ res.status(200).json({ status: "ok", transport: "http" });
2843
2778
  });
2844
2779
 
2845
- app.listen(port, host);
2846
- this.log('info', `MCP Server with SSE transport started successfully with ${this.tools.size} tools`);
2847
- this.log('info', `Listening on ${host}:${port}`);
2780
+ // Set up the HTTP transport endpoint
2781
+ app.post("/", async (req, res) => {
2782
+ res.header("Access-Control-Allow-Origin", "*");
2783
+ res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
2784
+ res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, x-session-id");
2785
+ await httpTransport.handleRequest(req, res, req.body);
2786
+ });
2787
+
2788
+ // Start the server
2789
+ const server = app.listen(port, host, () => {
2790
+ this.log('info', `MCP Server with HTTP streaming transport started successfully with ${this.tools.size} tools`);
2791
+ this.log('info', `Listening on http://${host}:${port}`);
2792
+ });
2793
+
2794
+ // Connect the MCP server to the transport
2795
+ await this.server.connect(httpTransport);
2796
+
2848
2797
  } catch (error) {
2849
2798
  console.error("Failed to start MCP server:", error);
2850
2799
  process.exit(1);
2851
2800
  }
2852
- }
2801
+ }
2853
2802
 
2854
2803
  /**
2855
2804
  * Start the server
@@ -2879,16 +2828,35 @@ async function main() {
2879
2828
  const argv = minimist(process.argv.slice(2), {
2880
2829
  string: ['host'],
2881
2830
  int: ['port'],
2882
- boolean: ['sse'],
2831
+ boolean: ['stdio', 'http', 'help'],
2883
2832
  default: {
2884
2833
  host: '127.0.0.1',
2885
2834
  port: 8100,
2835
+ stdio: true,
2886
2836
  }
2887
2837
  });
2838
+
2839
+ // Show help if requested
2840
+ if (argv.help) {
2841
+ console.log(`
2842
+ Hostinger API MCP Server
2843
+ Usage: hostinger-api-mcp [options]
2844
+ Options:
2845
+ --http Use HTTP streaming transport
2846
+ --stdio Use standard input/output transport (default)
2847
+ --host <host> Host to bind to (default: 127.0.0.1)
2848
+ --port <port> Port to bind to (default: 8100)
2849
+ --help Show this help message
2850
+ Environment Variables:
2851
+ API_TOKEN Your Hostinger API token (required)
2852
+ DEBUG Enable debug logging (true/false)
2853
+ `);
2854
+ process.exit(0);
2855
+ }
2888
2856
 
2889
2857
  const server = new MCPServer();
2890
- if (argv.sse) {
2891
- await server.startSse(argv.host, argv.port);
2858
+ if (argv.http) {
2859
+ await server.startHttp(argv.host, argv.port);
2892
2860
  } else {
2893
2861
  await server.startStdio();
2894
2862
  }
package/server.ts CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
- import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
5
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
6
+ import minimist from 'minimist';
7
+ import cors from "cors";
6
8
  import express from "express";
7
9
  import {Request, Response} from "express";
8
10
  import axios, { AxiosRequestConfig, AxiosError, AxiosResponse } from "axios";
@@ -1745,34 +1747,6 @@ const TOOLS: OpenApiTool[] = [
1745
1747
  }
1746
1748
  ]
1747
1749
  },
1748
- {
1749
- "name": "VPS_deleteBackupV1",
1750
- "description": "This endpoint deletes a specified backup for a virtual machine.",
1751
- "method": "DELETE",
1752
- "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/backups/{backupId}",
1753
- "inputSchema": {
1754
- "type": "object",
1755
- "properties": {
1756
- "virtualMachineId": {
1757
- "type": "integer",
1758
- "description": "Virtual Machine ID"
1759
- },
1760
- "backupId": {
1761
- "type": "integer",
1762
- "description": "Backup ID"
1763
- }
1764
- },
1765
- "required": [
1766
- "virtualMachineId",
1767
- "backupId"
1768
- ]
1769
- },
1770
- "security": [
1771
- {
1772
- "apiToken": []
1773
- }
1774
- ]
1775
- },
1776
1750
  {
1777
1751
  "name": "VPS_getBackupListV1",
1778
1752
  "description": "This endpoint retrieves a list of backups for a specified virtual machine.",
@@ -2079,6 +2053,10 @@ const TOOLS: OpenApiTool[] = [
2079
2053
  "ns2": {
2080
2054
  "type": "string",
2081
2055
  "description": "ns2 parameter"
2056
+ },
2057
+ "ns3": {
2058
+ "type": "string",
2059
+ "description": "ns3 parameter"
2082
2060
  }
2083
2061
  },
2084
2062
  "required": [
@@ -2528,7 +2506,7 @@ const SECURITY_SCHEMES: Record<string, SecurityScheme> = {
2528
2506
 
2529
2507
  /**
2530
2508
  * MCP Server for Hostinger API
2531
- * Generated from OpenAPI spec version 0.0.81
2509
+ * Generated from OpenAPI spec version 0.0.86
2532
2510
  */
2533
2511
  class MCPServer {
2534
2512
  private server: Server;
@@ -2550,7 +2528,7 @@ class MCPServer {
2550
2528
  this.server = new Server(
2551
2529
  {
2552
2530
  name: "hostinger-api-mcp",
2553
- version: "0.0.30",
2531
+ version: "0.0.32",
2554
2532
  },
2555
2533
  {
2556
2534
  capabilities: {
@@ -2575,7 +2553,7 @@ class MCPServer {
2575
2553
  });
2576
2554
  }
2577
2555
 
2578
- headers['User-Agent'] = 'hostinger-mcp-server/0.0.30';
2556
+ headers['User-Agent'] = 'hostinger-mcp-server/0.0.32';
2579
2557
 
2580
2558
  return headers;
2581
2559
  }
@@ -2702,62 +2680,12 @@ class MCPServer {
2702
2680
  return status < 500; // Resolve only if the status code is less than 500
2703
2681
  }
2704
2682
  };
2705
-
2706
- // Apply security headers based on tool security requirements
2707
- if (tool.security && Array.isArray(tool.security)) {
2708
- for (const requirement of tool.security) {
2709
- for (const securitySchemeName of Object.keys(requirement)) {
2710
- const securityDefinition = SECURITY_SCHEMES[securitySchemeName];
2711
-
2712
- if (securityDefinition) {
2713
- const authType = securityDefinition.type;
2714
-
2715
- // Handle API key
2716
- if (authType === 'apiKey') {
2717
- const apiKeyName = securityDefinition.name || '';
2718
- const envVarName = `${securitySchemeName.toUpperCase()}_${apiKeyName.toUpperCase()}`;
2719
- const apiKeyValue = process.env[envVarName];
2720
-
2721
- if (apiKeyValue) {
2722
- if (securityDefinition.in === 'header') {
2723
- config.headers = config.headers || {};
2724
- config.headers[apiKeyName] = apiKeyValue;
2725
- } else if (securityDefinition.in === 'query') {
2726
- config.params = config.params || {};
2727
- config.params[apiKeyName] = apiKeyValue;
2728
- }
2729
- } else {
2730
- this.log('warning', `API Key environment variable not found: ${envVarName}`);
2731
- }
2732
- }
2733
- // Handle bearer token
2734
- else if (authType === 'http' && securityDefinition.scheme === 'bearer') {
2735
- const envVarName = `${securitySchemeName.toUpperCase()}`;
2736
- const bearerToken = process.env[envVarName];
2737
-
2738
- if (bearerToken) {
2739
- config.headers = config.headers || {};
2740
- config.headers['Authorization'] = `Bearer ${bearerToken}`;
2741
- } else {
2742
- this.log('warning', `Bearer Token environment variable not found: ${envVarName}`);
2743
- }
2744
- }
2745
- // Handle basic auth
2746
- else if (authType === 'http' && securityDefinition.scheme === 'basic') {
2747
- const username = process.env[`${securitySchemeName.toUpperCase()}_USERNAME`];
2748
- const password = process.env[`${securitySchemeName.toUpperCase()}_PASSWORD`];
2749
-
2750
- if (username && password) {
2751
- const auth = Buffer.from(`${username}:${password}`).toString('base64');
2752
- config.headers = config.headers || {};
2753
- config.headers['Authorization'] = `Basic ${auth}`;
2754
- } else {
2755
- this.log('warning', `Basic auth credentials not found for ${securitySchemeName}`);
2756
- }
2757
- }
2758
- }
2759
- }
2760
- }
2683
+
2684
+ const bearerToken = process.env['API_TOKEN'] || process.env['APITOKEN']; // APITOKEN for backwards compatibility
2685
+ if (bearerToken) {
2686
+ config.headers['Authorization'] = `Bearer ${bearerToken}`;
2687
+ } else {
2688
+ this.log('error', `Bearer Token environment variable not found: API_TOKEN`);
2761
2689
  }
2762
2690
 
2763
2691
  // Add parameters based on request method
@@ -2833,48 +2761,67 @@ class MCPServer {
2833
2761
  }
2834
2762
  }
2835
2763
  }
2836
-
2764
+
2765
+ /**
2766
+ * Create and configure Express app with shared middleware
2767
+ */
2768
+ createApp() {
2769
+ const app = express();
2770
+ app.use(express.json());
2771
+ app.use(cors());
2772
+ return app;
2773
+ }
2774
+
2837
2775
  /**
2838
- * Start the sse server
2776
+ * Start the server with HTTP streaming transport
2839
2777
  */
2840
- async startSse(host: string, port: number): Promise<void> {
2778
+ async startHttp(host: string, port: number): Promise<void> {
2841
2779
  try {
2842
- // Create sse transport
2843
- const app = express();
2844
- app.use(express.json());
2780
+ const app = this.createApp();
2845
2781
 
2846
- let transport: SSEServerTransport;
2847
- const sessions = {} as Record<string, SSEServerTransport>;
2782
+ // Create HTTP transport with session management
2783
+ const httpTransport = new StreamableHTTPServerTransport({
2784
+ sessionIdGenerator: () => {
2785
+ // Generate a simple session ID
2786
+ return `session-${Date.now()}-${Math.random().toString(36).substring(7)}`;
2787
+ },
2788
+ });
2848
2789
 
2849
- app.get('/sse', (req: Request, res: Response) => {
2850
- transport = new SSEServerTransport('/messages', res);
2851
- sessions[transport.sessionId] = transport;
2852
-
2853
- res.on('close', () => {
2854
- delete sessions[transport.sessionId];
2855
- });
2856
-
2857
- this.server.connect(transport);
2790
+ // Set up CORS for all routes
2791
+ app.options("*", (req, res) => {
2792
+ res.header("Access-Control-Allow-Origin", "*");
2793
+ res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
2794
+ res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, x-session-id");
2795
+ res.sendStatus(200);
2858
2796
  });
2859
2797
 
2860
- app.post('/messages', (req: Request, res: Response) => {
2861
- const sessionId = req.query.sessionId as string;
2862
- const transport = sessions[sessionId];
2863
- if (transport) {
2864
- transport.handlePostMessage(req, res);
2865
- } else {
2866
- res.status(400).send('No transport found for sessionId');
2867
- }
2798
+ // Health check endpoint
2799
+ app.get("/health", (req, res) => {
2800
+ res.status(200).json({ status: "ok", transport: "http" });
2801
+ });
2802
+
2803
+ // Set up the HTTP transport endpoint
2804
+ app.post("/", async (req, res) => {
2805
+ res.header("Access-Control-Allow-Origin", "*");
2806
+ res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
2807
+ res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, x-session-id");
2808
+ await httpTransport.handleRequest(req, res, req.body);
2809
+ });
2810
+
2811
+ // Start the server
2812
+ const server = app.listen(port, host, () => {
2813
+ this.log('info', `MCP Server with HTTP streaming transport started successfully with ${this.tools.size} tools`);
2814
+ this.log('info', `Listening on http://${host}:${port}`);
2868
2815
  });
2869
2816
 
2870
- app.listen(port, host);
2871
- this.log('info', `MCP Server with SSE transport started successfully with ${this.tools.size} tools`);
2872
- this.log('info', `Listening on ${host}:${port}`);
2817
+ // Connect the MCP server to the transport
2818
+ await this.server.connect(httpTransport);
2819
+
2873
2820
  } catch (error) {
2874
2821
  console.error("Failed to start MCP server:", error);
2875
2822
  process.exit(1);
2876
2823
  }
2877
- }
2824
+ }
2878
2825
 
2879
2826
  /**
2880
2827
  * Start the stdio server
@@ -2904,17 +2851,35 @@ async function main(): Promise<void> {
2904
2851
  const argv = minimist(process.argv.slice(2), {
2905
2852
  string: ['host'],
2906
2853
  int: ['port'],
2907
- boolean: ['sse'],
2854
+ boolean: ['stdio', 'http', 'help'],
2908
2855
  default: {
2909
2856
  host: '127.0.0.1',
2910
2857
  port: 8100,
2858
+ stdio: true,
2911
2859
  }
2912
2860
  });
2913
2861
 
2914
- const server = new MCPServer();
2862
+ // Show help if requested
2863
+ if (argv.help) {
2864
+ console.log(`
2865
+ Hostinger API MCP Server
2866
+ Usage: hostinger-api-mcp [options]
2867
+ Options:
2868
+ --http Use HTTP streaming transport
2869
+ --stdio Use standard input/output transport (default)
2870
+ --host <host> Host to bind to (default: 127.0.0.1)
2871
+ --port <port> Port to bind to (default: 8100)
2872
+ --help Show this help message
2873
+ Environment Variables:
2874
+ API_TOKEN Your Hostinger API token (required)
2875
+ DEBUG Enable debug logging (true/false)
2876
+ `);
2877
+ process.exit(0);
2878
+ }
2915
2879
 
2916
- if (argv.sse) {
2917
- await server.startSse(argv.host, argv.port);
2880
+ const server = new MCPServer();
2881
+ if (argv.http) {
2882
+ await server.startHttp(argv.host, argv.port);
2918
2883
  } else {
2919
2884
  await server.startStdio();
2920
2885
  }
package/tsconfig.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "es2020",
3
+ "target": "es2022",
4
4
  "module": "esnext",
5
5
  "moduleResolution": "node",
6
6
  "esModuleInterop": true,
package/types.d.ts CHANGED
@@ -1007,23 +1007,6 @@ such as the action name, timestamp, and status.
1007
1007
  response: any; // Response structure will depend on the API
1008
1008
  };
1009
1009
 
1010
- /**
1011
- * This endpoint deletes a specified backup for a virtual machine.
1012
- */
1013
- "undefined": {
1014
- params: {
1015
- /**
1016
- * Virtual Machine ID
1017
- */
1018
- virtualMachineId: number;
1019
- /**
1020
- * Backup ID
1021
- */
1022
- backupId: number;
1023
- };
1024
- response: any; // Response structure will depend on the API
1025
- };
1026
-
1027
1010
  /**
1028
1011
  * This endpoint retrieves a list of backups for a specified virtual machine.
1029
1012
  */
@@ -1238,6 +1221,10 @@ Be aware, that improper nameserver configuration can lead to the virtual machine
1238
1221
  * ns2 parameter
1239
1222
  */
1240
1223
  ns2?: string;
1224
+ /**
1225
+ * ns3 parameter
1226
+ */
1227
+ ns3?: string;
1241
1228
  };
1242
1229
  response: any; // Response structure will depend on the API
1243
1230
  };