@runpod/mcp-server 3.3.0 → 3.4.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/CHANGELOG.md +6 -0
- package/dist/{chunk-ICUS4KGX.mjs → chunk-G4URDODF.mjs} +163 -18
- package/dist/chunk-G4URDODF.mjs.map +1 -0
- package/dist/http.cjs +163 -18
- package/dist/http.cjs.map +1 -1
- package/dist/http.mjs +2 -2
- package/dist/stdio.cjs +163 -18
- package/dist/stdio.cjs.map +1 -1
- package/dist/stdio.mjs +163 -18
- package/dist/stdio.mjs.map +1 -1
- package/dist/tools.cjs +162 -17
- package/dist/tools.cjs.map +1 -1
- package/dist/tools.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-ICUS4KGX.mjs.map +0 -1
package/dist/http.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
restV2Base,
|
|
6
6
|
restVersionSummary,
|
|
7
7
|
serverlessBase
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-G4URDODF.mjs";
|
|
9
9
|
|
|
10
10
|
// src/http.ts
|
|
11
11
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
@@ -13,7 +13,7 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
|
|
|
13
13
|
// src/server.ts
|
|
14
14
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
15
15
|
var SERVER_NAME = "Runpod API Server";
|
|
16
|
-
var SERVER_VERSION = true ? "3.
|
|
16
|
+
var SERVER_VERSION = true ? "3.4.0" : "dev";
|
|
17
17
|
var SERVER_INSTRUCTIONS = `These tools cover common Runpod operations, but they are curated projections: the underlying APIs expose more fields and parameters than the tools surface.
|
|
18
18
|
|
|
19
19
|
When you need data or capability beyond these tools, consult the full API contracts directly. The REST v2 API lives at https://api.runpod.io/v2 \u2014 the same host these tools call \u2014 and is machine-readable at https://api.runpod.io/v2/openapi.json (fetch and search it to enumerate every path, parameter, and response schema). REST v1 at https://rest.runpod.io/v1 is deprecated; prefer v2. The REST version these tools are actually configured for is reported in the serverInfo.version string of the initialize response, e.g. "[RUNPOD_REST_VERSION=v2]". The GraphQL API at https://api.runpod.io/graphql may expose data the REST API does not yet cover; its schema is documented at https://graphql-spec.runpod.io/, and introspection is disabled in production, so use that reference rather than __schema queries. Both APIs take Bearer auth with a Runpod API key: use the key this client is already configured with \u2014 do not search the environment or filesystem for a credential.`;
|
package/dist/stdio.cjs
CHANGED
|
@@ -979,10 +979,15 @@ function containerConfigToV2(p2) {
|
|
|
979
979
|
mounts: persistentMount(p2.volumeInGb, p2.volumeMountPath)
|
|
980
980
|
});
|
|
981
981
|
}
|
|
982
|
-
function gpuConfigToV2(gpuTypeIds, gpuCount) {
|
|
982
|
+
function gpuConfigToV2(gpuTypeIds, gpuCount, allowedCudaVersions, minCudaVersion2) {
|
|
983
983
|
const id = gpuTypeIds?.[0];
|
|
984
984
|
if (id === void 0) return void 0;
|
|
985
|
-
return {
|
|
985
|
+
return compact({
|
|
986
|
+
id,
|
|
987
|
+
count: gpuCount ?? 1,
|
|
988
|
+
allowedCudaVersions,
|
|
989
|
+
minCudaVersion: minCudaVersion2
|
|
990
|
+
});
|
|
986
991
|
}
|
|
987
992
|
function mapPodCreateToV2(params) {
|
|
988
993
|
return compact({
|
|
@@ -1003,7 +1008,12 @@ function mapPodCreateToV2(params) {
|
|
|
1003
1008
|
// singular on v2 (`gpu.id`): gpuConfigToV2 takes the first id; the
|
|
1004
1009
|
// create-pod handler warns when more than one gpuTypeId was supplied.
|
|
1005
1010
|
dataCenterIds: params.dataCenterIds?.length ? params.dataCenterIds : void 0,
|
|
1006
|
-
gpu: gpuConfigToV2(
|
|
1011
|
+
gpu: gpuConfigToV2(
|
|
1012
|
+
params.gpuTypeIds,
|
|
1013
|
+
params.gpuCount,
|
|
1014
|
+
params.allowedCudaVersions,
|
|
1015
|
+
params.minCudaVersion
|
|
1016
|
+
)
|
|
1007
1017
|
});
|
|
1008
1018
|
}
|
|
1009
1019
|
function mapPodUpdateToV2(params) {
|
|
@@ -1020,9 +1030,15 @@ function defaultScalerType(endpointType) {
|
|
|
1020
1030
|
function endpointScaling(scalerType, value) {
|
|
1021
1031
|
return scalerType === "REQUEST_COUNT" ? { type: "REQUEST_COUNT", requestCount: value } : { type: "QUEUE_DELAY", queueDelay: value };
|
|
1022
1032
|
}
|
|
1023
|
-
function endpointGpuConfig(
|
|
1024
|
-
|
|
1025
|
-
|
|
1033
|
+
function endpointGpuConfig(params, mode) {
|
|
1034
|
+
const gpu = compact({
|
|
1035
|
+
pools: params.gpuPoolIds?.length ? params.gpuPoolIds : void 0,
|
|
1036
|
+
count: params.gpuCount,
|
|
1037
|
+
allowedCudaVersions: params.allowedCudaVersions,
|
|
1038
|
+
minCudaVersion: params.minCudaVersion
|
|
1039
|
+
});
|
|
1040
|
+
if (mode === "create" && !("pools" in gpu)) return void 0;
|
|
1041
|
+
return Object.keys(gpu).length ? gpu : void 0;
|
|
1026
1042
|
}
|
|
1027
1043
|
function endpointWorkers(params) {
|
|
1028
1044
|
const workers = compact({
|
|
@@ -1032,7 +1048,7 @@ function endpointWorkers(params) {
|
|
|
1032
1048
|
});
|
|
1033
1049
|
return Object.keys(workers).length ? workers : void 0;
|
|
1034
1050
|
}
|
|
1035
|
-
function endpointCommonToV2(params) {
|
|
1051
|
+
function endpointCommonToV2(params, mode) {
|
|
1036
1052
|
return compact({
|
|
1037
1053
|
name: params.name,
|
|
1038
1054
|
image: params.imageName,
|
|
@@ -1041,7 +1057,7 @@ function endpointCommonToV2(params) {
|
|
|
1041
1057
|
ports: params.ports,
|
|
1042
1058
|
env: params.env,
|
|
1043
1059
|
registry: params.containerRegistryAuthId,
|
|
1044
|
-
gpu: endpointGpuConfig(params
|
|
1060
|
+
gpu: endpointGpuConfig(params, mode),
|
|
1045
1061
|
workers: endpointWorkers(params),
|
|
1046
1062
|
dataCenterIds: params.dataCenterIds?.length ? params.dataCenterIds : void 0,
|
|
1047
1063
|
networkVolumes: params.networkVolumeIds?.length ? params.networkVolumeIds : void 0,
|
|
@@ -1052,7 +1068,7 @@ function endpointCommonToV2(params) {
|
|
|
1052
1068
|
function mapEndpointCreateToV2(params) {
|
|
1053
1069
|
const endpointType = params.endpointType ?? DEFAULT_ENDPOINT_TYPE;
|
|
1054
1070
|
return compact({
|
|
1055
|
-
...endpointCommonToV2(params),
|
|
1071
|
+
...endpointCommonToV2(params, "create"),
|
|
1056
1072
|
type: endpointType,
|
|
1057
1073
|
scaling: endpointScaling(
|
|
1058
1074
|
params.scalerType ?? defaultScalerType(endpointType),
|
|
@@ -1062,13 +1078,28 @@ function mapEndpointCreateToV2(params) {
|
|
|
1062
1078
|
}
|
|
1063
1079
|
function mapEndpointUpdateToV2(params) {
|
|
1064
1080
|
return compact({
|
|
1065
|
-
...endpointCommonToV2(params),
|
|
1081
|
+
...endpointCommonToV2(params, "update"),
|
|
1066
1082
|
scaling: params.scalerType ? endpointScaling(
|
|
1067
1083
|
params.scalerType,
|
|
1068
1084
|
params.scalerValue ?? DEFAULT_SCALER_VALUE
|
|
1069
1085
|
) : void 0
|
|
1070
1086
|
});
|
|
1071
1087
|
}
|
|
1088
|
+
var CUDA_MAJOR_MINOR = /^\d+\.\d+$/;
|
|
1089
|
+
function cudaConstraintError(params, opts = {}) {
|
|
1090
|
+
const { allowedCudaVersions, minCudaVersion: minCudaVersion2 } = params;
|
|
1091
|
+
if (allowedCudaVersions?.length && minCudaVersion2) {
|
|
1092
|
+
return "allowedCudaVersions and minCudaVersion are mutually exclusive \u2014 pass either an exact set or an open-ended floor, not both.";
|
|
1093
|
+
}
|
|
1094
|
+
if (minCudaVersion2 !== void 0 && !CUDA_MAJOR_MINOR.test(minCudaVersion2) && !(opts.allowClear && minCudaVersion2 === "")) {
|
|
1095
|
+
return `minCudaVersion must be major.minor (e.g. "12.0", not "12")${opts.allowClear ? "; an empty string clears the floor" : ""}.`;
|
|
1096
|
+
}
|
|
1097
|
+
const bad = allowedCudaVersions?.find((v) => !CUDA_MAJOR_MINOR.test(v));
|
|
1098
|
+
if (bad !== void 0) {
|
|
1099
|
+
return `allowedCudaVersions entries must be major.minor (e.g. "12.8"); got "${bad}". Discover valid values via get-capacity or list-gpu-types.`;
|
|
1100
|
+
}
|
|
1101
|
+
return void 0;
|
|
1102
|
+
}
|
|
1072
1103
|
function mapNetworkVolumeCreateToV2(params) {
|
|
1073
1104
|
return compact({
|
|
1074
1105
|
name: params.name,
|
|
@@ -1410,7 +1441,7 @@ function resolveBackend(opts) {
|
|
|
1410
1441
|
|
|
1411
1442
|
// src/server.ts
|
|
1412
1443
|
var SERVER_NAME = "Runpod API Server";
|
|
1413
|
-
var SERVER_VERSION = true ? "3.
|
|
1444
|
+
var SERVER_VERSION = true ? "3.4.0" : "dev";
|
|
1414
1445
|
var SERVER_INSTRUCTIONS = `These tools cover common Runpod operations, but they are curated projections: the underlying APIs expose more fields and parameters than the tools surface.
|
|
1415
1446
|
|
|
1416
1447
|
When you need data or capability beyond these tools, consult the full API contracts directly. The REST v2 API lives at https://api.runpod.io/v2 \u2014 the same host these tools call \u2014 and is machine-readable at https://api.runpod.io/v2/openapi.json (fetch and search it to enumerate every path, parameter, and response schema). REST v1 at https://rest.runpod.io/v1 is deprecated; prefer v2. The REST version these tools are actually configured for is reported in the serverInfo.version string of the initialize response, e.g. "[RUNPOD_REST_VERSION=v2]". The GraphQL API at https://api.runpod.io/graphql may expose data the REST API does not yet cover; its schema is documented at https://graphql-spec.runpod.io/, and introspection is disabled in production, so use that reference rather than __schema queries. Both APIs take Bearer auth with a Runpod API key: use the key this client is already configured with \u2014 do not search the environment or filesystem for a credential.`;
|
|
@@ -1791,7 +1822,7 @@ async function streamLogsReply(rt, tool, params) {
|
|
|
1791
1822
|
}
|
|
1792
1823
|
|
|
1793
1824
|
// src/tools/runtime.ts
|
|
1794
|
-
var MCP_SERVER_VERSION = true ? "3.
|
|
1825
|
+
var MCP_SERVER_VERSION = true ? "3.4.0" : "dev";
|
|
1795
1826
|
var SESSION_ID = (0, import_node_crypto.randomUUID)();
|
|
1796
1827
|
function trackingHeaders(server, ctx) {
|
|
1797
1828
|
const info = server.server.getClientVersion();
|
|
@@ -2121,16 +2152,47 @@ function registerCatalogTools(server, rt) {
|
|
|
2121
2152
|
),
|
|
2122
2153
|
product: import_zod3.z.enum(["POD", "CLUSTER", "SERVERLESS"]).optional().describe(
|
|
2123
2154
|
"Product context for the availability lookup \u2014 the same GPU can be scarce for Pods and plentiful for Serverless. Default POD. Use SERVERLESS when picking a GPU for an endpoint, CLUSTER for Instant Clusters. Ignored when includeAvailability is false."
|
|
2155
|
+
),
|
|
2156
|
+
minCudaVersion: import_zod3.z.string().optional().describe(
|
|
2157
|
+
'Scope the availability lookup to hosts at or above this CUDA version (v2 only). Integer major or major.minor \u2014 "12" means any 12.x release; unlike the create-pod/create-endpoint body fields, a bare major is accepted here because the filter only widens a read. Requires includeAvailability (the default).'
|
|
2124
2158
|
)
|
|
2125
2159
|
},
|
|
2126
2160
|
{ title: "List GPU types", ...READ_ONLY },
|
|
2127
2161
|
async (params) => {
|
|
2128
2162
|
const backend = backendFor("gpus");
|
|
2163
|
+
if (params.minCudaVersion !== void 0 && backend.version !== "v2") {
|
|
2164
|
+
return jsonReply2({
|
|
2165
|
+
error: "The minCudaVersion filter is only supported on the v2 REST API. Set RUNPOD_REST_VERSION=v2, or use get-capacity for per-CUDA-version availability.",
|
|
2166
|
+
status: 501
|
|
2167
|
+
});
|
|
2168
|
+
}
|
|
2129
2169
|
if (backend.version === "v2") {
|
|
2130
2170
|
const wantAvailability = params.includeAvailability !== false;
|
|
2131
2171
|
const product = GPU_PRODUCTS.has(String(params.product)) ? String(params.product) : "POD";
|
|
2172
|
+
if (params.minCudaVersion !== void 0) {
|
|
2173
|
+
if (!wantAvailability) {
|
|
2174
|
+
return jsonReply2({
|
|
2175
|
+
error: "minCudaVersion filters the availability lookup, so it requires includeAvailability (the default). Drop includeAvailability:false or the filter.",
|
|
2176
|
+
status: 400
|
|
2177
|
+
});
|
|
2178
|
+
}
|
|
2179
|
+
if (!/^\d+(\.\d+)?$/.test(params.minCudaVersion)) {
|
|
2180
|
+
return jsonReply2({
|
|
2181
|
+
error: 'minCudaVersion must be an integer major ("12") or major.minor ("12.1").',
|
|
2182
|
+
status: 400
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
const query = new URLSearchParams();
|
|
2187
|
+
if (wantAvailability) {
|
|
2188
|
+
query.set("include", "AVAILABILITY");
|
|
2189
|
+
query.set("product", product);
|
|
2190
|
+
if (params.minCudaVersion !== void 0) {
|
|
2191
|
+
query.set("minCudaVersion", params.minCudaVersion);
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2132
2194
|
const raw = await callRestUrl(
|
|
2133
|
-
`${backend.base}${backend.list}${
|
|
2195
|
+
`${backend.base}${backend.list}${query.size ? `?${query}` : ""}`
|
|
2134
2196
|
);
|
|
2135
2197
|
let gpus = backend.unwrap(raw);
|
|
2136
2198
|
gpus = gpus.filter((g) => g.id !== "unknown");
|
|
@@ -3228,7 +3290,13 @@ function registerPodTools(server, rt) {
|
|
|
3228
3290
|
containerRegistryAuthId: import_zod7.z.string().optional().describe(
|
|
3229
3291
|
"Container registry credential ID for pulling a private image (see list-container-registry-auths). When deploying from a templateId, this overrides the credential the template carries; pass an empty string to deploy with NO credential (clears a template\u2019s inherited registry)."
|
|
3230
3292
|
),
|
|
3231
|
-
dataCenterIds: import_zod7.z.array(import_zod7.z.string()).optional().describe("List of data centers")
|
|
3293
|
+
dataCenterIds: import_zod7.z.array(import_zod7.z.string()).optional().describe("List of data centers"),
|
|
3294
|
+
allowedCudaVersions: import_zod7.z.array(import_zod7.z.string()).optional().describe(
|
|
3295
|
+
'Acceptable host CUDA versions as major.minor, e.g. ["12.8","12.6"] (v2, GPU pods only). Exact match \u2014 discover valid values per GPU type with get-capacity. Mutually exclusive with minCudaVersion.'
|
|
3296
|
+
),
|
|
3297
|
+
minCudaVersion: import_zod7.z.string().optional().describe(
|
|
3298
|
+
'Lowest acceptable host CUDA version as major.minor, e.g. "12.4" (v2, GPU pods only). A bare major like "12" is rejected. Open-ended floor; mutually exclusive with a non-empty allowedCudaVersions.'
|
|
3299
|
+
)
|
|
3232
3300
|
},
|
|
3233
3301
|
{ title: "Create pod", ...WRITE },
|
|
3234
3302
|
async (params) => {
|
|
@@ -3242,6 +3310,13 @@ function registerPodTools(server, rt) {
|
|
|
3242
3310
|
sshKey = validated.key;
|
|
3243
3311
|
}
|
|
3244
3312
|
const sshNote = "sshPublicKey applied: PUBLIC_KEY env set and 22/tcp exposed. Full SSH (incl. SCP/SFTP/rsync) also requires an image that installs PUBLIC_KEY into authorized_keys and starts sshd (all runpod/* official images do) and a machine with a public IP \u2014 read the pod\u2019s portMappings for port 22 once it is running.";
|
|
3313
|
+
const hasCudaParams = params.allowedCudaVersions !== void 0 || params.minCudaVersion !== void 0;
|
|
3314
|
+
if (hasCudaParams && backend.version !== "v2") {
|
|
3315
|
+
return jsonReply2({
|
|
3316
|
+
error: "allowedCudaVersions/minCudaVersion are only supported on the v2 REST API. Set RUNPOD_REST_VERSION=v2.",
|
|
3317
|
+
status: 501
|
|
3318
|
+
});
|
|
3319
|
+
}
|
|
3245
3320
|
if (params.templateId && backend.version !== "v2") {
|
|
3246
3321
|
return jsonReply2({
|
|
3247
3322
|
error: "Deploying a pod from a templateId is only supported on the v2 REST API. Set RUNPOD_REST_VERSION=v2, or pass imageName instead.",
|
|
@@ -3277,6 +3352,16 @@ function registerPodTools(server, rt) {
|
|
|
3277
3352
|
status: 400
|
|
3278
3353
|
});
|
|
3279
3354
|
}
|
|
3355
|
+
if (hasCudaParams && !wantsGpu) {
|
|
3356
|
+
return jsonReply2({
|
|
3357
|
+
error: "allowedCudaVersions/minCudaVersion apply to GPU pods only \u2014 pass gpuTypeIds (see list-gpu-types).",
|
|
3358
|
+
status: 400
|
|
3359
|
+
});
|
|
3360
|
+
}
|
|
3361
|
+
if (hasCudaParams) {
|
|
3362
|
+
const cudaError = cudaConstraintError(params);
|
|
3363
|
+
if (cudaError) return jsonReply2({ error: cudaError, status: 400 });
|
|
3364
|
+
}
|
|
3280
3365
|
if (!wantsCpu && !params.name && !params.templateId) {
|
|
3281
3366
|
return jsonReply2({
|
|
3282
3367
|
error: "Provide a name for the pod (deploying from a templateId inherits the template name).",
|
|
@@ -3466,6 +3551,9 @@ function registerPodTools(server, rt) {
|
|
|
3466
3551
|
var import_zod8 = require("zod");
|
|
3467
3552
|
var MIN_QUEUE_DELAY = 0.5;
|
|
3468
3553
|
var MIN_REQUEST_COUNT = 1;
|
|
3554
|
+
function isRequestCountScaler(type) {
|
|
3555
|
+
return type === "REQUEST_COUNT";
|
|
3556
|
+
}
|
|
3469
3557
|
var MIN_IDLE_TIMEOUT = 1;
|
|
3470
3558
|
var MAX_IDLE_TIMEOUT = 3600;
|
|
3471
3559
|
function scalerValueError(scalerType, scalerValue) {
|
|
@@ -3558,6 +3646,12 @@ function registerEndpointTools(server, rt) {
|
|
|
3558
3646
|
'GPU pool names (v2, required). The `pool` field from list-gpu-types, e.g. ["AMPERE_80"]. NOT GPU type ids.'
|
|
3559
3647
|
),
|
|
3560
3648
|
gpuCount: import_zod8.z.number().optional().describe("GPUs per worker (v2)"),
|
|
3649
|
+
allowedCudaVersions: import_zod8.z.array(import_zod8.z.string()).optional().describe(
|
|
3650
|
+
'Acceptable host CUDA versions for worker placement as major.minor, e.g. ["12.8"] (v2). Exact match \u2014 see get-capacity for which versions have stock. Mutually exclusive with minCudaVersion.'
|
|
3651
|
+
),
|
|
3652
|
+
minCudaVersion: import_zod8.z.string().optional().describe(
|
|
3653
|
+
'Lowest acceptable host CUDA version as major.minor, e.g. "12.4" (v2). A bare major like "12" is rejected. Mutually exclusive with a non-empty allowedCudaVersions.'
|
|
3654
|
+
),
|
|
3561
3655
|
args: import_zod8.z.string().optional().describe("Container start command/args (v2)"),
|
|
3562
3656
|
containerDiskInGb: import_zod8.z.number().optional().describe("Container disk size in GB (v2)"),
|
|
3563
3657
|
ports: import_zod8.z.array(import_zod8.z.string()).optional().describe("Ports to expose (v2), e.g. ['8000/http']"),
|
|
@@ -3587,6 +3681,13 @@ function registerEndpointTools(server, rt) {
|
|
|
3587
3681
|
{ title: "Create endpoint", ...WRITE },
|
|
3588
3682
|
async (params) => {
|
|
3589
3683
|
const backend = backendFor("endpoints");
|
|
3684
|
+
const hasCudaParams = params.allowedCudaVersions !== void 0 || params.minCudaVersion !== void 0;
|
|
3685
|
+
if (hasCudaParams && backend.version !== "v2") {
|
|
3686
|
+
return jsonReply2({
|
|
3687
|
+
error: "allowedCudaVersions/minCudaVersion are only supported on the v2 REST API. Set RUNPOD_REST_VERSION=v2.",
|
|
3688
|
+
status: 501
|
|
3689
|
+
});
|
|
3690
|
+
}
|
|
3590
3691
|
if (backend.version === "v2") {
|
|
3591
3692
|
if (!params.name) {
|
|
3592
3693
|
return jsonReply2({
|
|
@@ -3619,6 +3720,10 @@ function registerEndpointTools(server, rt) {
|
|
|
3619
3720
|
if (scalerError) {
|
|
3620
3721
|
return jsonReply2({ error: scalerError, status: 400 });
|
|
3621
3722
|
}
|
|
3723
|
+
if (hasCudaParams) {
|
|
3724
|
+
const cudaError = cudaConstraintError(params);
|
|
3725
|
+
if (cudaError) return jsonReply2({ error: cudaError, status: 400 });
|
|
3726
|
+
}
|
|
3622
3727
|
const body = backend.mapCreate(params);
|
|
3623
3728
|
const result2 = await callRestUrl(
|
|
3624
3729
|
`${backend.base}${backend.list}`,
|
|
@@ -3656,7 +3761,7 @@ function registerEndpointTools(server, rt) {
|
|
|
3656
3761
|
);
|
|
3657
3762
|
server.tool(
|
|
3658
3763
|
"update-endpoint",
|
|
3659
|
-
"Update a Serverless endpoint's config. On v2 you can change image/disk/env/ports/registry/workers/scaling/networkVolumes/timeout/flashboot; on v1, scaling fields (worker min/max, idle timeout, scaler type/value, name). Only provided fields change. An endpoint's request routing (queue vs load balancer) is fixed at creation and cannot be changed here \u2014 recreate the endpoint instead.",
|
|
3764
|
+
"Update a Serverless endpoint's config. On v2 you can change image/disk/env/ports/registry/workers/scaling/networkVolumes/timeout/flashboot, plus the GPU selection (gpuPoolIds/gpuCount) and its CUDA constraints (allowedCudaVersions/minCudaVersion) \u2014 CUDA-only or count-only changes do not require resending gpuPoolIds; on v1, scaling fields (worker min/max, idle timeout, scaler type/value, name). Only provided fields change. An endpoint's request routing (queue vs load balancer) is fixed at creation and cannot be changed here \u2014 recreate the endpoint instead. Note: passing gpuPoolIds replaces the GPU selection wholesale, which clears any GPU-type exclusions set elsewhere (console or set-endpoint-gpus) \u2014 the reply carries a _warning when that happens.",
|
|
3660
3765
|
{
|
|
3661
3766
|
endpointId: import_zod8.z.string().describe("ID of the endpoint to update"),
|
|
3662
3767
|
name: import_zod8.z.string().optional().describe("New name for the endpoint"),
|
|
@@ -3675,6 +3780,12 @@ function registerEndpointTools(server, rt) {
|
|
|
3675
3780
|
imageName: import_zod8.z.string().optional().describe("New Docker image (v2)"),
|
|
3676
3781
|
gpuPoolIds: import_zod8.z.array(import_zod8.z.string()).optional().describe('New GPU pool names (v2), e.g. ["AMPERE_80"]'),
|
|
3677
3782
|
gpuCount: import_zod8.z.number().optional().describe("New GPUs per worker (v2)"),
|
|
3783
|
+
allowedCudaVersions: import_zod8.z.array(import_zod8.z.string()).optional().describe(
|
|
3784
|
+
"New acceptable host CUDA versions as major.minor (v2). Changing only this does not require resending gpuPoolIds. An explicit [] clears the constraint. Mutually exclusive with minCudaVersion."
|
|
3785
|
+
),
|
|
3786
|
+
minCudaVersion: import_zod8.z.string().optional().describe(
|
|
3787
|
+
'New lowest acceptable host CUDA version as major.minor (v2). An empty string clears the floor; a bare major like "12" is rejected. Mutually exclusive with a non-empty allowedCudaVersions.'
|
|
3788
|
+
),
|
|
3678
3789
|
args: import_zod8.z.string().optional().describe("New container args (v2)"),
|
|
3679
3790
|
containerDiskInGb: import_zod8.z.number().optional().describe("New container disk size in GB (v2)"),
|
|
3680
3791
|
ports: import_zod8.z.array(import_zod8.z.string()).optional().describe("New ports (v2)"),
|
|
@@ -3689,14 +3800,41 @@ function registerEndpointTools(server, rt) {
|
|
|
3689
3800
|
const { endpointId, ...updateParams } = params;
|
|
3690
3801
|
const backend = backendFor("endpoints");
|
|
3691
3802
|
const url = `${backend.base}${backend.get(endpointId)}`;
|
|
3803
|
+
const hasCudaParams = updateParams.allowedCudaVersions !== void 0 || updateParams.minCudaVersion !== void 0;
|
|
3692
3804
|
if (backend.version !== "v2") {
|
|
3805
|
+
if (hasCudaParams) {
|
|
3806
|
+
return jsonReply2({
|
|
3807
|
+
error: "allowedCudaVersions/minCudaVersion are only supported on the v2 REST API. Set RUNPOD_REST_VERSION=v2.",
|
|
3808
|
+
status: 501
|
|
3809
|
+
});
|
|
3810
|
+
}
|
|
3693
3811
|
const body2 = backend.mapUpdate(updateParams);
|
|
3694
3812
|
return jsonReply2(await callRestUrl(url, "PATCH", body2));
|
|
3695
3813
|
}
|
|
3814
|
+
if (hasCudaParams) {
|
|
3815
|
+
const cudaError = cudaConstraintError(updateParams, {
|
|
3816
|
+
allowClear: true
|
|
3817
|
+
});
|
|
3818
|
+
if (cudaError) return jsonReply2({ error: cudaError, status: 400 });
|
|
3819
|
+
}
|
|
3820
|
+
if (updateParams.gpuPoolIds !== void 0 && !updateParams.gpuPoolIds.length) {
|
|
3821
|
+
return jsonReply2({
|
|
3822
|
+
error: "gpuPoolIds cannot be empty \u2014 omit it to keep the current GPU selection.",
|
|
3823
|
+
status: 400
|
|
3824
|
+
});
|
|
3825
|
+
}
|
|
3696
3826
|
let scalerType = updateParams.scalerType;
|
|
3697
|
-
|
|
3827
|
+
const needScalerRead = scalerType === void 0 && updateParams.scalerValue !== void 0;
|
|
3828
|
+
const needExclusionRead = (updateParams.gpuPoolIds?.length ?? 0) > 0;
|
|
3829
|
+
let clearedExclusions = [];
|
|
3830
|
+
if (needScalerRead || needExclusionRead) {
|
|
3698
3831
|
const current = await callRestUrl(url);
|
|
3699
|
-
|
|
3832
|
+
if (needScalerRead) {
|
|
3833
|
+
scalerType = isRequestCountScaler(current?.scaling?.type) ? "REQUEST_COUNT" : "QUEUE_DELAY";
|
|
3834
|
+
}
|
|
3835
|
+
if (needExclusionRead && current?.gpu?.excludedTypes?.length) {
|
|
3836
|
+
clearedExclusions = current.gpu.excludedTypes;
|
|
3837
|
+
}
|
|
3700
3838
|
}
|
|
3701
3839
|
const scalerError = scalerValueError(
|
|
3702
3840
|
scalerType,
|
|
@@ -3709,7 +3847,14 @@ function registerEndpointTools(server, rt) {
|
|
|
3709
3847
|
...updateParams,
|
|
3710
3848
|
scalerType
|
|
3711
3849
|
});
|
|
3712
|
-
|
|
3850
|
+
const result = await callRestUrl(url, "PATCH", body);
|
|
3851
|
+
if (clearedExclusions.length) {
|
|
3852
|
+
return jsonReply2({
|
|
3853
|
+
...result,
|
|
3854
|
+
_warning: `Supplying gpuPoolIds replaced the GPU selection wholesale, clearing ${clearedExclusions.length} GPU-type exclusion(s) previously set on this endpoint: ${clearedExclusions.join(", ")}. Re-apply them with set-endpoint-gpus if still wanted.`
|
|
3855
|
+
});
|
|
3856
|
+
}
|
|
3857
|
+
return jsonReply2(result);
|
|
3713
3858
|
}
|
|
3714
3859
|
);
|
|
3715
3860
|
server.tool(
|