@runpod/mcp-server 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +10 -0
- package/dist/{chunk-CRHHCQRI.mjs → chunk-D4AEYJ2O.mjs} +206 -154
- package/dist/chunk-D4AEYJ2O.mjs.map +1 -0
- package/dist/http.cjs +206 -154
- package/dist/http.cjs.map +1 -1
- package/dist/http.mjs +2 -2
- package/dist/stdio.cjs +685 -204
- package/dist/stdio.cjs.map +1 -1
- package/dist/stdio.mjs +262 -200
- package/dist/stdio.mjs.map +1 -1
- package/dist/tools.cjs +205 -153
- package/dist/tools.cjs.map +1 -1
- package/dist/tools.mjs +1 -1
- package/dist/wizard-37ZJSVB5.mjs +402 -0
- package/dist/wizard-37ZJSVB5.mjs.map +1 -0
- package/package.json +4 -1
- package/dist/chunk-CRHHCQRI.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @runpod/mcp-server
|
|
2
2
|
|
|
3
|
+
## 1.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f3ddd6d: Cap list-tool responses so they no longer overflow the agent's context window.
|
|
8
|
+
Every `list-*` tool (`list-pods`, `list-endpoints`, `list-templates`,
|
|
9
|
+
`list-network-volumes`, `list-container-registry-auths`) now accepts optional
|
|
10
|
+
`limit` and `cursor` parameters and returns at most `limit` items (default 20,
|
|
11
|
+
max 100) inside a `{ items, pagination }` envelope that reports `total`,
|
|
12
|
+
`returned`, `truncated`, and a `nextCursor` for fetching the next page.
|
|
13
|
+
|
|
14
|
+
The REST API does not yet support server-side pagination, so this is a
|
|
15
|
+
client-side cap; the `limit`/`cursor` signature is shaped to match the
|
|
16
|
+
cursor-based pagination the REST API will add, so the tool interface will not
|
|
17
|
+
change when server-side pagination lands.
|
|
18
|
+
|
|
19
|
+
- e59fbfe: Add a guided install wizard. Running `npx @runpod/mcp-server@latest add` detects installed agents (Claude Code, Claude Desktop, Cursor, Windsurf, Visual Studio Code), lets you pick which to configure, and writes the MCP configuration for each. It offers two connection modes: a hosted mode that points the agent at the hosted server and authenticates with the "Sign in with Runpod" OAuth flow (no API key stored on disk), and a local mode that runs the server via npx with a `RUNPOD_API_KEY`. `remove` undoes the changes. Existing config files keep their formatting and comments.
|
|
20
|
+
|
|
3
21
|
## 1.3.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -18,6 +18,16 @@ The server never holds a credential of its own and never shares one across users
|
|
|
18
18
|
|
|
19
19
|
## Quick start
|
|
20
20
|
|
|
21
|
+
### Guided install
|
|
22
|
+
|
|
23
|
+
The fastest way to get set up is the interactive installer. It detects the agents you have installed, asks which ones to configure, and writes the configuration for you:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx @runpod/mcp-server@latest add
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
It supports Claude Code, Claude Desktop, Cursor, Windsurf, and Visual Studio Code, and offers two connection modes. The recommended mode points the agent at the hosted server and lets it authenticate with the "Sign in with Runpod" OAuth flow, so no API key is stored on disk. The local mode runs the server through `npx` and stores a `RUNPOD_API_KEY` in the agent's config. To undo the changes later, run `npx @runpod/mcp-server@latest remove`.
|
|
30
|
+
|
|
21
31
|
### Run locally with `npx`
|
|
22
32
|
|
|
23
33
|
```bash
|
|
@@ -1,11 +1,70 @@
|
|
|
1
1
|
// src/tools.ts
|
|
2
|
-
import { z } from "zod";
|
|
2
|
+
import { z as z2 } from "zod";
|
|
3
3
|
import fetch from "node-fetch";
|
|
4
4
|
import { randomUUID } from "crypto";
|
|
5
|
+
|
|
6
|
+
// src/pagination.ts
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
var DEFAULT_LIST_LIMIT = 20;
|
|
9
|
+
var MAX_LIST_LIMIT = 100;
|
|
10
|
+
var listPaginationParams = {
|
|
11
|
+
limit: z.number().int().positive().max(MAX_LIST_LIMIT).optional().describe(
|
|
12
|
+
`Maximum number of items to return (default ${DEFAULT_LIST_LIMIT}, max ${MAX_LIST_LIMIT}). Use the returned nextCursor to fetch the next page.`
|
|
13
|
+
),
|
|
14
|
+
cursor: z.string().optional().describe(
|
|
15
|
+
"Opaque pagination cursor from a previous response (nextCursor). Omit to start from the beginning."
|
|
16
|
+
)
|
|
17
|
+
};
|
|
18
|
+
function decodeCursorOffset(cursor) {
|
|
19
|
+
if (!cursor) return 0;
|
|
20
|
+
try {
|
|
21
|
+
const decoded = Buffer.from(cursor, "base64").toString("utf8");
|
|
22
|
+
const offset = Number.parseInt(decoded, 10);
|
|
23
|
+
return Number.isFinite(offset) && offset >= 0 ? offset : 0;
|
|
24
|
+
} catch {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function encodeCursorOffset(offset) {
|
|
29
|
+
return Buffer.from(String(offset), "utf8").toString("base64");
|
|
30
|
+
}
|
|
31
|
+
function capListResult(result, options) {
|
|
32
|
+
const limit = Math.min(options.limit ?? DEFAULT_LIST_LIMIT, MAX_LIST_LIMIT);
|
|
33
|
+
const offset = decodeCursorOffset(options.cursor);
|
|
34
|
+
if (!Array.isArray(result)) {
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
38
|
+
]
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const total = result.length;
|
|
42
|
+
const page = result.slice(offset, offset + limit);
|
|
43
|
+
const nextOffset = offset + page.length;
|
|
44
|
+
const hasMore = nextOffset < total;
|
|
45
|
+
const envelope = {
|
|
46
|
+
items: page,
|
|
47
|
+
pagination: {
|
|
48
|
+
total,
|
|
49
|
+
returned: page.length,
|
|
50
|
+
offset,
|
|
51
|
+
truncated: hasMore,
|
|
52
|
+
nextCursor: hasMore ? encodeCursorOffset(nextOffset) : null,
|
|
53
|
+
note: hasMore ? `Showing ${page.length} of ${total}. Pass cursor=nextCursor to fetch more, or narrow the query with filters.` : void 0
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
content: [
|
|
58
|
+
{ type: "text", text: JSON.stringify(envelope, null, 2) }
|
|
59
|
+
]
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/tools.ts
|
|
5
64
|
var API_BASE_URL = process.env.RUNPOD_REST_API_URL ?? "https://rest.runpod.io/v1";
|
|
6
65
|
var SERVERLESS_API_BASE_URL = process.env.RUNPOD_SERVERLESS_API_URL ?? "https://api.runpod.ai/v2";
|
|
7
66
|
var GRAPHQL_URL = process.env.RUNPOD_PUBLIC_GRAPHQL_URL ?? "https://api.runpod.io/graphql";
|
|
8
|
-
var MCP_SERVER_VERSION = true ? "1.
|
|
67
|
+
var MCP_SERVER_VERSION = true ? "1.4.0" : "dev";
|
|
9
68
|
var SESSION_ID = randomUUID();
|
|
10
69
|
function sanitizeUaToken(value) {
|
|
11
70
|
return value.replace(/[()<>@,;:\\"/[\]?={}\s]/g, "_").slice(0, 64);
|
|
@@ -115,13 +174,13 @@ function registerTools(server, ctx) {
|
|
|
115
174
|
server.tool(
|
|
116
175
|
"list-gpu-types",
|
|
117
176
|
{
|
|
118
|
-
minMemoryGb:
|
|
119
|
-
secureCloudOnly:
|
|
120
|
-
communityCloudOnly:
|
|
121
|
-
searchTerm:
|
|
177
|
+
minMemoryGb: z2.number().optional().describe("Filter to GPUs with at least this much VRAM in GB"),
|
|
178
|
+
secureCloudOnly: z2.boolean().optional().describe("Filter to only GPUs available in secure cloud"),
|
|
179
|
+
communityCloudOnly: z2.boolean().optional().describe("Filter to only GPUs available in community cloud"),
|
|
180
|
+
searchTerm: z2.string().optional().describe(
|
|
122
181
|
"Search term to filter GPUs by name (e.g., 'A100', 'RTX 4090')"
|
|
123
182
|
),
|
|
124
|
-
includeUnavailable:
|
|
183
|
+
includeUnavailable: z2.boolean().optional().describe(
|
|
125
184
|
"Include GPUs that are currently out of stock. Default is false"
|
|
126
185
|
)
|
|
127
186
|
},
|
|
@@ -201,7 +260,7 @@ function registerTools(server, ctx) {
|
|
|
201
260
|
server.tool(
|
|
202
261
|
"list-data-centers",
|
|
203
262
|
{
|
|
204
|
-
region:
|
|
263
|
+
region: z2.string().optional().describe(
|
|
205
264
|
"Filter by region/location (e.g., 'United States', 'Europe', 'Canada')"
|
|
206
265
|
)
|
|
207
266
|
},
|
|
@@ -238,12 +297,13 @@ function registerTools(server, ctx) {
|
|
|
238
297
|
server.tool(
|
|
239
298
|
"list-pods",
|
|
240
299
|
{
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
300
|
+
...listPaginationParams,
|
|
301
|
+
computeType: z2.enum(["GPU", "CPU"]).optional().describe("Filter to only GPU or only CPU Pods"),
|
|
302
|
+
gpuTypeId: z2.array(z2.string()).optional().describe("Filter to Pods with any of the listed GPU types"),
|
|
303
|
+
dataCenterId: z2.array(z2.string()).optional().describe("Filter to Pods in any of the provided data centers"),
|
|
304
|
+
name: z2.string().optional().describe("Filter to Pods with the provided name"),
|
|
305
|
+
includeMachine: z2.boolean().optional().describe("Include information about the machine"),
|
|
306
|
+
includeNetworkVolume: z2.boolean().optional().describe("Include information about attached network volumes")
|
|
247
307
|
},
|
|
248
308
|
async (params) => {
|
|
249
309
|
const queryParams = new URLSearchParams();
|
|
@@ -267,22 +327,18 @@ function registerTools(server, ctx) {
|
|
|
267
327
|
);
|
|
268
328
|
const queryString = queryParams.toString() ? `?${queryParams.toString()}` : "";
|
|
269
329
|
const result = await runpodRequest(`/pods${queryString}`);
|
|
270
|
-
return {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
text: JSON.stringify(result, null, 2)
|
|
275
|
-
}
|
|
276
|
-
]
|
|
277
|
-
};
|
|
330
|
+
return capListResult(result, {
|
|
331
|
+
limit: params.limit,
|
|
332
|
+
cursor: params.cursor
|
|
333
|
+
});
|
|
278
334
|
}
|
|
279
335
|
);
|
|
280
336
|
server.tool(
|
|
281
337
|
"get-pod",
|
|
282
338
|
{
|
|
283
|
-
podId:
|
|
284
|
-
includeMachine:
|
|
285
|
-
includeNetworkVolume:
|
|
339
|
+
podId: z2.string().describe("ID of the pod to retrieve"),
|
|
340
|
+
includeMachine: z2.boolean().optional().describe("Include information about the machine"),
|
|
341
|
+
includeNetworkVolume: z2.boolean().optional().describe("Include information about attached network volumes")
|
|
286
342
|
},
|
|
287
343
|
async (params) => {
|
|
288
344
|
const queryParams = new URLSearchParams();
|
|
@@ -309,17 +365,17 @@ function registerTools(server, ctx) {
|
|
|
309
365
|
"create-pod",
|
|
310
366
|
'Create a new GPU/CPU pod on Runpod. If the user does not specify an image, recommend the "Runpod Pytorch 2.8.0" image (runpod/pytorch:1.0.2-cu1281-torch280-ubuntu2404) as the default \u2014 it has the most up-to-date CUDA and PyTorch versions.',
|
|
311
367
|
{
|
|
312
|
-
name:
|
|
313
|
-
imageName:
|
|
314
|
-
cloudType:
|
|
315
|
-
gpuTypeIds:
|
|
316
|
-
gpuCount:
|
|
317
|
-
containerDiskInGb:
|
|
318
|
-
volumeInGb:
|
|
319
|
-
volumeMountPath:
|
|
320
|
-
ports:
|
|
321
|
-
env:
|
|
322
|
-
dataCenterIds:
|
|
368
|
+
name: z2.string().optional().describe("Name for the pod"),
|
|
369
|
+
imageName: z2.string().describe("Docker image to use"),
|
|
370
|
+
cloudType: z2.enum(["SECURE", "COMMUNITY"]).optional().describe("SECURE or COMMUNITY cloud"),
|
|
371
|
+
gpuTypeIds: z2.array(z2.string()).optional().describe("List of acceptable GPU types"),
|
|
372
|
+
gpuCount: z2.number().optional().describe("Number of GPUs"),
|
|
373
|
+
containerDiskInGb: z2.number().optional().describe("Container disk size in GB"),
|
|
374
|
+
volumeInGb: z2.number().optional().describe("Volume size in GB"),
|
|
375
|
+
volumeMountPath: z2.string().optional().describe("Path to mount the volume"),
|
|
376
|
+
ports: z2.array(z2.string()).optional().describe("Ports to expose (e.g., '8888/http', '22/tcp')"),
|
|
377
|
+
env: z2.record(z2.string()).optional().describe("Environment variables"),
|
|
378
|
+
dataCenterIds: z2.array(z2.string()).optional().describe("List of data centers")
|
|
323
379
|
},
|
|
324
380
|
async (params) => {
|
|
325
381
|
const result = await runpodRequest("/pods", "POST", params);
|
|
@@ -336,14 +392,14 @@ function registerTools(server, ctx) {
|
|
|
336
392
|
server.tool(
|
|
337
393
|
"update-pod",
|
|
338
394
|
{
|
|
339
|
-
podId:
|
|
340
|
-
name:
|
|
341
|
-
imageName:
|
|
342
|
-
containerDiskInGb:
|
|
343
|
-
volumeInGb:
|
|
344
|
-
volumeMountPath:
|
|
345
|
-
ports:
|
|
346
|
-
env:
|
|
395
|
+
podId: z2.string().describe("ID of the pod to update"),
|
|
396
|
+
name: z2.string().optional().describe("New name for the pod"),
|
|
397
|
+
imageName: z2.string().optional().describe("New Docker image"),
|
|
398
|
+
containerDiskInGb: z2.number().optional().describe("New container disk size in GB"),
|
|
399
|
+
volumeInGb: z2.number().optional().describe("New volume size in GB"),
|
|
400
|
+
volumeMountPath: z2.string().optional().describe("New path to mount the volume"),
|
|
401
|
+
ports: z2.array(z2.string()).optional().describe("New ports to expose"),
|
|
402
|
+
env: z2.record(z2.string()).optional().describe("New environment variables")
|
|
347
403
|
},
|
|
348
404
|
async (params) => {
|
|
349
405
|
const { podId, ...updateParams } = params;
|
|
@@ -365,7 +421,7 @@ function registerTools(server, ctx) {
|
|
|
365
421
|
server.tool(
|
|
366
422
|
"start-pod",
|
|
367
423
|
{
|
|
368
|
-
podId:
|
|
424
|
+
podId: z2.string().describe("ID of the pod to start")
|
|
369
425
|
},
|
|
370
426
|
async (params) => {
|
|
371
427
|
const result = await runpodRequest(`/pods/${params.podId}/start`, "POST");
|
|
@@ -382,7 +438,7 @@ function registerTools(server, ctx) {
|
|
|
382
438
|
server.tool(
|
|
383
439
|
"stop-pod",
|
|
384
440
|
{
|
|
385
|
-
podId:
|
|
441
|
+
podId: z2.string().describe("ID of the pod to stop")
|
|
386
442
|
},
|
|
387
443
|
async (params) => {
|
|
388
444
|
const result = await runpodRequest(`/pods/${params.podId}/stop`, "POST");
|
|
@@ -399,7 +455,7 @@ function registerTools(server, ctx) {
|
|
|
399
455
|
server.tool(
|
|
400
456
|
"delete-pod",
|
|
401
457
|
{
|
|
402
|
-
podId:
|
|
458
|
+
podId: z2.string().describe("ID of the pod to delete")
|
|
403
459
|
},
|
|
404
460
|
async (params) => {
|
|
405
461
|
const result = await runpodRequest(`/pods/${params.podId}`, "DELETE");
|
|
@@ -416,8 +472,9 @@ function registerTools(server, ctx) {
|
|
|
416
472
|
server.tool(
|
|
417
473
|
"list-endpoints",
|
|
418
474
|
{
|
|
419
|
-
|
|
420
|
-
|
|
475
|
+
...listPaginationParams,
|
|
476
|
+
includeTemplate: z2.boolean().optional().describe("Include template information"),
|
|
477
|
+
includeWorkers: z2.boolean().optional().describe("Include information about workers")
|
|
421
478
|
},
|
|
422
479
|
async (params) => {
|
|
423
480
|
const queryParams = new URLSearchParams();
|
|
@@ -430,22 +487,18 @@ function registerTools(server, ctx) {
|
|
|
430
487
|
queryParams.append("includeWorkers", params.includeWorkers.toString());
|
|
431
488
|
const queryString = queryParams.toString() ? `?${queryParams.toString()}` : "";
|
|
432
489
|
const result = await runpodRequest(`/endpoints${queryString}`);
|
|
433
|
-
return {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
text: JSON.stringify(result, null, 2)
|
|
438
|
-
}
|
|
439
|
-
]
|
|
440
|
-
};
|
|
490
|
+
return capListResult(result, {
|
|
491
|
+
limit: params.limit,
|
|
492
|
+
cursor: params.cursor
|
|
493
|
+
});
|
|
441
494
|
}
|
|
442
495
|
);
|
|
443
496
|
server.tool(
|
|
444
497
|
"get-endpoint",
|
|
445
498
|
{
|
|
446
|
-
endpointId:
|
|
447
|
-
includeTemplate:
|
|
448
|
-
includeWorkers:
|
|
499
|
+
endpointId: z2.string().describe("ID of the endpoint to retrieve"),
|
|
500
|
+
includeTemplate: z2.boolean().optional().describe("Include template information"),
|
|
501
|
+
includeWorkers: z2.boolean().optional().describe("Include information about workers")
|
|
449
502
|
},
|
|
450
503
|
async (params) => {
|
|
451
504
|
const queryParams = new URLSearchParams();
|
|
@@ -473,14 +526,14 @@ function registerTools(server, ctx) {
|
|
|
473
526
|
server.tool(
|
|
474
527
|
"create-endpoint",
|
|
475
528
|
{
|
|
476
|
-
name:
|
|
477
|
-
templateId:
|
|
478
|
-
computeType:
|
|
479
|
-
gpuTypeIds:
|
|
480
|
-
gpuCount:
|
|
481
|
-
workersMin:
|
|
482
|
-
workersMax:
|
|
483
|
-
dataCenterIds:
|
|
529
|
+
name: z2.string().optional().describe("Name for the endpoint"),
|
|
530
|
+
templateId: z2.string().describe("Template ID to use"),
|
|
531
|
+
computeType: z2.enum(["GPU", "CPU"]).optional().describe("GPU or CPU endpoint"),
|
|
532
|
+
gpuTypeIds: z2.array(z2.string()).optional().describe("List of acceptable GPU types"),
|
|
533
|
+
gpuCount: z2.number().optional().describe("Number of GPUs per worker"),
|
|
534
|
+
workersMin: z2.number().optional().describe("Minimum number of workers"),
|
|
535
|
+
workersMax: z2.number().optional().describe("Maximum number of workers"),
|
|
536
|
+
dataCenterIds: z2.array(z2.string()).optional().describe("List of data centers")
|
|
484
537
|
},
|
|
485
538
|
async (params) => {
|
|
486
539
|
const result = await runpodRequest("/endpoints", "POST", params);
|
|
@@ -497,13 +550,13 @@ function registerTools(server, ctx) {
|
|
|
497
550
|
server.tool(
|
|
498
551
|
"update-endpoint",
|
|
499
552
|
{
|
|
500
|
-
endpointId:
|
|
501
|
-
name:
|
|
502
|
-
workersMin:
|
|
503
|
-
workersMax:
|
|
504
|
-
idleTimeout:
|
|
505
|
-
scalerType:
|
|
506
|
-
scalerValue:
|
|
553
|
+
endpointId: z2.string().describe("ID of the endpoint to update"),
|
|
554
|
+
name: z2.string().optional().describe("New name for the endpoint"),
|
|
555
|
+
workersMin: z2.number().optional().describe("New minimum number of workers"),
|
|
556
|
+
workersMax: z2.number().optional().describe("New maximum number of workers"),
|
|
557
|
+
idleTimeout: z2.number().optional().describe("New idle timeout in seconds"),
|
|
558
|
+
scalerType: z2.enum(["QUEUE_DELAY", "REQUEST_COUNT"]).optional().describe("Scaler type"),
|
|
559
|
+
scalerValue: z2.number().optional().describe("Scaler value")
|
|
507
560
|
},
|
|
508
561
|
async (params) => {
|
|
509
562
|
const { endpointId, ...updateParams } = params;
|
|
@@ -525,7 +578,7 @@ function registerTools(server, ctx) {
|
|
|
525
578
|
server.tool(
|
|
526
579
|
"delete-endpoint",
|
|
527
580
|
{
|
|
528
|
-
endpointId:
|
|
581
|
+
endpointId: z2.string().describe("ID of the endpoint to delete")
|
|
529
582
|
},
|
|
530
583
|
async (params) => {
|
|
531
584
|
const result = await runpodRequest(
|
|
@@ -542,24 +595,24 @@ function registerTools(server, ctx) {
|
|
|
542
595
|
};
|
|
543
596
|
}
|
|
544
597
|
);
|
|
545
|
-
const endpointIdSchema =
|
|
546
|
-
const jobIdSchema =
|
|
547
|
-
const inputSchema =
|
|
598
|
+
const endpointIdSchema = z2.string().regex(/^[a-zA-Z0-9_-]+$/, "Invalid endpoint ID format");
|
|
599
|
+
const jobIdSchema = z2.string().regex(/^[a-zA-Z0-9_-]+$/, "Invalid job ID format");
|
|
600
|
+
const inputSchema = z2.record(z2.unknown()).describe(
|
|
548
601
|
"Input payload for the worker handler. The expected fields depend on the deployed model or worker."
|
|
549
602
|
);
|
|
550
|
-
const webhookSchema =
|
|
603
|
+
const webhookSchema = z2.string().url().optional().describe(
|
|
551
604
|
"Webhook URL to receive job completion notifications instead of polling"
|
|
552
605
|
);
|
|
553
|
-
const policySchema =
|
|
554
|
-
executionTimeout:
|
|
555
|
-
lowPriority:
|
|
556
|
-
ttl:
|
|
606
|
+
const policySchema = z2.object({
|
|
607
|
+
executionTimeout: z2.number().optional().describe("Maximum execution time in milliseconds"),
|
|
608
|
+
lowPriority: z2.boolean().optional().describe("Submit as a low-priority job"),
|
|
609
|
+
ttl: z2.number().optional().describe("Time-to-live for the job result in milliseconds")
|
|
557
610
|
}).optional().describe("Execution policy options");
|
|
558
|
-
const s3ConfigSchema =
|
|
559
|
-
accessId:
|
|
560
|
-
accessSecret:
|
|
561
|
-
bucketName:
|
|
562
|
-
endpointUrl:
|
|
611
|
+
const s3ConfigSchema = z2.object({
|
|
612
|
+
accessId: z2.string().describe("S3 access key ID"),
|
|
613
|
+
accessSecret: z2.string().describe("S3 secret access key"),
|
|
614
|
+
bucketName: z2.string().describe("S3 bucket name"),
|
|
615
|
+
endpointUrl: z2.string().describe("S3 endpoint URL")
|
|
563
616
|
}).optional().describe("S3-compatible storage config for large outputs");
|
|
564
617
|
server.tool(
|
|
565
618
|
"run-endpoint",
|
|
@@ -599,7 +652,7 @@ function registerTools(server, ctx) {
|
|
|
599
652
|
"ID of the Serverless endpoint to run synchronously"
|
|
600
653
|
),
|
|
601
654
|
input: inputSchema,
|
|
602
|
-
wait:
|
|
655
|
+
wait: z2.number().min(1e3).max(3e5).optional().describe(
|
|
603
656
|
"How long in milliseconds the server should wait for a result before returning a job ID to poll (1000\u2013300000). Defaults to 90000 (90 seconds)."
|
|
604
657
|
),
|
|
605
658
|
webhook: webhookSchema,
|
|
@@ -815,9 +868,10 @@ function registerTools(server, ctx) {
|
|
|
815
868
|
"list-templates",
|
|
816
869
|
`List available templates. By default returns only the user's own templates. Use includeRunpodTemplates to also include official Runpod templates. The recommended default template for new pods is "Runpod Pytorch 2.8.0" (ID: runpod-torch-v280) \u2014 it has the latest CUDA and PyTorch versions.`,
|
|
817
870
|
{
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
871
|
+
...listPaginationParams,
|
|
872
|
+
includeRunpodTemplates: z2.boolean().optional().describe("Include official Runpod templates in the response"),
|
|
873
|
+
includePublicTemplates: z2.boolean().optional().describe("Include community-made public templates in the response"),
|
|
874
|
+
includeEndpointBoundTemplates: z2.boolean().optional().describe(
|
|
821
875
|
"Include templates bound to Serverless endpoints in the response"
|
|
822
876
|
)
|
|
823
877
|
},
|
|
@@ -833,20 +887,16 @@ function registerTools(server, ctx) {
|
|
|
833
887
|
const result = await runpodRequest(
|
|
834
888
|
`/templates${query ? `?${query}` : ""}`
|
|
835
889
|
);
|
|
836
|
-
return {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
text: JSON.stringify(result, null, 2)
|
|
841
|
-
}
|
|
842
|
-
]
|
|
843
|
-
};
|
|
890
|
+
return capListResult(result, {
|
|
891
|
+
limit: params.limit,
|
|
892
|
+
cursor: params.cursor
|
|
893
|
+
});
|
|
844
894
|
}
|
|
845
895
|
);
|
|
846
896
|
server.tool(
|
|
847
897
|
"get-template",
|
|
848
898
|
{
|
|
849
|
-
templateId:
|
|
899
|
+
templateId: z2.string().describe("ID of the template to retrieve")
|
|
850
900
|
},
|
|
851
901
|
async (params) => {
|
|
852
902
|
const result = await runpodRequest(`/templates/${params.templateId}`);
|
|
@@ -863,17 +913,20 @@ function registerTools(server, ctx) {
|
|
|
863
913
|
server.tool(
|
|
864
914
|
"create-template",
|
|
865
915
|
{
|
|
866
|
-
name:
|
|
867
|
-
imageName:
|
|
868
|
-
isServerless:
|
|
869
|
-
ports:
|
|
870
|
-
dockerEntrypoint:
|
|
871
|
-
dockerStartCmd:
|
|
872
|
-
env:
|
|
873
|
-
containerDiskInGb:
|
|
874
|
-
volumeInGb:
|
|
875
|
-
volumeMountPath:
|
|
876
|
-
readme:
|
|
916
|
+
name: z2.string().describe("Name for the template"),
|
|
917
|
+
imageName: z2.string().describe("Docker image to use"),
|
|
918
|
+
isServerless: z2.boolean().optional().describe("Is this a serverless template"),
|
|
919
|
+
ports: z2.array(z2.string()).optional().describe("Ports to expose"),
|
|
920
|
+
dockerEntrypoint: z2.array(z2.string()).optional().describe("Docker entrypoint commands"),
|
|
921
|
+
dockerStartCmd: z2.array(z2.string()).optional().describe("Docker start commands"),
|
|
922
|
+
env: z2.record(z2.string()).optional().describe("Environment variables"),
|
|
923
|
+
containerDiskInGb: z2.number().optional().describe("Container disk size in GB"),
|
|
924
|
+
volumeInGb: z2.number().optional().describe("Volume size in GB"),
|
|
925
|
+
volumeMountPath: z2.string().optional().describe("Path to mount the volume"),
|
|
926
|
+
readme: z2.string().optional().describe("README content in markdown format"),
|
|
927
|
+
containerRegistryAuthId: z2.string().optional().describe(
|
|
928
|
+
"ID of a container registry credential (from create-container-registry-auth / list-container-registry-auths) used to pull a private image. Required when imageName points at a private registry; without it serverless workers fail the image pull."
|
|
929
|
+
)
|
|
877
930
|
},
|
|
878
931
|
async (params) => {
|
|
879
932
|
const result = await runpodRequest("/templates", "POST", params);
|
|
@@ -890,12 +943,15 @@ function registerTools(server, ctx) {
|
|
|
890
943
|
server.tool(
|
|
891
944
|
"update-template",
|
|
892
945
|
{
|
|
893
|
-
templateId:
|
|
894
|
-
name:
|
|
895
|
-
imageName:
|
|
896
|
-
ports:
|
|
897
|
-
env:
|
|
898
|
-
readme:
|
|
946
|
+
templateId: z2.string().describe("ID of the template to update"),
|
|
947
|
+
name: z2.string().optional().describe("New name for the template"),
|
|
948
|
+
imageName: z2.string().optional().describe("New Docker image"),
|
|
949
|
+
ports: z2.array(z2.string()).optional().describe("New ports to expose"),
|
|
950
|
+
env: z2.record(z2.string()).optional().describe("New environment variables"),
|
|
951
|
+
readme: z2.string().optional().describe("New README content in markdown format"),
|
|
952
|
+
containerRegistryAuthId: z2.string().optional().describe(
|
|
953
|
+
"ID of a container registry credential (from create-container-registry-auth / list-container-registry-auths) used to pull a private image. Set this to attach a credential to a template referencing a private registry."
|
|
954
|
+
)
|
|
899
955
|
},
|
|
900
956
|
async (params) => {
|
|
901
957
|
const { templateId, ...updateParams } = params;
|
|
@@ -917,7 +973,7 @@ function registerTools(server, ctx) {
|
|
|
917
973
|
server.tool(
|
|
918
974
|
"delete-template",
|
|
919
975
|
{
|
|
920
|
-
templateId:
|
|
976
|
+
templateId: z2.string().describe("ID of the template to delete")
|
|
921
977
|
},
|
|
922
978
|
async (params) => {
|
|
923
979
|
const result = await runpodRequest(
|
|
@@ -934,21 +990,17 @@ function registerTools(server, ctx) {
|
|
|
934
990
|
};
|
|
935
991
|
}
|
|
936
992
|
);
|
|
937
|
-
server.tool("list-network-volumes",
|
|
993
|
+
server.tool("list-network-volumes", listPaginationParams, async (params) => {
|
|
938
994
|
const result = await runpodRequest("/networkvolumes");
|
|
939
|
-
return {
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
text: JSON.stringify(result, null, 2)
|
|
944
|
-
}
|
|
945
|
-
]
|
|
946
|
-
};
|
|
995
|
+
return capListResult(result, {
|
|
996
|
+
limit: params.limit,
|
|
997
|
+
cursor: params.cursor
|
|
998
|
+
});
|
|
947
999
|
});
|
|
948
1000
|
server.tool(
|
|
949
1001
|
"get-network-volume",
|
|
950
1002
|
{
|
|
951
|
-
networkVolumeId:
|
|
1003
|
+
networkVolumeId: z2.string().describe("ID of the network volume to retrieve")
|
|
952
1004
|
},
|
|
953
1005
|
async (params) => {
|
|
954
1006
|
const result = await runpodRequest(
|
|
@@ -967,9 +1019,9 @@ function registerTools(server, ctx) {
|
|
|
967
1019
|
server.tool(
|
|
968
1020
|
"create-network-volume",
|
|
969
1021
|
{
|
|
970
|
-
name:
|
|
971
|
-
size:
|
|
972
|
-
dataCenterId:
|
|
1022
|
+
name: z2.string().describe("Name for the network volume"),
|
|
1023
|
+
size: z2.number().describe("Size in GB (1-4000)"),
|
|
1024
|
+
dataCenterId: z2.string().describe("Data center ID")
|
|
973
1025
|
},
|
|
974
1026
|
async (params) => {
|
|
975
1027
|
const result = await runpodRequest("/networkvolumes", "POST", params);
|
|
@@ -986,9 +1038,9 @@ function registerTools(server, ctx) {
|
|
|
986
1038
|
server.tool(
|
|
987
1039
|
"update-network-volume",
|
|
988
1040
|
{
|
|
989
|
-
networkVolumeId:
|
|
990
|
-
name:
|
|
991
|
-
size:
|
|
1041
|
+
networkVolumeId: z2.string().describe("ID of the network volume to update"),
|
|
1042
|
+
name: z2.string().optional().describe("New name for the network volume"),
|
|
1043
|
+
size: z2.number().optional().describe("New size in GB (must be larger than current)")
|
|
992
1044
|
},
|
|
993
1045
|
async (params) => {
|
|
994
1046
|
const { networkVolumeId, ...updateParams } = params;
|
|
@@ -1010,7 +1062,7 @@ function registerTools(server, ctx) {
|
|
|
1010
1062
|
server.tool(
|
|
1011
1063
|
"delete-network-volume",
|
|
1012
1064
|
{
|
|
1013
|
-
networkVolumeId:
|
|
1065
|
+
networkVolumeId: z2.string().describe("ID of the network volume to delete")
|
|
1014
1066
|
},
|
|
1015
1067
|
async (params) => {
|
|
1016
1068
|
const result = await runpodRequest(
|
|
@@ -1027,21 +1079,21 @@ function registerTools(server, ctx) {
|
|
|
1027
1079
|
};
|
|
1028
1080
|
}
|
|
1029
1081
|
);
|
|
1030
|
-
server.tool(
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1082
|
+
server.tool(
|
|
1083
|
+
"list-container-registry-auths",
|
|
1084
|
+
listPaginationParams,
|
|
1085
|
+
async (params) => {
|
|
1086
|
+
const result = await runpodRequest("/containerregistryauth");
|
|
1087
|
+
return capListResult(result, {
|
|
1088
|
+
limit: params.limit,
|
|
1089
|
+
cursor: params.cursor
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
);
|
|
1041
1093
|
server.tool(
|
|
1042
1094
|
"get-container-registry-auth",
|
|
1043
1095
|
{
|
|
1044
|
-
containerRegistryAuthId:
|
|
1096
|
+
containerRegistryAuthId: z2.string().describe("ID of the container registry auth to retrieve")
|
|
1045
1097
|
},
|
|
1046
1098
|
async (params) => {
|
|
1047
1099
|
const result = await runpodRequest(
|
|
@@ -1060,9 +1112,9 @@ function registerTools(server, ctx) {
|
|
|
1060
1112
|
server.tool(
|
|
1061
1113
|
"create-container-registry-auth",
|
|
1062
1114
|
{
|
|
1063
|
-
name:
|
|
1064
|
-
username:
|
|
1065
|
-
password:
|
|
1115
|
+
name: z2.string().describe("Name for the container registry auth"),
|
|
1116
|
+
username: z2.string().describe("Registry username"),
|
|
1117
|
+
password: z2.string().describe("Registry password")
|
|
1066
1118
|
},
|
|
1067
1119
|
async (params) => {
|
|
1068
1120
|
const result = await runpodRequest(
|
|
@@ -1083,7 +1135,7 @@ function registerTools(server, ctx) {
|
|
|
1083
1135
|
server.tool(
|
|
1084
1136
|
"delete-container-registry-auth",
|
|
1085
1137
|
{
|
|
1086
|
-
containerRegistryAuthId:
|
|
1138
|
+
containerRegistryAuthId: z2.string().describe("ID of the container registry auth to delete")
|
|
1087
1139
|
},
|
|
1088
1140
|
async (params) => {
|
|
1089
1141
|
const result = await runpodRequest(
|
|
@@ -1105,4 +1157,4 @@ function registerTools(server, ctx) {
|
|
|
1105
1157
|
export {
|
|
1106
1158
|
registerTools
|
|
1107
1159
|
};
|
|
1108
|
-
//# sourceMappingURL=chunk-
|
|
1160
|
+
//# sourceMappingURL=chunk-D4AEYJ2O.mjs.map
|