xserver-mcp 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -3
- package/dist/index.js +435 -35
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17,6 +17,21 @@ function redactSensitiveValues(value) {
|
|
|
17
17
|
SENSITIVE_FIELD_PATTERN.test(key) ? "[REDACTED]" : redactSensitiveValues(child)
|
|
18
18
|
]));
|
|
19
19
|
}
|
|
20
|
+
function retryAfterSeconds(response) {
|
|
21
|
+
if (response.status !== 429)
|
|
22
|
+
return void 0;
|
|
23
|
+
const value = response.headers.get("retry-after");
|
|
24
|
+
if (value === null || !/^\d+$/.test(value))
|
|
25
|
+
return void 0;
|
|
26
|
+
const seconds = Number(value);
|
|
27
|
+
if (!Number.isSafeInteger(seconds))
|
|
28
|
+
return void 0;
|
|
29
|
+
return seconds;
|
|
30
|
+
}
|
|
31
|
+
function retryAfterGuidance(response) {
|
|
32
|
+
const seconds = retryAfterSeconds(response);
|
|
33
|
+
return seconds === void 0 ? void 0 : `\u518D\u8A66\u884C\u307E\u3067\u306E\u76EE\u5B89: ${seconds}\u79D2`;
|
|
34
|
+
}
|
|
20
35
|
var ApiError = class extends Error {
|
|
21
36
|
httpStatus;
|
|
22
37
|
errorCode;
|
|
@@ -53,8 +68,8 @@ var ApiClient = class {
|
|
|
53
68
|
async listServerPlans(params) {
|
|
54
69
|
return this.get("/v1/server/plans", params);
|
|
55
70
|
}
|
|
56
|
-
async registerServer(data,
|
|
57
|
-
return this.post("/v1/server", data, idempotencyHeaders(
|
|
71
|
+
async registerServer(data, idempotencyKey5) {
|
|
72
|
+
return this.post("/v1/server", data, idempotencyHeaders(idempotencyKey5));
|
|
58
73
|
}
|
|
59
74
|
async listServers() {
|
|
60
75
|
return this.get("/v1/server");
|
|
@@ -557,14 +572,14 @@ var ApiClient = class {
|
|
|
557
572
|
async getDomainPricing(params) {
|
|
558
573
|
return this.get("/v1/domain/pricing", params);
|
|
559
574
|
}
|
|
560
|
-
async registerDomain(data,
|
|
561
|
-
return this.post("/v1/domain", data, idempotencyHeaders(
|
|
575
|
+
async registerDomain(data, idempotencyKey5) {
|
|
576
|
+
return this.post("/v1/domain", data, idempotencyHeaders(idempotencyKey5));
|
|
562
577
|
}
|
|
563
|
-
async transferDomain(domainName2, data,
|
|
564
|
-
return this.post(`${this.domainPath(domainName2)}/transfer`, data, idempotencyHeaders(
|
|
578
|
+
async transferDomain(domainName2, data, idempotencyKey5) {
|
|
579
|
+
return this.post(`${this.domainPath(domainName2)}/transfer`, data, idempotencyHeaders(idempotencyKey5));
|
|
565
580
|
}
|
|
566
|
-
async renewDomain(domainName2, data,
|
|
567
|
-
return this.post(`${this.domainPath(domainName2)}/renew`, data, idempotencyHeaders(
|
|
581
|
+
async renewDomain(domainName2, data, idempotencyKey5) {
|
|
582
|
+
return this.post(`${this.domainPath(domainName2)}/renew`, data, idempotencyHeaders(idempotencyKey5));
|
|
568
583
|
}
|
|
569
584
|
// ================================================================
|
|
570
585
|
// WPhosting API(/v1/wphosting/{contract_id})
|
|
@@ -578,8 +593,8 @@ var ApiClient = class {
|
|
|
578
593
|
async listWphostingPlans(params) {
|
|
579
594
|
return this.get("/v1/wphosting/plans", params);
|
|
580
595
|
}
|
|
581
|
-
async registerWphosting(data,
|
|
582
|
-
return this.post("/v1/wphosting", data, idempotencyHeaders(
|
|
596
|
+
async registerWphosting(data, idempotencyKey5) {
|
|
597
|
+
return this.post("/v1/wphosting", data, idempotencyHeaders(idempotencyKey5));
|
|
583
598
|
}
|
|
584
599
|
async listWphostingContracts() {
|
|
585
600
|
return this.get("/v1/wphosting");
|
|
@@ -596,26 +611,26 @@ var ApiClient = class {
|
|
|
596
611
|
async getWphostingSite(contractId2, servername3) {
|
|
597
612
|
return this.get(this.wphostingSitePath(contractId2, servername3));
|
|
598
613
|
}
|
|
599
|
-
async createWphostingSite(contractId2, data,
|
|
600
|
-
return this.post(`${this.wphostingPath(contractId2)}/sites`, data, idempotencyHeaders(
|
|
614
|
+
async createWphostingSite(contractId2, data, idempotencyKey5) {
|
|
615
|
+
return this.post(`${this.wphostingPath(contractId2)}/sites`, data, idempotencyHeaders(idempotencyKey5));
|
|
601
616
|
}
|
|
602
|
-
async deleteWphostingSite(contractId2, servername3,
|
|
603
|
-
return this.delete(this.wphostingSitePath(contractId2, servername3), void 0, idempotencyHeaders(
|
|
617
|
+
async deleteWphostingSite(contractId2, servername3, idempotencyKey5) {
|
|
618
|
+
return this.delete(this.wphostingSitePath(contractId2, servername3), void 0, idempotencyHeaders(idempotencyKey5));
|
|
604
619
|
}
|
|
605
620
|
async getWphostingUsage(contractId2) {
|
|
606
621
|
return this.get(`${this.wphostingPath(contractId2)}/usage`);
|
|
607
622
|
}
|
|
608
|
-
async createWphostingStaging(contractId2, servername3, data,
|
|
609
|
-
return this.post(`${this.wphostingSitePath(contractId2, servername3)}/staging`, data, idempotencyHeaders(
|
|
623
|
+
async createWphostingStaging(contractId2, servername3, data, idempotencyKey5) {
|
|
624
|
+
return this.post(`${this.wphostingSitePath(contractId2, servername3)}/staging`, data, idempotencyHeaders(idempotencyKey5));
|
|
610
625
|
}
|
|
611
626
|
async listWphostingBackups(contractId2, servername3) {
|
|
612
627
|
return this.get(`${this.wphostingSitePath(contractId2, servername3)}/backups`);
|
|
613
628
|
}
|
|
614
|
-
async createWphostingBackup(contractId2, servername3, data,
|
|
615
|
-
return this.post(`${this.wphostingSitePath(contractId2, servername3)}/backups`, data, idempotencyHeaders(
|
|
629
|
+
async createWphostingBackup(contractId2, servername3, data, idempotencyKey5) {
|
|
630
|
+
return this.post(`${this.wphostingSitePath(contractId2, servername3)}/backups`, data, idempotencyHeaders(idempotencyKey5));
|
|
616
631
|
}
|
|
617
|
-
async restoreWphostingBackup(contractId2, servername3, backupId,
|
|
618
|
-
return this.post(`${this.wphostingSitePath(contractId2, servername3)}/backups/${enc(backupId)}/restore`, void 0, idempotencyHeaders(
|
|
632
|
+
async restoreWphostingBackup(contractId2, servername3, backupId, idempotencyKey5) {
|
|
633
|
+
return this.post(`${this.wphostingSitePath(contractId2, servername3)}/backups/${enc(backupId)}/restore`, void 0, idempotencyHeaders(idempotencyKey5));
|
|
619
634
|
}
|
|
620
635
|
async listWphostingBackupRestoreHistory(contractId2, servername3) {
|
|
621
636
|
return this.get(`${this.wphostingSitePath(contractId2, servername3)}/backups/restore-history`);
|
|
@@ -762,6 +777,78 @@ var ApiClient = class {
|
|
|
762
777
|
return this.put(`${this.wphostingSitePath(contractId2, servername3)}/security/${enc(key)}`, data);
|
|
763
778
|
}
|
|
764
779
|
// ================================================================
|
|
780
|
+
// VPS API(/v1/vps)
|
|
781
|
+
// ================================================================
|
|
782
|
+
vpsServerPath(uuid2) {
|
|
783
|
+
return `/v1/vps/servers/${enc(uuid2)}`;
|
|
784
|
+
}
|
|
785
|
+
async listVpsServers() {
|
|
786
|
+
return this.get("/v1/vps/servers");
|
|
787
|
+
}
|
|
788
|
+
async getVpsServer(uuid2) {
|
|
789
|
+
return this.get(this.vpsServerPath(uuid2));
|
|
790
|
+
}
|
|
791
|
+
async updateVpsMemo(uuid2, data) {
|
|
792
|
+
return this.put(`${this.vpsServerPath(uuid2)}/memo`, data);
|
|
793
|
+
}
|
|
794
|
+
async updateVpsName(uuid2, data) {
|
|
795
|
+
return this.put(`${this.vpsServerPath(uuid2)}/name`, data);
|
|
796
|
+
}
|
|
797
|
+
async updateVpsReverseDns(uuid2, data) {
|
|
798
|
+
return this.put(`${this.vpsServerPath(uuid2)}/reverse-dns`, data);
|
|
799
|
+
}
|
|
800
|
+
async getVpsPower(uuid2) {
|
|
801
|
+
return this.get(`${this.vpsServerPath(uuid2)}/power`);
|
|
802
|
+
}
|
|
803
|
+
async startVpsPower(uuid2) {
|
|
804
|
+
return this.post(`${this.vpsServerPath(uuid2)}/power/start`);
|
|
805
|
+
}
|
|
806
|
+
async rebootVpsPower(uuid2, data) {
|
|
807
|
+
return this.post(`${this.vpsServerPath(uuid2)}/power/reboot`, data);
|
|
808
|
+
}
|
|
809
|
+
async stopVpsPower(uuid2) {
|
|
810
|
+
return this.post(`${this.vpsServerPath(uuid2)}/power/stop`);
|
|
811
|
+
}
|
|
812
|
+
async getVpsPacketFilter(uuid2) {
|
|
813
|
+
return this.get(`${this.vpsServerPath(uuid2)}/packet-filter`);
|
|
814
|
+
}
|
|
815
|
+
async updateVpsPacketFilter(uuid2, data) {
|
|
816
|
+
return this.put(`${this.vpsServerPath(uuid2)}/packet-filter`, data);
|
|
817
|
+
}
|
|
818
|
+
async addVpsPacketFilterRule(uuid2, data) {
|
|
819
|
+
return this.post(`${this.vpsServerPath(uuid2)}/packet-filter/rules`, data);
|
|
820
|
+
}
|
|
821
|
+
async updateVpsPacketFilterRule(uuid2, ruleId, data) {
|
|
822
|
+
return this.put(`${this.vpsServerPath(uuid2)}/packet-filter/rules/${enc(ruleId)}`, data);
|
|
823
|
+
}
|
|
824
|
+
async deleteVpsPacketFilterRule(uuid2, ruleId) {
|
|
825
|
+
return this.delete(`${this.vpsServerPath(uuid2)}/packet-filter/rules/${enc(ruleId)}`);
|
|
826
|
+
}
|
|
827
|
+
async listVpsOsImages(uuid2) {
|
|
828
|
+
return this.get(`${this.vpsServerPath(uuid2)}/os-images`);
|
|
829
|
+
}
|
|
830
|
+
async reinstallVpsOs(uuid2, data) {
|
|
831
|
+
return this.post(`${this.vpsServerPath(uuid2)}/os-reinstall`, data);
|
|
832
|
+
}
|
|
833
|
+
async getVpsOsReinstall(uuid2) {
|
|
834
|
+
return this.get(`${this.vpsServerPath(uuid2)}/os-reinstall`);
|
|
835
|
+
}
|
|
836
|
+
async getVpsProtection(uuid2) {
|
|
837
|
+
return this.get(`${this.vpsServerPath(uuid2)}/protection`);
|
|
838
|
+
}
|
|
839
|
+
async updateVpsProtection(uuid2, data) {
|
|
840
|
+
return this.put(`${this.vpsServerPath(uuid2)}/protection`, data);
|
|
841
|
+
}
|
|
842
|
+
async listVpsPlans() {
|
|
843
|
+
return this.get("/v1/vps/plans");
|
|
844
|
+
}
|
|
845
|
+
async registerVps(data, idempotencyKey5) {
|
|
846
|
+
return this.post("/v1/vps/servers", data, idempotencyHeaders(idempotencyKey5));
|
|
847
|
+
}
|
|
848
|
+
async getVpsSignupStatus(id) {
|
|
849
|
+
return this.get(`/v1/vps/signup-status/${enc(id)}`);
|
|
850
|
+
}
|
|
851
|
+
// ================================================================
|
|
765
852
|
// HTTP 基盤
|
|
766
853
|
// ================================================================
|
|
767
854
|
async get(path, params) {
|
|
@@ -812,12 +899,23 @@ var ApiClient = class {
|
|
|
812
899
|
const dbg = (msg) => process.stderr.write(`[DEBUG] ${msg}
|
|
813
900
|
`);
|
|
814
901
|
dbg(`HTTP ${response.status} ${response.statusText}`);
|
|
815
|
-
const debugHeaders = [
|
|
902
|
+
const debugHeaders = [
|
|
903
|
+
"x-ratelimit-limit",
|
|
904
|
+
"x-ratelimit-remaining",
|
|
905
|
+
"x-ratelimit-reset",
|
|
906
|
+
"x-concurrent-limit",
|
|
907
|
+
"x-concurrent-remaining",
|
|
908
|
+
"content-type",
|
|
909
|
+
"location"
|
|
910
|
+
];
|
|
816
911
|
for (const h of debugHeaders) {
|
|
817
912
|
const v = response.headers.get(h);
|
|
818
913
|
if (v !== null)
|
|
819
914
|
dbg(` ${h}: ${v}`);
|
|
820
915
|
}
|
|
916
|
+
const retryAfter = retryAfterSeconds(response);
|
|
917
|
+
if (retryAfter !== void 0)
|
|
918
|
+
dbg(` retry-after: ${retryAfter}`);
|
|
821
919
|
}
|
|
822
920
|
const rateLimitHeader = response.headers.get("x-ratelimit-limit");
|
|
823
921
|
if (rateLimitHeader) {
|
|
@@ -828,12 +926,17 @@ var ApiClient = class {
|
|
|
828
926
|
};
|
|
829
927
|
}
|
|
830
928
|
const text = await response.text();
|
|
929
|
+
if (response.status === 202 && text.trim() === "") {
|
|
930
|
+
const location = response.headers.get("location");
|
|
931
|
+
return { accepted: true, location };
|
|
932
|
+
}
|
|
831
933
|
let data;
|
|
832
934
|
try {
|
|
833
935
|
data = JSON.parse(text);
|
|
834
936
|
} catch {
|
|
835
937
|
if (this.debug) {
|
|
836
|
-
|
|
938
|
+
const bodyBytes = Buffer.byteLength(text, "utf8");
|
|
939
|
+
process.stderr.write(`[DEBUG] Response body omitted because it is not valid JSON (${bodyBytes} bytes)
|
|
837
940
|
`);
|
|
838
941
|
}
|
|
839
942
|
throw new ApiError(`Response parse error (HTTP ${response.status})`, response.status, "PARSE_ERROR", []);
|
|
@@ -842,7 +945,10 @@ var ApiClient = class {
|
|
|
842
945
|
const err = data;
|
|
843
946
|
const errorCode = err?.error?.code || "UNKNOWN_ERROR";
|
|
844
947
|
const errorMessage = err?.error?.message || "\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F";
|
|
845
|
-
const errors = err?.error?.errors || [];
|
|
948
|
+
const errors = [...err?.error?.errors || []];
|
|
949
|
+
const retryGuidance = retryAfterGuidance(response);
|
|
950
|
+
if (retryGuidance)
|
|
951
|
+
errors.push(retryGuidance);
|
|
846
952
|
throw new ApiError(errorMessage, response.status, errorCode, errors);
|
|
847
953
|
}
|
|
848
954
|
return data;
|
|
@@ -851,8 +957,8 @@ var ApiClient = class {
|
|
|
851
957
|
function enc(s) {
|
|
852
958
|
return encodeURIComponent(s);
|
|
853
959
|
}
|
|
854
|
-
function idempotencyHeaders(
|
|
855
|
-
return
|
|
960
|
+
function idempotencyHeaders(idempotencyKey5) {
|
|
961
|
+
return idempotencyKey5 === void 0 ? void 0 : { "Idempotency-Key": idempotencyKey5 };
|
|
856
962
|
}
|
|
857
963
|
|
|
858
964
|
// ../../shared/dist/billing-confirmation.js
|
|
@@ -934,6 +1040,13 @@ function compactDetails(details) {
|
|
|
934
1040
|
|
|
935
1041
|
// ../../shared/dist/brand-config.js
|
|
936
1042
|
function resolveServerPlanBrand(brand, service, planId2) {
|
|
1043
|
+
if (service === "vps") {
|
|
1044
|
+
return {
|
|
1045
|
+
serviceName: brand.vpsServiceName,
|
|
1046
|
+
termsUrl: brand.vpsTermsUrl,
|
|
1047
|
+
privacyUrl: brand.vpsPrivacyUrl
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
937
1050
|
if (service === "server" && planId2 !== void 0) {
|
|
938
1051
|
const override = brand.serverPlanOverrides?.find((o) => planId2.startsWith(o.planIdPrefix));
|
|
939
1052
|
if (override !== void 0) {
|
|
@@ -1222,8 +1335,69 @@ var billingExecuteAnnotations = {
|
|
|
1222
1335
|
idempotentHint: true,
|
|
1223
1336
|
openWorldHint: true
|
|
1224
1337
|
};
|
|
1338
|
+
async function confirmOsReinstallOperation(server, input) {
|
|
1339
|
+
if (!supportsFormElicitation(server)) {
|
|
1340
|
+
throw new Error("OS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u306B\u306F MCP form elicitation \u5BFE\u5FDC\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u304C\u5FC5\u8981\u3067\u3059\u3002\u975E\u5BFE\u5FDC\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u3067\u306F\u5B9F\u884C\u3067\u304D\u307E\u305B\u3093\u3002");
|
|
1341
|
+
}
|
|
1342
|
+
const protectionLine = input.protectionEnabled === true ? "- \u64CD\u4F5C\u4FDD\u8B77\uFF08os_reinstall\uFF09\u306F\u6709\u52B9\u3067\u3059\u3002API \u306F 409 PROTECTED \u3067\u62D2\u5426\u3057\u307E\u3059\u3002" : input.protectionEnabled === false ? "- \u64CD\u4F5C\u4FDD\u8B77\uFF08os_reinstall\uFF09\u306F\u7121\u52B9\u3067\u3059\u3002\u5B9F\u884C\u3059\u308B\u3068\u30C7\u30FC\u30BF\u304C\u524A\u9664\u3055\u308C\u307E\u3059\u3002" : "- \u64CD\u4F5C\u4FDD\u8B77\u306E\u72B6\u614B\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u5B9F\u884C\u524D\u306B get_vps_protection \u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002";
|
|
1343
|
+
const message = [
|
|
1344
|
+
"OS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u306F\u30B5\u30FC\u30D0\u30FC\u5185\u306E\u30C7\u30FC\u30BF\u30FB\u8A2D\u5B9A\u3092\u3059\u3079\u3066\u524A\u9664\u3057\u307E\u3059\u3002",
|
|
1345
|
+
"\u3010\u5BFE\u8C61\u3011",
|
|
1346
|
+
`- uuid: ${input.uuid}`,
|
|
1347
|
+
`- image_id: ${input.imageId}`,
|
|
1348
|
+
protectionLine,
|
|
1349
|
+
"VPS\u306F\u505C\u6B62\u4E2D\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\u8AA4\u64CD\u4F5C\u9632\u6B62\u306B\u306F update_vps_protection \u3067 os_reinstall \u3092 true \u306B\u3067\u304D\u307E\u3059\u3002",
|
|
1350
|
+
"\u5185\u5BB9\u3092\u78BA\u8A8D\u3057\u3001\u627F\u8A8D\u3059\u308B\u5834\u5408\u306E\u307F\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
|
|
1351
|
+
].join("\n");
|
|
1352
|
+
let result;
|
|
1353
|
+
try {
|
|
1354
|
+
result = await server.server.elicitInput({
|
|
1355
|
+
mode: "form",
|
|
1356
|
+
message,
|
|
1357
|
+
requestedSchema: {
|
|
1358
|
+
type: "object",
|
|
1359
|
+
properties: {
|
|
1360
|
+
confirm_reinstall: {
|
|
1361
|
+
type: "boolean",
|
|
1362
|
+
title: "\u30C7\u30FC\u30BF\u5168\u6D88\u53BB\u3092\u627F\u8A8D\u3059\u308B",
|
|
1363
|
+
description: `${input.uuid} \u3092 ${input.imageId} \u3067\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3059\u308B`
|
|
1364
|
+
}
|
|
1365
|
+
},
|
|
1366
|
+
required: ["confirm_reinstall"]
|
|
1367
|
+
}
|
|
1368
|
+
}, { timeout: BILLING_CONFIRMATION_TIMEOUT_MS });
|
|
1369
|
+
} catch (error) {
|
|
1370
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
1371
|
+
throw new Error(`OS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u78BA\u8A8D\uFF08elicitation\uFF09\u306B\u5931\u6557\u3057\u305F\u305F\u3081\u4E2D\u6B62\u3057\u307E\u3057\u305F: ${detail}`);
|
|
1372
|
+
}
|
|
1373
|
+
if (result.action === "decline" || result.action === "cancel") {
|
|
1374
|
+
throw new Error("\u5229\u7528\u8005\u304COS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u78BA\u8A8D\u3092\u62D2\u5426\u307E\u305F\u306F\u30AD\u30E3\u30F3\u30BB\u30EB\u3057\u305F\u305F\u3081\u3001\u4E2D\u6B62\u3057\u307E\u3057\u305F\u3002");
|
|
1375
|
+
}
|
|
1376
|
+
if (result.action !== "accept" || result.content == null || typeof result.content !== "object") {
|
|
1377
|
+
throw new Error("OS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u78BA\u8A8D\u306E\u5FDC\u7B54\u304C\u4E0D\u6B63\u306A\u305F\u3081\u3001\u4E2D\u6B62\u3057\u307E\u3057\u305F\u3002");
|
|
1378
|
+
}
|
|
1379
|
+
if (result.content.confirm_reinstall !== true) {
|
|
1380
|
+
throw new Error("\u30C7\u30FC\u30BF\u5168\u6D88\u53BB\u306E\u627F\u8A8D\u304C\u78BA\u8A8D\u3067\u304D\u306A\u304B\u3063\u305F\u305F\u3081\u3001OS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3092\u4E2D\u6B62\u3057\u307E\u3057\u305F\u3002");
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1225
1383
|
|
|
1226
1384
|
// ../core/dist/helper.js
|
|
1385
|
+
import { stripVTControlCharacters } from "util";
|
|
1386
|
+
var MAX_MCP_ERROR_TEXT_LENGTH = 4096;
|
|
1387
|
+
var LINE_BREAK_PATTERN = /[\r\n\u2028\u2029]+/g;
|
|
1388
|
+
var CONTROL_CHARACTER_PATTERN = /[\u0000-\u001f\u007f-\u009f]/g;
|
|
1389
|
+
var TRUNCATED_SUFFIX = "\n[\u30A8\u30E9\u30FC\u51FA\u529B\u3092\u7701\u7565\u3057\u307E\u3057\u305F]";
|
|
1390
|
+
function sanitizeMcpErrorValue(value) {
|
|
1391
|
+
return stripVTControlCharacters(String(value)).replace(LINE_BREAK_PATTERN, " ").replace(CONTROL_CHARACTER_PATTERN, "");
|
|
1392
|
+
}
|
|
1393
|
+
function limitMcpErrorText(value) {
|
|
1394
|
+
if (value.length <= MAX_MCP_ERROR_TEXT_LENGTH)
|
|
1395
|
+
return value;
|
|
1396
|
+
let prefix = value.slice(0, MAX_MCP_ERROR_TEXT_LENGTH - TRUNCATED_SUFFIX.length);
|
|
1397
|
+
if (/[\ud800-\udbff]$/.test(prefix))
|
|
1398
|
+
prefix = prefix.slice(0, -1);
|
|
1399
|
+
return prefix + TRUNCATED_SUFFIX;
|
|
1400
|
+
}
|
|
1227
1401
|
function serverToolName(brand, action, feature) {
|
|
1228
1402
|
return `${brand.brand}_${action}_server_${feature}`;
|
|
1229
1403
|
}
|
|
@@ -1233,6 +1407,9 @@ function domainToolName(brand, action, feature) {
|
|
|
1233
1407
|
function wphostingToolName(brand, verb, resource) {
|
|
1234
1408
|
return `${brand.brand}_${verb}_wphosting_${resource}`;
|
|
1235
1409
|
}
|
|
1410
|
+
function vpsToolName(brand, verb, resource) {
|
|
1411
|
+
return `${brand.brand}_${verb}_vps_${resource}`;
|
|
1412
|
+
}
|
|
1236
1413
|
async function callApi(fn) {
|
|
1237
1414
|
try {
|
|
1238
1415
|
const result = await fn();
|
|
@@ -1240,16 +1417,16 @@ async function callApi(fn) {
|
|
|
1240
1417
|
} catch (e) {
|
|
1241
1418
|
let msg;
|
|
1242
1419
|
if (e instanceof ApiError) {
|
|
1243
|
-
msg = `Error [HTTP ${e.httpStatus}] ${e.errorCode}: ${e.message}`;
|
|
1420
|
+
msg = `Error [HTTP ${e.httpStatus}] ${sanitizeMcpErrorValue(e.errorCode)}: ${sanitizeMcpErrorValue(e.message)}`;
|
|
1244
1421
|
if (e.errors.length > 0) {
|
|
1245
|
-
msg += "\n" + e.errors.map((err) => ` - ${err}`).join("\n");
|
|
1422
|
+
msg += "\n" + e.errors.map((err) => ` - ${sanitizeMcpErrorValue(err)}`).join("\n");
|
|
1246
1423
|
}
|
|
1247
1424
|
} else if (e instanceof Error) {
|
|
1248
|
-
msg = `Error: ${e.message}`;
|
|
1425
|
+
msg = `Error: ${sanitizeMcpErrorValue(e.message)}`;
|
|
1249
1426
|
} else {
|
|
1250
|
-
msg = `Error: ${
|
|
1427
|
+
msg = `Error: ${sanitizeMcpErrorValue(e)}`;
|
|
1251
1428
|
}
|
|
1252
|
-
return { content: [{ type: "text", text: msg }], isError: true };
|
|
1429
|
+
return { content: [{ type: "text", text: limitMcpErrorText(msg) }], isError: true };
|
|
1253
1430
|
}
|
|
1254
1431
|
}
|
|
1255
1432
|
|
|
@@ -1272,6 +1449,7 @@ function description(text) {
|
|
|
1272
1449
|
return `${text}\u3002servername\u89E3\u6C7A\u3092\u884C\u308F\u306A\u3044Server\u30A2\u30AB\u30A6\u30F3\u30C8\u30FB\u5951\u7D04\u30EC\u30D9\u30EB\u306E\u64CD\u4F5C\u3067\u3059`;
|
|
1273
1450
|
}
|
|
1274
1451
|
function registerServerAccountTools(server, client, brand, options = {}) {
|
|
1452
|
+
server.tool(serverToolName(brand, "get", "api_key_info"), description("API\u30AD\u30FC\u60C5\u5831\u3068Server\u30B5\u30FC\u30D3\u30B9\u306E\u6A29\u9650\u30FB\u5BFE\u8C61\u3092\u53D6\u5F97"), {}, async () => callApi(() => client.getMe()));
|
|
1275
1453
|
server.tool(serverToolName(brand, "list", "plans"), description("\u7533\u8FBC\u53EF\u80FD\u306A\u30B5\u30FC\u30D0\u30FC\u30D7\u30E9\u30F3\u3092\u53D6\u5F97"), {
|
|
1276
1454
|
plan_id: z2.string().min(1).max(64).optional().describe("\u7D5E\u308A\u8FBC\u3080\u30D7\u30E9\u30F3ID\u3002\u8907\u6570\u306F\u30AB\u30F3\u30DE\u533A\u5207\u308A")
|
|
1277
1455
|
}, async ({ plan_id }) => callApi(() => client.listServerPlans(plan_id ? { plan_id } : void 0)));
|
|
@@ -2202,7 +2380,7 @@ function registerAccessDenyTools(server, client, brand) {
|
|
|
2202
2380
|
server.tool(serverToolName(brand, "update", "access_deny"), "\u30A2\u30AF\u30BB\u30B9\u62D2\u5426\u8A2D\u5B9A\u306E\u30E1\u30E2\u3092\u66F4\u65B0", {
|
|
2203
2381
|
deny_id: z25.string().describe("\u30A2\u30AF\u30BB\u30B9\u62D2\u5426\u8A2D\u5B9A\u306EID"),
|
|
2204
2382
|
memo: z25.string().describe("\u30E1\u30E2\uFF08\u7A7A\u6587\u5B57\u3067\u30AF\u30EA\u30A2\uFF09")
|
|
2205
|
-
}, async ({ deny_id, memo:
|
|
2383
|
+
}, async ({ deny_id, memo: memo3 }) => callApi(() => client.updateAccessDeny(deny_id, { memo: memo3 })));
|
|
2206
2384
|
server.tool(serverToolName(brand, "delete", "access_deny"), "\u30A2\u30AF\u30BB\u30B9\u62D2\u5426\u8A2D\u5B9A\u3092\u524A\u9664", {
|
|
2207
2385
|
deny_id: z25.string().describe("\u30A2\u30AF\u30BB\u30B9\u62D2\u5426\u8A2D\u5B9A\u306EID")
|
|
2208
2386
|
}, async ({ deny_id }) => callApi(() => client.deleteAccessDeny(deny_id)));
|
|
@@ -2593,7 +2771,7 @@ function registerWphostingTools(server, client, brand, options = {}) {
|
|
|
2593
2771
|
server.tool(wphostingToolName(brand, "update", "memo"), description3("WPhosting\u5951\u7D04\u30E1\u30E2\u3092\u66F4\u65B0"), {
|
|
2594
2772
|
contract_id: contractId,
|
|
2595
2773
|
memo: z30.string().max(500).describe("\u5951\u7D04\u30E1\u30E2\uFF08\u7A7A\u6587\u5B57\u53EF\u3001500\u6587\u5B57\u4EE5\u5185\uFF09")
|
|
2596
|
-
}, async ({ contract_id, memo:
|
|
2774
|
+
}, async ({ contract_id, memo: memo3 }) => callApi(() => client.updateWphostingMemo(contract_id, { memo: memo3 })));
|
|
2597
2775
|
server.tool(wphostingToolName(brand, "preview", "signup"), description3("\u8AB2\u91D1\u3055\u308C\u308BWPhosting\u65B0\u898F\u5951\u7D04\u3092dry-run\u3057\u3001\u5B9F\u7533\u8ACB\u524D\u306E\u91D1\u984D\u3092\u78BA\u8A8D\u3002\u7D50\u679C\u306E legal_notices \u3092\u30C1\u30E3\u30C3\u30C8\u4E0A\u306E\u30AF\u30EA\u30C3\u30AF\u53EF\u80FD\u306AMarkdown\u30EA\u30F3\u30AF\u3068\u3057\u3066\u5229\u7528\u8005\u3078\u63D0\u793A\u3057\u3066\u304B\u3089execute\u3092\u6848\u5185\u3057\u3066\u304F\u3060\u3055\u3044"), signupInput2, billingPreviewAnnotations, async ({ agree_to_terms: _agreeToTerms, auto_renew, ...input }) => callApi(async () => billingPreviewResult(await client.registerWphosting({
|
|
2598
2776
|
...input,
|
|
2599
2777
|
auto_renew: auto_renew === "enabled",
|
|
@@ -2932,6 +3110,213 @@ function registerWphostingTools(server, client, brand, options = {}) {
|
|
|
2932
3110
|
}, "updateWphostingSecurity", (a) => [a.contract_id, a.servername, a.key, { is_enable: a.is_enable }]);
|
|
2933
3111
|
}
|
|
2934
3112
|
|
|
3113
|
+
// ../core/dist/tools/vps/index.js
|
|
3114
|
+
import { z as z31 } from "zod";
|
|
3115
|
+
var readOnlyAnnotations = {
|
|
3116
|
+
readOnlyHint: true,
|
|
3117
|
+
destructiveHint: false,
|
|
3118
|
+
idempotentHint: true,
|
|
3119
|
+
openWorldHint: true
|
|
3120
|
+
};
|
|
3121
|
+
var additiveWriteAnnotations = {
|
|
3122
|
+
readOnlyHint: false,
|
|
3123
|
+
destructiveHint: false,
|
|
3124
|
+
idempotentHint: false,
|
|
3125
|
+
openWorldHint: true
|
|
3126
|
+
};
|
|
3127
|
+
var idempotentWriteAnnotations = {
|
|
3128
|
+
readOnlyHint: false,
|
|
3129
|
+
destructiveHint: false,
|
|
3130
|
+
idempotentHint: true,
|
|
3131
|
+
openWorldHint: true
|
|
3132
|
+
};
|
|
3133
|
+
var destructiveWriteAnnotations = {
|
|
3134
|
+
readOnlyHint: false,
|
|
3135
|
+
destructiveHint: true,
|
|
3136
|
+
idempotentHint: true,
|
|
3137
|
+
openWorldHint: true
|
|
3138
|
+
};
|
|
3139
|
+
var destructiveNonIdempotentWriteAnnotations = {
|
|
3140
|
+
readOnlyHint: false,
|
|
3141
|
+
destructiveHint: true,
|
|
3142
|
+
idempotentHint: false,
|
|
3143
|
+
openWorldHint: true
|
|
3144
|
+
};
|
|
3145
|
+
var uuid = z31.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).describe("VPS\u306E uuid\uFF08list_vps_servers \u3067\u53D6\u5F97\uFF09");
|
|
3146
|
+
var memo2 = z31.string().max(500).describe("\u30E1\u30E2\uFF08\u7A7A\u6587\u5B57\u3067\u524A\u9664\u3001500\u6587\u5B57\u4EE5\u5185\uFF09");
|
|
3147
|
+
var expectedTotalPrice3 = z31.number().int().nonnegative().describe("preview\u3068\u4E00\u81F4\u3059\u308B\u7A0E\u8FBC\u5408\u8A08\u91D1\u984D");
|
|
3148
|
+
var idempotencyKey4 = z31.string().regex(/^[A-Za-z0-9_-]{8,64}$/).describe("Idempotency-Key\uFF08\u82F1\u6570\u5B57\u30FB_\u30FB-\u30018\uFF5E64\u6587\u5B57\uFF09");
|
|
3149
|
+
var packetFilterType = z31.enum(["ssh", "web", "web_http", "mysql", "postgresql", "mail", "rdp", "custom"]).describe("\u30EB\u30FC\u30EB\u7A2E\u5225");
|
|
3150
|
+
function vpsSignupScopeLabel(brand) {
|
|
3151
|
+
return brand.brand === "shincloud" ? "\u30B7\u30F3VPS\uFF08\u30B9\u30BF\u30F3\u30C0\u30FC\u30C9\u30FB\u5927\u5BB9\u91CF\u30E1\u30E2\u30EA\uFF09" : "VPS\u30FB\u30D3\u30B8\u30CD\u30B9VPS";
|
|
3152
|
+
}
|
|
3153
|
+
function vpsPlanIdExample(brand) {
|
|
3154
|
+
return brand.brand === "shincloud" ? "vps-2gb / vps-highmem-4gb" : "vps-4gb / business-4gb";
|
|
3155
|
+
}
|
|
3156
|
+
var signupInput3 = (brand) => ({
|
|
3157
|
+
plan_id: z31.string().min(1).max(64).describe(`\u30D7\u30E9\u30F3ID\uFF08${vpsPlanIdExample(brand)} \u306A\u3069\uFF09`),
|
|
3158
|
+
period: z31.number().int().min(1).max(60).describe("\u5951\u7D04\u671F\u9593\uFF08\u6708\u6570\u3002\u30D7\u30E9\u30F3\u53D6\u5F97\u30C4\u30FC\u30EB\u304C\u8FD4\u3057\u305F months \u304B\u3089\u6307\u5B9A\uFF09"),
|
|
3159
|
+
image_id: z31.string().min(1).describe("OS\u30A4\u30E1\u30FC\u30B8ID\uFF08list_vps_plans \u306E os_images[].image_id\uFF09"),
|
|
3160
|
+
root_password: z31.string().min(9).max(70).describe("root\u30D1\u30B9\u30EF\u30FC\u30C9\uFF089\u301C70\u6587\u5B57\uFF09"),
|
|
3161
|
+
expected_total_price: expectedTotalPrice3,
|
|
3162
|
+
agree_to_terms: z31.literal(true).describe("VPS\u5951\u7D04\u306E\u5229\u7528\u898F\u7D04\u3078\u306E\u660E\u793A\u540C\u610F"),
|
|
3163
|
+
name: z31.string().min(1).max(50).optional().describe("\u30B5\u30FC\u30D0\u30FC\u540D"),
|
|
3164
|
+
ssh_key_name: z31.string().min(1).optional().describe("\u767B\u9332\u6E08\u307FSSH\u30AD\u30FC\u540D"),
|
|
3165
|
+
ssh_public_key: z31.string().min(1).optional().describe("\u767B\u9332\u3059\u308B\u516C\u958B\u9375\uFF08ssh_key_name \u3068\u4F75\u7528\uFF09"),
|
|
3166
|
+
partner_code: z31.string().regex(/^[A-Za-z0-9]{1,50}$/).optional().describe("\u304A\u53D6\u6B21\u5E97\u30B3\u30FC\u30C9"),
|
|
3167
|
+
auto_renew: z31.enum(["enabled", "disabled"]).describe("\u81EA\u52D5\u66F4\u65B0\uFF08enabled: \u6709\u52B9 / disabled: \u7121\u52B9\u3001\u660E\u793A\u6307\u5B9A\u5FC5\u9808\uFF09")
|
|
3168
|
+
});
|
|
3169
|
+
var osReinstallInput = {
|
|
3170
|
+
uuid,
|
|
3171
|
+
image_id: z31.string().min(1).describe("\u30A4\u30E1\u30FC\u30B8ID\uFF08list_vps_os_images \u306E image_id\uFF09"),
|
|
3172
|
+
root_password: z31.string().min(9).max(70).describe("\u7BA1\u7406\u8005\u30D1\u30B9\u30EF\u30FC\u30C9\uFF089\u301C70\u6587\u5B57\uFF09"),
|
|
3173
|
+
ssh_key_name: z31.string().min(1).optional().describe("\u767B\u9332\u6E08\u307FSSH\u30AD\u30FC\u540D\uFF08Windows\u3067\u306F\u6307\u5B9A\u4E0D\u53EF\uFF09"),
|
|
3174
|
+
ssh_public_key: z31.string().min(1).optional().describe("\u767B\u9332\u3059\u308B\u516C\u958B\u9375"),
|
|
3175
|
+
basic_password: z31.string().min(12).max(64).regex(/^[A-Za-z0-9]+$/).optional().describe("\u7BA1\u7406\u30C4\u30FC\u30EBBasic\u8A8D\u8A3C\uFF08requires_basic_password \u306E\u30A4\u30E1\u30FC\u30B8\u306E\u307F\u3002\u534A\u89D2\u82F1\u6570\u5B5712\u301C64\u6587\u5B57\uFF09")
|
|
3176
|
+
};
|
|
3177
|
+
function description4(text) {
|
|
3178
|
+
return `${text}\u3002\u5BFE\u8C61\u306F uuid \u3067\u6307\u5B9A\u3057\u307E\u3059\u3002Star8 \u306B\u306F VPS \u306F\u3042\u308A\u307E\u305B\u3093`;
|
|
3179
|
+
}
|
|
3180
|
+
function acceptedNextStep(checkTool) {
|
|
3181
|
+
return {
|
|
3182
|
+
next_step: `202 Accepted \u3067\u3059\u3002\u5B8C\u4E86\u307E\u3067\u30DD\u30FC\u30EA\u30F3\u30B0\u305B\u305A\u3001${checkTool} \u3067\u72B6\u614B\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`
|
|
3183
|
+
};
|
|
3184
|
+
}
|
|
3185
|
+
async function protectionEnabled(client, target) {
|
|
3186
|
+
try {
|
|
3187
|
+
const result = await client.getVpsProtection(target);
|
|
3188
|
+
return result.protection?.os_reinstall ?? null;
|
|
3189
|
+
} catch {
|
|
3190
|
+
return null;
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
3193
|
+
function registerVpsTools(server, client, brand, options = {}) {
|
|
3194
|
+
if (brand.brand !== "xserver" && brand.brand !== "shincloud") {
|
|
3195
|
+
throw new Error(`--services=vps is not supported for brand "${brand.brand}"; use XServer or \u30B7\u30F3\u30AF\u30E9\u30A6\u30C9.`);
|
|
3196
|
+
}
|
|
3197
|
+
server.tool(vpsToolName(brand, "list", "servers"), description4("\u5951\u7D04\u4E2D\u306EVPS\u4E00\u89A7\u3092\u53D6\u5F97"), {}, readOnlyAnnotations, async () => callApi(() => client.listVpsServers()));
|
|
3198
|
+
server.tool(vpsToolName(brand, "get", "server"), description4("VPS\u8A73\u7D30\u3092\u53D6\u5F97"), { uuid }, readOnlyAnnotations, async ({ uuid: target }) => callApi(() => client.getVpsServer(target)));
|
|
3199
|
+
server.tool(vpsToolName(brand, "update", "memo"), description4("VPS\u30E1\u30E2\u3092\u5909\u66F4"), { uuid, memo: memo2 }, destructiveWriteAnnotations, async ({ uuid: target, memo: value }) => callApi(() => client.updateVpsMemo(target, { memo: value })));
|
|
3200
|
+
server.tool(vpsToolName(brand, "update", "name"), description4("VPS\u30B5\u30FC\u30D0\u30FC\u540D\u3092\u5909\u66F4"), {
|
|
3201
|
+
uuid,
|
|
3202
|
+
name: z31.string().min(1).max(50).describe("\u30B5\u30FC\u30D0\u30FC\u540D\uFF08\u534A\u89D2\u82F1\u5C0F\u6587\u5B57\u30FB\u6570\u5B57\u30FB-\u30FB_\uFF09")
|
|
3203
|
+
}, destructiveWriteAnnotations, async ({ uuid: target, name }) => callApi(() => client.updateVpsName(target, { name })));
|
|
3204
|
+
server.tool(vpsToolName(brand, "update", "reverse_dns"), description4("\u9006\u5F15\u304D\u30DB\u30B9\u30C8\u540D\u3092\u5909\u66F4"), {
|
|
3205
|
+
uuid,
|
|
3206
|
+
hostname: z31.string().min(1).max(253).describe("\u9006\u5F15\u304D\u30DB\u30B9\u30C8\u540D")
|
|
3207
|
+
}, destructiveWriteAnnotations, async ({ uuid: target, hostname }) => callApi(() => client.updateVpsReverseDns(target, { hostname })));
|
|
3208
|
+
server.tool(vpsToolName(brand, "get", "power"), description4("\u96FB\u6E90\u72B6\u614B\u3092\u53D6\u5F97\u3002start/reboot/stop \u306E\u9032\u6357\u78BA\u8A8D\u5148"), { uuid }, readOnlyAnnotations, async ({ uuid: target }) => callApi(() => client.getVpsPower(target)));
|
|
3209
|
+
for (const [verb, method] of [
|
|
3210
|
+
["start", "startVpsPower"],
|
|
3211
|
+
["reboot", "rebootVpsPower"],
|
|
3212
|
+
["stop", "stopVpsPower"]
|
|
3213
|
+
]) {
|
|
3214
|
+
server.tool(vpsToolName(brand, verb, "power"), description4(`VPS\u3092${verb === "start" ? "\u8D77\u52D5" : verb === "reboot" ? "\u518D\u8D77\u52D5" : "\u505C\u6B62"}\uFF08202 Accepted\u3002get_vps_power \u3067\u78BA\u8A8D\uFF09`), { uuid }, verb === "start" ? idempotentWriteAnnotations : verb === "stop" ? destructiveWriteAnnotations : destructiveNonIdempotentWriteAnnotations, async ({ uuid: target }) => callApi(async () => {
|
|
3215
|
+
const result = await client[method](target);
|
|
3216
|
+
return {
|
|
3217
|
+
...result,
|
|
3218
|
+
...acceptedNextStep(vpsToolName(brand, "get", "power"))
|
|
3219
|
+
};
|
|
3220
|
+
}));
|
|
3221
|
+
}
|
|
3222
|
+
server.tool(vpsToolName(brand, "get", "packet_filter"), description4("\u30D1\u30B1\u30C3\u30C8\u30D5\u30A3\u30EB\u30BF\u30FC\u8A2D\u5B9A\u3092\u53D6\u5F97"), { uuid }, readOnlyAnnotations, async ({ uuid: target }) => callApi(() => client.getVpsPacketFilter(target)));
|
|
3223
|
+
server.tool(vpsToolName(brand, "update", "packet_filter"), description4("\u30D1\u30B1\u30C3\u30C8\u30D5\u30A3\u30EB\u30BF\u30FC\u306E\u6709\u52B9/\u7121\u52B9\u3092\u5207\u66FF"), { uuid, enabled: z31.boolean().describe("true \u3067\u6709\u52B9 / false \u3067\u7121\u52B9") }, destructiveWriteAnnotations, async ({ uuid: target, enabled }) => callApi(() => client.updateVpsPacketFilter(target, { enabled })));
|
|
3224
|
+
server.tool(vpsToolName(brand, "add", "packet_filter_rule"), description4("\u30D1\u30B1\u30C3\u30C8\u30D5\u30A3\u30EB\u30BF\u30FC\u306E\u30EB\u30FC\u30EB\u3092\u8FFD\u52A0"), {
|
|
3225
|
+
uuid,
|
|
3226
|
+
type: packetFilterType,
|
|
3227
|
+
protocol: z31.enum(["tcp", "udp", "icmp"]).optional().describe("custom \u306E\u5834\u5408\u306F\u5FC5\u9808"),
|
|
3228
|
+
port: z31.string().optional().describe("\u5358\u4E00\u307E\u305F\u306F\u7BC4\u56F2\u3002custom \u306E icmp \u4EE5\u5916\u3067\u5FC5\u9808"),
|
|
3229
|
+
allowed_ip: z31.string().optional().describe("all \u307E\u305F\u306F IP/CIDR\uFF08custom \u306E\u307F\uFF09"),
|
|
3230
|
+
memo: z31.string().max(500).optional().describe("\u30E1\u30E2\uFF08custom \u306E\u307F\uFF09")
|
|
3231
|
+
}, additiveWriteAnnotations, async ({ uuid: target, ...data }) => callApi(() => client.addVpsPacketFilterRule(target, data)));
|
|
3232
|
+
server.tool(vpsToolName(brand, "update", "packet_filter_rule"), description4("\u30D1\u30B1\u30C3\u30C8\u30D5\u30A3\u30EB\u30BF\u30FC\u306E\u30EB\u30FC\u30EB\u3092\u5909\u66F4"), {
|
|
3233
|
+
uuid,
|
|
3234
|
+
rule_id: z31.number().int().positive().describe("\u30EB\u30FC\u30EBID"),
|
|
3235
|
+
protocol: z31.enum(["tcp", "udp", "icmp"]).optional(),
|
|
3236
|
+
port: z31.string().optional(),
|
|
3237
|
+
allowed_ip: z31.string().optional(),
|
|
3238
|
+
memo: z31.string().max(500).optional()
|
|
3239
|
+
}, destructiveWriteAnnotations, async ({ uuid: target, rule_id, ...data }) => callApi(() => client.updateVpsPacketFilterRule(target, String(rule_id), data)));
|
|
3240
|
+
server.tool(vpsToolName(brand, "delete", "packet_filter_rule"), description4("\u30D1\u30B1\u30C3\u30C8\u30D5\u30A3\u30EB\u30BF\u30FC\u306E\u30EB\u30FC\u30EB\u3092\u524A\u9664"), { uuid, rule_id: z31.number().int().positive().describe("\u30EB\u30FC\u30EBID") }, destructiveWriteAnnotations, async ({ uuid: target, rule_id }) => callApi(() => client.deleteVpsPacketFilterRule(target, String(rule_id))));
|
|
3241
|
+
server.tool(vpsToolName(brand, "list", "os_images"), description4("\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3067\u304D\u308B\u30A4\u30E1\u30FC\u30B8\u4E00\u89A7\u3092\u53D6\u5F97\u3002requires_basic_password \u3092\u78BA\u8A8D\u3059\u308B\u3053\u3068"), { uuid }, readOnlyAnnotations, async ({ uuid: target }) => callApi(() => client.listVpsOsImages(target)));
|
|
3242
|
+
server.tool(vpsToolName(brand, "get", "os_reinstall"), description4("OS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u306E\u72B6\u6CC1\u3092\u78BA\u8A8D\uFF08\u30DD\u30FC\u30EA\u30F3\u30B0\u63A8\u5968\u9593\u9694 30\u79D2\uFF09"), { uuid }, readOnlyAnnotations, async ({ uuid: target }) => callApi(() => client.getVpsOsReinstall(target)));
|
|
3243
|
+
server.tool(vpsToolName(brand, "preview", "os_reinstall"), description4("OS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u524D\u306B\u5BFE\u8C61\u30FB\u64CD\u4F5C\u4FDD\u8B77\u3092\u78BA\u8A8D\u3002\u30C7\u30FC\u30BF\u5168\u6D88\u53BB\u3002execute \u306F\u9AD8\u30EA\u30B9\u30AF\u30B2\u30FC\u30C8\u304C\u5FC5\u8981"), osReinstallInput, billingPreviewAnnotations, async ({ uuid: target, image_id }) => callApi(async () => {
|
|
3244
|
+
const result = await client.getVpsProtection(target);
|
|
3245
|
+
return {
|
|
3246
|
+
uuid: target,
|
|
3247
|
+
image_id,
|
|
3248
|
+
protection: result.protection,
|
|
3249
|
+
warning: "\u30B5\u30FC\u30D0\u30FC\u5185\u306E\u30C7\u30FC\u30BF\u30FB\u8A2D\u5B9A\u306F\u3059\u3079\u3066\u524A\u9664\u3055\u308C\u307E\u3059\u3002VPS\u306F\u505C\u6B62\u4E2D\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002",
|
|
3250
|
+
next_step: "protection.os_reinstall \u304C true \u306E\u3068\u304D\u306F API \u304C 409 \u3067\u6B62\u307E\u308A\u307E\u3059\u3002\u5B9F\u884C\u3059\u308B\u5834\u5408\u306F execute \u30C4\u30FC\u30EB\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002"
|
|
3251
|
+
};
|
|
3252
|
+
}));
|
|
3253
|
+
server.tool(vpsToolName(brand, "get", "protection"), description4("\u64CD\u4F5C\u4FDD\u8B77\u3092\u53D6\u5F97\uFF08os_reinstall \u304C true \u306A\u3089 API \u304B\u3089\u306E\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3092\u62D2\u5426\uFF09"), { uuid }, readOnlyAnnotations, async ({ uuid: target }) => callApi(() => client.getVpsProtection(target)));
|
|
3254
|
+
server.tool(vpsToolName(brand, "update", "protection"), description4("\u64CD\u4F5C\u4FDD\u8B77\u3092\u5909\u66F4"), {
|
|
3255
|
+
uuid,
|
|
3256
|
+
os_reinstall: z31.boolean().describe("true \u3067\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3092\u62D2\u5426 / false \u3067\u89E3\u9664")
|
|
3257
|
+
}, destructiveWriteAnnotations, async ({ uuid: target, os_reinstall }) => callApi(() => client.updateVpsProtection(target, { os_reinstall })));
|
|
3258
|
+
server.tool(vpsToolName(brand, "list", "plans"), description4(`\u304A\u7533\u3057\u8FBC\u307F\u53EF\u80FD\u306A\u30D7\u30E9\u30F3\u30FB\u6599\u91D1\u30FBOS\u30A4\u30E1\u30FC\u30B8\u3092\u53D6\u5F97\u3002\u7533\u8FBC\u5BFE\u8C61\u306F ${vpsSignupScopeLabel(brand)} \u306E\u307F`), {}, readOnlyAnnotations, async () => callApi(() => client.listVpsPlans()));
|
|
3259
|
+
server.tool(vpsToolName(brand, "get", "signup_status"), description4("\u304A\u7533\u3057\u8FBC\u307F\u72B6\u6CC1\u3092\u78BA\u8A8D\uFF08id \u306F\u7533\u8FBC\u5FDC\u7B54\u306E\u30B5\u30FC\u30D3\u30B9\u30B3\u30FC\u30C9\uFF09"), { id: z31.number().int().positive().describe("\u65B0\u898F\u304A\u7533\u3057\u8FBC\u307F\u5FDC\u7B54\u306E id") }, readOnlyAnnotations, async ({ id }) => callApi(() => client.getVpsSignupStatus(String(id))));
|
|
3260
|
+
server.tool(vpsToolName(brand, "preview", "signup"), description4("\u8AB2\u91D1\u3055\u308C\u308BVPS\u65B0\u898F\u5951\u7D04\u3092 dry-run \u3057\u3001\u5B9F\u7533\u8ACB\u524D\u306E\u91D1\u984D\u3092\u78BA\u8A8D\u3002\u7D50\u679C\u306E legal_notices \u3092\u30C1\u30E3\u30C3\u30C8\u4E0A\u306E\u30AF\u30EA\u30C3\u30AF\u53EF\u80FD\u306AMarkdown\u30EA\u30F3\u30AF\u3068\u3057\u3066\u5229\u7528\u8005\u3078\u63D0\u793A\u3057\u3066\u304B\u3089execute\u3092\u6848\u5185\u3057\u3066\u304F\u3060\u3055\u3044"), signupInput3(brand), billingPreviewAnnotations, async ({ agree_to_terms: _agreeToTerms, auto_renew, ...input }) => callApi(async () => billingPreviewResult(await client.registerVps({
|
|
3261
|
+
...input,
|
|
3262
|
+
auto_renew: auto_renew === "enabled",
|
|
3263
|
+
agree_to_terms: true,
|
|
3264
|
+
dry_run: true
|
|
3265
|
+
}), signupLegalNoticeLines(brand, "vps", input.plan_id))));
|
|
3266
|
+
if (options.enableHighRiskExecute) {
|
|
3267
|
+
server.tool(vpsToolName(brand, "execute", "signup"), description4(`\u660E\u793A\u627F\u8A8D\u5F8C\u306BVPS\u65B0\u898F\u5951\u7D04\u3092\u5B9F\u7533\u8ACB\uFF08\u8AB2\u91D1\u3055\u308C\u539F\u5247\u53D6\u308A\u6D88\u3057\u4E0D\u53EF\u3002\u5BFE\u8C61\u306F ${vpsSignupScopeLabel(brand)}\uFF09`), { ...signupInput3(brand), idempotency_key: idempotencyKey4 }, billingExecuteAnnotations, async ({ agree_to_terms: _agreeToTerms, idempotency_key, ...input }) => callApi(async () => {
|
|
3268
|
+
const data = {
|
|
3269
|
+
...input,
|
|
3270
|
+
auto_renew: input.auto_renew === "enabled",
|
|
3271
|
+
agree_to_terms: true
|
|
3272
|
+
};
|
|
3273
|
+
const preview = await client.registerVps({
|
|
3274
|
+
...data,
|
|
3275
|
+
dry_run: true
|
|
3276
|
+
});
|
|
3277
|
+
const totalPrice = Number(preview.total_price);
|
|
3278
|
+
if (!Number.isFinite(totalPrice)) {
|
|
3279
|
+
throw new Error("dry-run\u7D50\u679C\u304B\u3089\u5408\u8A08\u91D1\u984D\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002");
|
|
3280
|
+
}
|
|
3281
|
+
if (totalPrice !== input.expected_total_price) {
|
|
3282
|
+
throw new Error(`\u4FA1\u683C\u4E0D\u4E00\u81F4\u306E\u305F\u3081\u5B9F\u7533\u8ACB\u3092\u4E2D\u6B62\u3057\u307E\u3057\u305F\uFF08\u898B\u7A4D ${totalPrice}\u5186 / \u6307\u5B9A ${input.expected_total_price}\u5186\uFF09\u3002`);
|
|
3283
|
+
}
|
|
3284
|
+
assertBillingFormElicitationSupported(server);
|
|
3285
|
+
const planName = await resolvePlanName(() => client.listVpsPlans(), input.plan_id);
|
|
3286
|
+
await confirmBillingOperation(server, {
|
|
3287
|
+
operation: signupOperationName(brand, "vps", input.plan_id),
|
|
3288
|
+
target: `${planLabel(input.plan_id, planName)} / \u5951\u7D04\u671F\u9593 ${input.period}\u304B\u6708 / ${input.image_id}`,
|
|
3289
|
+
targetLabel: "\u7533\u8FBC\u5185\u5BB9",
|
|
3290
|
+
details: compactDetails([
|
|
3291
|
+
autoRenewDetail(input.auto_renew === "enabled"),
|
|
3292
|
+
partnerCodeDetail(input.partner_code)
|
|
3293
|
+
]),
|
|
3294
|
+
legalNoticeLines: signupLegalNoticeLines(brand, "vps", input.plan_id),
|
|
3295
|
+
totalPrice,
|
|
3296
|
+
requireTermsAgreement: true
|
|
3297
|
+
});
|
|
3298
|
+
return client.registerVps({ ...data, dry_run: false }, idempotency_key);
|
|
3299
|
+
}));
|
|
3300
|
+
server.tool(vpsToolName(brand, "execute", "os_reinstall"), description4("\u660E\u793A\u627F\u8A8D\u5F8C\u306BOS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3092\u5B9F\u884C\uFF08\u30C7\u30FC\u30BF\u5168\u6D88\u53BB\u3002202 Accepted\u3002get_vps_os_reinstall \u3067\u78BA\u8A8D\uFF09"), osReinstallInput, destructiveNonIdempotentWriteAnnotations, async ({ uuid: target, image_id, root_password, ...optional }) => callApi(async () => {
|
|
3301
|
+
const protection = await protectionEnabled(client, target);
|
|
3302
|
+
await confirmOsReinstallOperation(server, {
|
|
3303
|
+
uuid: target,
|
|
3304
|
+
imageId: image_id,
|
|
3305
|
+
protectionEnabled: protection
|
|
3306
|
+
});
|
|
3307
|
+
const result = await client.reinstallVpsOs(target, {
|
|
3308
|
+
image_id,
|
|
3309
|
+
root_password,
|
|
3310
|
+
...optional
|
|
3311
|
+
});
|
|
3312
|
+
return {
|
|
3313
|
+
...result,
|
|
3314
|
+
...acceptedNextStep(vpsToolName(brand, "get", "os_reinstall"))
|
|
3315
|
+
};
|
|
3316
|
+
}));
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
|
|
2935
3320
|
// ../core/dist/tools/index.js
|
|
2936
3321
|
function registerServerTools(server, client, brand, resolver, options = {}) {
|
|
2937
3322
|
registerServerAccountTools(server, client, brand, options);
|
|
@@ -2976,10 +3361,13 @@ function registerAllTools(server, client, brand, service = "server", options = {
|
|
|
2976
3361
|
if (services.includes("wphosting")) {
|
|
2977
3362
|
registerWphostingTools(server, client, brand, options);
|
|
2978
3363
|
}
|
|
3364
|
+
if (services.includes("vps")) {
|
|
3365
|
+
registerVpsTools(server, client, brand, options);
|
|
3366
|
+
}
|
|
2979
3367
|
}
|
|
2980
3368
|
|
|
2981
3369
|
// ../core/dist/index.js
|
|
2982
|
-
var MCP_SERVICES = ["server", "domain", "wphosting"];
|
|
3370
|
+
var MCP_SERVICES = ["server", "domain", "wphosting", "vps"];
|
|
2983
3371
|
function optionValue(argv, index) {
|
|
2984
3372
|
const arg = argv[index];
|
|
2985
3373
|
if (arg === "--services") {
|
|
@@ -3047,6 +3435,11 @@ XSERVER_SERVERNAME\u7B49\u304C\u3042\u308B\u5834\u5408\u306F\u305D\u306E\u30B5\u
|
|
|
3047
3435
|
\u5BFE\u8C61\u306Fcontract_id\uFF08\u5951\u7D04\uFF09\u3068site servername\uFF08\u672C\u756A\u307E\u305F\u306F\u30B9\u30C6\u30FC\u30B8\u30F3\u30B0\u74B0\u5883\uFF09\u306E2\u8EF8\u3067\u5FC5\u305A\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u66F8\u304D\u8FBC\u307F\u524D\u306B\u4E21\u65B9\u3092\u5229\u7528\u8005\u3078\u63D0\u793A\u3057\u3001\u5BFE\u8C61\u304C\u66D6\u6627\u306A\u3089\u63A8\u6E2C\u305B\u305A\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
|
3048
3436
|
202\u64CD\u4F5C\u306Foperations API\u3092\u4F7F\u308F\u305A\u3001\u5404\u30C4\u30FC\u30EB\u8AAC\u660E\u306B\u8A18\u8F09\u3057\u305F\u30B5\u30A4\u30C8\u3001\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3001\u5FA9\u5143\u5C65\u6B74\u306E\u78BA\u8A8D\u5148\u3067status\u307E\u305F\u306F\u5BFE\u8C61\u306E\u6D88\u5931\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
|
3049
3437
|
\u30B5\u30A4\u30C8\u524A\u9664\u3068\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u5FA9\u5143\u306Fpreview\u3067\u5BFE\u8C61\u30FB\u5F71\u97FF\u3092\u78BA\u8A8D\u3057\u3001\u660E\u793A\u627F\u8A8D\u5F8C\u306Bexecute\u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002`);
|
|
3438
|
+
}
|
|
3439
|
+
if (services.includes("vps")) {
|
|
3440
|
+
sections.push(`VPS \u2014 ${brand.displayName}\u306EVPS\u3092\u7BA1\u7406\u3057\u307E\u3059\u3002\u5BFE\u8C61\u306F uuid \u3067\u3059\u3002Star8 \u306B VPS \u306F\u3042\u308A\u307E\u305B\u3093\u3002
|
|
3441
|
+
\u96FB\u6E90\u64CD\u4F5C\u3068OS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u306F202 Accepted\uFF08\u672C\u6587\u306A\u3057\uFF0BLocation\uFF09\u3067\u3059\u3002\u30C4\u30FC\u30EB\u5185\u3067\u5B8C\u4E86\u307E\u3067\u5F85\u305F\u305A\u3001get_vps_power / get_vps_os_reinstall \u3067\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
|
3442
|
+
OS\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u306F\u30C7\u30FC\u30BF\u5168\u6D88\u53BB\u3067\u3059\u3002execute \u306E\u524D\u306B protection \u72B6\u614B\u3092\u78BA\u8A8D\u3057\u3001form elicitation \u306B\u3088\u308B\u627F\u8A8D\u304C\u5FC5\u9808\u3067\u3059\u3002\u65B0\u898F\u304A\u7533\u3057\u8FBC\u307F\u306F ${vpsSignupScopeLabel(brand)} \u306E\u307F\u3067\u3001\u8AB2\u91D1 execute \u306E\u524D\u306B preview \u304C\u5FC5\u8981\u3067\u3059\u3002`);
|
|
3050
3443
|
}
|
|
3051
3444
|
return `${brand.displayName} MCP \u2014 \u6709\u52B9\u306A\u30B5\u30FC\u30D3\u30B9: ${services.join(", ")}
|
|
3052
3445
|
|
|
@@ -3062,7 +3455,11 @@ async function run(brand, options) {
|
|
|
3062
3455
|
const enableHighRiskExecute = (process.env[`${envPrefix}_MCP_ENABLE_HIGH_RISK_EXECUTE`] ?? process.env.XSERVER_MCP_ENABLE_HIGH_RISK_EXECUTE) === "1";
|
|
3063
3456
|
let services;
|
|
3064
3457
|
try {
|
|
3065
|
-
const supportedServices =
|
|
3458
|
+
const supportedServices = ["server", "domain"];
|
|
3459
|
+
if (brand.brand === "xserver")
|
|
3460
|
+
supportedServices.push("wphosting");
|
|
3461
|
+
if (brand.brand === "xserver" || brand.brand === "shincloud")
|
|
3462
|
+
supportedServices.push("vps");
|
|
3066
3463
|
services = parseMcpServices(process.argv.slice(2), supportedServices);
|
|
3067
3464
|
} catch (error) {
|
|
3068
3465
|
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -3101,7 +3498,7 @@ async function run(brand, options) {
|
|
|
3101
3498
|
// package.json
|
|
3102
3499
|
var package_default = {
|
|
3103
3500
|
name: "xserver-mcp",
|
|
3104
|
-
version: "1.
|
|
3501
|
+
version: "1.5.0",
|
|
3105
3502
|
description: "Official MCP server for XServer API \u2014 manage your XServer hosting from AI assistants",
|
|
3106
3503
|
type: "module",
|
|
3107
3504
|
bin: {
|
|
@@ -3169,6 +3566,9 @@ await run({
|
|
|
3169
3566
|
],
|
|
3170
3567
|
wphostingTermsUrl: "https://wp.xserver.ne.jp/rule/rule.php",
|
|
3171
3568
|
wphostingPrivacyUrl: "https://wp.xserver.ne.jp/privacy_announcement.php",
|
|
3569
|
+
vpsServiceName: "XServer VPS",
|
|
3570
|
+
vpsTermsUrl: "https://vps.xserver.ne.jp/rule/rule.php",
|
|
3571
|
+
vpsPrivacyUrl: "https://vps.xserver.ne.jp/privacy_announcement.php",
|
|
3172
3572
|
commandName: "xserver-mcp",
|
|
3173
3573
|
configDir: "xserver-mcp"
|
|
3174
3574
|
}, {
|