@runpod/mcp-server 4.4.0 → 4.6.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 +42 -0
- package/README.md +4 -4
- package/dist/http.cjs +643 -89
- package/dist/http.cjs.map +1 -1
- package/dist/http.d.cts +12 -1
- package/dist/http.d.ts +12 -1
- package/dist/http.mjs +642 -89
- package/dist/http.mjs.map +1 -1
- package/dist/stdio.cjs +556 -70
- package/dist/stdio.cjs.map +1 -1
- package/dist/stdio.mjs +556 -70
- package/dist/stdio.mjs.map +1 -1
- package/package.json +3 -2
package/dist/http.cjs
CHANGED
|
@@ -28,12 +28,87 @@ __export(http_exports, {
|
|
|
28
28
|
parseMcpMessages: () => parseMcpMessages,
|
|
29
29
|
prefersJsonResponse: () => prefersJsonResponse,
|
|
30
30
|
requestLogSampleRate: () => requestLogSampleRate,
|
|
31
|
+
requestProfile: () => requestProfile,
|
|
31
32
|
summarizeRpc: () => summarizeRpc
|
|
32
33
|
});
|
|
33
34
|
module.exports = __toCommonJS(http_exports);
|
|
34
35
|
var import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
35
36
|
var import_types2 = require("@modelcontextprotocol/sdk/types.js");
|
|
36
37
|
|
|
38
|
+
// src/alp/sink.ts
|
|
39
|
+
var ALREADY_SUBMITTED_NOTE = "This account has already made this one-time submission; nothing new was stored. Do not call this again on this account \u2014 continue your task.";
|
|
40
|
+
var ALP_REFERRAL_SOURCES = [
|
|
41
|
+
"searched",
|
|
42
|
+
"user_named",
|
|
43
|
+
"recommended",
|
|
44
|
+
"other"
|
|
45
|
+
];
|
|
46
|
+
var ALP_REFERRAL_USE_CASES = [
|
|
47
|
+
"inference",
|
|
48
|
+
"fine_tuning",
|
|
49
|
+
"training",
|
|
50
|
+
"image_video_generation",
|
|
51
|
+
"dev_environment",
|
|
52
|
+
"batch_processing",
|
|
53
|
+
"other"
|
|
54
|
+
];
|
|
55
|
+
function isSinkUrl(value) {
|
|
56
|
+
try {
|
|
57
|
+
const url = new URL(value);
|
|
58
|
+
return url.protocol === "https:" && url.hostname.endsWith(".convex.site") && url.pathname === "/alp/submit";
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function sinkRouteUrl(submitUrl, path) {
|
|
64
|
+
if (!isSinkUrl(submitUrl)) return null;
|
|
65
|
+
const url = new URL(submitUrl);
|
|
66
|
+
url.pathname = path;
|
|
67
|
+
return url.toString();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/alp/answered.ts
|
|
71
|
+
var ANSWERED_TIMEOUT_MS = 2500;
|
|
72
|
+
async function hasAnswered(identity, route, opts = {}) {
|
|
73
|
+
const env = opts.env ?? process.env;
|
|
74
|
+
const submitUrl = env.ALP_SINK_URL;
|
|
75
|
+
const sinkSecret = env.ALP_SINK_SECRET;
|
|
76
|
+
if (!identity || !submitUrl || !sinkSecret) return null;
|
|
77
|
+
const url = sinkRouteUrl(submitUrl, "/alp/answered");
|
|
78
|
+
if (!url) {
|
|
79
|
+
console.warn("alp_sink_misconfigured");
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const sinkFetch = opts.sinkFetch ?? fetch;
|
|
84
|
+
const response = await sinkFetch(url, {
|
|
85
|
+
method: "POST",
|
|
86
|
+
headers: {
|
|
87
|
+
"Content-Type": "application/json",
|
|
88
|
+
"X-ALP-Secret": sinkSecret
|
|
89
|
+
},
|
|
90
|
+
// The resolved account id and the route, nothing from any request body.
|
|
91
|
+
body: JSON.stringify({ identity, route }),
|
|
92
|
+
signal: AbortSignal.timeout(ANSWERED_TIMEOUT_MS)
|
|
93
|
+
});
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
console.warn("alp_answered_sink_error", { status: response.status });
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const body = await response.json().catch(() => null);
|
|
99
|
+
if (body?.ok !== true || typeof body.answered !== "boolean") {
|
|
100
|
+
console.warn("alp_answered_sink_unrecognized", {
|
|
101
|
+
status: response.status
|
|
102
|
+
});
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return body.answered;
|
|
106
|
+
} catch {
|
|
107
|
+
console.warn("alp_answered_sink_unreachable");
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
37
112
|
// src/specgen/server.ts
|
|
38
113
|
var import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
39
114
|
var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
@@ -359,8 +434,10 @@ function coerceScalars(value, schema, defs, depth = 0) {
|
|
|
359
434
|
var generatedTools = [
|
|
360
435
|
{
|
|
361
436
|
name: "create-cluster",
|
|
437
|
+
title: "Create cluster",
|
|
362
438
|
operationId: "createCluster",
|
|
363
439
|
description: "Create an instant cluster (multiple pods with high-speed interconnect). BILLABLE from creation for every pod in the cluster: it rents compute.podCount identical pods at once, each with compute.gpuCountPerPod GPUs of compute.gpuTypeId \u2014 state the hourly price for the total GPU count (podCount * gpuCountPerPod, priced from the catalog tools) and create only after the user's explicit go on that quoted shape and total hourly price. Verify GPU stock first via the catalog tools. The compute shape and type are fixed at creation; only the name can be changed later. The container configuration applies to every pod, and templateId is the only private-image path \u2014 a bare registry property is rejected. Delete with delete-cluster when finished.",
|
|
440
|
+
directoryDescription: "Create an Instant Cluster: compute.podCount identical Pods joined by a high-speed interconnect, each with compute.gpuCountPerPod GPUs of compute.gpuTypeId. Billable from creation for every Pod in the cluster, at the GPU type's hourly price times the total GPU count. The compute shape and type are fixed at creation; only the name can change later. The container configuration applies to every Pod, and templateId is the only way to use a private image; a bare registry property is rejected.",
|
|
364
441
|
method: "POST",
|
|
365
442
|
path: "/v2/clusters",
|
|
366
443
|
params: [],
|
|
@@ -376,7 +453,8 @@ var generatedTools = [
|
|
|
376
453
|
type: "object",
|
|
377
454
|
properties: {
|
|
378
455
|
body: {
|
|
379
|
-
$ref: "#/$defs/CreateClusterRequest"
|
|
456
|
+
$ref: "#/$defs/CreateClusterRequest",
|
|
457
|
+
type: "object"
|
|
380
458
|
}
|
|
381
459
|
},
|
|
382
460
|
required: ["body"],
|
|
@@ -596,6 +674,7 @@ var generatedTools = [
|
|
|
596
674
|
},
|
|
597
675
|
{
|
|
598
676
|
name: "create-delegation",
|
|
677
|
+
title: "Create ECR delegation",
|
|
599
678
|
operationId: "createDelegation",
|
|
600
679
|
description: "Register an ECR delegation",
|
|
601
680
|
method: "POST",
|
|
@@ -612,7 +691,8 @@ var generatedTools = [
|
|
|
612
691
|
type: "object",
|
|
613
692
|
properties: {
|
|
614
693
|
body: {
|
|
615
|
-
$ref: "#/$defs/CreateDelegationRequest"
|
|
694
|
+
$ref: "#/$defs/CreateDelegationRequest",
|
|
695
|
+
type: "object"
|
|
616
696
|
}
|
|
617
697
|
},
|
|
618
698
|
required: ["body"],
|
|
@@ -641,8 +721,10 @@ var generatedTools = [
|
|
|
641
721
|
},
|
|
642
722
|
{
|
|
643
723
|
name: "create-endpoint",
|
|
724
|
+
title: "Create endpoint",
|
|
644
725
|
operationId: "createEndpoint",
|
|
645
726
|
description: "Create a serverless endpoint. BILLABLE: state the worker's hourly price (from the catalog tools) before creating. Worker hardware is one of two choices: the gpu object (gpu.pools takes serverless pool ids from the catalog, e.g. ADA_24, never display names; gpu.count sets GPUs per worker) or the cpu array of CPU flavor configurations for a CPU endpoint. type and scaling are required and fix the request-routing model. Workers cold-start on the first job: expect minutes, poll with get-job-status wait.",
|
|
727
|
+
directoryDescription: "Create a Serverless endpoint. Billable while its workers run, at the worker's hourly price. Worker hardware is either the gpu object (gpu.pools takes Serverless pool ids such as ADA_24, and gpu.count sets GPUs per worker) or the cpu array of CPU flavor configurations. type and scaling are required and set the request-routing model. Workers cold-start on their first job, which commonly takes minutes.",
|
|
646
728
|
method: "POST",
|
|
647
729
|
path: "/v2/serverless",
|
|
648
730
|
params: [],
|
|
@@ -658,7 +740,8 @@ var generatedTools = [
|
|
|
658
740
|
type: "object",
|
|
659
741
|
properties: {
|
|
660
742
|
body: {
|
|
661
|
-
$ref: "#/$defs/CreateEndpointRequest"
|
|
743
|
+
$ref: "#/$defs/CreateEndpointRequest",
|
|
744
|
+
type: "object"
|
|
662
745
|
}
|
|
663
746
|
},
|
|
664
747
|
required: ["body"],
|
|
@@ -1086,6 +1169,7 @@ var generatedTools = [
|
|
|
1086
1169
|
},
|
|
1087
1170
|
{
|
|
1088
1171
|
name: "create-global-volume",
|
|
1172
|
+
title: "Create global volume",
|
|
1089
1173
|
operationId: "createGlobalVolume",
|
|
1090
1174
|
description: "Create a global volume. Provisions a new global volume \u2014 storage that mounts into workloads in any data center. Only a `name` is required; storage is provisioned for you. Accounts have a cap on how many global volumes they can hold; creating one past it fails with `400`. Returns `201` with the created global volume, including its assigned `id`.",
|
|
1091
1175
|
method: "POST",
|
|
@@ -1102,7 +1186,8 @@ var generatedTools = [
|
|
|
1102
1186
|
type: "object",
|
|
1103
1187
|
properties: {
|
|
1104
1188
|
body: {
|
|
1105
|
-
$ref: "#/$defs/CreateGlobalVolumeRequest"
|
|
1189
|
+
$ref: "#/$defs/CreateGlobalVolumeRequest",
|
|
1190
|
+
type: "object"
|
|
1106
1191
|
}
|
|
1107
1192
|
},
|
|
1108
1193
|
required: ["body"],
|
|
@@ -1127,6 +1212,7 @@ var generatedTools = [
|
|
|
1127
1212
|
},
|
|
1128
1213
|
{
|
|
1129
1214
|
name: "create-network-volume",
|
|
1215
|
+
title: "Create network volume",
|
|
1130
1216
|
operationId: "createNetworkVolume",
|
|
1131
1217
|
description: "Create a network volume. Provisions a new network volume \u2014 persistent, network-attached storage that can be mounted into pods and serverless workers. Required inputs are `name`, `size` (in GB), and `dataCenter`; an optional `type` selects the storage tier and is immutable after creation. See `CreateNetworkVolumeRequest` for the size bounds and tier options. This creates a billable persistent resource that keeps incurring storage charges until it is deleted. Returns `201` with the created network volume, including its assigned `id`.",
|
|
1132
1218
|
method: "POST",
|
|
@@ -1143,7 +1229,8 @@ var generatedTools = [
|
|
|
1143
1229
|
type: "object",
|
|
1144
1230
|
properties: {
|
|
1145
1231
|
body: {
|
|
1146
|
-
$ref: "#/$defs/CreateNetworkVolumeRequest"
|
|
1232
|
+
$ref: "#/$defs/CreateNetworkVolumeRequest",
|
|
1233
|
+
type: "object"
|
|
1147
1234
|
}
|
|
1148
1235
|
},
|
|
1149
1236
|
required: ["body"],
|
|
@@ -1192,8 +1279,10 @@ var generatedTools = [
|
|
|
1192
1279
|
},
|
|
1193
1280
|
{
|
|
1194
1281
|
name: "create-pod",
|
|
1282
|
+
title: "Create Pod",
|
|
1195
1283
|
operationId: "createPod",
|
|
1196
1284
|
description: 'Rent a GPU/CPU pod. BILLABLE from creation until stop/terminate: state the hourly price before creating. GPU selection is the gpu object: gpu.id takes a catalog GPU type id (e.g. "NVIDIA GeForce RTX 4090"), verified via list-gpu-types, and gpu.count sets the GPU count; cloud/data-center choice constrains stock.',
|
|
1285
|
+
directoryDescription: 'Create a GPU or CPU Pod. Billable from creation until it is stopped or terminated. GPU selection is the gpu object: gpu.id takes a GPU type id such as "NVIDIA GeForce RTX 4090", and gpu.count sets the number of GPUs. Cloud tier and data center choices limit which machines can host it.',
|
|
1197
1286
|
method: "POST",
|
|
1198
1287
|
path: "/v2/pods",
|
|
1199
1288
|
params: [],
|
|
@@ -1209,7 +1298,8 @@ var generatedTools = [
|
|
|
1209
1298
|
type: "object",
|
|
1210
1299
|
properties: {
|
|
1211
1300
|
body: {
|
|
1212
|
-
$ref: "#/$defs/CreatePodRequest"
|
|
1301
|
+
$ref: "#/$defs/CreatePodRequest",
|
|
1302
|
+
type: "object"
|
|
1213
1303
|
}
|
|
1214
1304
|
},
|
|
1215
1305
|
required: ["body"],
|
|
@@ -1559,6 +1649,7 @@ var generatedTools = [
|
|
|
1559
1649
|
},
|
|
1560
1650
|
{
|
|
1561
1651
|
name: "create-registry",
|
|
1652
|
+
title: "Create registry credential",
|
|
1562
1653
|
operationId: "createRegistry",
|
|
1563
1654
|
description: "Create a container registry credential. Stores credentials for a private container registry. Credentials are write-only.",
|
|
1564
1655
|
method: "POST",
|
|
@@ -1575,7 +1666,8 @@ var generatedTools = [
|
|
|
1575
1666
|
type: "object",
|
|
1576
1667
|
properties: {
|
|
1577
1668
|
body: {
|
|
1578
|
-
$ref: "#/$defs/CreateRegistryRequest"
|
|
1669
|
+
$ref: "#/$defs/CreateRegistryRequest",
|
|
1670
|
+
type: "object"
|
|
1579
1671
|
}
|
|
1580
1672
|
},
|
|
1581
1673
|
required: ["body"],
|
|
@@ -1610,6 +1702,7 @@ var generatedTools = [
|
|
|
1610
1702
|
},
|
|
1611
1703
|
{
|
|
1612
1704
|
name: "create-secret",
|
|
1705
|
+
title: "Create secret",
|
|
1613
1706
|
operationId: "createSecret",
|
|
1614
1707
|
description: "Create a secret. Stores a new account-scoped encrypted string. `name` must be unique across the account's secrets and is immutable; `value` is write-only and can never be read back through the API. Use the secret from pods, serverless endpoints, and templates by setting an environment variable's value to `{{ RUNPOD_SECRET_<name> }}` \u2014 Runpod substitutes the stored value when the pod or worker boots. Returns `201` with the created secret's metadata, or `409` when the name is already taken.",
|
|
1615
1708
|
method: "POST",
|
|
@@ -1619,7 +1712,7 @@ var generatedTools = [
|
|
|
1619
1712
|
annotations: {
|
|
1620
1713
|
readOnlyHint: false,
|
|
1621
1714
|
destructiveHint: false,
|
|
1622
|
-
idempotentHint:
|
|
1715
|
+
idempotentHint: true,
|
|
1623
1716
|
openWorldHint: true
|
|
1624
1717
|
},
|
|
1625
1718
|
schemaOnDemand: true,
|
|
@@ -1627,7 +1720,8 @@ var generatedTools = [
|
|
|
1627
1720
|
type: "object",
|
|
1628
1721
|
properties: {
|
|
1629
1722
|
body: {
|
|
1630
|
-
$ref: "#/$defs/CreateSecretRequest"
|
|
1723
|
+
$ref: "#/$defs/CreateSecretRequest",
|
|
1724
|
+
type: "object"
|
|
1631
1725
|
}
|
|
1632
1726
|
},
|
|
1633
1727
|
required: ["body"],
|
|
@@ -1664,6 +1758,7 @@ var generatedTools = [
|
|
|
1664
1758
|
},
|
|
1665
1759
|
{
|
|
1666
1760
|
name: "create-template",
|
|
1761
|
+
title: "Create template",
|
|
1667
1762
|
operationId: "createTemplate",
|
|
1668
1763
|
description: "Create a template. Creates a reusable container-configuration preset \u2014 image, disk, ports, env, registry, and mount settings \u2014 for pods and serverless endpoints. Pass its ID as `templateId` to `createPod` or `createEndpoint`, or spread its fields into the request body directly. Returns the created template.",
|
|
1669
1764
|
method: "POST",
|
|
@@ -1681,7 +1776,8 @@ var generatedTools = [
|
|
|
1681
1776
|
type: "object",
|
|
1682
1777
|
properties: {
|
|
1683
1778
|
body: {
|
|
1684
|
-
$ref: "#/$defs/CreateTemplateRequest"
|
|
1779
|
+
$ref: "#/$defs/CreateTemplateRequest",
|
|
1780
|
+
type: "object"
|
|
1685
1781
|
}
|
|
1686
1782
|
},
|
|
1687
1783
|
required: ["body"],
|
|
@@ -1865,8 +1961,10 @@ var generatedTools = [
|
|
|
1865
1961
|
},
|
|
1866
1962
|
{
|
|
1867
1963
|
name: "delete-cluster",
|
|
1964
|
+
title: "Delete cluster",
|
|
1868
1965
|
operationId: "deleteCluster",
|
|
1869
1966
|
description: "Delete a cluster permanently: it terminates every member pod. Verify the id with get-cluster, and list-cluster-pods for what the delete takes down, before deleting; delete only clusters your own tool calls created in this conversation, or the one the user asked you to delete by id \u2014 a name found by listing is not attribution.",
|
|
1967
|
+
directoryDescription: "Delete an Instant Cluster permanently. Every member Pod is terminated and its container disk is lost.",
|
|
1870
1968
|
method: "DELETE",
|
|
1871
1969
|
path: "/v2/clusters/{id}",
|
|
1872
1970
|
params: [
|
|
@@ -1895,8 +1993,10 @@ var generatedTools = [
|
|
|
1895
1993
|
},
|
|
1896
1994
|
{
|
|
1897
1995
|
name: "delete-endpoint",
|
|
1996
|
+
title: "Delete endpoint",
|
|
1898
1997
|
operationId: "deleteEndpoint",
|
|
1899
1998
|
description: "Delete a serverless endpoint permanently and immediately. Verify the id belongs to the intended endpoint (get-endpoint) before deleting; delete only endpoints your own tool calls created in this conversation, or the one the user asked you to delete by id \u2014 a name found by listing is not attribution.",
|
|
1999
|
+
directoryDescription: "Delete a Serverless endpoint permanently and immediately.",
|
|
1900
2000
|
method: "DELETE",
|
|
1901
2001
|
path: "/v2/serverless/{id}",
|
|
1902
2002
|
params: [
|
|
@@ -1925,6 +2025,7 @@ var generatedTools = [
|
|
|
1925
2025
|
},
|
|
1926
2026
|
{
|
|
1927
2027
|
name: "delete-global-volume",
|
|
2028
|
+
title: "Delete global volume",
|
|
1928
2029
|
operationId: "deleteGlobalVolume",
|
|
1929
2030
|
description: "Delete a global volume. Permanently deletes a global volume and its stored data. Fails with `409` while the volume is still mounted: terminate every pod that mounts it (stopped pods count) and detach it from every serverless endpoint first. Nothing is detached or terminated on your behalf.",
|
|
1930
2031
|
method: "DELETE",
|
|
@@ -1955,6 +2056,7 @@ var generatedTools = [
|
|
|
1955
2056
|
},
|
|
1956
2057
|
{
|
|
1957
2058
|
name: "delete-network-volume",
|
|
2059
|
+
title: "Delete network volume",
|
|
1958
2060
|
operationId: "deleteNetworkVolume",
|
|
1959
2061
|
description: "Delete a network volume. Permanently deletes a network volume and releases its storage.",
|
|
1960
2062
|
method: "DELETE",
|
|
@@ -1985,8 +2087,10 @@ var generatedTools = [
|
|
|
1985
2087
|
},
|
|
1986
2088
|
{
|
|
1987
2089
|
name: "delete-pod",
|
|
2090
|
+
title: "Delete Pod",
|
|
1988
2091
|
operationId: "deletePod",
|
|
1989
2092
|
description: "Terminate a pod permanently \u2014 its container disk is lost. Distinguish from stopping (pod-action stop) which releases the GPU but keeps volume data. Verify the id with get-pod first; terminate only pods your own tool calls created in this conversation, or the one the user asked you to terminate by id \u2014 a name found by listing is not attribution.",
|
|
2093
|
+
directoryDescription: "Terminate a Pod permanently. Its container disk is lost; data on an attached network volume is kept. Stopping a Pod instead releases its compute but keeps its disk.",
|
|
1990
2094
|
method: "DELETE",
|
|
1991
2095
|
path: "/v2/pods/{id}",
|
|
1992
2096
|
params: [
|
|
@@ -2015,6 +2119,7 @@ var generatedTools = [
|
|
|
2015
2119
|
},
|
|
2016
2120
|
{
|
|
2017
2121
|
name: "delete-registry",
|
|
2122
|
+
title: "Delete registry credential",
|
|
2018
2123
|
operationId: "deleteRegistry",
|
|
2019
2124
|
description: "Delete a container registry credential. Permanently deletes a container registry credential by ID. Rejected if any pod currently uses this credential to pull its image. Templates that reference it are not part of that check \u2014 they silently lose the reference (`registry` becomes null) instead of blocking the delete.",
|
|
2020
2125
|
method: "DELETE",
|
|
@@ -2044,8 +2149,10 @@ var generatedTools = [
|
|
|
2044
2149
|
},
|
|
2045
2150
|
{
|
|
2046
2151
|
name: "delete-secret",
|
|
2152
|
+
title: "Delete secret",
|
|
2047
2153
|
operationId: "deleteSecret",
|
|
2048
2154
|
description: "Delete a secret permanently. Environment variables referencing its name ({{ RUNPOD_SECRET_<name> }}) stop resolving at the next pod or worker boot; running instances keep the value they started with. Verify the id with get-secret first; delete only secrets your own tool calls created in this conversation, or the one the user asked you to delete by id \u2014 a name found by listing is not attribution.",
|
|
2155
|
+
directoryDescription: "Delete a secret permanently. Environment variables that reference it ({{ RUNPOD_SECRET_<name> }}) stop resolving at the next Pod or worker boot; running instances keep the value they started with.",
|
|
2049
2156
|
method: "DELETE",
|
|
2050
2157
|
path: "/v2/account/secrets/{id}",
|
|
2051
2158
|
params: [
|
|
@@ -2074,8 +2181,10 @@ var generatedTools = [
|
|
|
2074
2181
|
},
|
|
2075
2182
|
{
|
|
2076
2183
|
name: "delete-template",
|
|
2184
|
+
title: "Delete template",
|
|
2077
2185
|
operationId: "deleteTemplate",
|
|
2078
2186
|
description: "Delete a template permanently. Verify with get-template first; a template referenced by a live endpoint should not be deleted.",
|
|
2187
|
+
directoryDescription: "Delete a template permanently. An endpoint that references the template can stop working once it is deleted.",
|
|
2079
2188
|
method: "DELETE",
|
|
2080
2189
|
path: "/v2/templates/{id}",
|
|
2081
2190
|
params: [
|
|
@@ -2103,6 +2212,7 @@ var generatedTools = [
|
|
|
2103
2212
|
},
|
|
2104
2213
|
{
|
|
2105
2214
|
name: "get-cluster",
|
|
2215
|
+
title: "Get cluster",
|
|
2106
2216
|
operationId: "getCluster",
|
|
2107
2217
|
description: "Get a cluster. Returns a single cluster by ID. The pods field is an aggregate summary (total + count by status); fetch the member pods themselves from /v2/clusters/{id}/pods.",
|
|
2108
2218
|
method: "GET",
|
|
@@ -2133,6 +2243,7 @@ var generatedTools = [
|
|
|
2133
2243
|
},
|
|
2134
2244
|
{
|
|
2135
2245
|
name: "get-cpu-type",
|
|
2246
|
+
title: "Get CPU type",
|
|
2136
2247
|
operationId: "getCpuType",
|
|
2137
2248
|
description: "Get a CPU type. Returns a single CPU type with pricing. Availability details are included only when requested with include=AVAILABILITY, which requires `product` \u2014 stock differs by product context.",
|
|
2138
2249
|
method: "GET",
|
|
@@ -2209,6 +2320,7 @@ var generatedTools = [
|
|
|
2209
2320
|
},
|
|
2210
2321
|
{
|
|
2211
2322
|
name: "get-data-center",
|
|
2323
|
+
title: "Get data center",
|
|
2212
2324
|
operationId: "getDataCenter",
|
|
2213
2325
|
description: "Get a data center. Returns a single data center. Availability is included only when requested with include=GPU_AVAILABILITY or include=CPU_AVAILABILITY.",
|
|
2214
2326
|
method: "GET",
|
|
@@ -2258,6 +2370,7 @@ var generatedTools = [
|
|
|
2258
2370
|
},
|
|
2259
2371
|
{
|
|
2260
2372
|
name: "get-endpoint",
|
|
2373
|
+
title: "Get endpoint",
|
|
2261
2374
|
operationId: "getEndpoint",
|
|
2262
2375
|
description: "Get a serverless endpoint. Returns a single serverless endpoint by ID.",
|
|
2263
2376
|
method: "GET",
|
|
@@ -2288,6 +2401,7 @@ var generatedTools = [
|
|
|
2288
2401
|
},
|
|
2289
2402
|
{
|
|
2290
2403
|
name: "get-endpoint-build",
|
|
2404
|
+
title: "Get endpoint build",
|
|
2291
2405
|
operationId: "getEndpointBuild",
|
|
2292
2406
|
description: "Get a serverless endpoint build. Returns one of the endpoint's GitHub builds by id, regardless of age \u2014 no need to page through `GET /v2/serverless/{id}/builds` to reach it.",
|
|
2293
2407
|
method: "GET",
|
|
@@ -2326,6 +2440,7 @@ var generatedTools = [
|
|
|
2326
2440
|
},
|
|
2327
2441
|
{
|
|
2328
2442
|
name: "get-global-volume",
|
|
2443
|
+
title: "Get global volume",
|
|
2329
2444
|
operationId: "getGlobalVolume",
|
|
2330
2445
|
description: "Get a global volume. Returns a single global volume by ID.",
|
|
2331
2446
|
method: "GET",
|
|
@@ -2356,6 +2471,7 @@ var generatedTools = [
|
|
|
2356
2471
|
},
|
|
2357
2472
|
{
|
|
2358
2473
|
name: "get-gpu-type",
|
|
2474
|
+
title: "Get GPU type",
|
|
2359
2475
|
operationId: "getGpuType",
|
|
2360
2476
|
description: "Get a GPU type. Returns a single GPU type with pricing. Availability details are included only when requested with include=AVAILABILITY, which requires `product` \u2014 stock differs by product context.",
|
|
2361
2477
|
method: "GET",
|
|
@@ -2434,7 +2550,8 @@ var generatedTools = [
|
|
|
2434
2550
|
},
|
|
2435
2551
|
cloud: {
|
|
2436
2552
|
$ref: "#/$defs/GpuCloudFilter",
|
|
2437
|
-
description: "Cloud type for availability and lowest-price calculations. Valid only with include=AVAILABILITY. Supported values: SECURE, COMMUNITY. Upstream default when omitted: SECURE."
|
|
2553
|
+
description: "Cloud type for availability and lowest-price calculations. Valid only with include=AVAILABILITY. Supported values: SECURE, COMMUNITY. Upstream default when omitted: SECURE.",
|
|
2554
|
+
type: "string"
|
|
2438
2555
|
},
|
|
2439
2556
|
countryCodes: {
|
|
2440
2557
|
type: "array",
|
|
@@ -2480,6 +2597,7 @@ var generatedTools = [
|
|
|
2480
2597
|
},
|
|
2481
2598
|
{
|
|
2482
2599
|
name: "get-network-volume",
|
|
2600
|
+
title: "Get network volume",
|
|
2483
2601
|
operationId: "getNetworkVolume",
|
|
2484
2602
|
description: "Get a network volume. Returns a single network volume by ID.",
|
|
2485
2603
|
method: "GET",
|
|
@@ -2510,6 +2628,7 @@ var generatedTools = [
|
|
|
2510
2628
|
},
|
|
2511
2629
|
{
|
|
2512
2630
|
name: "get-organization",
|
|
2631
|
+
title: "Get organization",
|
|
2513
2632
|
operationId: "getOrganization",
|
|
2514
2633
|
description: "Get your current organization. Returns the authenticated caller's current organization. Organization context comes from the caller's membership; no organization selector is required. Returns 404 when the caller does not belong to an organization, or 403 when organizations are unavailable to the caller.",
|
|
2515
2634
|
method: "GET",
|
|
@@ -2529,6 +2648,7 @@ var generatedTools = [
|
|
|
2529
2648
|
},
|
|
2530
2649
|
{
|
|
2531
2650
|
name: "get-pod",
|
|
2651
|
+
title: "Get Pod",
|
|
2532
2652
|
operationId: "getPod",
|
|
2533
2653
|
description: "Get a pod. Returns a single pod by ID.",
|
|
2534
2654
|
method: "GET",
|
|
@@ -2559,6 +2679,7 @@ var generatedTools = [
|
|
|
2559
2679
|
},
|
|
2560
2680
|
{
|
|
2561
2681
|
name: "get-registry",
|
|
2682
|
+
title: "Get registry credential",
|
|
2562
2683
|
operationId: "getRegistry",
|
|
2563
2684
|
description: "Get a container registry credential. Returns a single container registry credential by ID. `username` and `password` are never included in the response \u2014 credentials are write-only, matching `createRegistry`.",
|
|
2564
2685
|
method: "GET",
|
|
@@ -2588,6 +2709,7 @@ var generatedTools = [
|
|
|
2588
2709
|
},
|
|
2589
2710
|
{
|
|
2590
2711
|
name: "get-secret",
|
|
2712
|
+
title: "Get secret",
|
|
2591
2713
|
operationId: "getSecret",
|
|
2592
2714
|
description: "Get a secret. Returns a single secret's metadata by ID. The value is write-only and never returned.",
|
|
2593
2715
|
method: "GET",
|
|
@@ -2618,6 +2740,7 @@ var generatedTools = [
|
|
|
2618
2740
|
},
|
|
2619
2741
|
{
|
|
2620
2742
|
name: "get-ssh-keys",
|
|
2743
|
+
title: "Get SSH keys",
|
|
2621
2744
|
operationId: "getSshKeys",
|
|
2622
2745
|
description: "List registered SSH public keys. Returns the account's registered SSH public keys \u2014 the keys provisioned into pods created with `startSsh` and used to authenticate the SSH connections reported in a pod's `ssh` block.",
|
|
2623
2746
|
method: "GET",
|
|
@@ -2637,6 +2760,7 @@ var generatedTools = [
|
|
|
2637
2760
|
},
|
|
2638
2761
|
{
|
|
2639
2762
|
name: "get-template",
|
|
2763
|
+
title: "Get template",
|
|
2640
2764
|
operationId: "getTemplate",
|
|
2641
2765
|
description: "Get a template. Returns the full configuration of a single template by ID. Serves both templates you own and public catalog templates \u2014 everything you can read. Updates and deletes remain restricted to templates you own.",
|
|
2642
2766
|
method: "GET",
|
|
@@ -2666,6 +2790,7 @@ var generatedTools = [
|
|
|
2666
2790
|
},
|
|
2667
2791
|
{
|
|
2668
2792
|
name: "list-billing",
|
|
2793
|
+
title: "List billing",
|
|
2669
2794
|
operationId: "listBilling",
|
|
2670
2795
|
description: "Get aggregated billing history. Returns time-bucketed total spend across all billable Runpod resources for the authenticated user. Use startTime/endTime with bucketSize for an explicit range, or lastN with bucketSize for the most recent buckets. Each record reports one bucket's total plus pod, serverless, storage, public endpoint, and Instant Cluster cost components. The metadata block echoes the resolved query window, record count, and totals across all returned buckets.",
|
|
2671
2796
|
method: "GET",
|
|
@@ -2710,7 +2835,8 @@ var generatedTools = [
|
|
|
2710
2835
|
},
|
|
2711
2836
|
bucketSize: {
|
|
2712
2837
|
$ref: "#/$defs/BillingBucketSize",
|
|
2713
|
-
description: "Length of each billing time bucket. Defaults to day."
|
|
2838
|
+
description: "Length of each billing time bucket. Defaults to day.",
|
|
2839
|
+
type: "string"
|
|
2714
2840
|
},
|
|
2715
2841
|
lastN: {
|
|
2716
2842
|
type: "integer",
|
|
@@ -2738,6 +2864,7 @@ var generatedTools = [
|
|
|
2738
2864
|
},
|
|
2739
2865
|
{
|
|
2740
2866
|
name: "list-cluster-billing",
|
|
2867
|
+
title: "List cluster billing",
|
|
2741
2868
|
operationId: "listClusterBilling",
|
|
2742
2869
|
description: "Get cluster billing history. Returns Cluster billing history for the authenticated user, split into time buckets by startTime/endTime with bucketSize or by lastN recent buckets. Use clusterId to filter to one cluster; without it, records are emitted per cluster per bucket. Each record includes GPU compute, disk, inter-node networking, and total amounts. Clusters are GPU-only, so no CPU cost component is returned.",
|
|
2743
2870
|
method: "GET",
|
|
@@ -2786,7 +2913,8 @@ var generatedTools = [
|
|
|
2786
2913
|
},
|
|
2787
2914
|
bucketSize: {
|
|
2788
2915
|
$ref: "#/$defs/BillingBucketSize",
|
|
2789
|
-
description: "Length of each billing time bucket. Defaults to day."
|
|
2916
|
+
description: "Length of each billing time bucket. Defaults to day.",
|
|
2917
|
+
type: "string"
|
|
2790
2918
|
},
|
|
2791
2919
|
lastN: {
|
|
2792
2920
|
type: "integer",
|
|
@@ -2818,6 +2946,7 @@ var generatedTools = [
|
|
|
2818
2946
|
},
|
|
2819
2947
|
{
|
|
2820
2948
|
name: "list-cluster-pods",
|
|
2949
|
+
title: "List cluster Pods",
|
|
2821
2950
|
operationId: "listClusterPods",
|
|
2822
2951
|
description: "List a cluster's pods. Returns the full member pods of a cluster. The cluster summary (`GET /v2/clusters/{id}`) carries only aggregate pod counts; this endpoint returns each member as a complete Pod object.",
|
|
2823
2952
|
method: "GET",
|
|
@@ -2848,6 +2977,7 @@ var generatedTools = [
|
|
|
2848
2977
|
},
|
|
2849
2978
|
{
|
|
2850
2979
|
name: "list-clusters",
|
|
2980
|
+
title: "List clusters",
|
|
2851
2981
|
operationId: "listClusters",
|
|
2852
2982
|
description: "List clusters. Returns clusters owned by the authenticated user, cursor-paginated newest-first; an omitted `limit` defaults to 1000. Follow `pagination.nextCursor` until `hasNextPage` is false.",
|
|
2853
2983
|
method: "GET",
|
|
@@ -2888,6 +3018,7 @@ var generatedTools = [
|
|
|
2888
3018
|
},
|
|
2889
3019
|
{
|
|
2890
3020
|
name: "list-cpu-types",
|
|
3021
|
+
title: "List CPU types",
|
|
2891
3022
|
operationId: "listCpuTypes",
|
|
2892
3023
|
description: "List CPU types. Returns available CPU flavors. Availability is included only when requested with include=AVAILABILITY, which requires `product` \u2014 stock differs by product context.",
|
|
2893
3024
|
method: "GET",
|
|
@@ -2956,6 +3087,7 @@ var generatedTools = [
|
|
|
2956
3087
|
},
|
|
2957
3088
|
{
|
|
2958
3089
|
name: "list-data-centers",
|
|
3090
|
+
title: "List data centers",
|
|
2959
3091
|
operationId: "listDataCenters",
|
|
2960
3092
|
description: "List data centers. Returns available data center locations with region, compliance, supported network volume tiers, and global networking support. Use include=GPU_AVAILABILITY or include=CPU_AVAILABILITY to add per-resource availability arrays to each data center. The regions, networkVolumeTypes, compliance, and globalNetwork query parameters filter the list before it is returned.",
|
|
2961
3093
|
method: "GET",
|
|
@@ -3083,6 +3215,7 @@ var generatedTools = [
|
|
|
3083
3215
|
},
|
|
3084
3216
|
{
|
|
3085
3217
|
name: "list-delegations",
|
|
3218
|
+
title: "List ECR delegations",
|
|
3086
3219
|
operationId: "listDelegations",
|
|
3087
3220
|
description: "List all ECR delegations",
|
|
3088
3221
|
method: "GET",
|
|
@@ -3102,6 +3235,7 @@ var generatedTools = [
|
|
|
3102
3235
|
},
|
|
3103
3236
|
{
|
|
3104
3237
|
name: "list-endpoint-billing",
|
|
3238
|
+
title: "List endpoint billing",
|
|
3105
3239
|
operationId: "listEndpointBilling",
|
|
3106
3240
|
description: "Get public endpoint billing history. Returns Runpod public endpoint billing history for the authenticated user, split into time buckets by startTime/endTime with bucketSize or by lastN recent buckets. Each record reports the endpoint total for one bucket, and metadata echoes the resolved query window, record count, and total endpoint amount across all returned records.",
|
|
3107
3241
|
method: "GET",
|
|
@@ -3146,7 +3280,8 @@ var generatedTools = [
|
|
|
3146
3280
|
},
|
|
3147
3281
|
bucketSize: {
|
|
3148
3282
|
$ref: "#/$defs/BillingBucketSize",
|
|
3149
|
-
description: "Length of each billing time bucket. Defaults to day."
|
|
3283
|
+
description: "Length of each billing time bucket. Defaults to day.",
|
|
3284
|
+
type: "string"
|
|
3150
3285
|
},
|
|
3151
3286
|
lastN: {
|
|
3152
3287
|
type: "integer",
|
|
@@ -3174,6 +3309,7 @@ var generatedTools = [
|
|
|
3174
3309
|
},
|
|
3175
3310
|
{
|
|
3176
3311
|
name: "list-endpoint-builds",
|
|
3312
|
+
title: "List endpoint builds",
|
|
3177
3313
|
operationId: "listEndpointBuilds",
|
|
3178
3314
|
description: "List serverless endpoint builds. Returns the endpoint's GitHub build history, newest first (Runpod GitHub-build integration), cursor-paginated; an omitted `limit` defaults to 100, so a bare request returns at most the 100 most recent builds. Any build can also be fetched by id via `GET /v2/serverless/{id}/builds/{buildId}`. Stream a build's logs via `/v2/serverless/{id}/builds/{buildId}/logs`.",
|
|
3179
3315
|
method: "GET",
|
|
@@ -3223,6 +3359,7 @@ var generatedTools = [
|
|
|
3223
3359
|
},
|
|
3224
3360
|
{
|
|
3225
3361
|
name: "list-endpoint-releases",
|
|
3362
|
+
title: "List endpoint releases",
|
|
3226
3363
|
operationId: "listEndpointReleases",
|
|
3227
3364
|
description: "List serverless endpoint releases. Returns the endpoint's release history (newest first) plus a rollout summary of how many workers are running the current version. Each release is a versioned configuration snapshot with a `diff` of what changed; build-driven releases carry a `buildId` (fetch build detail via the builds sub-routes). Releases are cursor-paginated newest-first; an omitted `limit` defaults to 1000. The rollout summary always describes the endpoint's current state, independent of the page requested.",
|
|
3228
3365
|
method: "GET",
|
|
@@ -3272,6 +3409,7 @@ var generatedTools = [
|
|
|
3272
3409
|
},
|
|
3273
3410
|
{
|
|
3274
3411
|
name: "list-endpoint-workers",
|
|
3412
|
+
title: "List endpoint workers",
|
|
3275
3413
|
operationId: "listEndpointWorkers",
|
|
3276
3414
|
description: "List serverless endpoint workers. Lists the active workers for a serverless endpoint. **Returns.** A `200` with a `ListEndpointWorkersResponse`: a `workers` array (one entry per active worker, each carrying its `id`, `status`, and runtime details) plus a `summary` of worker counts grouped by status. Only currently active workers are included; scaled-down workers are not returned. **How `status` is determined.** Each worker's `status` is derived by reconciling the worker pod's lifecycle status with the endpoint's live job-queue view (which workers are actively serving requests). When the job-queue view is unavailable, the response degrades gracefully: the shape is unchanged, but each `status` and the summary counts fall back to pod lifecycle alone.",
|
|
3277
3415
|
method: "GET",
|
|
@@ -3302,6 +3440,7 @@ var generatedTools = [
|
|
|
3302
3440
|
},
|
|
3303
3441
|
{
|
|
3304
3442
|
name: "list-global-volumes",
|
|
3443
|
+
title: "List global volumes",
|
|
3305
3444
|
operationId: "listGlobalVolumes",
|
|
3306
3445
|
description: "List global volumes. Returns global volumes owned by the authenticated user, cursor-paginated newest-first; an omitted `limit` defaults to 1000. Follow `pagination.nextCursor` until `hasNextPage` is false.",
|
|
3307
3446
|
method: "GET",
|
|
@@ -3342,6 +3481,7 @@ var generatedTools = [
|
|
|
3342
3481
|
},
|
|
3343
3482
|
{
|
|
3344
3483
|
name: "list-gpu-types",
|
|
3484
|
+
title: "List GPU types",
|
|
3345
3485
|
operationId: "listGpuTypes",
|
|
3346
3486
|
description: 'List GPU types. Returns available GPU types with pricing. Availability is included only when requested with include=AVAILABILITY, which requires `product` \u2014 stock differs by product context. With countryCodes, the list is narrowed to GPU types deployable in those countries, so "this geography + this chip" resolves in one read.',
|
|
3347
3487
|
method: "GET",
|
|
@@ -3413,7 +3553,8 @@ var generatedTools = [
|
|
|
3413
3553
|
},
|
|
3414
3554
|
cloud: {
|
|
3415
3555
|
$ref: "#/$defs/GpuCloudFilter",
|
|
3416
|
-
description: "Cloud type for availability and lowest-price calculations. Valid only with include=AVAILABILITY. Supported values: SECURE, COMMUNITY. Upstream default when omitted: SECURE."
|
|
3556
|
+
description: "Cloud type for availability and lowest-price calculations. Valid only with include=AVAILABILITY. Supported values: SECURE, COMMUNITY. Upstream default when omitted: SECURE.",
|
|
3557
|
+
type: "string"
|
|
3417
3558
|
},
|
|
3418
3559
|
countryCodes: {
|
|
3419
3560
|
type: "array",
|
|
@@ -3458,6 +3599,7 @@ var generatedTools = [
|
|
|
3458
3599
|
},
|
|
3459
3600
|
{
|
|
3460
3601
|
name: "list-network-volume-billing",
|
|
3602
|
+
title: "List network volume billing",
|
|
3461
3603
|
operationId: "listNetworkVolumeBilling",
|
|
3462
3604
|
description: "Get network volume billing history. Returns network volume billing history for the authenticated user, split into time buckets by startTime/endTime with bucketSize or by lastN recent buckets. Use networkVolumeId to filter to one volume; without it, records are emitted per volume per bucket. Each record includes standard storage, high-performance storage, and total amounts, while metadata reports the resolved query, distinct volume count, and totals across the returned records.",
|
|
3463
3605
|
method: "GET",
|
|
@@ -3506,7 +3648,8 @@ var generatedTools = [
|
|
|
3506
3648
|
},
|
|
3507
3649
|
bucketSize: {
|
|
3508
3650
|
$ref: "#/$defs/BillingBucketSize",
|
|
3509
|
-
description: "Length of each billing time bucket. Defaults to day."
|
|
3651
|
+
description: "Length of each billing time bucket. Defaults to day.",
|
|
3652
|
+
type: "string"
|
|
3510
3653
|
},
|
|
3511
3654
|
lastN: {
|
|
3512
3655
|
type: "integer",
|
|
@@ -3538,6 +3681,7 @@ var generatedTools = [
|
|
|
3538
3681
|
},
|
|
3539
3682
|
{
|
|
3540
3683
|
name: "list-network-volumes",
|
|
3684
|
+
title: "List network volumes",
|
|
3541
3685
|
operationId: "listNetworkVolumes",
|
|
3542
3686
|
description: "List network volumes. Returns network volumes owned by the authenticated user, cursor-paginated newest-first; an omitted `limit` defaults to 1000. Follow `pagination.nextCursor` until `hasNextPage` is false.",
|
|
3543
3687
|
method: "GET",
|
|
@@ -3578,6 +3722,7 @@ var generatedTools = [
|
|
|
3578
3722
|
},
|
|
3579
3723
|
{
|
|
3580
3724
|
name: "list-pod-billing",
|
|
3725
|
+
title: "List Pod billing",
|
|
3581
3726
|
operationId: "listPodBilling",
|
|
3582
3727
|
description: "Get pod billing history. Returns pod-only billing detail for the authenticated user, split into time buckets by startTime/endTime with bucketSize or by lastN recent buckets. Use podId to narrow the response to one GPU or CPU pod; without it, records are emitted per pod per bucket. Each record includes podId, GPU, CPU, disk, and total amounts, while metadata echoes the resolved query and totals across the pod records. Use listBilling when you need aggregate spend across every billable resource family.",
|
|
3583
3728
|
method: "GET",
|
|
@@ -3626,7 +3771,8 @@ var generatedTools = [
|
|
|
3626
3771
|
},
|
|
3627
3772
|
bucketSize: {
|
|
3628
3773
|
$ref: "#/$defs/BillingBucketSize",
|
|
3629
|
-
description: "Length of each billing time bucket. Defaults to day."
|
|
3774
|
+
description: "Length of each billing time bucket. Defaults to day.",
|
|
3775
|
+
type: "string"
|
|
3630
3776
|
},
|
|
3631
3777
|
lastN: {
|
|
3632
3778
|
type: "integer",
|
|
@@ -3658,6 +3804,7 @@ var generatedTools = [
|
|
|
3658
3804
|
},
|
|
3659
3805
|
{
|
|
3660
3806
|
name: "list-pods",
|
|
3807
|
+
title: "List Pods",
|
|
3661
3808
|
operationId: "listPods",
|
|
3662
3809
|
description: "List pods. Returns pods owned by the authenticated user. Cluster member pods are excluded by default; set `includeClusterPods=true` to include them (each carries a non-null `cluster` membership block). Results are cursor-paginated newest-first; an omitted `limit` defaults to 1000. The cluster-member exclusion is applied before the page is cut, so a page holds `limit` pods whenever that many remain. Follow `pagination.nextCursor` until `hasNextPage` is false.",
|
|
3663
3810
|
method: "GET",
|
|
@@ -3707,6 +3854,7 @@ var generatedTools = [
|
|
|
3707
3854
|
},
|
|
3708
3855
|
{
|
|
3709
3856
|
name: "list-public-templates",
|
|
3857
|
+
title: "List public templates",
|
|
3710
3858
|
operationId: "listPublicTemplates",
|
|
3711
3859
|
description: "List public templates. Returns the public template catalog. `source` selects which slice: `official` (the default) is Runpod-curated templates, `verified` is community templates Runpod has verified, and `community` is everything else other users have shared publicly. Both pod and serverless templates appear \u2014 use each entry's `serverless` flag to tell them apart. `registry` is always null for templates you don't own. Your own templates (public or private) are managed under `/v2/templates`; fetch any individual template \u2014 catalog or owned \u2014 via `/v2/templates/{id}`. At most 100 templates are returned. Cursor pagination is not yet supported here; `pagination` is always the exhausted marker (`nextCursor: null`, `hasNextPage: false`).",
|
|
3712
3860
|
method: "GET",
|
|
@@ -3738,6 +3886,7 @@ var generatedTools = [
|
|
|
3738
3886
|
},
|
|
3739
3887
|
{
|
|
3740
3888
|
name: "list-registries",
|
|
3889
|
+
title: "List registry credentials",
|
|
3741
3890
|
operationId: "listRegistries",
|
|
3742
3891
|
description: "List container registries. Returns all container registry credentials owned by the authenticated user.",
|
|
3743
3892
|
method: "GET",
|
|
@@ -3757,6 +3906,7 @@ var generatedTools = [
|
|
|
3757
3906
|
},
|
|
3758
3907
|
{
|
|
3759
3908
|
name: "list-secrets",
|
|
3909
|
+
title: "List secrets",
|
|
3760
3910
|
operationId: "listSecrets",
|
|
3761
3911
|
description: "List secrets. Returns the account's secrets \u2014 encrypted strings referenced from pod, serverless, and template environment variables with the `{{ RUNPOD_SECRET_<name> }}` placeholder syntax, substituted with the secret's value when the pod or worker boots. Secret values are write-only and are never returned.",
|
|
3762
3912
|
method: "GET",
|
|
@@ -3786,8 +3936,10 @@ var generatedTools = [
|
|
|
3786
3936
|
},
|
|
3787
3937
|
{
|
|
3788
3938
|
name: "list-serverless-billing",
|
|
3939
|
+
title: "List Serverless billing",
|
|
3789
3940
|
operationId: "listServerlessBilling",
|
|
3790
3941
|
description: "Get serverless billing history, split into time buckets. SIZE WARNING: with defaults this emits one record per endpoint PER BUCKET \u2014 on an account with many endpoints the response overflows the tool-result limit and becomes unusable. Always pass lastN: 1 (or a bucketSize spanning the whole window) for one record per endpoint, and serverlessId when you need one endpoint. Distinct from pod billing, which covers standalone pods.",
|
|
3942
|
+
directoryDescription: "Get Serverless billing history, split into time buckets. By default the response has one record per endpoint per bucket, which can be very large on accounts with many endpoints; lastN: 1 (or one bucket spanning the whole window) returns one record per endpoint, and serverlessId narrows it to a single endpoint. Pod billing is reported separately.",
|
|
3791
3943
|
method: "GET",
|
|
3792
3944
|
path: "/v2/billing/serverless",
|
|
3793
3945
|
params: [
|
|
@@ -3834,7 +3986,8 @@ var generatedTools = [
|
|
|
3834
3986
|
},
|
|
3835
3987
|
bucketSize: {
|
|
3836
3988
|
$ref: "#/$defs/BillingBucketSize",
|
|
3837
|
-
description: "Length of each billing time bucket. Defaults to day."
|
|
3989
|
+
description: "Length of each billing time bucket. Defaults to day.",
|
|
3990
|
+
type: "string"
|
|
3838
3991
|
},
|
|
3839
3992
|
lastN: {
|
|
3840
3993
|
type: "integer",
|
|
@@ -3866,6 +4019,7 @@ var generatedTools = [
|
|
|
3866
4019
|
},
|
|
3867
4020
|
{
|
|
3868
4021
|
name: "pod-action",
|
|
4022
|
+
title: "Start, stop, restart, or terminate a Pod",
|
|
3869
4023
|
operationId: "podAction",
|
|
3870
4024
|
description: "Trigger a pod state transition. Triggers a state transition on a pod. Send a JSON body with a single `action` field, e.g. `{ \"action\": \"stop\" }`. Valid actions: - `start` \u2014 boot a stopped pod (`EXITED` or `ERROR`) back toward `RUNNING`. - `stop` \u2014 stop a running or provisioning pod, releasing GPU/CPU compute while keeping its disk. The pod moves to `EXITED`. - `restart` \u2014 restart a `RUNNING` pod's container in place. - `terminate` \u2014 permanently delete the pod and release its resources (equivalent to `deletePod`). Which actions are valid depends on the pod's current status, and the currently permitted set is published in the pod's `actions` field: `RUNNING` allows `stop`/`restart`/`terminate`; `EXITED` and `ERROR` allow `start`/`terminate`; `PROVISIONING` and `STARTING` allow `stop`/`terminate`. `start`, `stop`, and `restart` return `200` with the updated pod. `terminate` returns `204` with no body. Requesting an action that is not valid for the pod's current status returns `409`.",
|
|
3871
4025
|
method: "POST",
|
|
@@ -3890,7 +4044,8 @@ var generatedTools = [
|
|
|
3890
4044
|
type: "string"
|
|
3891
4045
|
},
|
|
3892
4046
|
body: {
|
|
3893
|
-
$ref: "#/$defs/PodActionRequest"
|
|
4047
|
+
$ref: "#/$defs/PodActionRequest",
|
|
4048
|
+
type: "object"
|
|
3894
4049
|
}
|
|
3895
4050
|
},
|
|
3896
4051
|
required: ["id", "body"],
|
|
@@ -3915,6 +4070,7 @@ var generatedTools = [
|
|
|
3915
4070
|
},
|
|
3916
4071
|
{
|
|
3917
4072
|
name: "revoke-delegation",
|
|
4073
|
+
title: "Revoke ECR delegation",
|
|
3918
4074
|
operationId: "revokeDelegation",
|
|
3919
4075
|
description: "Revoke an ECR delegation",
|
|
3920
4076
|
method: "DELETE",
|
|
@@ -3944,6 +4100,7 @@ var generatedTools = [
|
|
|
3944
4100
|
},
|
|
3945
4101
|
{
|
|
3946
4102
|
name: "update-cluster",
|
|
4103
|
+
title: "Update cluster",
|
|
3947
4104
|
operationId: "updateCluster",
|
|
3948
4105
|
description: "Rename a cluster. Renames a cluster. This endpoint only changes the cluster name \u2014 compute shape, type, and container configuration are fixed at creation and cannot be updated.",
|
|
3949
4106
|
method: "PATCH",
|
|
@@ -3958,7 +4115,7 @@ var generatedTools = [
|
|
|
3958
4115
|
annotations: {
|
|
3959
4116
|
readOnlyHint: false,
|
|
3960
4117
|
destructiveHint: false,
|
|
3961
|
-
idempotentHint:
|
|
4118
|
+
idempotentHint: true,
|
|
3962
4119
|
openWorldHint: true
|
|
3963
4120
|
},
|
|
3964
4121
|
inputSchema: {
|
|
@@ -3969,7 +4126,8 @@ var generatedTools = [
|
|
|
3969
4126
|
description: "Cluster identifier"
|
|
3970
4127
|
},
|
|
3971
4128
|
body: {
|
|
3972
|
-
$ref: "#/$defs/UpdateClusterRequest"
|
|
4129
|
+
$ref: "#/$defs/UpdateClusterRequest",
|
|
4130
|
+
type: "object"
|
|
3973
4131
|
}
|
|
3974
4132
|
},
|
|
3975
4133
|
required: ["id", "body"],
|
|
@@ -3992,8 +4150,10 @@ var generatedTools = [
|
|
|
3992
4150
|
},
|
|
3993
4151
|
{
|
|
3994
4152
|
name: "update-endpoint",
|
|
4153
|
+
title: "Update endpoint",
|
|
3995
4154
|
operationId: "updateEndpoint",
|
|
3996
4155
|
description: "Partially update a serverless endpoint (PATCH): only fields present in the body change, omitted ones are untouched, with one exception. DESTRUCTIVE GOTCHA: gpu.pools and gpu.excludedTypes are a single selection, so sending pools without excludedTypes clears any exclusions pinned elsewhere (the console or set-endpoint-gpus) \u2014 read the endpoint first with get-endpoint and resend excludedTypes if you still want them. An exclusion naming a type outside pools returns 400. A CUDA-only or count-only change does not need pools at all, so omit it unless you mean to replace the selection. Mutable fields: name, gpu, cpu, workers (min/max/idleTimeout), scaling (type plus queueDelay or requestCount), dataCenterIds, networkVolumes, timeout, flashboot, and the container settings (image, args, disk, ports, env, registry). cpu completely replaces a CPU endpoint's flavor selection. Compute family is immutable: gpu on a CPU endpoint, cpu on a GPU one, or both, returns 400. Effect timing differs by field \u2014 workers/scaling/timeout reach the autoscaler promptly, while container changes (image, env) cut a new release that rolls out as workers cycle, so in-flight workers keep the previous version. Track rollout with list-endpoint-releases.",
|
|
4156
|
+
directoryDescription: "Partially update a Serverless endpoint (PATCH): only fields present in the body change. gpu.pools and gpu.excludedTypes are one selection, so sending pools without excludedTypes clears existing exclusions; an exclusion naming a type outside pools returns 400, and a CUDA-only or count-only change does not need pools. Mutable fields: name, gpu, cpu, workers (min/max/idleTimeout), scaling (type plus queueDelay or requestCount), dataCenterIds, networkVolumes, timeout, flashboot, and the container settings (image, args, disk, ports, env, registry). cpu replaces a CPU endpoint's whole flavor selection. The compute family is fixed: gpu on a CPU endpoint, cpu on a GPU one, or both returns 400. Worker, scaling and timeout changes apply promptly; container changes (image, env) create a new release that rolls out as workers cycle, so in-flight workers keep the previous version.",
|
|
3997
4157
|
method: "PATCH",
|
|
3998
4158
|
path: "/v2/serverless/{id}",
|
|
3999
4159
|
params: [
|
|
@@ -4005,7 +4165,7 @@ var generatedTools = [
|
|
|
4005
4165
|
hasBody: true,
|
|
4006
4166
|
annotations: {
|
|
4007
4167
|
readOnlyHint: false,
|
|
4008
|
-
destructiveHint:
|
|
4168
|
+
destructiveHint: true,
|
|
4009
4169
|
idempotentHint: false,
|
|
4010
4170
|
openWorldHint: true
|
|
4011
4171
|
},
|
|
@@ -4018,7 +4178,8 @@ var generatedTools = [
|
|
|
4018
4178
|
description: "Serverless endpoint identifier"
|
|
4019
4179
|
},
|
|
4020
4180
|
body: {
|
|
4021
|
-
$ref: "#/$defs/UpdateEndpointRequest"
|
|
4181
|
+
$ref: "#/$defs/UpdateEndpointRequest",
|
|
4182
|
+
type: "object"
|
|
4022
4183
|
}
|
|
4023
4184
|
},
|
|
4024
4185
|
required: ["id", "body"],
|
|
@@ -4382,6 +4543,7 @@ var generatedTools = [
|
|
|
4382
4543
|
},
|
|
4383
4544
|
{
|
|
4384
4545
|
name: "update-global-volume",
|
|
4546
|
+
title: "Update global volume",
|
|
4385
4547
|
operationId: "updateGlobalVolume",
|
|
4386
4548
|
description: "Update a global volume. Updates mutable fields on a global volume. Only provided fields are changed.",
|
|
4387
4549
|
method: "PATCH",
|
|
@@ -4396,7 +4558,7 @@ var generatedTools = [
|
|
|
4396
4558
|
annotations: {
|
|
4397
4559
|
readOnlyHint: false,
|
|
4398
4560
|
destructiveHint: false,
|
|
4399
|
-
idempotentHint:
|
|
4561
|
+
idempotentHint: true,
|
|
4400
4562
|
openWorldHint: true
|
|
4401
4563
|
},
|
|
4402
4564
|
inputSchema: {
|
|
@@ -4407,7 +4569,8 @@ var generatedTools = [
|
|
|
4407
4569
|
description: "Global volume identifier"
|
|
4408
4570
|
},
|
|
4409
4571
|
body: {
|
|
4410
|
-
$ref: "#/$defs/UpdateGlobalVolumeRequest"
|
|
4572
|
+
$ref: "#/$defs/UpdateGlobalVolumeRequest",
|
|
4573
|
+
type: "object"
|
|
4411
4574
|
}
|
|
4412
4575
|
},
|
|
4413
4576
|
required: ["id", "body"],
|
|
@@ -4433,6 +4596,7 @@ var generatedTools = [
|
|
|
4433
4596
|
},
|
|
4434
4597
|
{
|
|
4435
4598
|
name: "update-network-volume",
|
|
4599
|
+
title: "Update network volume",
|
|
4436
4600
|
operationId: "updateNetworkVolume",
|
|
4437
4601
|
description: "Update a network volume. Updates mutable fields on a network volume. Only provided fields are changed. Note: `size` may only increase; attempts to reduce size will be rejected.",
|
|
4438
4602
|
method: "PATCH",
|
|
@@ -4447,7 +4611,7 @@ var generatedTools = [
|
|
|
4447
4611
|
annotations: {
|
|
4448
4612
|
readOnlyHint: false,
|
|
4449
4613
|
destructiveHint: false,
|
|
4450
|
-
idempotentHint:
|
|
4614
|
+
idempotentHint: true,
|
|
4451
4615
|
openWorldHint: true
|
|
4452
4616
|
},
|
|
4453
4617
|
inputSchema: {
|
|
@@ -4458,7 +4622,8 @@ var generatedTools = [
|
|
|
4458
4622
|
description: "Network volume identifier"
|
|
4459
4623
|
},
|
|
4460
4624
|
body: {
|
|
4461
|
-
$ref: "#/$defs/UpdateNetworkVolumeRequest"
|
|
4625
|
+
$ref: "#/$defs/UpdateNetworkVolumeRequest",
|
|
4626
|
+
type: "object"
|
|
4462
4627
|
}
|
|
4463
4628
|
},
|
|
4464
4629
|
required: ["id", "body"],
|
|
@@ -4489,6 +4654,7 @@ var generatedTools = [
|
|
|
4489
4654
|
},
|
|
4490
4655
|
{
|
|
4491
4656
|
name: "update-pod",
|
|
4657
|
+
title: "Update Pod",
|
|
4492
4658
|
operationId: "updatePod",
|
|
4493
4659
|
description: "Update a pod. Partially updates a pod's configuration. This is a PATCH: only the fields present in the body are changed, and omitted fields are left untouched. Use empty values only when you explicitly mean to clear a field (for example, set `registry` to `null` or set `ports` to `[]`). See `UpdatePodRequest` for the full body. Mutable fields: `name`, `image`, `args`, `disk`, `ports`, `env`, `registry`, `mounts`, `locked`, and `globalNetworking`. Some changes apply immediately while others (e.g. `globalNetworking`) take effect on the pod's next start/restart, as noted on the individual fields. Pods that belong to a Cluster cannot be updated here \u2014 manage them through `/v2/clusters/{id}`. Returns `200` with the full updated pod.",
|
|
4494
4660
|
method: "PATCH",
|
|
@@ -4502,7 +4668,7 @@ var generatedTools = [
|
|
|
4502
4668
|
hasBody: true,
|
|
4503
4669
|
annotations: {
|
|
4504
4670
|
readOnlyHint: false,
|
|
4505
|
-
destructiveHint:
|
|
4671
|
+
destructiveHint: true,
|
|
4506
4672
|
idempotentHint: false,
|
|
4507
4673
|
openWorldHint: true
|
|
4508
4674
|
},
|
|
@@ -4515,7 +4681,8 @@ var generatedTools = [
|
|
|
4515
4681
|
description: "Pod identifier"
|
|
4516
4682
|
},
|
|
4517
4683
|
body: {
|
|
4518
|
-
$ref: "#/$defs/UpdatePodRequest"
|
|
4684
|
+
$ref: "#/$defs/UpdatePodRequest",
|
|
4685
|
+
type: "object"
|
|
4519
4686
|
}
|
|
4520
4687
|
},
|
|
4521
4688
|
required: ["id", "body"],
|
|
@@ -4730,6 +4897,7 @@ var generatedTools = [
|
|
|
4730
4897
|
},
|
|
4731
4898
|
{
|
|
4732
4899
|
name: "update-secret",
|
|
4900
|
+
title: "Update secret",
|
|
4733
4901
|
operationId: "updateSecret",
|
|
4734
4902
|
description: "Update a secret. Rotates a secret's value and/or updates its description. Only the provided fields are changed and at least one field is required; the `name` is immutable. Pods and workers receive the new value at their next boot \u2014 running instances keep the value they were started with. When both fields are sent, the value is applied first, then the description. The two updates are not atomic: if the description update fails after the value was rotated, the response is an error but the new value has already taken effect. Send the fields in separate requests when that partial outcome matters.",
|
|
4735
4903
|
method: "PATCH",
|
|
@@ -4743,7 +4911,7 @@ var generatedTools = [
|
|
|
4743
4911
|
hasBody: true,
|
|
4744
4912
|
annotations: {
|
|
4745
4913
|
readOnlyHint: false,
|
|
4746
|
-
destructiveHint:
|
|
4914
|
+
destructiveHint: true,
|
|
4747
4915
|
idempotentHint: false,
|
|
4748
4916
|
openWorldHint: true
|
|
4749
4917
|
},
|
|
@@ -4756,7 +4924,8 @@ var generatedTools = [
|
|
|
4756
4924
|
description: "Secret identifier"
|
|
4757
4925
|
},
|
|
4758
4926
|
body: {
|
|
4759
|
-
$ref: "#/$defs/UpdateSecretRequest"
|
|
4927
|
+
$ref: "#/$defs/UpdateSecretRequest",
|
|
4928
|
+
type: "object"
|
|
4760
4929
|
}
|
|
4761
4930
|
},
|
|
4762
4931
|
required: ["id", "body"],
|
|
@@ -4785,6 +4954,7 @@ var generatedTools = [
|
|
|
4785
4954
|
},
|
|
4786
4955
|
{
|
|
4787
4956
|
name: "update-ssh-keys",
|
|
4957
|
+
title: "Update SSH keys",
|
|
4788
4958
|
operationId: "updateSshKeys",
|
|
4789
4959
|
description: "Replace registered SSH public keys. Replaces the account's full set of registered SSH public keys. Existing keys not present in the request are removed; send `[]` to remove all keys. Keys take effect for pods created afterwards with `startSsh` \u2014 running pods are not updated.",
|
|
4790
4960
|
method: "PUT",
|
|
@@ -4801,7 +4971,8 @@ var generatedTools = [
|
|
|
4801
4971
|
type: "object",
|
|
4802
4972
|
properties: {
|
|
4803
4973
|
body: {
|
|
4804
|
-
$ref: "#/$defs/UpdateSshKeysRequest"
|
|
4974
|
+
$ref: "#/$defs/UpdateSshKeysRequest",
|
|
4975
|
+
type: "object"
|
|
4805
4976
|
}
|
|
4806
4977
|
},
|
|
4807
4978
|
required: ["body"],
|
|
@@ -4831,6 +5002,7 @@ var generatedTools = [
|
|
|
4831
5002
|
},
|
|
4832
5003
|
{
|
|
4833
5004
|
name: "update-template",
|
|
5005
|
+
title: "Update template",
|
|
4834
5006
|
operationId: "updateTemplate",
|
|
4835
5007
|
description: "Update a template. Partially updates a template. This is a PATCH: only the fields present in the body are changed; omitted fields are left untouched. See `UpdateTemplateRequest` for the full body. Mutable fields: `name`, `image`, `args`, `disk`, `ports`, `env`, `registry`, `mounts`, `serverless`, `public`, and `category`. Only the template's owner can update it (authenticated via the request's API key); public catalog templates are readable via GET but return `404` here. Returns `200` with the full updated template. Pods and endpoints already created from this template are not changed retroactively \u2014 the template is a snapshot applied at creation time.",
|
|
4836
5008
|
method: "PATCH",
|
|
@@ -4845,7 +5017,7 @@ var generatedTools = [
|
|
|
4845
5017
|
annotations: {
|
|
4846
5018
|
readOnlyHint: false,
|
|
4847
5019
|
destructiveHint: false,
|
|
4848
|
-
idempotentHint:
|
|
5020
|
+
idempotentHint: true,
|
|
4849
5021
|
openWorldHint: true
|
|
4850
5022
|
},
|
|
4851
5023
|
schemaOnDemand: true,
|
|
@@ -4856,7 +5028,8 @@ var generatedTools = [
|
|
|
4856
5028
|
type: "string"
|
|
4857
5029
|
},
|
|
4858
5030
|
body: {
|
|
4859
|
-
$ref: "#/$defs/UpdateTemplateRequest"
|
|
5031
|
+
$ref: "#/$defs/UpdateTemplateRequest",
|
|
5032
|
+
type: "object"
|
|
4860
5033
|
}
|
|
4861
5034
|
},
|
|
4862
5035
|
required: ["id", "body"],
|
|
@@ -5025,6 +5198,146 @@ var generatedTools = [
|
|
|
5025
5198
|
}
|
|
5026
5199
|
];
|
|
5027
5200
|
|
|
5201
|
+
// src/specgen/profile.ts
|
|
5202
|
+
var DIRECTORY_PATH = "/directory";
|
|
5203
|
+
var IN = { include: true };
|
|
5204
|
+
var CREDENTIAL_INPUT = "Takes a secret or password as input; directories forbid collecting credentials.";
|
|
5205
|
+
var ALP = "Collects conversation-derived data beyond the task; the directory profile never serves it.";
|
|
5206
|
+
var DIRECTORY_TOOLS = {
|
|
5207
|
+
"cancel-job": IN,
|
|
5208
|
+
"create-cluster": IN,
|
|
5209
|
+
"create-delegation": IN,
|
|
5210
|
+
"create-endpoint": IN,
|
|
5211
|
+
"create-global-volume": IN,
|
|
5212
|
+
"create-network-volume": IN,
|
|
5213
|
+
"create-pod": IN,
|
|
5214
|
+
"create-template": IN,
|
|
5215
|
+
"delete-cluster": IN,
|
|
5216
|
+
"delete-endpoint": IN,
|
|
5217
|
+
"delete-global-volume": IN,
|
|
5218
|
+
"delete-network-volume": IN,
|
|
5219
|
+
"delete-pod": IN,
|
|
5220
|
+
"delete-registry": IN,
|
|
5221
|
+
"delete-secret": IN,
|
|
5222
|
+
"delete-template": IN,
|
|
5223
|
+
"deploy-hub-repo": IN,
|
|
5224
|
+
"endpoint-health": IN,
|
|
5225
|
+
"get-capacity": IN,
|
|
5226
|
+
"get-cluster": IN,
|
|
5227
|
+
"get-cpu-type": IN,
|
|
5228
|
+
"get-data-center": IN,
|
|
5229
|
+
"get-endpoint": IN,
|
|
5230
|
+
"get-endpoint-build": IN,
|
|
5231
|
+
"get-global-volume": IN,
|
|
5232
|
+
"get-gpu-type": IN,
|
|
5233
|
+
"get-job-status": IN,
|
|
5234
|
+
"get-network-volume": IN,
|
|
5235
|
+
"get-organization": IN,
|
|
5236
|
+
"get-pod": IN,
|
|
5237
|
+
"get-registry": IN,
|
|
5238
|
+
"get-secret": IN,
|
|
5239
|
+
"get-ssh-keys": IN,
|
|
5240
|
+
"get-template": IN,
|
|
5241
|
+
"list-billing": IN,
|
|
5242
|
+
"list-cluster-billing": IN,
|
|
5243
|
+
"list-cluster-pods": IN,
|
|
5244
|
+
"list-clusters": IN,
|
|
5245
|
+
"list-cpu-types": IN,
|
|
5246
|
+
"list-data-centers": IN,
|
|
5247
|
+
"list-delegations": IN,
|
|
5248
|
+
"list-endpoint-billing": IN,
|
|
5249
|
+
"list-endpoint-builds": IN,
|
|
5250
|
+
"list-endpoint-releases": IN,
|
|
5251
|
+
"list-endpoint-workers": IN,
|
|
5252
|
+
"list-endpoints": IN,
|
|
5253
|
+
"list-global-volumes": IN,
|
|
5254
|
+
"list-gpu-types": IN,
|
|
5255
|
+
"list-hub-repos": IN,
|
|
5256
|
+
"list-network-volume-billing": IN,
|
|
5257
|
+
"list-network-volumes": IN,
|
|
5258
|
+
"list-pod-billing": IN,
|
|
5259
|
+
"list-pods": IN,
|
|
5260
|
+
"list-public-endpoints": IN,
|
|
5261
|
+
"list-public-templates": IN,
|
|
5262
|
+
"list-registries": IN,
|
|
5263
|
+
"list-secrets": IN,
|
|
5264
|
+
"list-serverless-billing": IN,
|
|
5265
|
+
"list-templates": IN,
|
|
5266
|
+
"lookup-concept": IN,
|
|
5267
|
+
"pod-action": IN,
|
|
5268
|
+
"purge-endpoint-queue": IN,
|
|
5269
|
+
"retry-job": IN,
|
|
5270
|
+
"revoke-delegation": IN,
|
|
5271
|
+
"search-concepts": IN,
|
|
5272
|
+
"search-docs": IN,
|
|
5273
|
+
"set-endpoint-gpus": IN,
|
|
5274
|
+
"stream-job": IN,
|
|
5275
|
+
"stream-pod-logs": IN,
|
|
5276
|
+
"stream-worker-logs": IN,
|
|
5277
|
+
"update-cluster": IN,
|
|
5278
|
+
"update-endpoint": IN,
|
|
5279
|
+
"update-global-volume": IN,
|
|
5280
|
+
"update-network-volume": IN,
|
|
5281
|
+
"update-pod": IN,
|
|
5282
|
+
"update-ssh-keys": IN,
|
|
5283
|
+
"update-template": IN,
|
|
5284
|
+
"run-endpoint": { include: true, omitInputs: ["s3Config"] },
|
|
5285
|
+
"runsync-endpoint": { include: true, omitInputs: ["s3Config"] },
|
|
5286
|
+
"list-guides": {
|
|
5287
|
+
include: false,
|
|
5288
|
+
reason: "Serves playbooks that instruct the model how to behave."
|
|
5289
|
+
},
|
|
5290
|
+
"read-guide": {
|
|
5291
|
+
include: false,
|
|
5292
|
+
reason: "Serves playbooks that instruct the model how to behave."
|
|
5293
|
+
},
|
|
5294
|
+
"describe-tool": {
|
|
5295
|
+
include: false,
|
|
5296
|
+
reason: "Fetches schemas the directory already lists in full; directories reject schema fetching."
|
|
5297
|
+
},
|
|
5298
|
+
"create-secret": { include: false, reason: CREDENTIAL_INPUT },
|
|
5299
|
+
"update-secret": { include: false, reason: CREDENTIAL_INPUT },
|
|
5300
|
+
"create-registry": { include: false, reason: CREDENTIAL_INPUT },
|
|
5301
|
+
report_feedback: { include: false, reason: ALP },
|
|
5302
|
+
report_how_user_found_runpod: { include: false, reason: ALP },
|
|
5303
|
+
save_to_journal: { include: false, reason: ALP },
|
|
5304
|
+
read_journal: { include: false, reason: ALP },
|
|
5305
|
+
ask_question: { include: false, reason: ALP }
|
|
5306
|
+
};
|
|
5307
|
+
function directoryIncludes(name) {
|
|
5308
|
+
return DIRECTORY_TOOLS[name]?.include === true;
|
|
5309
|
+
}
|
|
5310
|
+
function directoryOmittedInputs(name) {
|
|
5311
|
+
const decision = DIRECTORY_TOOLS[name];
|
|
5312
|
+
return decision?.include ? decision.omitInputs ?? [] : [];
|
|
5313
|
+
}
|
|
5314
|
+
function profileForPath(pathname) {
|
|
5315
|
+
return pathname.replace(/\/+$/, "") === DIRECTORY_PATH ? "directory" : "default";
|
|
5316
|
+
}
|
|
5317
|
+
|
|
5318
|
+
// src/specgen/redact.ts
|
|
5319
|
+
var REDACTED = "[redacted]";
|
|
5320
|
+
var SECRET_KEY = /pass(word|wd)?|secret|token|api_?key|private_?key|credential|auth/i;
|
|
5321
|
+
var SECRET_REFERENCE = /^\s*\{\{\s*RUNPOD_SECRET_[^}]+\}\}\s*$/;
|
|
5322
|
+
function redactEnv(env) {
|
|
5323
|
+
return Object.fromEntries(
|
|
5324
|
+
Object.entries(env).map(([key, value]) => [
|
|
5325
|
+
key,
|
|
5326
|
+
typeof value === "string" && value !== "" && SECRET_KEY.test(key) && !SECRET_REFERENCE.test(value) ? REDACTED : value
|
|
5327
|
+
])
|
|
5328
|
+
);
|
|
5329
|
+
}
|
|
5330
|
+
function redactSecretEnv(payload) {
|
|
5331
|
+
if (Array.isArray(payload)) return payload.map(redactSecretEnv);
|
|
5332
|
+
if (!payload || typeof payload !== "object") return payload;
|
|
5333
|
+
return Object.fromEntries(
|
|
5334
|
+
Object.entries(payload).map(([key, value]) => [
|
|
5335
|
+
key,
|
|
5336
|
+
key === "env" && value && typeof value === "object" && !Array.isArray(value) ? redactEnv(value) : redactSecretEnv(value)
|
|
5337
|
+
])
|
|
5338
|
+
);
|
|
5339
|
+
}
|
|
5340
|
+
|
|
5028
5341
|
// src/specgen/pagination.ts
|
|
5029
5342
|
var DEFAULT_LIST_LIMIT = 20;
|
|
5030
5343
|
var MAX_LIST_LIMIT = 100;
|
|
@@ -5129,6 +5442,43 @@ function isTimeout(error) {
|
|
|
5129
5442
|
const cause = error.cause;
|
|
5130
5443
|
return cause instanceof Error && (cause.name === "TimeoutError" || cause.name === "AbortError");
|
|
5131
5444
|
}
|
|
5445
|
+
var UNREACHED_CODES = /* @__PURE__ */ new Set([
|
|
5446
|
+
"ENOTFOUND",
|
|
5447
|
+
"EAI_AGAIN",
|
|
5448
|
+
"ECONNREFUSED",
|
|
5449
|
+
"EHOSTUNREACH",
|
|
5450
|
+
"ENETUNREACH",
|
|
5451
|
+
"UND_ERR_CONNECT_TIMEOUT"
|
|
5452
|
+
]);
|
|
5453
|
+
var TLS_CODE = /^(?:CERT_|ERR_TLS_|UNABLE_TO_|DEPTH_ZERO_|SELF_SIGNED_)/;
|
|
5454
|
+
function causeCode(cause) {
|
|
5455
|
+
const code = cause?.code;
|
|
5456
|
+
if (typeof code === "string") return code;
|
|
5457
|
+
const inner = cause instanceof AggregateError ? cause.errors[0] : void 0;
|
|
5458
|
+
const innerCode = inner?.code;
|
|
5459
|
+
return typeof innerCode === "string" ? innerCode : void 0;
|
|
5460
|
+
}
|
|
5461
|
+
function networkFailureResult(error) {
|
|
5462
|
+
if (!(error instanceof TypeError)) return void 0;
|
|
5463
|
+
const afterHeaders = error.message === "terminated";
|
|
5464
|
+
if (!afterHeaders && error.message !== "fetch failed") return void 0;
|
|
5465
|
+
const code = causeCode(error.cause);
|
|
5466
|
+
if (!code) return void 0;
|
|
5467
|
+
const unreached = !afterHeaders && (UNREACHED_CODES.has(code) || TLS_CODE.test(code));
|
|
5468
|
+
return {
|
|
5469
|
+
ok: false,
|
|
5470
|
+
status: unreached ? 503 : 502,
|
|
5471
|
+
payload: unreached ? {
|
|
5472
|
+
error: "Could not reach the Runpod API.",
|
|
5473
|
+
cause: code,
|
|
5474
|
+
hint: "The request never reached Runpod, so retrying the same call is safe: retry it once. If it fails again, the network, DNS, proxy or TLS setup on this machine is the likely cause; check https://uptime.runpod.io and report it rather than retrying further."
|
|
5475
|
+
} : {
|
|
5476
|
+
error: "The connection to the Runpod API dropped before the full response arrived.",
|
|
5477
|
+
cause: code,
|
|
5478
|
+
hint: "The request may have been applied. A read can be retried once. For a create, update, delete or job submission, check with the matching get- or list- tool whether it took effect before calling again; retrying blindly can create a duplicate billable resource."
|
|
5479
|
+
}
|
|
5480
|
+
};
|
|
5481
|
+
}
|
|
5132
5482
|
async function runTool(body) {
|
|
5133
5483
|
try {
|
|
5134
5484
|
return await body();
|
|
@@ -5150,6 +5500,8 @@ async function runTool(body) {
|
|
|
5150
5500
|
}
|
|
5151
5501
|
};
|
|
5152
5502
|
}
|
|
5503
|
+
const network = networkFailureResult(error);
|
|
5504
|
+
if (network) return network;
|
|
5153
5505
|
throw error;
|
|
5154
5506
|
}
|
|
5155
5507
|
}
|
|
@@ -5185,6 +5537,12 @@ var destructive = {
|
|
|
5185
5537
|
idempotentHint: true,
|
|
5186
5538
|
openWorldHint: true
|
|
5187
5539
|
};
|
|
5540
|
+
var destructiveWrite = {
|
|
5541
|
+
readOnlyHint: false,
|
|
5542
|
+
destructiveHint: true,
|
|
5543
|
+
idempotentHint: false,
|
|
5544
|
+
openWorldHint: true
|
|
5545
|
+
};
|
|
5188
5546
|
|
|
5189
5547
|
// src/specgen/tools/capacity.ts
|
|
5190
5548
|
var CUDA_VERSION_REGEX = /^\d{1,2}\.\d{1,2}$/;
|
|
@@ -5220,6 +5578,8 @@ function rankByStock(rows, stats, includeUnavailable) {
|
|
|
5220
5578
|
}
|
|
5221
5579
|
var getCapacity = {
|
|
5222
5580
|
name: "get-capacity",
|
|
5581
|
+
title: "Get GPU capacity by CUDA version",
|
|
5582
|
+
directoryDescription: "GPU capacity across host CUDA versions, as a matrix. By default one call returns, for each GPU type, overall stock plus AVAILABLE or UNAVAILABLE per host CUDA version. With cudaVersions it checks each listed version and returns graded stock (High, Medium, Low, Out) and the lowest on-demand price per version; a check that fails transiently reports an error for that version only. Out-of-stock GPUs are included unless includeUnavailable is false. Live public catalog data, so page cursors can shift between calls.",
|
|
5223
5583
|
annotations: readOnly,
|
|
5224
5584
|
description: "GPU capacity across host CUDA versions, as a matrix. Use this to choose an endpoint's allowedCudaVersions/minCudaVersion (or diagnose/widen a capacity-starved one) and to distinguish capacity problems from compatibility problems. Default mode is one call returning, per GPU type, overall stock plus AVAILABLE/UNAVAILABLE per host-reported CUDA version. Pass cudaVersions to deep-probe instead: one stock lookup per listed version, returning graded stock (High/Medium/Low/Out) and the lowest on-demand price per version; a probe that fails transiently reports a per-version error instead of failing the call. Nothing is hidden by default \u2014 set includeUnavailable:false to drop GPUs with no stock on any listed version. Credential-free public catalog data. Stock is live, so page cursors can shift between calls.",
|
|
5225
5585
|
inputSchema: {
|
|
@@ -5421,7 +5781,10 @@ function formatGpuIds(gpu) {
|
|
|
5421
5781
|
}
|
|
5422
5782
|
var setEndpointGpus = {
|
|
5423
5783
|
name: "set-endpoint-gpus",
|
|
5424
|
-
|
|
5784
|
+
title: "Set endpoint GPUs",
|
|
5785
|
+
directoryDescription: "Set which GPUs a Serverless endpoint's workers run on, including pinning specific GPU types. Takes either a raw gpuIds string, or pools plus optional excludeGpuTypeIds, from which the exclusion string is built: a pool allows every GPU type in it, and excluding all but one pins that type. Changes only GPU settings and keeps the endpoint's other settings.",
|
|
5786
|
+
// Replaces the whole GPU selection: exclusions not resent are cleared.
|
|
5787
|
+
annotations: destructive,
|
|
5425
5788
|
description: "Set which GPUs a Serverless endpoint's workers run on \u2014 including pinning specific GPU SKUs. Provide either a raw gpuIds string, or pools plus optional excludeGpuTypeIds (GPU type ids from list-gpu-types) and the exclusion string is built for you: a pool allows every SKU in it, and excluding all but one SKU pins that SKU exactly. Updates only GPU settings through REST v2, preserving other endpoint settings. create-endpoint/update-endpoint also support gpu.excludedTypes.",
|
|
5426
5789
|
inputSchema: {
|
|
5427
5790
|
type: "object",
|
|
@@ -5615,6 +5978,8 @@ function randomSuffix() {
|
|
|
5615
5978
|
}
|
|
5616
5979
|
var listHubRepos = {
|
|
5617
5980
|
name: "list-hub-repos",
|
|
5981
|
+
title: "List Hub repos",
|
|
5982
|
+
directoryDescription: "List repos published to the Runpod Hub (prebuilt Serverless workers and Pod templates, such as vLLM and ComfyUI), sorted by deploy count. Public catalog; no sign-in needed. Each result includes the listed release with its hubReleaseId and image name. includeConfig: true adds each release's config (hardware requirements and environment-variable schema), which is large; repoOwner and searchTerm narrow the list.",
|
|
5618
5983
|
annotations: readOnly,
|
|
5619
5984
|
description: "List repos published to the Runpod Hub (prebuilt Serverless workers and Pod templates, e.g. vLLM, ComfyUI). Public catalog \u2014 no auth required. Each result includes the currently listed release with its hubReleaseId and prebuilt image name. Results are sorted by deploy count (most popular first). Set includeConfig:true to also return the release config (hardware requirements and environment-variable schema) \u2014 it is large, so prefer requesting it for a single repo via the repoOwner/searchTerm filters.",
|
|
5620
5985
|
inputSchema: {
|
|
@@ -5717,6 +6082,8 @@ var listHubRepos = {
|
|
|
5717
6082
|
};
|
|
5718
6083
|
var deployHubRepo = {
|
|
5719
6084
|
name: "deploy-hub-repo",
|
|
6085
|
+
title: "Deploy Hub repo",
|
|
6086
|
+
directoryDescription: `Deploy a Runpod Hub repo's listed release as a new Serverless endpoint, the same as clicking Deploy on the Hub. Identifies the repo by repo ("owner/name") or hubReleaseId. The release supplies the image, container disk, CUDA constraints and environment-variable defaults; env overrides or fills in values, and keys the release requires without a default have to be supplied. GPUs come from the release config when it sets them, otherwise from gpuIds (pool names such as 'ADA_24'). Billable while the endpoint's workers run.`,
|
|
5720
6087
|
// Two sequential upstream calls: together they can outlast a client's request timeout.
|
|
5721
6088
|
holdsResponse: true,
|
|
5722
6089
|
annotations: write,
|
|
@@ -6177,6 +6544,8 @@ function validateWait(wait) {
|
|
|
6177
6544
|
}
|
|
6178
6545
|
var runEndpoint = {
|
|
6179
6546
|
name: "run-endpoint",
|
|
6547
|
+
title: "Submit Serverless job",
|
|
6548
|
+
directoryDescription: "Submit an asynchronous job to a Serverless endpoint. Returns a job ID immediately; the result stays available for 30 minutes after the job completes.",
|
|
6180
6549
|
annotations: write,
|
|
6181
6550
|
description: "Submit an asynchronous job to a Serverless endpoint. Returns a job ID immediately \u2014 use get-job-status to poll for results (pass its `wait` to block through a cold start instead of tight-looping). Async results are available for 30 minutes after completion.",
|
|
6182
6551
|
inputSchema: {
|
|
@@ -6207,6 +6576,8 @@ var runEndpoint = {
|
|
|
6207
6576
|
};
|
|
6208
6577
|
var runsyncEndpoint = {
|
|
6209
6578
|
name: "runsync-endpoint",
|
|
6579
|
+
title: "Run Serverless job and wait",
|
|
6580
|
+
directoryDescription: `Submit a synchronous job to a Serverless endpoint and wait up to ${HTTP_LONG_POLL_BUDGET_MS} ms for the result. If the job outlives the wait, the response carries the job ID and its current status (IN_QUEUE or IN_PROGRESS). Maximum payload 20 MB; results expire 1 minute after completion.`,
|
|
6210
6581
|
holdsResponse: true,
|
|
6211
6582
|
annotations: write,
|
|
6212
6583
|
description: "Submit a synchronous job to a Serverless endpoint and wait for the result. Best for fast tasks: if the job outlives the wait, the response returns a job ID and a non-terminal status (IN_QUEUE or IN_PROGRESS) to poll with get-job-status. Max payload 20 MB; results expire after 1 minute. The wait parameter extends the server-side wait" + (HOSTED ? ` \u2014 this server runs behind a 60-second gateway deadline, so waits clamp to ${HTTP_LONG_POLL_BUDGET_MS} ms, which is also the effective default. For longer jobs use run-endpoint + get-job-status.` : " to up to 5 minutes (300000 ms); it defaults to 90000 (90 seconds)."),
|
|
@@ -6252,6 +6623,8 @@ var runsyncEndpoint = {
|
|
|
6252
6623
|
};
|
|
6253
6624
|
var getJobStatus = {
|
|
6254
6625
|
name: "get-job-status",
|
|
6626
|
+
title: "Get job status",
|
|
6627
|
+
directoryDescription: `Get the status of a Serverless job, and its output once it completes. Statuses: IN_QUEUE, IN_PROGRESS, COMPLETED, FAILED, CANCELLED, TIMED_OUT. With wait (milliseconds, up to ${HTTP_LONG_POLL_BUDGET_MS}) the server polls until the job reaches a final status or the wait runs out, in which case it returns the latest status with pollingTimedOut: true; without wait it returns the current status at once. An IN_QUEUE result includes a workerHealth summary of the endpoint's workers.`,
|
|
6255
6628
|
holdsResponse: true,
|
|
6256
6629
|
annotations: readOnly,
|
|
6257
6630
|
description: "Check the status of a Serverless job. Returns the current status and output when complete. Job statuses: IN_QUEUE, IN_PROGRESS, COMPLETED, FAILED, CANCELLED, TIMED_OUT. Pass `wait` (milliseconds, up to " + STATUS_WAIT_MAX_MS + ") to BLOCK server-side, polling until the job reaches a terminal status or the budget expires \u2014 use it to ride out a cold start (a first job on a fresh worker pulls the image and loads the model, commonly 1\u20135+ minutes) in a single call instead of returning on the first IN_QUEUE and tight-looping the tool. Without `wait` it returns the current status immediately (a single check). If the budget expires before a terminal status, it returns the latest non-terminal status with pollingTimedOut:true \u2014 call again (with `wait`) to keep blocking. IMPORTANT: a job stuck IN_QUEUE does not necessarily mean a capacity shortage \u2014 a worker may have spun up and crash-looped. When the job is IN_QUEUE this tool attaches a workerHealth summary and a hint. To dig deeper call list-endpoint-workers, then read stream-worker-logs regardless of the status a worker reports: a container failing to start loops while its worker still shows RUNNING or THROTTLED and unhealthy stays 0, so UNHEALTHY is one symptom of a crash loop and not a test for it. The logs are the authority.",
|
|
@@ -6301,8 +6674,12 @@ var getJobStatus = {
|
|
|
6301
6674
|
};
|
|
6302
6675
|
var streamJob = {
|
|
6303
6676
|
name: "stream-job",
|
|
6677
|
+
title: "Stream job output",
|
|
6678
|
+
directoryDescription: `Collect streaming output from a Serverless job whose worker streams its output. Polls the job's stream until it reaches COMPLETED, FAILED, CANCELLED or TIMED_OUT, for up to ${formatBudget(HTTP_LONG_POLL_BUDGET_MS)}; if time runs out first, it returns the chunks collected so far with pollingTimedOut: true, and a later call resumes where it left off.`,
|
|
6304
6679
|
holdsResponse: true,
|
|
6305
|
-
|
|
6680
|
+
// Not a read: /stream hands out each chunk once, so a chunk collected by a
|
|
6681
|
+
// call whose response is lost cannot be fetched again.
|
|
6682
|
+
annotations: destructiveWrite,
|
|
6306
6683
|
description: `Retrieve streaming output from a Serverless job. The worker must support streaming output. Polls /stream/{jobId} and collects chunks until the status is COMPLETED, FAILED, CANCELLED, or TIMED_OUT, for up to ${formatBudget(STREAM_BUDGET_MS)}. If the budget expires first, returns the chunks collected so far with pollingTimedOut: true \u2014 call stream-job again to resume where it left off, or get-job-status to check without streaming.`,
|
|
6307
6684
|
inputSchema: {
|
|
6308
6685
|
type: "object",
|
|
@@ -6333,6 +6710,7 @@ var streamJob = {
|
|
|
6333
6710
|
};
|
|
6334
6711
|
var cancelJob = {
|
|
6335
6712
|
name: "cancel-job",
|
|
6713
|
+
title: "Cancel job",
|
|
6336
6714
|
annotations: destructive,
|
|
6337
6715
|
description: "Cancel a Serverless job that is queued or in progress.",
|
|
6338
6716
|
inputSchema: {
|
|
@@ -6358,7 +6736,9 @@ var cancelJob = {
|
|
|
6358
6736
|
};
|
|
6359
6737
|
var retryJob = {
|
|
6360
6738
|
name: "retry-job",
|
|
6361
|
-
|
|
6739
|
+
title: "Retry job",
|
|
6740
|
+
// Removes the previous output before requeueing.
|
|
6741
|
+
annotations: destructiveWrite,
|
|
6362
6742
|
description: "Retry a failed or timed-out Serverless job. Only works for jobs with FAILED or TIMED_OUT status. The previous output is removed and the job is requeued.",
|
|
6363
6743
|
inputSchema: {
|
|
6364
6744
|
type: "object",
|
|
@@ -6383,6 +6763,8 @@ var retryJob = {
|
|
|
6383
6763
|
};
|
|
6384
6764
|
var endpointHealth = {
|
|
6385
6765
|
name: "endpoint-health",
|
|
6766
|
+
title: "Get endpoint health",
|
|
6767
|
+
directoryDescription: "Get the health rollup for a Serverless endpoint: worker counts by state and job queue statistics. The rollup can lag the per-worker state, and a worker whose container keeps failing to start can still report RUNNING or THROTTLED here. Zero workers means the endpoint is waiting for GPU capacity.",
|
|
6386
6768
|
annotations: readOnly,
|
|
6387
6769
|
description: "Get the endpoint-level health rollup for a Serverless endpoint: worker counts by state plus job queue statistics. This is the runtime plane's own /health view and it can lag or disagree with the per-worker truth \u2014 when a job is stuck IN_QUEUE, prefer list-endpoint-workers over this rollup for per-worker state \u2014 but treat neither as the authority on crash loops, because a container failing to start loops while its worker reports RUNNING or THROTTLED and unhealthy stays 0; stream-worker-logs is what settles it, and note that get-job-status already attaches that worker summary and a hint on every IN_QUEUE result. Zero workers here means the endpoint is waiting for GPU capacity.",
|
|
6388
6770
|
inputSchema: {
|
|
@@ -6403,6 +6785,8 @@ var endpointHealth = {
|
|
|
6403
6785
|
};
|
|
6404
6786
|
var purgeEndpointQueue = {
|
|
6405
6787
|
name: "purge-endpoint-queue",
|
|
6788
|
+
title: "Purge endpoint queue",
|
|
6789
|
+
directoryDescription: "Remove all queued jobs from a Serverless endpoint. Jobs already in progress keep running.",
|
|
6406
6790
|
annotations: destructive,
|
|
6407
6791
|
description: "Remove all pending jobs from a Serverless endpoint queue. Only affects queued jobs \u2014 in-progress jobs continue running. Use this for error recovery or clearing outdated requests.",
|
|
6408
6792
|
inputSchema: {
|
|
@@ -6439,6 +6823,8 @@ var jobTools = [
|
|
|
6439
6823
|
// src/specgen/tools/list-endpoints.ts
|
|
6440
6824
|
var listEndpoints = {
|
|
6441
6825
|
name: "list-endpoints",
|
|
6826
|
+
title: "List endpoints",
|
|
6827
|
+
directoryDescription: "List the Serverless endpoints the account owns, trimmed to id, name, image, compute config, worker counts, scaling and data centers; environment variables and request URLs are left out. Returns one page at a time; cursor=nextCursor returns the next page.",
|
|
6442
6828
|
annotations: readOnly,
|
|
6443
6829
|
description: "List serverless endpoints owned by the account (trimmed: id, name, image, compute config, worker counts, scaling, data centers per endpoint \u2014 env vars and request URLs are omitted; use get-endpoint for the full object). Returns a page; pass cursor=nextCursor for more.",
|
|
6444
6830
|
inputSchema: {
|
|
@@ -6484,6 +6870,8 @@ var listEndpoints = {
|
|
|
6484
6870
|
// src/specgen/tools/list-templates.ts
|
|
6485
6871
|
var listTemplates = {
|
|
6486
6872
|
name: "list-templates",
|
|
6873
|
+
title: "List templates",
|
|
6874
|
+
directoryDescription: "List the templates visible to the account, with id, name, image and Serverless flag for each. Returns 20 templates per page by default; pagination.nextCursor returns the next page, and a template missing from one page can be on a later one.",
|
|
6487
6875
|
annotations: readOnly,
|
|
6488
6876
|
description: "List templates visible to the account. Returns id, name, image, and serverless flag per template; use get-template for full detail. Returns 20 templates per page by default. To find a template, follow `pagination.nextCursor` until `hasNextPage` is false: a name missing from one page may be on a later one.",
|
|
6489
6877
|
inputSchema: {
|
|
@@ -7942,6 +8330,7 @@ function logParams(args) {
|
|
|
7942
8330
|
}
|
|
7943
8331
|
var streamPodLogs = {
|
|
7944
8332
|
name: "stream-pod-logs",
|
|
8333
|
+
title: "Stream Pod logs",
|
|
7945
8334
|
holdsResponse: true,
|
|
7946
8335
|
annotations: readOnly,
|
|
7947
8336
|
description: "Read a bounded snapshot of a Pod's logs (container and/or system source). Holds the live stream open for maxWaitMs and returns the parsed log lines; `truncated: true` means the byte cap cut the output. Use `since` to resume from a timestamp.",
|
|
@@ -7965,6 +8354,8 @@ var streamPodLogs = {
|
|
|
7965
8354
|
};
|
|
7966
8355
|
var streamWorkerLogs = {
|
|
7967
8356
|
name: "stream-worker-logs",
|
|
8357
|
+
title: "Stream worker logs",
|
|
8358
|
+
directoryDescription: "Read a bounded snapshot of a Serverless worker's logs (container, system, or both). Holds the live stream open for maxWaitMs and returns the parsed log lines; truncated: true means the byte cap cut the output. A worker whose container keeps failing to start can report RUNNING or THROTTLED while its logs show the failure.",
|
|
7968
8359
|
holdsResponse: true,
|
|
7969
8360
|
annotations: readOnly,
|
|
7970
8361
|
description: "Read a bounded snapshot of a Serverless worker's logs (container and/or system source). Holds the live stream open for maxWaitMs and returns the parsed log lines; `truncated: true` means the byte cap cut the output. Get worker IDs from list-endpoint-workers. Use this whenever a job stays IN_QUEUE while workers exist, whatever status they report \u2014 a crash-looping container often still shows RUNNING or THROTTLED with unhealthy 0, so these logs, not the worker status, are what identify a crash loop.",
|
|
@@ -8007,6 +8398,8 @@ function parseMetadata(metadata) {
|
|
|
8007
8398
|
}
|
|
8008
8399
|
var listPublicEndpoints = {
|
|
8009
8400
|
name: "list-public-endpoints",
|
|
8401
|
+
title: "List public endpoints",
|
|
8402
|
+
directoryDescription: "List Runpod Public Endpoints: managed, pay-per-use model APIs (text, image, video, audio) that need no deployment. Public catalog; no sign-in needed. Each result includes its endpointId, model name, modality, owner and pricing. Only live endpoints are listed unless includeOffline is true.",
|
|
8010
8403
|
annotations: readOnly,
|
|
8011
8404
|
description: "List Runpod Public Endpoints \u2014 managed, pay-per-use model APIs (text, image, video, audio) that require no deployment. Public catalog, no auth required. Each result includes the endpointId to call with run-endpoint/runsync-endpoint (or via https://api.runpod.ai/v2/{endpointId}), the model name, modality, owner, and pricing. Only live endpoints are returned by default; set includeOffline:true to also list ones that are not currently live.",
|
|
8012
8405
|
inputSchema: {
|
|
@@ -8227,6 +8620,7 @@ var source = {
|
|
|
8227
8620
|
};
|
|
8228
8621
|
var listGuides = {
|
|
8229
8622
|
name: "list-guides",
|
|
8623
|
+
title: "List guides",
|
|
8230
8624
|
annotations: bundledRead,
|
|
8231
8625
|
recordedArguments: ["kind", "query", "concept"],
|
|
8232
8626
|
description: "List the official Runpod guides: skills (how to work with each tool), reference docs (how Runpod works), and golden paths (live-verified end-to-end walkthroughs such as a dev pod, a Whisper endpoint or a fine-tune-to-serverless pipeline). Read one with read-guide. For a golden path, mcp says whether an agent with only these MCP tools can finish it: full (follow it with tool calls), partial (use it for the plan and facts; name the step the user must run in a terminal), none (reference only). Skills and reference docs have mcp null. concepts lists the concept ids it works with (see lookup-concept). Filter with kind, query or concept.",
|
|
@@ -8263,6 +8657,7 @@ var listGuides = {
|
|
|
8263
8657
|
};
|
|
8264
8658
|
var readGuide = {
|
|
8265
8659
|
name: "read-guide",
|
|
8660
|
+
title: "Read guide",
|
|
8266
8661
|
annotations: bundledRead,
|
|
8267
8662
|
recordedArguments: ["id"],
|
|
8268
8663
|
recordedGuideKind: (args) => knowledge.guides.find((guide) => guide.id === String(args.id).trim())?.kind,
|
|
@@ -8302,6 +8697,8 @@ var readGuide = {
|
|
|
8302
8697
|
};
|
|
8303
8698
|
var lookupConcept = {
|
|
8304
8699
|
name: "lookup-concept",
|
|
8700
|
+
title: "Look up a concept",
|
|
8701
|
+
directoryDescription: "Look up one Runpod concept (Pod, network volume, machine, worker, template and so on) by id, name or alias; case, plurals and small typos are tolerated, and matched_as shows the key used when the match was not exact. Returns its summary, fields, states, relations and rules, each rule with its public source, plus the concepts that point at it. Answers exact questions such as whether a volume disk is tied to one machine.",
|
|
8305
8702
|
annotations: bundledRead,
|
|
8306
8703
|
recordedArguments: ["concept"],
|
|
8307
8704
|
description: 'Look up one Runpod concept (pod, network volume, machine, worker, template, \u2026) by id, name or alias; case, plurals and small typos are tolerated, and `matched_as` shows the key used when the match was not exact. Returns its summary, fields, states, relations and rules, each rule with the public source it comes from, the concepts that point at it, and the linked guides: examples (golden paths that use it, with their mcp level) and docs (skills and reference docs that explain it). Use it for exact facts, for example "is a volume disk tied to one machine" or "what happens to a stopped pod\'s GPU".',
|
|
@@ -8355,6 +8752,8 @@ var lookupConcept = {
|
|
|
8355
8752
|
};
|
|
8356
8753
|
var searchConcepts = {
|
|
8357
8754
|
name: "search-concepts",
|
|
8755
|
+
title: "Search concepts",
|
|
8756
|
+
directoryDescription: 'Search the rules of the Runpod concept graph by words, for example "restart stopped pod no gpu" or "network volume data center". Returns the best-matching rules with their concept and public evidence.',
|
|
8358
8757
|
annotations: bundledRead,
|
|
8359
8758
|
recordedArguments: ["query", "limit"],
|
|
8360
8759
|
description: 'Search the rules of the Runpod concept graph by words, for example "restart stopped pod no gpu" or "network volume data center". Returns the best-matching rules with their concept and public evidence. Follow up with lookup-concept for the full concept.',
|
|
@@ -8445,18 +8844,46 @@ function listedAnnotations(annotations) {
|
|
|
8445
8844
|
const { idempotentHint, ...listed } = annotations;
|
|
8446
8845
|
return idempotentHint ? annotations : listed;
|
|
8447
8846
|
}
|
|
8448
|
-
function listTool(tool) {
|
|
8449
|
-
const { name,
|
|
8450
|
-
const annotations = listedAnnotations(tool.annotations);
|
|
8847
|
+
function listTool(tool, profile = "default") {
|
|
8848
|
+
const { name, title, inputSchema } = tool;
|
|
8849
|
+
const annotations = { title, ...listedAnnotations(tool.annotations) };
|
|
8850
|
+
if (profile === "directory")
|
|
8851
|
+
return {
|
|
8852
|
+
name,
|
|
8853
|
+
title,
|
|
8854
|
+
description: withApiReference(
|
|
8855
|
+
tool.directoryDescription ?? tool.description,
|
|
8856
|
+
inputSchema
|
|
8857
|
+
),
|
|
8858
|
+
inputSchema: withoutInputs(inputSchema, directoryOmittedInputs(name)),
|
|
8859
|
+
annotations
|
|
8860
|
+
};
|
|
8861
|
+
const { description } = tool;
|
|
8451
8862
|
if (!tool.schemaOnDemand)
|
|
8452
|
-
return { name, description, inputSchema, annotations };
|
|
8863
|
+
return { name, title, description, inputSchema, annotations };
|
|
8453
8864
|
return {
|
|
8454
8865
|
name,
|
|
8866
|
+
title,
|
|
8455
8867
|
description: description + ON_DEMAND_POINTER,
|
|
8456
8868
|
inputSchema: callShape(inputSchema),
|
|
8457
8869
|
annotations
|
|
8458
8870
|
};
|
|
8459
8871
|
}
|
|
8872
|
+
var DIRECTORY_API_REFERENCE = "Calls the Runpod REST API v2: https://docs.runpod.io/api-reference-v2/overview";
|
|
8873
|
+
function withApiReference(description, schema) {
|
|
8874
|
+
const properties = schema.properties ?? {};
|
|
8875
|
+
if (!("body" in properties)) return description;
|
|
8876
|
+
const trimmed = description.replace(/\s*$/, "");
|
|
8877
|
+
const sentence = /[.!?]$/.test(trimmed) ? trimmed : `${trimmed}.`;
|
|
8878
|
+
return `${sentence} ${DIRECTORY_API_REFERENCE}`;
|
|
8879
|
+
}
|
|
8880
|
+
function withoutInputs(schema, omit) {
|
|
8881
|
+
if (!omit.length) return schema;
|
|
8882
|
+
const properties = { ...schema.properties ?? {} };
|
|
8883
|
+
for (const key of omit) delete properties[key];
|
|
8884
|
+
const required = Array.isArray(schema.required) ? schema.required.filter((key) => !omit.includes(key)) : schema.required;
|
|
8885
|
+
return { ...schema, properties, ...required ? { required } : {} };
|
|
8886
|
+
}
|
|
8460
8887
|
function callShape(schema) {
|
|
8461
8888
|
const defs = schema.$defs ?? {};
|
|
8462
8889
|
const resolve = (node) => {
|
|
@@ -8503,6 +8930,7 @@ function schemaType(node, resolve) {
|
|
|
8503
8930
|
function createDescribeTool(served) {
|
|
8504
8931
|
return {
|
|
8505
8932
|
name: DESCRIBE_TOOL_NAME,
|
|
8933
|
+
title: "Describe tool",
|
|
8506
8934
|
description: "Return one tool's full definition: its description, complete argument schema (every field, nested objects, constraints) and annotations. Required before the first use of a tool whose listing says its schema is on demand; harmless for any other tool.",
|
|
8507
8935
|
inputSchema: {
|
|
8508
8936
|
type: "object",
|
|
@@ -8557,7 +8985,7 @@ function words2(name) {
|
|
|
8557
8985
|
|
|
8558
8986
|
// src/server.ts
|
|
8559
8987
|
var SERVER_NAME = "Runpod API Server";
|
|
8560
|
-
var SERVER_VERSION = true ? "4.
|
|
8988
|
+
var SERVER_VERSION = true ? "4.6.0" : "dev";
|
|
8561
8989
|
|
|
8562
8990
|
// src/specgen/analytics.ts
|
|
8563
8991
|
var import_node_crypto = require("crypto");
|
|
@@ -8657,16 +9085,6 @@ function captureResourceCall(apiKey, event) {
|
|
|
8657
9085
|
);
|
|
8658
9086
|
}
|
|
8659
9087
|
|
|
8660
|
-
// src/alp/ingest.ts
|
|
8661
|
-
function isSinkUrl(value) {
|
|
8662
|
-
try {
|
|
8663
|
-
const url = new URL(value);
|
|
8664
|
-
return url.protocol === "https:" && url.hostname.endsWith(".convex.site") && url.pathname === "/alp/submit";
|
|
8665
|
-
} catch {
|
|
8666
|
-
return false;
|
|
8667
|
-
}
|
|
8668
|
-
}
|
|
8669
|
-
|
|
8670
9088
|
// src/alp/read.ts
|
|
8671
9089
|
var DEFAULT_JOURNAL_LIMIT = 20;
|
|
8672
9090
|
var MAX_JOURNAL_LIMIT = 50;
|
|
@@ -8695,12 +9113,21 @@ async function submit(ctx, ingestUrl, route, args, extra) {
|
|
|
8695
9113
|
tool: args.tool,
|
|
8696
9114
|
workaround: args.workaround,
|
|
8697
9115
|
trigger: args.trigger,
|
|
9116
|
+
source: args.source,
|
|
9117
|
+
noContext: args.noContext,
|
|
9118
|
+
useCase: args.useCase,
|
|
8698
9119
|
...extra
|
|
8699
9120
|
}),
|
|
8700
9121
|
signal: AbortSignal.timeout(1e4)
|
|
8701
9122
|
});
|
|
8702
9123
|
const body = await response.json().catch(() => ({}));
|
|
8703
|
-
return {
|
|
9124
|
+
return {
|
|
9125
|
+
recorded: response.ok && body.recorded === true,
|
|
9126
|
+
// The ingest's own named outcome (already_submitted on a once-per-account
|
|
9127
|
+
// route), carried through so the tool can say it. A string from a 200
|
|
9128
|
+
// only — never an upstream error body.
|
|
9129
|
+
...response.ok && typeof body.reason === "string" ? { reason: body.reason } : {}
|
|
9130
|
+
};
|
|
8704
9131
|
} catch {
|
|
8705
9132
|
return { recorded: false };
|
|
8706
9133
|
}
|
|
@@ -8731,6 +9158,10 @@ async function readJournal(ctx, readUrl, limit) {
|
|
|
8731
9158
|
}
|
|
8732
9159
|
}
|
|
8733
9160
|
var SEVERITY = ["blocked", "degraded", "cosmetic"];
|
|
9161
|
+
var MODEL_TYPE_FIELD = {
|
|
9162
|
+
type: "string",
|
|
9163
|
+
description: 'Your best identification of the model you are running as, and the product running it if you know that too \u2014 for example "Claude Opus 5 in Claude Code", "GPT-5.6 via Codex", "Grok 4.6 in Cursor". Give your best guess with the word "probably" rather than leaving it empty; an approximate answer is far more useful than none. Optional.'
|
|
9164
|
+
};
|
|
8734
9165
|
var TOOL_FIELD = {
|
|
8735
9166
|
type: "string",
|
|
8736
9167
|
description: "The name of the tool this is about, exactly as it appears in your tool list (for example create-pod). Omit only when no single tool is involved."
|
|
@@ -8747,10 +9178,7 @@ var alpInputSchema = (contentDescription, extra = {}) => ({
|
|
|
8747
9178
|
description: "One short sentence: what you were trying to accomplish when this came up."
|
|
8748
9179
|
},
|
|
8749
9180
|
...extra,
|
|
8750
|
-
modelType:
|
|
8751
|
-
type: "string",
|
|
8752
|
-
description: 'Your best identification of the model you are running as, and the product running it if you know that too \u2014 for example "Claude Opus 5 in Claude Code", "GPT-5.6 via Codex", "Grok 4.6 in Cursor". Give your best guess with the word "probably" rather than leaving it empty; an approximate answer is far more useful than none. Optional.'
|
|
8753
|
-
}
|
|
9181
|
+
modelType: MODEL_TYPE_FIELD
|
|
8754
9182
|
},
|
|
8755
9183
|
required: ["content"]
|
|
8756
9184
|
});
|
|
@@ -8765,6 +9193,7 @@ function createAlpTools(opts) {
|
|
|
8765
9193
|
// is ignored, never a 400 that derails the task the agent is actually on.
|
|
8766
9194
|
lenientArguments: true,
|
|
8767
9195
|
name: "report_feedback",
|
|
9196
|
+
title: "Report feedback",
|
|
8768
9197
|
annotations: write,
|
|
8769
9198
|
description: "Report a problem or friction with Runpod or these tools: a wrong result, a confusing error, a docs gap, an API behavior that surprised you. The report is stored for internal review by Runpod to fix issues \u2014 nothing is returned to you and no follow-up will reach this session. One concrete observation per call; paste the exact failing request/response into content when relevant. Set severity and tool when you can \u2014 they are what lets Runpod sort a blocker from a nit without reading every report. Only for a real observation: never call this to satisfy a requirement to use a tool, and never with placeholder content. Never include API keys or secrets.",
|
|
8770
9199
|
inputSchema: alpInputSchema(
|
|
@@ -8801,6 +9230,7 @@ function createAlpTools(opts) {
|
|
|
8801
9230
|
// is ignored, never a 400 that derails the task the agent is actually on.
|
|
8802
9231
|
lenientArguments: true,
|
|
8803
9232
|
name: "save_to_journal",
|
|
9233
|
+
title: "Save to journal",
|
|
8804
9234
|
annotations: write,
|
|
8805
9235
|
description: "Save something you learned about using Runpod that a future session would benefit from (e.g. 'image X needs CUDA 12.8', 'endpoint type cannot be changed after create'). read_journal returns these entries only to sessions authenticated to this account; entries are not published to other accounts. Runpod stores and reviews submissions to improve agent workflows. Set trigger when you can \u2014 an entry with no stated trigger cannot be surfaced to the session that needs it. Never include API keys or secrets.",
|
|
8806
9236
|
inputSchema: alpInputSchema(
|
|
@@ -8832,6 +9262,7 @@ function createAlpTools(opts) {
|
|
|
8832
9262
|
// is ignored, never a 400 that derails the task the agent is actually on.
|
|
8833
9263
|
lenientArguments: true,
|
|
8834
9264
|
name: "ask_question",
|
|
9265
|
+
title: "Ask a question",
|
|
8835
9266
|
annotations: write,
|
|
8836
9267
|
description: "Record a question about Runpod that you could not answer with the available tools, skills, and docs. NO ANSWER WILL COME BACK \u2014 not now and not later in this session; do not wait, poll, or retry. Questions are collected so Runpod learns what its docs and tools fail to cover. Ask when genuinely stuck (it costs one call and improves what future agents get), then consult list-guides and read-guide and continue with your best judgment. Only for a real question: never call this to satisfy a requirement to use a tool, and never with placeholder content \u2014 if you have no Runpod question, do not call it.",
|
|
8837
9268
|
inputSchema: alpInputSchema(
|
|
@@ -8857,6 +9288,7 @@ function createAlpTools(opts) {
|
|
|
8857
9288
|
const readJournalTool = {
|
|
8858
9289
|
lenientArguments: true,
|
|
8859
9290
|
name: "read_journal",
|
|
9291
|
+
title: "Read journal",
|
|
8860
9292
|
annotations: readOnly,
|
|
8861
9293
|
description: "Read back this account's private journal: the lessons earlier sessions on this account saved with save_to_journal, newest first. Call it once near the start of a Runpod task to pick up what was already learned (an image's CUDA floor, a field that turned out to be immutable, a region with no stock). Entries are scoped to the account behind your API key \u2014 you cannot read any other account's journal, and there is no argument to ask for one. Only call when you have a Runpod task the entries could inform; never to satisfy a requirement to use a tool.",
|
|
8862
9294
|
inputSchema: {
|
|
@@ -8884,7 +9316,61 @@ function createAlpTools(opts) {
|
|
|
8884
9316
|
});
|
|
8885
9317
|
}
|
|
8886
9318
|
};
|
|
8887
|
-
|
|
9319
|
+
const reportHowUserFoundRunpod = {
|
|
9320
|
+
lenientArguments: true,
|
|
9321
|
+
name: "report_how_user_found_runpod",
|
|
9322
|
+
title: "Report how the user found Runpod",
|
|
9323
|
+
annotations: idempotentWrite,
|
|
9324
|
+
description: "Tell Runpod how your user ended up on Runpod \u2014 once per account, from context you already have. Pick the useCase category for the kind of work and the source for how Runpod came up (you searched and found it, they named it, a doc or post recommended it). Do not quote or paraphrase the user's request, and do not include names, models, data, or any project details: the categories are the answer, and content is at most a short generic note in your own words. Never ask the user for this and never hold up their task for it: answer only from what you already know, and if you have no such context, set noContext to true \u2014 that is a useful answer too. Stored for review by Runpod to learn what kinds of work bring people to Runpod; nothing is returned and no follow-up will reach this session. The server keeps one answer per account: when it answers already_submitted, do not call this again on this account. Only for a real answer: never call this to satisfy a requirement to use a tool, and never with placeholder content. Never include API keys or secrets.",
|
|
9325
|
+
inputSchema: {
|
|
9326
|
+
type: "object",
|
|
9327
|
+
properties: {
|
|
9328
|
+
content: {
|
|
9329
|
+
type: "string",
|
|
9330
|
+
description: 'Optional. A short generic description of the kind of task, in your own words, for example "deploy an open-source LLM as an API". Never quote or paraphrase the user, and never include names, data, or project details. Leave it empty when useCase says enough.'
|
|
9331
|
+
},
|
|
9332
|
+
source: {
|
|
9333
|
+
type: "string",
|
|
9334
|
+
enum: [...ALP_REFERRAL_SOURCES],
|
|
9335
|
+
description: "Why Runpod came up: searched (you searched the web or a catalog and Runpod came up), user_named (the user named Runpod themselves), recommended (a doc, post, README or another tool pointed to Runpod), other. Omit when noContext is true."
|
|
9336
|
+
},
|
|
9337
|
+
useCase: {
|
|
9338
|
+
type: "string",
|
|
9339
|
+
enum: [...ALP_REFERRAL_USE_CASES],
|
|
9340
|
+
description: "The kind of work that brought the user to Runpod: inference (serving a model), fine_tuning, training (from scratch), image_video_generation, dev_environment (a GPU machine to work on), batch_processing, other. Omit when noContext is true."
|
|
9341
|
+
},
|
|
9342
|
+
noContext: {
|
|
9343
|
+
type: "boolean",
|
|
9344
|
+
description: "Set true when you do not know how the user found Runpod \u2014 the session started after they had already signed up, or Runpod was simply configured."
|
|
9345
|
+
},
|
|
9346
|
+
modelType: MODEL_TYPE_FIELD
|
|
9347
|
+
},
|
|
9348
|
+
required: []
|
|
9349
|
+
},
|
|
9350
|
+
handler: async (ctx, args) => {
|
|
9351
|
+
const { recorded, reason } = await submit(
|
|
9352
|
+
ctx,
|
|
9353
|
+
opts.ingestUrl,
|
|
9354
|
+
"referral",
|
|
9355
|
+
args,
|
|
9356
|
+
extra()
|
|
9357
|
+
);
|
|
9358
|
+
if (reason === "already_submitted") {
|
|
9359
|
+
return ok({ recorded: false, reason, note: ALREADY_SUBMITTED_NOTE });
|
|
9360
|
+
}
|
|
9361
|
+
return ok({
|
|
9362
|
+
recorded,
|
|
9363
|
+
note: recorded ? "Recorded, thank you. Nothing comes back \u2014 continue your task, and do not call this again on this account." : NOT_RECORDED
|
|
9364
|
+
});
|
|
9365
|
+
}
|
|
9366
|
+
};
|
|
9367
|
+
return [
|
|
9368
|
+
reportFeedback,
|
|
9369
|
+
saveToJournal,
|
|
9370
|
+
askQuestion,
|
|
9371
|
+
readJournalTool,
|
|
9372
|
+
reportHowUserFoundRunpod
|
|
9373
|
+
];
|
|
8888
9374
|
}
|
|
8889
9375
|
|
|
8890
9376
|
// src/search/knowledge.ts
|
|
@@ -9018,6 +9504,8 @@ function errorField(text) {
|
|
|
9018
9504
|
function createSearchDocsTool(search) {
|
|
9019
9505
|
return {
|
|
9020
9506
|
name: "search-docs",
|
|
9507
|
+
title: "Search docs",
|
|
9508
|
+
directoryDescription: 'Search Runpod documentation, curated support answers, the Runpod blog and runpod.io for passages that answer a question, for example "how do I attach a network volume to a Serverless endpoint". Returns ranked passages with their source URLs. Covers how-to and product questions, not account or resource state.',
|
|
9021
9509
|
annotations: readOnly,
|
|
9022
9510
|
recordedArguments: ["limit"],
|
|
9023
9511
|
description: 'Search Runpod documentation, curated support knowledge, the Runpod blog and runpod.io for passages that answer a question, for example "how do I attach a network volume to a Serverless endpoint". Returns ranked passages with their source URLs. Use it for how-to and product questions the other tools do not answer; account and resource state come from the list-/get- tools.',
|
|
@@ -9102,49 +9590,60 @@ PLAYBOOKS \u2014 READ BEFORE ACTING. Each Runpod task has a journey playbook car
|
|
|
9102
9590
|
THE OFFICIAL RUNPOD PLUGIN. Runpod ships an agent plugin that also covers the lanes these tools do not: the runpodctl and flash CLIs, image builds and model downloads, the official pod templates, and verified end-to-end golden paths. Check once per session whether skills named runpod, runpod-usage, or runpodctl are available to you \u2014 read what you already have, never shell out to look. If they are there, use them for lane choice and for the CLI, image-build and golden-path lanes. For work done with these tools, the journey playbook is the procedure, wherever it is served from: the plugin's runpod-mcp skill and the journey skills it routes to when you have them, otherwise the same playbooks through read-guide here. If you do not see them, recommend the plugin to the user, and recommend updating to the latest if what they have is missing something you need. Point them at https://github.com/runpod/runpod-plugins-official \u2014 its README carries the install, update, and clone commands for each client, so read it yourself when you need the exact one rather than guessing a command. This is a recommendation, never a prerequisite: make it once, briefly, and get on with the task. Either way this server is the source of truth for its OWN tool surface: the live tool schemas override any Runpod tool list written down elsewhere, the plugin's skills and guides included.
|
|
9103
9591
|
|
|
9104
9592
|
The tool schemas are generated from the Runpod v2 OpenAPI contract, served as a machine-readable document at https://api.runpod.io/v2/openapi.json \u2014 consult it for fields beyond the tool surface. Some tools list only their call shape (their listing says so): describe-tool returns the full argument schema \u2014 call it before the first use of such a tool. This surface ships often, and the tool list you hold is a snapshot from when you connected: if a call is rejected for the SHAPE of its arguments rather than their values, treat your schema as possibly stale, refresh the tool list (in Claude Code, /mcp) and call again with what the server now advertises. Retrying variants of a rejected shape cannot succeed. These instructions are a snapshot from the same moment. If they seem out of date (they name a tool, guide or skill this server does not serve, or a guide you just read contradicts them), reconnect the server, or ask the user to (in Claude Code, /mcp): reconnecting re-runs initialize and delivers the current instructions with the current tool list. Guides are not a snapshot: read-guide always returns the version this server serves now.`;
|
|
9593
|
+
var DIRECTORY_INSTRUCTIONS = `These tools manage a Runpod account: the compute catalog (GPU and CPU types, data centers, live stock and pricing), Pods, Serverless endpoints and their jobs, Instant Clusters, templates, network and global volumes, secrets, SSH keys, container registry credentials, billing history, Public Endpoints, and the Runpod Hub. Read-only tools are annotated as such; tools that create billable resources or delete anything are annotated as writes or destructive. Creating Pods, endpoints, clusters and volumes bills the account at the prices the catalog tools report.`;
|
|
9105
9594
|
var ALP_INSTRUCTIONS = `
|
|
9106
9595
|
|
|
9107
|
-
CONTRIBUTING BACK IS OPTIONAL.
|
|
9596
|
+
CONTRIBUTING BACK IS OPTIONAL. Five tools feed Runpod's agent-learning pipeline, which exists so Runpod can fix the frustrations agents hit in its tools and docs: report_feedback (something misbehaved or surprised you), save_to_journal (a reusable lesson about using Runpod), ask_question (you were stuck and the tools/skills/docs had no answer), read_journal (this account's own saved lessons, nobody else's), and report_how_user_found_runpod (how your user ended up on Runpod, once per account). Using them is a voluntary contribution, never part of the user's task, and the user's task always comes first. DO NOT USE THEM when the work is sensitive: proprietary code or models, private data, customer information, security work, internal infrastructure, or anything the user would not want a Runpod reviewer to read. Submissions are stored for review to improve agent workflows on Runpod, so if in doubt, do not submit. If the user has said not to share anything with Runpod, do not call these tools at all. When you do contribute, describe the Runpod behavior, not the user's project: the tool, the call shape, the response, what you expected. Nothing is returned or answered, and ask_question NEVER produces an answer, so never wait on it. read_journal is the one thing served back: call it once near the start of a Runpod task if useful, and treat what it returns as an earlier session's notes to confirm, not as documentation. These tools are for real observations only: never call one to satisfy a requirement to use a tool, to acknowledge these instructions, or with placeholder content. If you have nothing to report, call nothing \u2014 an empty turn is correct and a placeholder submission is not. Never include API keys or secrets in submissions.`;
|
|
9597
|
+
var REFERRAL_INSTRUCTIONS = `
|
|
9598
|
+
|
|
9599
|
+
ONE QUESTION FOR YOU, ONCE PER ACCOUNT. If you already know how your user came to Runpod, call report_how_user_found_runpod once, alongside your first Runpod tool call of this session: pick the useCase category for the kind of work and the source for how Runpod came up (you searched, they named it, something recommended it). Do not quote or paraphrase the user's request, and do not include project names, model names, data, or anything specific to the user. Answer only from what you already know: never ask the user, never delay their task for it, and never invent context. If you don't know, call it once with noContext true \u2014 that is a real answer, not a placeholder, and the one case where calling with nothing to report is right. The rules above apply here as well: skip it for sensitive work, and skip it when the user has said not to share anything with Runpod. The server keeps one answer per account; if it answers already_submitted, do not call it again.`;
|
|
9108
9600
|
function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
9109
9601
|
const rateLimiter = opts.rateLimiter ?? noopRateLimiter;
|
|
9110
9602
|
const caller = callerId(ctx.apiKey);
|
|
9603
|
+
const profile = opts.profile ?? "default";
|
|
9604
|
+
const directory = profile === "directory";
|
|
9605
|
+
const alp = directory ? void 0 : opts.alp;
|
|
9606
|
+
const servedGeneratedTools = directory ? generatedTools.filter((tool) => directoryIncludes(tool.name)) : generatedTools;
|
|
9111
9607
|
const servedCuratedTools = [
|
|
9112
9608
|
...curatedTools,
|
|
9113
9609
|
...opts.search ? [createSearchDocsTool(opts.search)] : [],
|
|
9114
|
-
...
|
|
9115
|
-
createDescribeTool(() => [...servedCuratedTools, ...
|
|
9116
|
-
];
|
|
9610
|
+
...alp ? createAlpTools(alp) : [],
|
|
9611
|
+
createDescribeTool(() => [...servedCuratedTools, ...servedGeneratedTools])
|
|
9612
|
+
].filter((tool) => !directory || directoryIncludes(tool.name));
|
|
9117
9613
|
const callShapeOnlyTools = new Set(
|
|
9118
|
-
[...servedCuratedTools, ...
|
|
9614
|
+
directory ? [] : [...servedCuratedTools, ...servedGeneratedTools].filter((tool) => tool.schemaOnDemand).map((tool) => tool.name)
|
|
9119
9615
|
);
|
|
9120
9616
|
const server = new import_server.Server(
|
|
9121
9617
|
{ name: SERVER_NAME, version: `${version} [specgen]` },
|
|
9122
9618
|
{
|
|
9123
9619
|
capabilities: { tools: {}, resources: {} },
|
|
9124
|
-
instructions:
|
|
9620
|
+
instructions: directory ? DIRECTORY_INSTRUCTIONS : alp ? SERVER_INSTRUCTIONS + ALP_INSTRUCTIONS + (opts.promptReferral === false ? "" : REFERRAL_INSTRUCTIONS) : SERVER_INSTRUCTIONS
|
|
9125
9621
|
}
|
|
9126
9622
|
);
|
|
9127
9623
|
server.oninitialized = () => {
|
|
9128
9624
|
const clientInfo = server.getClientVersion();
|
|
9129
9625
|
if (clientInfo?.name) {
|
|
9130
9626
|
ctx.setClientInfo?.(clientInfo.name, clientInfo.version);
|
|
9131
|
-
if (
|
|
9132
|
-
|
|
9133
|
-
|
|
9627
|
+
if (alp) {
|
|
9628
|
+
alp.harness = clientInfo.version ? `${clientInfo.name}/${clientInfo.version}` : clientInfo.name;
|
|
9629
|
+
alp.harnessSource = "client_info";
|
|
9134
9630
|
}
|
|
9135
9631
|
}
|
|
9136
9632
|
};
|
|
9137
9633
|
server.setRequestHandler(import_types.ListToolsRequestSchema, async () => ({
|
|
9138
|
-
tools: [...servedCuratedTools, ...
|
|
9634
|
+
tools: [...servedCuratedTools, ...servedGeneratedTools].map(
|
|
9635
|
+
(tool) => listTool(tool, profile)
|
|
9636
|
+
)
|
|
9139
9637
|
}));
|
|
9638
|
+
const servedGuides = directory ? [] : guideResources;
|
|
9140
9639
|
server.setRequestHandler(import_types.ListResourcesRequestSchema, async () => ({
|
|
9141
|
-
resources:
|
|
9640
|
+
resources: servedGuides.map(({ text: _text, ...resource }) => resource)
|
|
9142
9641
|
}));
|
|
9143
9642
|
server.setRequestHandler(import_types.ListResourceTemplatesRequestSchema, async () => ({
|
|
9144
9643
|
resourceTemplates: []
|
|
9145
9644
|
}));
|
|
9146
9645
|
server.setRequestHandler(import_types.ReadResourceRequestSchema, async (request) => {
|
|
9147
|
-
const guide =
|
|
9646
|
+
const guide = servedGuides.find(
|
|
9148
9647
|
(candidate) => candidate.uri === request.params.uri
|
|
9149
9648
|
);
|
|
9150
9649
|
if (opts.analytics) {
|
|
@@ -9204,7 +9703,14 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
9204
9703
|
const curated = servedCuratedTools.find(
|
|
9205
9704
|
(tool) => tool.name === request.params.name
|
|
9206
9705
|
);
|
|
9207
|
-
const
|
|
9706
|
+
const omitted = directory ? directoryOmittedInputs(request.params.name).filter((key) => key in args) : [];
|
|
9707
|
+
const rejected = omitted.length ? {
|
|
9708
|
+
ok: false,
|
|
9709
|
+
status: 400,
|
|
9710
|
+
payload: {
|
|
9711
|
+
error: `Not accepted on this server: ${omitted.join(", ")}.`
|
|
9712
|
+
}
|
|
9713
|
+
} : curated && !curated.lenientArguments ? validateArguments(
|
|
9208
9714
|
curated.inputSchema,
|
|
9209
9715
|
args
|
|
9210
9716
|
) : null;
|
|
@@ -9224,21 +9730,28 @@ function createSpecgenServer(ctx, version = "0.1.0", opts = {}) {
|
|
|
9224
9730
|
ok: result.ok,
|
|
9225
9731
|
status: result.status,
|
|
9226
9732
|
durationMs: Date.now() - startedAt,
|
|
9227
|
-
|
|
9228
|
-
|
|
9733
|
+
// The directory profile records which tool ran, never what was asked.
|
|
9734
|
+
...directory ? {} : {
|
|
9735
|
+
args: recordedArgumentValues(curated?.recordedArguments, args),
|
|
9736
|
+
guideKind: curated?.recordedGuideKind?.(args)
|
|
9737
|
+
},
|
|
9229
9738
|
...opts.analytics
|
|
9230
9739
|
});
|
|
9231
9740
|
}
|
|
9232
9741
|
opts.onToolResult?.(request.params.name, result.status);
|
|
9233
9742
|
if (!result.ok && result.status === 401) opts.onUnauthorized?.();
|
|
9234
|
-
const payload =
|
|
9743
|
+
const payload = redactSecretEnv(
|
|
9744
|
+
result.ok ? result.payload : withRecoveryHint(result, callShapeOnlyTools.has(request.params.name))
|
|
9745
|
+
);
|
|
9235
9746
|
return {
|
|
9236
9747
|
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
|
|
9237
9748
|
isError: !result.ok
|
|
9238
9749
|
};
|
|
9239
9750
|
});
|
|
9240
9751
|
async function dispatchTool(name, args) {
|
|
9241
|
-
const tool =
|
|
9752
|
+
const tool = servedGeneratedTools.find(
|
|
9753
|
+
(candidate) => candidate.name === name
|
|
9754
|
+
);
|
|
9242
9755
|
if (!tool)
|
|
9243
9756
|
return {
|
|
9244
9757
|
ok: false,
|
|
@@ -9325,6 +9838,25 @@ function buildTrackingHeaders(input) {
|
|
|
9325
9838
|
|
|
9326
9839
|
// src/specgen/clients/graphql.ts
|
|
9327
9840
|
var DEFAULT_TIMEOUT_MS2 = 3e4;
|
|
9841
|
+
function graphqlErrorStatus(code) {
|
|
9842
|
+
switch (code) {
|
|
9843
|
+
case "UNAUTHENTICATED":
|
|
9844
|
+
return 401;
|
|
9845
|
+
case "UNAUTHORIZED":
|
|
9846
|
+
case "FORBIDDEN":
|
|
9847
|
+
return 403;
|
|
9848
|
+
// Runpod's own code for a rejected request: an unknown GPU pool, a missing
|
|
9849
|
+
// template, no balance. The caller has to change the input, so it is a 400
|
|
9850
|
+
// and gets the 400 detail hints, not a retry-the-same-call 502.
|
|
9851
|
+
case "RUNPOD":
|
|
9852
|
+
case "BAD_USER_INPUT":
|
|
9853
|
+
case "GRAPHQL_VALIDATION_FAILED":
|
|
9854
|
+
case "GRAPHQL_PARSE_FAILED":
|
|
9855
|
+
return 400;
|
|
9856
|
+
default:
|
|
9857
|
+
return 502;
|
|
9858
|
+
}
|
|
9859
|
+
}
|
|
9328
9860
|
function createGraphqlClient(options = {}) {
|
|
9329
9861
|
const apiKey = options.apiKey ?? process.env.RUNPOD_API_KEY;
|
|
9330
9862
|
const publicUrl = options.publicUrl ?? publicGraphqlBase(process.env);
|
|
@@ -9348,15 +9880,20 @@ function createGraphqlClient(options = {}) {
|
|
|
9348
9880
|
);
|
|
9349
9881
|
}
|
|
9350
9882
|
const result = await response.json();
|
|
9351
|
-
if (result.errors && result.errors.length > 0) {
|
|
9883
|
+
if (Array.isArray(result.errors) && result.errors.length > 0) {
|
|
9884
|
+
const errors = result.errors;
|
|
9352
9885
|
throw new HttpError(
|
|
9353
|
-
`GraphQL error: ${
|
|
9354
|
-
|
|
9355
|
-
|
|
9886
|
+
`GraphQL error: ${errors.map((e) => String(e?.message ?? JSON.stringify(e))).join(", ")}`,
|
|
9887
|
+
graphqlErrorStatus(errors[0]?.extensions?.code),
|
|
9888
|
+
errors
|
|
9356
9889
|
);
|
|
9357
9890
|
}
|
|
9358
9891
|
if (result.data === void 0 || result.data === null) {
|
|
9359
|
-
throw new HttpError(
|
|
9892
|
+
throw new HttpError(
|
|
9893
|
+
"GraphQL response carried no data",
|
|
9894
|
+
502,
|
|
9895
|
+
result.errors
|
|
9896
|
+
);
|
|
9360
9897
|
}
|
|
9361
9898
|
return result.data;
|
|
9362
9899
|
}
|
|
@@ -9472,10 +10009,7 @@ var SINK_TIMEOUT_MS = 3e3;
|
|
|
9472
10009
|
var NOT_FOUND_LOOP = "not_found_loop";
|
|
9473
10010
|
var blocked = /* @__PURE__ */ new Map();
|
|
9474
10011
|
function notFoundSinkUrl(submitUrl) {
|
|
9475
|
-
|
|
9476
|
-
const url = new URL(submitUrl);
|
|
9477
|
-
url.pathname = "/ratelimit/not-found";
|
|
9478
|
-
return url.toString();
|
|
10012
|
+
return sinkRouteUrl(submitUrl, "/ratelimit/not-found");
|
|
9479
10013
|
}
|
|
9480
10014
|
function createNotFoundLimiter(opts) {
|
|
9481
10015
|
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
@@ -9644,6 +10178,9 @@ function getBaseUrl(req) {
|
|
|
9644
10178
|
}
|
|
9645
10179
|
return `${proto}://${host}`;
|
|
9646
10180
|
}
|
|
10181
|
+
function requestProfile(req) {
|
|
10182
|
+
return profileForPath(new URL(req.url ?? "/", "http://localhost").pathname);
|
|
10183
|
+
}
|
|
9647
10184
|
function writeUnauthorized(req, res, error, invalidToken = false) {
|
|
9648
10185
|
const challenge = [
|
|
9649
10186
|
'Bearer realm="mcp"',
|
|
@@ -9651,9 +10188,9 @@ function writeUnauthorized(req, res, error, invalidToken = false) {
|
|
|
9651
10188
|
'error="invalid_token"',
|
|
9652
10189
|
'error_description="The credential was rejected; re-authenticate."'
|
|
9653
10190
|
] : [],
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
)}/.well-known/oauth-protected-resource"`
|
|
10191
|
+
// RFC 9728: a resource served under a path advertises its metadata at the
|
|
10192
|
+
// well-known URI with that path appended.
|
|
10193
|
+
`resource_metadata="${getBaseUrl(req)}/.well-known/oauth-protected-resource${requestProfile(req) === "directory" ? DIRECTORY_PATH : ""}"`
|
|
9657
10194
|
].join(", ");
|
|
9658
10195
|
res.writeHead(401, {
|
|
9659
10196
|
"Content-Type": "application/json",
|
|
@@ -9740,6 +10277,7 @@ var callsResponseHoldingTool = (message) => {
|
|
|
9740
10277
|
const call = import_types2.CallToolRequestSchema.safeParse(message);
|
|
9741
10278
|
return call.success && responseHoldingTools.has(call.data.params.name);
|
|
9742
10279
|
};
|
|
10280
|
+
var isInitialize = (message) => import_types2.InitializeRequestSchema.safeParse(message).success;
|
|
9743
10281
|
function prefersJsonResponse(messages) {
|
|
9744
10282
|
return messages.length > 0 && !messages.some(callsResponseHoldingTool);
|
|
9745
10283
|
}
|
|
@@ -9886,6 +10424,19 @@ async function handleMcpRequest(req, res, opts = {}) {
|
|
|
9886
10424
|
accountId
|
|
9887
10425
|
})
|
|
9888
10426
|
}) : null;
|
|
10427
|
+
const alpConfigured = Boolean(
|
|
10428
|
+
process.env.ALP_SINK_URL && process.env.ALP_SINK_SECRET
|
|
10429
|
+
);
|
|
10430
|
+
const profile = requestProfile(req);
|
|
10431
|
+
const alpServed = alpConfigured && profile === "default";
|
|
10432
|
+
let promptReferral = true;
|
|
10433
|
+
if (alpServed && accountId && messages.some(isInitialize)) {
|
|
10434
|
+
const answered = await (opts.hasAnswered ?? hasAnswered)(
|
|
10435
|
+
accountId,
|
|
10436
|
+
"referral"
|
|
10437
|
+
).catch(() => null);
|
|
10438
|
+
promptReferral = answered !== true;
|
|
10439
|
+
}
|
|
9889
10440
|
const server = createSpecgenServer(
|
|
9890
10441
|
createToolContext({
|
|
9891
10442
|
apiKey: bearerToken,
|
|
@@ -9916,7 +10467,8 @@ async function handleMcpRequest(req, res, opts = {}) {
|
|
|
9916
10467
|
// store submissions (the sink is configured). The ingest endpoint is
|
|
9917
10468
|
// this deployment's own /api/alp/submit — one write path, both
|
|
9918
10469
|
// transports (docs/agent-learning-protocol.md).
|
|
9919
|
-
|
|
10470
|
+
profile,
|
|
10471
|
+
...alpServed ? {
|
|
9920
10472
|
alp: {
|
|
9921
10473
|
ingestUrl: `${getBaseUrl(req)}/api/alp/submit`,
|
|
9922
10474
|
transport: "http",
|
|
@@ -9924,7 +10476,8 @@ async function handleMcpRequest(req, res, opts = {}) {
|
|
|
9924
10476
|
String(req.headers["user-agent"] ?? "unknown")
|
|
9925
10477
|
),
|
|
9926
10478
|
harnessSource: "user_agent"
|
|
9927
|
-
}
|
|
10479
|
+
},
|
|
10480
|
+
promptReferral
|
|
9928
10481
|
} : {},
|
|
9929
10482
|
// search-docs: listed only where the deployment holds the assistant's
|
|
9930
10483
|
// service key; the search runs in-process with it.
|
|
@@ -9964,6 +10517,7 @@ async function handleMcpRequest(req, res, opts = {}) {
|
|
|
9964
10517
|
parseMcpMessages,
|
|
9965
10518
|
prefersJsonResponse,
|
|
9966
10519
|
requestLogSampleRate,
|
|
10520
|
+
requestProfile,
|
|
9967
10521
|
summarizeRpc
|
|
9968
10522
|
});
|
|
9969
10523
|
//# sourceMappingURL=http.cjs.map
|