hostinger-api-mcp 0.0.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 (4) hide show
  1. package/.env.example +10 -0
  2. package/README.md +922 -0
  3. package/package.json +35 -0
  4. package/server.js +1896 -0
package/server.js ADDED
@@ -0,0 +1,1896 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import axios from "axios";
5
+ import { config as dotenvConfig } from "dotenv";
6
+ import { ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
7
+ // Load environment variables
8
+ dotenvConfig();
9
+ // Define tool schemas
10
+ const TOOLS = [
11
+ {
12
+ "name": "billing_getCatalogItemListV1",
13
+ "description": "This endpoint retrieves a list of catalog items available for order. \n\nPrices in catalog items is displayed as cents (without floating point), e.g: float `17.99` is displayed as integer `1799`.",
14
+ "method": "GET",
15
+ "path": "/api/billing/v1/catalog",
16
+ "inputSchema": {
17
+ "type": "object",
18
+ "properties": {},
19
+ "required": []
20
+ },
21
+ "security": [
22
+ {
23
+ "apiToken": []
24
+ }
25
+ ]
26
+ },
27
+ {
28
+ "name": "billing_createNewServiceOrderV1",
29
+ "description": "This endpoint creates a new service order. \n\nTo place order, you need to provide payment method ID and list of price items from the catalog endpoint together with quantity.\nCoupons also can be provided during order creation.\n\nOrders created using this endpoint will be set for automatically renewal.",
30
+ "method": "POST",
31
+ "path": "/api/billing/v1/orders",
32
+ "inputSchema": {
33
+ "type": "object",
34
+ "properties": {
35
+ "payment_method_id": {
36
+ "type": "integer",
37
+ "description": "Payment method ID"
38
+ },
39
+ "items": {
40
+ "type": "array",
41
+ "description": "items property"
42
+ },
43
+ "coupons": {
44
+ "type": "array",
45
+ "description": "coupons property"
46
+ }
47
+ },
48
+ "required": [
49
+ "payment_method_id",
50
+ "items"
51
+ ]
52
+ },
53
+ "security": [
54
+ {
55
+ "apiToken": []
56
+ }
57
+ ]
58
+ },
59
+ {
60
+ "name": "billing_setDefaultPaymentMethodV1",
61
+ "description": "This endpoint sets default payment method for your account.",
62
+ "method": "POST",
63
+ "path": "/api/billing/v1/payment-methods/{paymentMethodId}",
64
+ "inputSchema": {
65
+ "type": "object",
66
+ "properties": {
67
+ "paymentMethodId": {
68
+ "type": "integer",
69
+ "description": "Payment method ID"
70
+ }
71
+ },
72
+ "required": [
73
+ "paymentMethodId"
74
+ ]
75
+ },
76
+ "security": [
77
+ {
78
+ "apiToken": []
79
+ }
80
+ ]
81
+ },
82
+ {
83
+ "name": "billing_deletePaymentMethodV1",
84
+ "description": "This endpoint deletes a payment method from your account.",
85
+ "method": "DELETE",
86
+ "path": "/api/billing/v1/payment-methods/{paymentMethodId}",
87
+ "inputSchema": {
88
+ "type": "object",
89
+ "properties": {
90
+ "paymentMethodId": {
91
+ "type": "integer",
92
+ "description": "Payment method ID"
93
+ }
94
+ },
95
+ "required": [
96
+ "paymentMethodId"
97
+ ]
98
+ },
99
+ "security": [
100
+ {
101
+ "apiToken": []
102
+ }
103
+ ]
104
+ },
105
+ {
106
+ "name": "billing_getPaymentMethodListV1",
107
+ "description": "This endpoint retrieves a list of available payment methods that can be used for placing new orders.\n\nIf you want to add new payment method, please use [hPanel](https://hpanel.hostinger.com/billing/payment-methods).",
108
+ "method": "GET",
109
+ "path": "/api/billing/v1/payment-methods",
110
+ "inputSchema": {
111
+ "type": "object",
112
+ "properties": {},
113
+ "required": []
114
+ },
115
+ "security": [
116
+ {
117
+ "apiToken": []
118
+ }
119
+ ]
120
+ },
121
+ {
122
+ "name": "billing_cancelSubscriptionV1",
123
+ "description": "This endpoint cancels a subscription and stops any further billing.",
124
+ "method": "DELETE",
125
+ "path": "/api/billing/v1/subscriptions/{subscriptionId}",
126
+ "inputSchema": {
127
+ "type": "object",
128
+ "properties": {
129
+ "subscriptionId": {
130
+ "type": "string",
131
+ "description": "Subscription ID"
132
+ }
133
+ },
134
+ "required": [
135
+ "subscriptionId"
136
+ ]
137
+ },
138
+ "security": [
139
+ {
140
+ "apiToken": []
141
+ }
142
+ ]
143
+ },
144
+ {
145
+ "name": "billing_getSubscriptionListV1",
146
+ "description": "This endpoint retrieves a list of all subscriptions associated with your account.",
147
+ "method": "GET",
148
+ "path": "/api/billing/v1/subscriptions",
149
+ "inputSchema": {
150
+ "type": "object",
151
+ "properties": {},
152
+ "required": []
153
+ },
154
+ "security": [
155
+ {
156
+ "apiToken": []
157
+ }
158
+ ]
159
+ },
160
+ {
161
+ "name": "domains_getDomainListV1",
162
+ "description": "This endpoint retrieves a list of all domains associated with your account.",
163
+ "method": "GET",
164
+ "path": "/api/domains/v1/portfolio",
165
+ "inputSchema": {
166
+ "type": "object",
167
+ "properties": {},
168
+ "required": []
169
+ },
170
+ "security": [
171
+ {
172
+ "apiToken": []
173
+ }
174
+ ]
175
+ },
176
+ {
177
+ "name": "VPS_getDataCentersListV1",
178
+ "description": "This endpoint retrieves a list of all data centers available.",
179
+ "method": "GET",
180
+ "path": "/api/vps/v1/data-centers",
181
+ "inputSchema": {
182
+ "type": "object",
183
+ "properties": {},
184
+ "required": []
185
+ },
186
+ "security": [
187
+ {
188
+ "apiToken": []
189
+ }
190
+ ]
191
+ },
192
+ {
193
+ "name": "VPS_activateFirewallV1",
194
+ "description": "This endpoint activates a firewall for a specified virtual machine. \n\nOnly one firewall can be active for a virtual machine at a time.",
195
+ "method": "POST",
196
+ "path": "/api/vps/v1/firewall/{firewallId}/activate/{virtualMachineId}",
197
+ "inputSchema": {
198
+ "type": "object",
199
+ "properties": {
200
+ "firewallId": {
201
+ "type": "integer",
202
+ "description": "Firewall ID"
203
+ },
204
+ "virtualMachineId": {
205
+ "type": "integer",
206
+ "description": "Virtual Machine ID"
207
+ }
208
+ },
209
+ "required": [
210
+ "firewallId",
211
+ "virtualMachineId"
212
+ ]
213
+ },
214
+ "security": [
215
+ {
216
+ "apiToken": []
217
+ }
218
+ ]
219
+ },
220
+ {
221
+ "name": "VPS_deactivateFirewallV1",
222
+ "description": "This endpoint deactivates a firewall for a specified virtual machine.",
223
+ "method": "POST",
224
+ "path": "/api/vps/v1/firewall/{firewallId}/deactivate/{virtualMachineId}",
225
+ "inputSchema": {
226
+ "type": "object",
227
+ "properties": {
228
+ "firewallId": {
229
+ "type": "integer",
230
+ "description": "Firewall ID"
231
+ },
232
+ "virtualMachineId": {
233
+ "type": "integer",
234
+ "description": "Virtual Machine ID"
235
+ }
236
+ },
237
+ "required": [
238
+ "firewallId",
239
+ "virtualMachineId"
240
+ ]
241
+ },
242
+ "security": [
243
+ {
244
+ "apiToken": []
245
+ }
246
+ ]
247
+ },
248
+ {
249
+ "name": "VPS_getFirewallV1",
250
+ "description": "This endpoint retrieves firewall by its ID and rules associated with it.",
251
+ "method": "GET",
252
+ "path": "/api/vps/v1/firewall/{firewallId}",
253
+ "inputSchema": {
254
+ "type": "object",
255
+ "properties": {
256
+ "firewallId": {
257
+ "type": "integer",
258
+ "description": "Firewall ID"
259
+ }
260
+ },
261
+ "required": [
262
+ "firewallId"
263
+ ]
264
+ },
265
+ "security": [
266
+ {
267
+ "apiToken": []
268
+ }
269
+ ]
270
+ },
271
+ {
272
+ "name": "VPS_deleteFirewallV1",
273
+ "description": "This endpoint deletes a specified firewall. \n\nAny virtual machine that has this firewall activated will automatically have it deactivated.",
274
+ "method": "DELETE",
275
+ "path": "/api/vps/v1/firewall/{firewallId}",
276
+ "inputSchema": {
277
+ "type": "object",
278
+ "properties": {
279
+ "firewallId": {
280
+ "type": "integer",
281
+ "description": "Firewall ID"
282
+ }
283
+ },
284
+ "required": [
285
+ "firewallId"
286
+ ]
287
+ },
288
+ "security": [
289
+ {
290
+ "apiToken": []
291
+ }
292
+ ]
293
+ },
294
+ {
295
+ "name": "VPS_getFirewallListV1",
296
+ "description": "This endpoint retrieves a list of all firewalls available.",
297
+ "method": "GET",
298
+ "path": "/api/vps/v1/firewall",
299
+ "inputSchema": {
300
+ "type": "object",
301
+ "properties": {
302
+ "page": {
303
+ "type": "integer",
304
+ "description": "Page number"
305
+ }
306
+ },
307
+ "required": []
308
+ },
309
+ "security": [
310
+ {
311
+ "apiToken": []
312
+ }
313
+ ]
314
+ },
315
+ {
316
+ "name": "VPS_createNewFirewallV1",
317
+ "description": "This endpoint creates a new firewall.",
318
+ "method": "POST",
319
+ "path": "/api/vps/v1/firewall",
320
+ "inputSchema": {
321
+ "type": "object",
322
+ "properties": {
323
+ "name": {
324
+ "type": "string",
325
+ "description": "name property"
326
+ }
327
+ },
328
+ "required": [
329
+ "name"
330
+ ]
331
+ },
332
+ "security": [
333
+ {
334
+ "apiToken": []
335
+ }
336
+ ]
337
+ },
338
+ {
339
+ "name": "VPS_updateFirewallRuleV1",
340
+ "description": "This endpoint updates a specific firewall rule from a specified firewall.\n\nAny virtual machine that has this firewall activated will loose sync with the firewall and will have to be synced again manually.",
341
+ "method": "PUT",
342
+ "path": "/api/vps/v1/firewall/{firewallId}/rules/{ruleId}",
343
+ "inputSchema": {
344
+ "type": "object",
345
+ "properties": {
346
+ "firewallId": {
347
+ "type": "integer",
348
+ "description": "Firewall ID"
349
+ },
350
+ "ruleId": {
351
+ "type": "integer",
352
+ "description": "Firewall Rule ID"
353
+ },
354
+ "protocol": {
355
+ "type": "string",
356
+ "description": "protocol property",
357
+ "enum": [
358
+ "TCP",
359
+ "UDP",
360
+ "ICMP",
361
+ "GRE",
362
+ "any",
363
+ "ESP",
364
+ "AH",
365
+ "ICMPv6",
366
+ "SSH",
367
+ "HTTP",
368
+ "HTTPS",
369
+ "MySQL",
370
+ "PostgreSQL"
371
+ ]
372
+ },
373
+ "port": {
374
+ "type": "string",
375
+ "description": "Port or port range, ex: 1024:2048"
376
+ },
377
+ "source": {
378
+ "type": "string",
379
+ "description": "source property",
380
+ "enum": [
381
+ "any",
382
+ "custom"
383
+ ]
384
+ },
385
+ "source_detail": {
386
+ "type": "string",
387
+ "description": "IP range, CIDR, single IP or `any`"
388
+ }
389
+ },
390
+ "required": [
391
+ "firewallId",
392
+ "ruleId",
393
+ "protocol",
394
+ "port",
395
+ "source",
396
+ "source_detail"
397
+ ]
398
+ },
399
+ "security": [
400
+ {
401
+ "apiToken": []
402
+ }
403
+ ]
404
+ },
405
+ {
406
+ "name": "VPS_deleteFirewallRuleV1",
407
+ "description": "This endpoint deletes a specific firewall rule from a specified firewall.\n\nAny virtual machine that has this firewall activated will loose sync with the firewall and will have to be synced again manually.",
408
+ "method": "DELETE",
409
+ "path": "/api/vps/v1/firewall/{firewallId}/rules/{ruleId}",
410
+ "inputSchema": {
411
+ "type": "object",
412
+ "properties": {
413
+ "firewallId": {
414
+ "type": "integer",
415
+ "description": "Firewall ID"
416
+ },
417
+ "ruleId": {
418
+ "type": "integer",
419
+ "description": "Firewall Rule ID"
420
+ }
421
+ },
422
+ "required": [
423
+ "firewallId",
424
+ "ruleId"
425
+ ]
426
+ },
427
+ "security": [
428
+ {
429
+ "apiToken": []
430
+ }
431
+ ]
432
+ },
433
+ {
434
+ "name": "VPS_createFirewallRuleV1",
435
+ "description": "This endpoint creates new firewall rule from a specified firewall. \nBy default, the firewall drops all incoming traffic, which means you must add accept rules for all ports you want to use.\n\nAny virtual machine that has this firewall activated will loose sync with the firewall and will have to be synced again manually.",
436
+ "method": "POST",
437
+ "path": "/api/vps/v1/firewall/{firewallId}/rules",
438
+ "inputSchema": {
439
+ "type": "object",
440
+ "properties": {
441
+ "firewallId": {
442
+ "type": "integer",
443
+ "description": "Firewall ID"
444
+ },
445
+ "protocol": {
446
+ "type": "string",
447
+ "description": "protocol property",
448
+ "enum": [
449
+ "TCP",
450
+ "UDP",
451
+ "ICMP",
452
+ "GRE",
453
+ "any",
454
+ "ESP",
455
+ "AH",
456
+ "ICMPv6",
457
+ "SSH",
458
+ "HTTP",
459
+ "HTTPS",
460
+ "MySQL",
461
+ "PostgreSQL"
462
+ ]
463
+ },
464
+ "port": {
465
+ "type": "string",
466
+ "description": "Port or port range, ex: 1024:2048"
467
+ },
468
+ "source": {
469
+ "type": "string",
470
+ "description": "source property",
471
+ "enum": [
472
+ "any",
473
+ "custom"
474
+ ]
475
+ },
476
+ "source_detail": {
477
+ "type": "string",
478
+ "description": "IP range, CIDR, single IP or `any`"
479
+ }
480
+ },
481
+ "required": [
482
+ "firewallId",
483
+ "protocol",
484
+ "port",
485
+ "source",
486
+ "source_detail"
487
+ ]
488
+ },
489
+ "security": [
490
+ {
491
+ "apiToken": []
492
+ }
493
+ ]
494
+ },
495
+ {
496
+ "name": "VPS_syncFirewallV1",
497
+ "description": "This endpoint syncs a firewall for a specified virtual machine.\n\nFirewall can loose sync with virtual machine if the firewall has new rules added, removed or updated.",
498
+ "method": "POST",
499
+ "path": "/api/vps/v1/firewall/{firewallId}/sync/{virtualMachineId}",
500
+ "inputSchema": {
501
+ "type": "object",
502
+ "properties": {
503
+ "firewallId": {
504
+ "type": "integer",
505
+ "description": "Firewall ID"
506
+ },
507
+ "virtualMachineId": {
508
+ "type": "integer",
509
+ "description": "Virtual Machine ID"
510
+ }
511
+ },
512
+ "required": [
513
+ "firewallId",
514
+ "virtualMachineId"
515
+ ]
516
+ },
517
+ "security": [
518
+ {
519
+ "apiToken": []
520
+ }
521
+ ]
522
+ },
523
+ {
524
+ "name": "VPS_getPostInstallScriptV1",
525
+ "description": "This endpoint retrieves post-install script by its ID.",
526
+ "method": "GET",
527
+ "path": "/api/vps/v1/post-install-scripts/{postInstallScriptId}",
528
+ "inputSchema": {
529
+ "type": "object",
530
+ "properties": {
531
+ "postInstallScriptId": {
532
+ "type": "integer",
533
+ "description": "Post-install script ID"
534
+ }
535
+ },
536
+ "required": [
537
+ "postInstallScriptId"
538
+ ]
539
+ },
540
+ "security": [
541
+ {
542
+ "apiToken": []
543
+ }
544
+ ]
545
+ },
546
+ {
547
+ "name": "VPS_updatePostInstallScriptV1",
548
+ "description": "This endpoint updates a specific post-install script.",
549
+ "method": "PUT",
550
+ "path": "/api/vps/v1/post-install-scripts/{postInstallScriptId}",
551
+ "inputSchema": {
552
+ "type": "object",
553
+ "properties": {
554
+ "postInstallScriptId": {
555
+ "type": "integer",
556
+ "description": "Post-install script ID"
557
+ },
558
+ "name": {
559
+ "type": "string",
560
+ "description": "Name of the script"
561
+ },
562
+ "content": {
563
+ "type": "string",
564
+ "description": "Content of the script"
565
+ }
566
+ },
567
+ "required": [
568
+ "postInstallScriptId",
569
+ "name",
570
+ "content"
571
+ ]
572
+ },
573
+ "security": [
574
+ {
575
+ "apiToken": []
576
+ }
577
+ ]
578
+ },
579
+ {
580
+ "name": "VPS_deleteAPostInstallScriptV1",
581
+ "description": "This endpoint deletes a post-install script from your account. ",
582
+ "method": "DELETE",
583
+ "path": "/api/vps/v1/post-install-scripts/{postInstallScriptId}",
584
+ "inputSchema": {
585
+ "type": "object",
586
+ "properties": {
587
+ "postInstallScriptId": {
588
+ "type": "integer",
589
+ "description": "Post-install script ID"
590
+ }
591
+ },
592
+ "required": [
593
+ "postInstallScriptId"
594
+ ]
595
+ },
596
+ "security": [
597
+ {
598
+ "apiToken": []
599
+ }
600
+ ]
601
+ },
602
+ {
603
+ "name": "VPS_getPostInstallScriptListV1",
604
+ "description": "This endpoint retrieves a list of post-install scripts associated with your account.",
605
+ "method": "GET",
606
+ "path": "/api/vps/v1/post-install-scripts",
607
+ "inputSchema": {
608
+ "type": "object",
609
+ "properties": {
610
+ "page": {
611
+ "type": "integer",
612
+ "description": "Page number"
613
+ }
614
+ },
615
+ "required": []
616
+ },
617
+ "security": [
618
+ {
619
+ "apiToken": []
620
+ }
621
+ ]
622
+ },
623
+ {
624
+ "name": "VPS_createPostInstallScriptV1",
625
+ "description": "This endpoint allows you to add a new post-install script to your account, \nwhich can then be used run after the installation of a virtual machine instance.\n\nThe script contents will be saved to the file `/post_install` with executable attribute set and will be executed once virtual machine is installed.\nThe output of the script will be redirected to `/post_install.log`. Maximum script size is 48KB. ",
626
+ "method": "POST",
627
+ "path": "/api/vps/v1/post-install-scripts",
628
+ "inputSchema": {
629
+ "type": "object",
630
+ "properties": {
631
+ "name": {
632
+ "type": "string",
633
+ "description": "Name of the script"
634
+ },
635
+ "content": {
636
+ "type": "string",
637
+ "description": "Content of the script"
638
+ }
639
+ },
640
+ "required": [
641
+ "name",
642
+ "content"
643
+ ]
644
+ },
645
+ "security": [
646
+ {
647
+ "apiToken": []
648
+ }
649
+ ]
650
+ },
651
+ {
652
+ "name": "VPS_attachPublicKeyV1",
653
+ "description": "This endpoint attaches an existing public keys from your account to a specified virtual machine.\n\nMultiple keys can be attached to a single virtual machine.",
654
+ "method": "POST",
655
+ "path": "/api/vps/v1/public-keys/attach/{virtualMachineId}",
656
+ "inputSchema": {
657
+ "type": "object",
658
+ "properties": {
659
+ "virtualMachineId": {
660
+ "type": "integer",
661
+ "description": "Virtual Machine ID"
662
+ },
663
+ "ids": {
664
+ "type": "array",
665
+ "description": "Public Key IDs to attach"
666
+ }
667
+ },
668
+ "required": [
669
+ "virtualMachineId",
670
+ "ids"
671
+ ]
672
+ },
673
+ "security": [
674
+ {
675
+ "apiToken": []
676
+ }
677
+ ]
678
+ },
679
+ {
680
+ "name": "VPS_deleteAPublicKeyV1",
681
+ "description": "This endpoint deletes a public key from your account. \n\n**Deleting public key from account does not remove it from virtual machine** ",
682
+ "method": "DELETE",
683
+ "path": "/api/vps/v1/public-keys/{publicKeyId}",
684
+ "inputSchema": {
685
+ "type": "object",
686
+ "properties": {
687
+ "publicKeyId": {
688
+ "type": "integer",
689
+ "description": "Public Key ID"
690
+ }
691
+ },
692
+ "required": [
693
+ "publicKeyId"
694
+ ]
695
+ },
696
+ "security": [
697
+ {
698
+ "apiToken": []
699
+ }
700
+ ]
701
+ },
702
+ {
703
+ "name": "VPS_getPublicKeyListV1",
704
+ "description": "This endpoint retrieves a list of public keys associated with your account.",
705
+ "method": "GET",
706
+ "path": "/api/vps/v1/public-keys",
707
+ "inputSchema": {
708
+ "type": "object",
709
+ "properties": {
710
+ "page": {
711
+ "type": "integer",
712
+ "description": "Page number"
713
+ }
714
+ },
715
+ "required": []
716
+ },
717
+ "security": [
718
+ {
719
+ "apiToken": []
720
+ }
721
+ ]
722
+ },
723
+ {
724
+ "name": "VPS_createNewPublicKeyV1",
725
+ "description": "This endpoint allows you to add a new public key to your account, \nwhich can then be attached to virtual machine instances for secure access.",
726
+ "method": "POST",
727
+ "path": "/api/vps/v1/public-keys",
728
+ "inputSchema": {
729
+ "type": "object",
730
+ "properties": {
731
+ "name": {
732
+ "type": "string",
733
+ "description": "name property"
734
+ },
735
+ "key": {
736
+ "type": "string",
737
+ "description": "key property"
738
+ }
739
+ },
740
+ "required": [
741
+ "name",
742
+ "key"
743
+ ]
744
+ },
745
+ "security": [
746
+ {
747
+ "apiToken": []
748
+ }
749
+ ]
750
+ },
751
+ {
752
+ "name": "VPS_getTemplateV1",
753
+ "description": "This endpoint retrieves details of a specific OS template for virtual machines.",
754
+ "method": "GET",
755
+ "path": "/api/vps/v1/templates/{templateId}",
756
+ "inputSchema": {
757
+ "type": "object",
758
+ "properties": {
759
+ "templateId": {
760
+ "type": "integer",
761
+ "description": "Template ID"
762
+ }
763
+ },
764
+ "required": [
765
+ "templateId"
766
+ ]
767
+ },
768
+ "security": [
769
+ {
770
+ "apiToken": []
771
+ }
772
+ ]
773
+ },
774
+ {
775
+ "name": "VPS_getTemplateListV1",
776
+ "description": "This endpoint retrieves a list of available OS templates for virtual machines.",
777
+ "method": "GET",
778
+ "path": "/api/vps/v1/templates",
779
+ "inputSchema": {
780
+ "type": "object",
781
+ "properties": {},
782
+ "required": []
783
+ },
784
+ "security": [
785
+ {
786
+ "apiToken": []
787
+ }
788
+ ]
789
+ },
790
+ {
791
+ "name": "VPS_getActionV1",
792
+ "description": "This endpoint retrieves details of a specific action performed on a specified virtual machine. \n\nThis endpoint allows you to view detailed information about a particular action, including the action name, timestamp, and status.",
793
+ "method": "GET",
794
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/actions/{actionId}",
795
+ "inputSchema": {
796
+ "type": "object",
797
+ "properties": {
798
+ "virtualMachineId": {
799
+ "type": "integer",
800
+ "description": "Virtual Machine ID"
801
+ },
802
+ "actionId": {
803
+ "type": "integer",
804
+ "description": "Action ID"
805
+ }
806
+ },
807
+ "required": [
808
+ "virtualMachineId",
809
+ "actionId"
810
+ ]
811
+ },
812
+ "security": [
813
+ {
814
+ "apiToken": []
815
+ }
816
+ ]
817
+ },
818
+ {
819
+ "name": "VPS_getActionListV1",
820
+ "description": "This endpoint retrieves a list of actions performed on a specified virtual machine.\n\nActions are operations or events that have been executed on the virtual machine, such as starting, stopping, or modifying \nthe machine. This endpoint allows you to view the history of these actions, providing details about each action, \nsuch as the action name, timestamp, and status.",
821
+ "method": "GET",
822
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/actions",
823
+ "inputSchema": {
824
+ "type": "object",
825
+ "properties": {
826
+ "virtualMachineId": {
827
+ "type": "integer",
828
+ "description": "Virtual Machine ID"
829
+ },
830
+ "page": {
831
+ "type": "integer",
832
+ "description": "Page number"
833
+ }
834
+ },
835
+ "required": [
836
+ "virtualMachineId"
837
+ ]
838
+ },
839
+ "security": [
840
+ {
841
+ "apiToken": []
842
+ }
843
+ ]
844
+ },
845
+ {
846
+ "name": "VPS_getAttachedPublicKeysV1",
847
+ "description": "This endpoint retrieves a list of public keys attached to a specified virtual machine.",
848
+ "method": "GET",
849
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/public-keys",
850
+ "inputSchema": {
851
+ "type": "object",
852
+ "properties": {
853
+ "virtualMachineId": {
854
+ "type": "integer",
855
+ "description": "Virtual Machine ID"
856
+ },
857
+ "page": {
858
+ "type": "integer",
859
+ "description": "Page number"
860
+ }
861
+ },
862
+ "required": [
863
+ "virtualMachineId"
864
+ ]
865
+ },
866
+ "security": [
867
+ {
868
+ "apiToken": []
869
+ }
870
+ ]
871
+ },
872
+ {
873
+ "name": "VPS_deleteBackupV1",
874
+ "description": "This endpoint deletes a specified backup for a virtual machine.",
875
+ "method": "DELETE",
876
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/backups/{backupId}",
877
+ "inputSchema": {
878
+ "type": "object",
879
+ "properties": {
880
+ "virtualMachineId": {
881
+ "type": "integer",
882
+ "description": "Virtual Machine ID"
883
+ },
884
+ "backupId": {
885
+ "type": "integer",
886
+ "description": "Backup ID"
887
+ }
888
+ },
889
+ "required": [
890
+ "virtualMachineId",
891
+ "backupId"
892
+ ]
893
+ },
894
+ "security": [
895
+ {
896
+ "apiToken": []
897
+ }
898
+ ]
899
+ },
900
+ {
901
+ "name": "VPS_getBackupListV1",
902
+ "description": "This endpoint retrieves a list of backups for a specified virtual machine.",
903
+ "method": "GET",
904
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/backups",
905
+ "inputSchema": {
906
+ "type": "object",
907
+ "properties": {
908
+ "page": {
909
+ "type": "integer",
910
+ "description": "Page number"
911
+ },
912
+ "virtualMachineId": {
913
+ "type": "integer",
914
+ "description": "Virtual Machine ID"
915
+ }
916
+ },
917
+ "required": [
918
+ "virtualMachineId"
919
+ ]
920
+ },
921
+ "security": [
922
+ {
923
+ "apiToken": []
924
+ }
925
+ ]
926
+ },
927
+ {
928
+ "name": "VPS_restoreBackupV1",
929
+ "description": "This endpoint restores a backup for a specified virtual machine.\n\nThe system will then initiate the restore process, which may take some time depending on the size of the backup.\n\n**All data on the virtual machine will be overwritten with the data from the backup.**",
930
+ "method": "POST",
931
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/backups/{backupId}/restore",
932
+ "inputSchema": {
933
+ "type": "object",
934
+ "properties": {
935
+ "virtualMachineId": {
936
+ "type": "integer",
937
+ "description": "Virtual Machine ID"
938
+ },
939
+ "backupId": {
940
+ "type": "integer",
941
+ "description": "Backup ID"
942
+ }
943
+ },
944
+ "required": [
945
+ "virtualMachineId",
946
+ "backupId"
947
+ ]
948
+ },
949
+ "security": [
950
+ {
951
+ "apiToken": []
952
+ }
953
+ ]
954
+ },
955
+ {
956
+ "name": "VPS_setHostnameV1",
957
+ "description": "This endpoint sets the hostname for a specified virtual machine. \nChanging hostname does not update PTR record automatically.\nIf you want your virtual machine to be reachable by a hostname, \nyou need to point your domain A/AAAA records to virtual machine IP as well.",
958
+ "method": "PUT",
959
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/hostname",
960
+ "inputSchema": {
961
+ "type": "object",
962
+ "properties": {
963
+ "virtualMachineId": {
964
+ "type": "integer",
965
+ "description": "Virtual Machine ID"
966
+ },
967
+ "hostname": {
968
+ "type": "string",
969
+ "description": "hostname property"
970
+ }
971
+ },
972
+ "required": [
973
+ "virtualMachineId",
974
+ "hostname"
975
+ ]
976
+ },
977
+ "security": [
978
+ {
979
+ "apiToken": []
980
+ }
981
+ ]
982
+ },
983
+ {
984
+ "name": "VPS_resetHostnameV1",
985
+ "description": "This endpoint resets the hostname and PTR record of a specified virtual machine to the default value.",
986
+ "method": "DELETE",
987
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/hostname",
988
+ "inputSchema": {
989
+ "type": "object",
990
+ "properties": {
991
+ "virtualMachineId": {
992
+ "type": "integer",
993
+ "description": "Virtual Machine ID"
994
+ }
995
+ },
996
+ "required": [
997
+ "virtualMachineId"
998
+ ]
999
+ },
1000
+ "security": [
1001
+ {
1002
+ "apiToken": []
1003
+ }
1004
+ ]
1005
+ },
1006
+ {
1007
+ "name": "VPS_getVirtualMachineV1",
1008
+ "description": "This endpoint retrieves detailed information about a specified virtual machine.",
1009
+ "method": "GET",
1010
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}",
1011
+ "inputSchema": {
1012
+ "type": "object",
1013
+ "properties": {
1014
+ "virtualMachineId": {
1015
+ "type": "integer",
1016
+ "description": "Virtual Machine ID"
1017
+ }
1018
+ },
1019
+ "required": [
1020
+ "virtualMachineId"
1021
+ ]
1022
+ },
1023
+ "security": [
1024
+ {
1025
+ "apiToken": []
1026
+ }
1027
+ ]
1028
+ },
1029
+ {
1030
+ "name": "VPS_getVirtualMachineListV1",
1031
+ "description": "This endpoint retrieves a list of all available virtual machines.",
1032
+ "method": "GET",
1033
+ "path": "/api/vps/v1/virtual-machines",
1034
+ "inputSchema": {
1035
+ "type": "object",
1036
+ "properties": {},
1037
+ "required": []
1038
+ },
1039
+ "security": [
1040
+ {
1041
+ "apiToken": []
1042
+ }
1043
+ ]
1044
+ },
1045
+ {
1046
+ "name": "VPS_getScanMetricsV1",
1047
+ "description": "This endpoint retrieves the scan metrics for the [Monarx](https://www.monarx.com/) malware scanner installed on a specified virtual machine.\nThe scan metrics provide detailed information about the malware scans performed by Monarx, including the number of scans, \ndetected threats, and other relevant statistics. This information is useful for monitoring the security status of the \nvirtual machine and assessing the effectiveness of the malware scanner.",
1048
+ "method": "GET",
1049
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/monarx",
1050
+ "inputSchema": {
1051
+ "type": "object",
1052
+ "properties": {
1053
+ "virtualMachineId": {
1054
+ "type": "integer",
1055
+ "description": "Virtual Machine ID"
1056
+ }
1057
+ },
1058
+ "required": [
1059
+ "virtualMachineId"
1060
+ ]
1061
+ },
1062
+ "security": [
1063
+ {
1064
+ "apiToken": []
1065
+ }
1066
+ ]
1067
+ },
1068
+ {
1069
+ "name": "VPS_installMonarxV1",
1070
+ "description": "This endpoint installs the Monarx malware scanner on a specified virtual machine. \n\n[Monarx](https://www.monarx.com/) is a security tool designed to detect and prevent malware infections on virtual machines. \nBy installing Monarx, users can enhance the security of their virtual machines, ensuring that they are protected against malicious software.",
1071
+ "method": "POST",
1072
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/monarx",
1073
+ "inputSchema": {
1074
+ "type": "object",
1075
+ "properties": {
1076
+ "virtualMachineId": {
1077
+ "type": "integer",
1078
+ "description": "Virtual Machine ID"
1079
+ }
1080
+ },
1081
+ "required": [
1082
+ "virtualMachineId"
1083
+ ]
1084
+ },
1085
+ "security": [
1086
+ {
1087
+ "apiToken": []
1088
+ }
1089
+ ]
1090
+ },
1091
+ {
1092
+ "name": "VPS_uninstallMonarxV1",
1093
+ "description": "This endpoint uninstalls the Monarx malware scanner on a specified virtual machine.\nIf Monarx is not installed, the request will still be processed without any effect.",
1094
+ "method": "DELETE",
1095
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/monarx",
1096
+ "inputSchema": {
1097
+ "type": "object",
1098
+ "properties": {
1099
+ "virtualMachineId": {
1100
+ "type": "integer",
1101
+ "description": "Virtual Machine ID"
1102
+ }
1103
+ },
1104
+ "required": [
1105
+ "virtualMachineId"
1106
+ ]
1107
+ },
1108
+ "security": [
1109
+ {
1110
+ "apiToken": []
1111
+ }
1112
+ ]
1113
+ },
1114
+ {
1115
+ "name": "VPS_getMetricsV1",
1116
+ "description": "This endpoint retrieves the historical metrics for a specified virtual machine.\nIt includes the following metrics: \n- CPU usage\n- Memory usage\n- Disk usage\n- Network usage\n- Uptime",
1117
+ "method": "GET",
1118
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/metrics",
1119
+ "inputSchema": {
1120
+ "type": "object",
1121
+ "properties": {
1122
+ "virtualMachineId": {
1123
+ "type": "integer",
1124
+ "description": "Virtual Machine ID"
1125
+ },
1126
+ "date_from": {
1127
+ "type": "string",
1128
+ "description": "the date-time notation as defined by RFC 3339, section 5.6"
1129
+ },
1130
+ "date_to": {
1131
+ "type": "string",
1132
+ "description": "the date-time notation as defined by RFC 3339, section 5.6"
1133
+ }
1134
+ },
1135
+ "required": [
1136
+ "virtualMachineId",
1137
+ "date_from",
1138
+ "date_to"
1139
+ ]
1140
+ },
1141
+ "security": [
1142
+ {
1143
+ "apiToken": []
1144
+ }
1145
+ ]
1146
+ },
1147
+ {
1148
+ "name": "VPS_setNameserversV1",
1149
+ "description": "This endpoint sets the nameservers for a specified virtual machine.\nBe aware, that improper nameserver configuration can lead to the virtual machine being unable to resolve domain names.",
1150
+ "method": "PUT",
1151
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/nameservers",
1152
+ "inputSchema": {
1153
+ "type": "object",
1154
+ "properties": {
1155
+ "virtualMachineId": {
1156
+ "type": "integer",
1157
+ "description": "Virtual Machine ID"
1158
+ },
1159
+ "ns1": {
1160
+ "type": "string",
1161
+ "description": "ns1 property"
1162
+ },
1163
+ "ns2": {
1164
+ "type": "string",
1165
+ "description": "ns2 property"
1166
+ }
1167
+ },
1168
+ "required": [
1169
+ "virtualMachineId",
1170
+ "ns1"
1171
+ ]
1172
+ },
1173
+ "security": [
1174
+ {
1175
+ "apiToken": []
1176
+ }
1177
+ ]
1178
+ },
1179
+ {
1180
+ "name": "VPS_createPTRRecordV1",
1181
+ "description": "This endpoint creates or updates a PTR (Pointer) record for a specified virtual machine.",
1182
+ "method": "POST",
1183
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/ptr",
1184
+ "inputSchema": {
1185
+ "type": "object",
1186
+ "properties": {
1187
+ "virtualMachineId": {
1188
+ "type": "integer",
1189
+ "description": "Virtual Machine ID"
1190
+ }
1191
+ },
1192
+ "required": [
1193
+ "virtualMachineId"
1194
+ ]
1195
+ },
1196
+ "security": [
1197
+ {
1198
+ "apiToken": []
1199
+ }
1200
+ ]
1201
+ },
1202
+ {
1203
+ "name": "VPS_deletePTRRecordV1",
1204
+ "description": "This endpoint deletes a PTR (Pointer) record for a specified virtual machine. \n\nOnce deleted, reverse DNS lookups to the virtual machine's IP address will no longer return the previously configured hostname.",
1205
+ "method": "DELETE",
1206
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/ptr",
1207
+ "inputSchema": {
1208
+ "type": "object",
1209
+ "properties": {
1210
+ "virtualMachineId": {
1211
+ "type": "integer",
1212
+ "description": "Virtual Machine ID"
1213
+ }
1214
+ },
1215
+ "required": [
1216
+ "virtualMachineId"
1217
+ ]
1218
+ },
1219
+ "security": [
1220
+ {
1221
+ "apiToken": []
1222
+ }
1223
+ ]
1224
+ },
1225
+ {
1226
+ "name": "VPS_setPanelPasswordV1",
1227
+ "description": "This endpoint sets the panel password for a specified virtual machine. \nIf virtual machine does not use panel OS, the request will still be processed without any effect.\nRequirements for the password is the same as in the [recreate virtual machine endpoint](/#tag/vps-virtual-machine/POST/api/vps/v1/virtual-machines/{virtualMachineId}/recreate).",
1228
+ "method": "PUT",
1229
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/panel-password",
1230
+ "inputSchema": {
1231
+ "type": "object",
1232
+ "properties": {
1233
+ "virtualMachineId": {
1234
+ "type": "integer",
1235
+ "description": "Virtual Machine ID"
1236
+ },
1237
+ "password": {
1238
+ "type": "string",
1239
+ "description": "Panel password for the virtual machine"
1240
+ }
1241
+ },
1242
+ "required": [
1243
+ "virtualMachineId",
1244
+ "password"
1245
+ ]
1246
+ },
1247
+ "security": [
1248
+ {
1249
+ "apiToken": []
1250
+ }
1251
+ ]
1252
+ },
1253
+ {
1254
+ "name": "VPS_startRecoveryModeV1",
1255
+ "description": "This endpoint initiates the recovery mode for a specified virtual machine. \nRecovery mode is a special state that allows users to perform system rescue operations, \nsuch as repairing file systems, recovering data, or troubleshooting issues that prevent the virtual machine \nfrom booting normally. \n\nVirtual machine will boot recovery disk image and original disk image will be mounted in `/mnt` directory.",
1256
+ "method": "POST",
1257
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/recovery",
1258
+ "inputSchema": {
1259
+ "type": "object",
1260
+ "properties": {
1261
+ "virtualMachineId": {
1262
+ "type": "integer",
1263
+ "description": "Virtual Machine ID"
1264
+ },
1265
+ "root_password": {
1266
+ "type": "string",
1267
+ "description": "Temporary root password for recovery mode"
1268
+ }
1269
+ },
1270
+ "required": [
1271
+ "virtualMachineId",
1272
+ "root_password"
1273
+ ]
1274
+ },
1275
+ "security": [
1276
+ {
1277
+ "apiToken": []
1278
+ }
1279
+ ]
1280
+ },
1281
+ {
1282
+ "name": "VPS_stopRecoveryModeV1",
1283
+ "description": "This endpoint stops the recovery mode for a specified virtual machine. \nIf virtual machine is not in recovery mode, this operation will fail.",
1284
+ "method": "DELETE",
1285
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/recovery",
1286
+ "inputSchema": {
1287
+ "type": "object",
1288
+ "properties": {
1289
+ "virtualMachineId": {
1290
+ "type": "integer",
1291
+ "description": "Virtual Machine ID"
1292
+ }
1293
+ },
1294
+ "required": [
1295
+ "virtualMachineId"
1296
+ ]
1297
+ },
1298
+ "security": [
1299
+ {
1300
+ "apiToken": []
1301
+ }
1302
+ ]
1303
+ },
1304
+ {
1305
+ "name": "VPS_recreateVirtualMachineV1",
1306
+ "description": "This endpoint will recreate a virtual machine from scratch. \nThe recreation process involves reinstalling the operating system and resetting the virtual machine to its initial state.\nSnapshots, if there are any, will be deleted.\n\n## Password Requirements\nPassword will be checked against leaked password databases. \nRequirements for the password are:\n- At least 8 characters long\n- At least one uppercase letter\n- At least one lowercase letter\n- At least one number\n- Is not leaked publicly\n\n**This operation is irreversible and will result in the loss of all data stored on the virtual machine!**",
1307
+ "method": "POST",
1308
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/recreate",
1309
+ "inputSchema": {
1310
+ "type": "object",
1311
+ "properties": {
1312
+ "virtualMachineId": {
1313
+ "type": "integer",
1314
+ "description": "Virtual Machine ID"
1315
+ },
1316
+ "template_id": {
1317
+ "type": "integer",
1318
+ "description": "Template ID"
1319
+ },
1320
+ "password": {
1321
+ "type": "string",
1322
+ "description": "Password for the virtual machine. If not provided, random password will be generated. Password will not be shown in the response."
1323
+ },
1324
+ "post_install_script_id": {
1325
+ "type": "integer",
1326
+ "description": "Post-install script ID"
1327
+ }
1328
+ },
1329
+ "required": [
1330
+ "virtualMachineId",
1331
+ "template_id"
1332
+ ]
1333
+ },
1334
+ "security": [
1335
+ {
1336
+ "apiToken": []
1337
+ }
1338
+ ]
1339
+ },
1340
+ {
1341
+ "name": "VPS_restartVirtualMachineV1",
1342
+ "description": "This endpoint restarts a specified virtual machine. This is equivalent to fully stopping and starting the virtual machine.\nIf the virtual machine was stopped, it will be started.",
1343
+ "method": "POST",
1344
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/restart",
1345
+ "inputSchema": {
1346
+ "type": "object",
1347
+ "properties": {
1348
+ "virtualMachineId": {
1349
+ "type": "integer",
1350
+ "description": "Virtual Machine ID"
1351
+ }
1352
+ },
1353
+ "required": [
1354
+ "virtualMachineId"
1355
+ ]
1356
+ },
1357
+ "security": [
1358
+ {
1359
+ "apiToken": []
1360
+ }
1361
+ ]
1362
+ },
1363
+ {
1364
+ "name": "VPS_setRootPasswordV1",
1365
+ "description": "This endpoint sets the root password for a specified virtual machine. \nRequirements for the password is the same as in the [recreate virtual machine endpoint](/#tag/vps-virtual-machine/POST/api/vps/v1/virtual-machines/{virtualMachineId}/recreate).",
1366
+ "method": "PUT",
1367
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/root-password",
1368
+ "inputSchema": {
1369
+ "type": "object",
1370
+ "properties": {
1371
+ "virtualMachineId": {
1372
+ "type": "integer",
1373
+ "description": "Virtual Machine ID"
1374
+ },
1375
+ "password": {
1376
+ "type": "string",
1377
+ "description": "Root password for the virtual machine"
1378
+ }
1379
+ },
1380
+ "required": [
1381
+ "virtualMachineId",
1382
+ "password"
1383
+ ]
1384
+ },
1385
+ "security": [
1386
+ {
1387
+ "apiToken": []
1388
+ }
1389
+ ]
1390
+ },
1391
+ {
1392
+ "name": "VPS_setupNewVirtualMachineV1",
1393
+ "description": "This endpoint will setup newly purchased virtual machine. Such virtual machines has `initial` state. \nNew virtual machine can be purchased using [`/api/billing/v1/orders`](/#tag/billing-orders/POST/api/billing/v1/orders) endpoint. ",
1394
+ "method": "POST",
1395
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/setup",
1396
+ "inputSchema": {
1397
+ "type": "object",
1398
+ "properties": {
1399
+ "virtualMachineId": {
1400
+ "type": "integer",
1401
+ "description": "Virtual Machine ID"
1402
+ },
1403
+ "template_id": {
1404
+ "type": "integer",
1405
+ "description": "Template ID"
1406
+ },
1407
+ "data_center_id": {
1408
+ "type": "integer",
1409
+ "description": "Data center ID"
1410
+ },
1411
+ "post_install_script_id": {
1412
+ "type": "integer",
1413
+ "description": "Post-install script ID"
1414
+ },
1415
+ "password": {
1416
+ "type": "string",
1417
+ "description": "Password for the virtual machine. If not provided, random password will be generated. Password will not be shown in the response."
1418
+ },
1419
+ "hostname": {
1420
+ "type": "string",
1421
+ "description": "Override default hostname of the virtual machine"
1422
+ },
1423
+ "install_monarx": {
1424
+ "type": "boolean",
1425
+ "description": "Install Monarx malware scanner (if supported)"
1426
+ },
1427
+ "enable_backups": {
1428
+ "type": "boolean",
1429
+ "description": "Enable weekly backup schedule"
1430
+ },
1431
+ "ns1": {
1432
+ "type": "string",
1433
+ "description": "ns1 property"
1434
+ },
1435
+ "ns2": {
1436
+ "type": "string",
1437
+ "description": "ns2 property"
1438
+ },
1439
+ "public_key": {
1440
+ "type": "object",
1441
+ "description": "public_key property"
1442
+ }
1443
+ },
1444
+ "required": [
1445
+ "virtualMachineId",
1446
+ "data_center_id",
1447
+ "template_id"
1448
+ ]
1449
+ },
1450
+ "security": [
1451
+ {
1452
+ "apiToken": []
1453
+ }
1454
+ ]
1455
+ },
1456
+ {
1457
+ "name": "VPS_getSnapshotV1",
1458
+ "description": "This endpoint retrieves a snapshot for a specified virtual machine.",
1459
+ "method": "GET",
1460
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/snapshot",
1461
+ "inputSchema": {
1462
+ "type": "object",
1463
+ "properties": {
1464
+ "virtualMachineId": {
1465
+ "type": "integer",
1466
+ "description": "Virtual Machine ID"
1467
+ }
1468
+ },
1469
+ "required": [
1470
+ "virtualMachineId"
1471
+ ]
1472
+ },
1473
+ "security": [
1474
+ {
1475
+ "apiToken": []
1476
+ }
1477
+ ]
1478
+ },
1479
+ {
1480
+ "name": "VPS_createSnapshotV1",
1481
+ "description": "This endpoint creates a snapshot of a specified virtual machine. \nA snapshot captures the state and data of the virtual machine at a specific point in time, \nallowing users to restore the virtual machine to that state if needed. \nThis operation is useful for backup purposes, system recovery, \nand testing changes without affecting the current state of the virtual machine.\n\n**Creating new snapshot will overwrite the existing snapshot!**",
1482
+ "method": "POST",
1483
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/snapshot",
1484
+ "inputSchema": {
1485
+ "type": "object",
1486
+ "properties": {
1487
+ "virtualMachineId": {
1488
+ "type": "integer",
1489
+ "description": "Virtual Machine ID"
1490
+ }
1491
+ },
1492
+ "required": [
1493
+ "virtualMachineId"
1494
+ ]
1495
+ },
1496
+ "security": [
1497
+ {
1498
+ "apiToken": []
1499
+ }
1500
+ ]
1501
+ },
1502
+ {
1503
+ "name": "VPS_deleteSnapshotV1",
1504
+ "description": "This endpoint deletes a snapshot of a specified virtual machine.",
1505
+ "method": "DELETE",
1506
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/snapshot",
1507
+ "inputSchema": {
1508
+ "type": "object",
1509
+ "properties": {
1510
+ "virtualMachineId": {
1511
+ "type": "integer",
1512
+ "description": "Virtual Machine ID"
1513
+ }
1514
+ },
1515
+ "required": [
1516
+ "virtualMachineId"
1517
+ ]
1518
+ },
1519
+ "security": [
1520
+ {
1521
+ "apiToken": []
1522
+ }
1523
+ ]
1524
+ },
1525
+ {
1526
+ "name": "VPS_restoreSnapshotV1",
1527
+ "description": "This endpoint restores a specified virtual machine to a previous state using a snapshot. \nRestoring from a snapshot allows users to revert the virtual machine to that state, which is useful for system recovery, undoing changes, or testing.",
1528
+ "method": "POST",
1529
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/snapshot/restore",
1530
+ "inputSchema": {
1531
+ "type": "object",
1532
+ "properties": {
1533
+ "virtualMachineId": {
1534
+ "type": "integer",
1535
+ "description": "Virtual Machine ID"
1536
+ }
1537
+ },
1538
+ "required": [
1539
+ "virtualMachineId"
1540
+ ]
1541
+ },
1542
+ "security": [
1543
+ {
1544
+ "apiToken": []
1545
+ }
1546
+ ]
1547
+ },
1548
+ {
1549
+ "name": "VPS_startVirtualMachineV1",
1550
+ "description": "This endpoint starts a specified virtual machine. \nIf the virtual machine is already running, the request will still be processed without any effect.",
1551
+ "method": "POST",
1552
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/start",
1553
+ "inputSchema": {
1554
+ "type": "object",
1555
+ "properties": {
1556
+ "virtualMachineId": {
1557
+ "type": "integer",
1558
+ "description": "Virtual Machine ID"
1559
+ }
1560
+ },
1561
+ "required": [
1562
+ "virtualMachineId"
1563
+ ]
1564
+ },
1565
+ "security": [
1566
+ {
1567
+ "apiToken": []
1568
+ }
1569
+ ]
1570
+ },
1571
+ {
1572
+ "name": "VPS_stopVirtualMachineV1",
1573
+ "description": "This endpoint stops a specified virtual machine. \nIf the virtual machine is already stopped, the request will still be processed without any effect.",
1574
+ "method": "POST",
1575
+ "path": "/api/vps/v1/virtual-machines/{virtualMachineId}/stop",
1576
+ "inputSchema": {
1577
+ "type": "object",
1578
+ "properties": {
1579
+ "virtualMachineId": {
1580
+ "type": "integer",
1581
+ "description": "Virtual Machine ID"
1582
+ }
1583
+ },
1584
+ "required": [
1585
+ "virtualMachineId"
1586
+ ]
1587
+ },
1588
+ "security": [
1589
+ {
1590
+ "apiToken": []
1591
+ }
1592
+ ]
1593
+ }
1594
+ ];
1595
+ const SECURITY_SCHEMES = {
1596
+ "apiToken": {
1597
+ "type": "http",
1598
+ "description": "API Token authentication",
1599
+ "scheme": "bearer"
1600
+ }
1601
+ };
1602
+ /**
1603
+ * MCP Server for Hostinger API
1604
+ * Generated from OpenAPI spec version 0.0.9
1605
+ */
1606
+ class MCPServer {
1607
+ constructor() {
1608
+ this.tools = new Map();
1609
+ // Initialize properties
1610
+ this.debug = process.env.DEBUG === "true";
1611
+ this.baseUrl = process.env.API_BASE_URL || "https://developers.hostinger.com";
1612
+ this.headers = this.parseHeaders(process.env.API_HEADERS || "");
1613
+ // Initialize tools map - do this before creating server
1614
+ this.initializeTools();
1615
+ // Create MCP server with correct capabilities
1616
+ this.server = new Server({
1617
+ name: process.env.SERVER_NAME || "hostinger-api-mcp",
1618
+ version: process.env.SERVER_VERSION || "0.0.1",
1619
+ }, {
1620
+ capabilities: {
1621
+ tools: {}, // Enable tools capability
1622
+ },
1623
+ });
1624
+ // Set up request handlers - don't log here
1625
+ this.setupHandlers();
1626
+ }
1627
+ /**
1628
+ * Parse headers from string
1629
+ */
1630
+ parseHeaders(headerStr) {
1631
+ const headers = {};
1632
+ if (headerStr) {
1633
+ headerStr.split(",").forEach((header) => {
1634
+ const [key, value] = header.split(":");
1635
+ if (key && value)
1636
+ headers[key.trim()] = value.trim();
1637
+ });
1638
+ }
1639
+ headers['User-Agent'] = 'hostinger-mcp-server/0.0.1';
1640
+ return headers;
1641
+ }
1642
+ /**
1643
+ * Initialize tools map from OpenAPI spec
1644
+ * This runs before the server is connected, so don't log here
1645
+ */
1646
+ initializeTools() {
1647
+ // Initialize each tool in the tools map
1648
+ for (const tool of TOOLS) {
1649
+ this.tools.set(tool.name, {
1650
+ name: tool.name,
1651
+ description: tool.description,
1652
+ inputSchema: tool.inputSchema,
1653
+ // Don't include security at the tool level
1654
+ });
1655
+ }
1656
+ // Don't log here, we're not connected yet
1657
+ console.error(`Initialized ${this.tools.size} tools`);
1658
+ }
1659
+ /**
1660
+ * Set up request handlers
1661
+ */
1662
+ setupHandlers() {
1663
+ // Handle tool listing requests
1664
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
1665
+ this.log('debug', "Handling ListTools request");
1666
+ // Return tools in the format expected by MCP SDK
1667
+ return {
1668
+ tools: Array.from(this.tools.entries()).map(([id, tool]) => ({
1669
+ id,
1670
+ ...tool,
1671
+ })),
1672
+ };
1673
+ });
1674
+ // Handle tool execution requests
1675
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
1676
+ const { id, name, arguments: params } = request.params;
1677
+ this.log('debug', "Handling CallTool request", { id, name, params });
1678
+ let toolName;
1679
+ let toolDetails;
1680
+ // Find the requested tool
1681
+ for (const [tid, tool] of this.tools.entries()) {
1682
+ if (tool.name === name) {
1683
+ toolName = name;
1684
+ break;
1685
+ }
1686
+ }
1687
+ if (!toolName) {
1688
+ throw new Error(`Tool not found: ${name}`);
1689
+ }
1690
+ toolDetails = TOOLS.find(t => t.name === toolName);
1691
+ if (!toolDetails) {
1692
+ throw new Error(`Tool details not found for ID: ${toolName}`);
1693
+ }
1694
+ try {
1695
+ this.log('info', `Executing tool: ${toolName}`);
1696
+ // Execute the API call
1697
+ const result = await this.executeApiCall(toolDetails, params || {});
1698
+ // Return the result in correct MCP format
1699
+ return {
1700
+ content: [
1701
+ {
1702
+ type: "text",
1703
+ text: JSON.stringify(result)
1704
+ }
1705
+ ]
1706
+ };
1707
+ }
1708
+ catch (error) {
1709
+ const errorMessage = error instanceof Error ? error.message : String(error);
1710
+ this.log('error', `Error executing tool ${toolName}: ${errorMessage}`);
1711
+ throw error;
1712
+ }
1713
+ });
1714
+ }
1715
+ /**
1716
+ * Execute an API call for a tool
1717
+ */
1718
+ async executeApiCall(tool, params) {
1719
+ // Get method and path from tool
1720
+ const method = tool.method;
1721
+ let path = tool.path;
1722
+ // Clone params to avoid modifying the original
1723
+ const requestParams = { ...params };
1724
+ // Replace path parameters with values from params
1725
+ Object.entries(requestParams).forEach(([key, value]) => {
1726
+ const placeholder = `{${key}}`;
1727
+ if (path.includes(placeholder)) {
1728
+ path = path.replace(placeholder, encodeURIComponent(String(value)));
1729
+ delete requestParams[key]; // Remove used parameter
1730
+ }
1731
+ });
1732
+ // Build the full URL
1733
+ const baseUrl = this.baseUrl.endsWith("/") ? this.baseUrl : `${this.baseUrl}/`;
1734
+ const cleanPath = path.startsWith("/") ? path.slice(1) : path;
1735
+ const url = new URL(cleanPath, baseUrl).toString();
1736
+ this.log('debug', `API Request: ${method} ${url}`);
1737
+ try {
1738
+ // Configure the request
1739
+ const config = {
1740
+ method: method.toLowerCase(),
1741
+ url,
1742
+ headers: { ...this.headers },
1743
+ };
1744
+ // Apply security headers based on tool security requirements
1745
+ if (tool.security && Array.isArray(tool.security)) {
1746
+ for (const requirement of tool.security) {
1747
+ for (const securitySchemeName of Object.keys(requirement)) {
1748
+ const securityDefinition = SECURITY_SCHEMES[securitySchemeName];
1749
+ if (securityDefinition) {
1750
+ const authType = securityDefinition.type;
1751
+ // Handle API key
1752
+ if (authType === 'apiKey') {
1753
+ const apiKeyName = securityDefinition.name || '';
1754
+ const envVarName = `${securitySchemeName.toUpperCase()}_${apiKeyName.toUpperCase()}`;
1755
+ const apiKeyValue = process.env[envVarName];
1756
+ if (apiKeyValue) {
1757
+ if (securityDefinition.in === 'header') {
1758
+ config.headers = config.headers || {};
1759
+ config.headers[apiKeyName] = apiKeyValue;
1760
+ }
1761
+ else if (securityDefinition.in === 'query') {
1762
+ config.params = config.params || {};
1763
+ config.params[apiKeyName] = apiKeyValue;
1764
+ }
1765
+ }
1766
+ else {
1767
+ this.log('warning', `API Key environment variable not found: ${envVarName}`);
1768
+ }
1769
+ }
1770
+ // Handle bearer token
1771
+ else if (authType === 'http' && securityDefinition.scheme === 'bearer') {
1772
+ const envVarName = `${securitySchemeName.toUpperCase()}`;
1773
+ const bearerToken = process.env[envVarName];
1774
+ if (bearerToken) {
1775
+ config.headers = config.headers || {};
1776
+ config.headers['Authorization'] = `Bearer ${bearerToken}`;
1777
+ }
1778
+ else {
1779
+ this.log('warning', `Bearer Token environment variable not found: ${envVarName}`);
1780
+ }
1781
+ }
1782
+ // Handle basic auth
1783
+ else if (authType === 'http' && securityDefinition.scheme === 'basic') {
1784
+ const username = process.env[`${securitySchemeName.toUpperCase()}_USERNAME`];
1785
+ const password = process.env[`${securitySchemeName.toUpperCase()}_PASSWORD`];
1786
+ if (username && password) {
1787
+ const auth = Buffer.from(`${username}:${password}`).toString('base64');
1788
+ config.headers = config.headers || {};
1789
+ config.headers['Authorization'] = `Basic ${auth}`;
1790
+ }
1791
+ else {
1792
+ this.log('warning', `Basic auth credentials not found for ${securitySchemeName}`);
1793
+ }
1794
+ }
1795
+ }
1796
+ }
1797
+ }
1798
+ }
1799
+ // Add parameters based on request method
1800
+ if (["GET", "DELETE"].includes(method)) {
1801
+ // For GET/DELETE, send params as query string
1802
+ config.params = { ...(config.params || {}), ...requestParams };
1803
+ }
1804
+ else {
1805
+ // For POST/PUT/PATCH, send params as JSON body
1806
+ config.data = requestParams;
1807
+ if (config.headers) {
1808
+ config.headers["Content-Type"] = "application/json";
1809
+ }
1810
+ }
1811
+ this.log('debug', "Request config:", {
1812
+ url: config.url,
1813
+ method: config.method,
1814
+ params: config.params,
1815
+ headers: config.headers ? Object.keys(config.headers) : []
1816
+ });
1817
+ // Execute the request
1818
+ const response = await axios(config);
1819
+ this.log('debug', `Response status: ${response.status}`);
1820
+ return response.data;
1821
+ }
1822
+ catch (error) {
1823
+ const errorMessage = error instanceof Error ? error.message : String(error);
1824
+ this.log('error', `API request failed: ${errorMessage}`);
1825
+ if (axios.isAxiosError(error)) {
1826
+ const axiosError = error;
1827
+ const responseData = axiosError.response?.data;
1828
+ const responseStatus = axiosError.response?.status;
1829
+ this.log('error', 'API Error Details:', {
1830
+ status: responseStatus,
1831
+ data: typeof responseData === 'object' ? JSON.stringify(responseData) : String(responseData)
1832
+ });
1833
+ // Rethrow with more context for better error handling
1834
+ const detailedError = new Error(`API request failed with status ${responseStatus}: ${errorMessage}`);
1835
+ detailedError.response = axiosError.response;
1836
+ throw detailedError;
1837
+ }
1838
+ throw error;
1839
+ }
1840
+ }
1841
+ /**
1842
+ * Log messages with appropriate level
1843
+ * Only sends to MCP if we're connected
1844
+ */
1845
+ log(level, message, data) {
1846
+ // Always log to stderr for visibility
1847
+ console.error(`[${level.toUpperCase()}] ${message}${data ? ': ' + JSON.stringify(data) : ''}`);
1848
+ // Only try to send via MCP if we're in debug mode or it's important
1849
+ if (this.debug || level !== 'debug') {
1850
+ try {
1851
+ // Only send if server exists and is connected
1852
+ if (this.server && this.server.isConnected) {
1853
+ this.server.sendLoggingMessage({
1854
+ level,
1855
+ data: `[MCP Server] ${message}${data ? ': ' + JSON.stringify(data) : ''}`
1856
+ });
1857
+ }
1858
+ }
1859
+ catch (e) {
1860
+ // If logging fails, log to stderr
1861
+ console.error('Failed to send log via MCP:', e.message);
1862
+ }
1863
+ }
1864
+ }
1865
+ /**
1866
+ * Start the server
1867
+ */
1868
+ async start() {
1869
+ try {
1870
+ // Create stdio transport
1871
+ const transport = new StdioServerTransport();
1872
+ console.error("MCP Server starting on stdio transport");
1873
+ // Connect to the transport
1874
+ await this.server.connect(transport);
1875
+ // Now we can safely log via MCP
1876
+ console.error(`Registered ${this.tools.size} tools`);
1877
+ this.log('info', `MCP Server started successfully with ${this.tools.size} tools`);
1878
+ }
1879
+ catch (error) {
1880
+ console.error("Failed to start MCP server:", error);
1881
+ process.exit(1);
1882
+ }
1883
+ }
1884
+ }
1885
+ // Start the server
1886
+ async function main() {
1887
+ try {
1888
+ const server = new MCPServer();
1889
+ await server.start();
1890
+ }
1891
+ catch (error) {
1892
+ console.error("Failed to start server:", error);
1893
+ process.exit(1);
1894
+ }
1895
+ }
1896
+ main();