@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/dist/http.cjs CHANGED
@@ -39,7 +39,7 @@ var import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamable
39
39
  // src/server.ts
40
40
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
41
41
  var SERVER_NAME = "Runpod API Server";
42
- var SERVER_VERSION = true ? "1.3.0" : "dev";
42
+ var SERVER_VERSION = true ? "1.4.0" : "dev";
43
43
  function createServer(version = SERVER_VERSION) {
44
44
  return new import_mcp.McpServer({
45
45
  name: SERVER_NAME,
@@ -52,13 +52,72 @@ function createServer(version = SERVER_VERSION) {
52
52
  }
53
53
 
54
54
  // src/tools.ts
55
- var import_zod = require("zod");
55
+ var import_zod2 = require("zod");
56
56
  var import_node_fetch = __toESM(require("node-fetch"), 1);
57
57
  var import_node_crypto = require("crypto");
58
+
59
+ // src/pagination.ts
60
+ var import_zod = require("zod");
61
+ var DEFAULT_LIST_LIMIT = 20;
62
+ var MAX_LIST_LIMIT = 100;
63
+ var listPaginationParams = {
64
+ limit: import_zod.z.number().int().positive().max(MAX_LIST_LIMIT).optional().describe(
65
+ `Maximum number of items to return (default ${DEFAULT_LIST_LIMIT}, max ${MAX_LIST_LIMIT}). Use the returned nextCursor to fetch the next page.`
66
+ ),
67
+ cursor: import_zod.z.string().optional().describe(
68
+ "Opaque pagination cursor from a previous response (nextCursor). Omit to start from the beginning."
69
+ )
70
+ };
71
+ function decodeCursorOffset(cursor) {
72
+ if (!cursor) return 0;
73
+ try {
74
+ const decoded = Buffer.from(cursor, "base64").toString("utf8");
75
+ const offset = Number.parseInt(decoded, 10);
76
+ return Number.isFinite(offset) && offset >= 0 ? offset : 0;
77
+ } catch {
78
+ return 0;
79
+ }
80
+ }
81
+ function encodeCursorOffset(offset) {
82
+ return Buffer.from(String(offset), "utf8").toString("base64");
83
+ }
84
+ function capListResult(result, options) {
85
+ const limit = Math.min(options.limit ?? DEFAULT_LIST_LIMIT, MAX_LIST_LIMIT);
86
+ const offset = decodeCursorOffset(options.cursor);
87
+ if (!Array.isArray(result)) {
88
+ return {
89
+ content: [
90
+ { type: "text", text: JSON.stringify(result, null, 2) }
91
+ ]
92
+ };
93
+ }
94
+ const total = result.length;
95
+ const page = result.slice(offset, offset + limit);
96
+ const nextOffset = offset + page.length;
97
+ const hasMore = nextOffset < total;
98
+ const envelope = {
99
+ items: page,
100
+ pagination: {
101
+ total,
102
+ returned: page.length,
103
+ offset,
104
+ truncated: hasMore,
105
+ nextCursor: hasMore ? encodeCursorOffset(nextOffset) : null,
106
+ note: hasMore ? `Showing ${page.length} of ${total}. Pass cursor=nextCursor to fetch more, or narrow the query with filters.` : void 0
107
+ }
108
+ };
109
+ return {
110
+ content: [
111
+ { type: "text", text: JSON.stringify(envelope, null, 2) }
112
+ ]
113
+ };
114
+ }
115
+
116
+ // src/tools.ts
58
117
  var API_BASE_URL = process.env.RUNPOD_REST_API_URL ?? "https://rest.runpod.io/v1";
59
118
  var SERVERLESS_API_BASE_URL = process.env.RUNPOD_SERVERLESS_API_URL ?? "https://api.runpod.ai/v2";
60
119
  var GRAPHQL_URL = process.env.RUNPOD_PUBLIC_GRAPHQL_URL ?? "https://api.runpod.io/graphql";
61
- var MCP_SERVER_VERSION = true ? "1.3.0" : "dev";
120
+ var MCP_SERVER_VERSION = true ? "1.4.0" : "dev";
62
121
  var SESSION_ID = (0, import_node_crypto.randomUUID)();
63
122
  function sanitizeUaToken(value) {
64
123
  return value.replace(/[()<>@,;:\\"/[\]?={}\s]/g, "_").slice(0, 64);
@@ -168,13 +227,13 @@ function registerTools(server, ctx) {
168
227
  server.tool(
169
228
  "list-gpu-types",
170
229
  {
171
- minMemoryGb: import_zod.z.number().optional().describe("Filter to GPUs with at least this much VRAM in GB"),
172
- secureCloudOnly: import_zod.z.boolean().optional().describe("Filter to only GPUs available in secure cloud"),
173
- communityCloudOnly: import_zod.z.boolean().optional().describe("Filter to only GPUs available in community cloud"),
174
- searchTerm: import_zod.z.string().optional().describe(
230
+ minMemoryGb: import_zod2.z.number().optional().describe("Filter to GPUs with at least this much VRAM in GB"),
231
+ secureCloudOnly: import_zod2.z.boolean().optional().describe("Filter to only GPUs available in secure cloud"),
232
+ communityCloudOnly: import_zod2.z.boolean().optional().describe("Filter to only GPUs available in community cloud"),
233
+ searchTerm: import_zod2.z.string().optional().describe(
175
234
  "Search term to filter GPUs by name (e.g., 'A100', 'RTX 4090')"
176
235
  ),
177
- includeUnavailable: import_zod.z.boolean().optional().describe(
236
+ includeUnavailable: import_zod2.z.boolean().optional().describe(
178
237
  "Include GPUs that are currently out of stock. Default is false"
179
238
  )
180
239
  },
@@ -254,7 +313,7 @@ function registerTools(server, ctx) {
254
313
  server.tool(
255
314
  "list-data-centers",
256
315
  {
257
- region: import_zod.z.string().optional().describe(
316
+ region: import_zod2.z.string().optional().describe(
258
317
  "Filter by region/location (e.g., 'United States', 'Europe', 'Canada')"
259
318
  )
260
319
  },
@@ -291,12 +350,13 @@ function registerTools(server, ctx) {
291
350
  server.tool(
292
351
  "list-pods",
293
352
  {
294
- computeType: import_zod.z.enum(["GPU", "CPU"]).optional().describe("Filter to only GPU or only CPU Pods"),
295
- gpuTypeId: import_zod.z.array(import_zod.z.string()).optional().describe("Filter to Pods with any of the listed GPU types"),
296
- dataCenterId: import_zod.z.array(import_zod.z.string()).optional().describe("Filter to Pods in any of the provided data centers"),
297
- name: import_zod.z.string().optional().describe("Filter to Pods with the provided name"),
298
- includeMachine: import_zod.z.boolean().optional().describe("Include information about the machine"),
299
- includeNetworkVolume: import_zod.z.boolean().optional().describe("Include information about attached network volumes")
353
+ ...listPaginationParams,
354
+ computeType: import_zod2.z.enum(["GPU", "CPU"]).optional().describe("Filter to only GPU or only CPU Pods"),
355
+ gpuTypeId: import_zod2.z.array(import_zod2.z.string()).optional().describe("Filter to Pods with any of the listed GPU types"),
356
+ dataCenterId: import_zod2.z.array(import_zod2.z.string()).optional().describe("Filter to Pods in any of the provided data centers"),
357
+ name: import_zod2.z.string().optional().describe("Filter to Pods with the provided name"),
358
+ includeMachine: import_zod2.z.boolean().optional().describe("Include information about the machine"),
359
+ includeNetworkVolume: import_zod2.z.boolean().optional().describe("Include information about attached network volumes")
300
360
  },
301
361
  async (params) => {
302
362
  const queryParams = new URLSearchParams();
@@ -320,22 +380,18 @@ function registerTools(server, ctx) {
320
380
  );
321
381
  const queryString = queryParams.toString() ? `?${queryParams.toString()}` : "";
322
382
  const result = await runpodRequest(`/pods${queryString}`);
323
- return {
324
- content: [
325
- {
326
- type: "text",
327
- text: JSON.stringify(result, null, 2)
328
- }
329
- ]
330
- };
383
+ return capListResult(result, {
384
+ limit: params.limit,
385
+ cursor: params.cursor
386
+ });
331
387
  }
332
388
  );
333
389
  server.tool(
334
390
  "get-pod",
335
391
  {
336
- podId: import_zod.z.string().describe("ID of the pod to retrieve"),
337
- includeMachine: import_zod.z.boolean().optional().describe("Include information about the machine"),
338
- includeNetworkVolume: import_zod.z.boolean().optional().describe("Include information about attached network volumes")
392
+ podId: import_zod2.z.string().describe("ID of the pod to retrieve"),
393
+ includeMachine: import_zod2.z.boolean().optional().describe("Include information about the machine"),
394
+ includeNetworkVolume: import_zod2.z.boolean().optional().describe("Include information about attached network volumes")
339
395
  },
340
396
  async (params) => {
341
397
  const queryParams = new URLSearchParams();
@@ -362,17 +418,17 @@ function registerTools(server, ctx) {
362
418
  "create-pod",
363
419
  '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.',
364
420
  {
365
- name: import_zod.z.string().optional().describe("Name for the pod"),
366
- imageName: import_zod.z.string().describe("Docker image to use"),
367
- cloudType: import_zod.z.enum(["SECURE", "COMMUNITY"]).optional().describe("SECURE or COMMUNITY cloud"),
368
- gpuTypeIds: import_zod.z.array(import_zod.z.string()).optional().describe("List of acceptable GPU types"),
369
- gpuCount: import_zod.z.number().optional().describe("Number of GPUs"),
370
- containerDiskInGb: import_zod.z.number().optional().describe("Container disk size in GB"),
371
- volumeInGb: import_zod.z.number().optional().describe("Volume size in GB"),
372
- volumeMountPath: import_zod.z.string().optional().describe("Path to mount the volume"),
373
- ports: import_zod.z.array(import_zod.z.string()).optional().describe("Ports to expose (e.g., '8888/http', '22/tcp')"),
374
- env: import_zod.z.record(import_zod.z.string()).optional().describe("Environment variables"),
375
- dataCenterIds: import_zod.z.array(import_zod.z.string()).optional().describe("List of data centers")
421
+ name: import_zod2.z.string().optional().describe("Name for the pod"),
422
+ imageName: import_zod2.z.string().describe("Docker image to use"),
423
+ cloudType: import_zod2.z.enum(["SECURE", "COMMUNITY"]).optional().describe("SECURE or COMMUNITY cloud"),
424
+ gpuTypeIds: import_zod2.z.array(import_zod2.z.string()).optional().describe("List of acceptable GPU types"),
425
+ gpuCount: import_zod2.z.number().optional().describe("Number of GPUs"),
426
+ containerDiskInGb: import_zod2.z.number().optional().describe("Container disk size in GB"),
427
+ volumeInGb: import_zod2.z.number().optional().describe("Volume size in GB"),
428
+ volumeMountPath: import_zod2.z.string().optional().describe("Path to mount the volume"),
429
+ ports: import_zod2.z.array(import_zod2.z.string()).optional().describe("Ports to expose (e.g., '8888/http', '22/tcp')"),
430
+ env: import_zod2.z.record(import_zod2.z.string()).optional().describe("Environment variables"),
431
+ dataCenterIds: import_zod2.z.array(import_zod2.z.string()).optional().describe("List of data centers")
376
432
  },
377
433
  async (params) => {
378
434
  const result = await runpodRequest("/pods", "POST", params);
@@ -389,14 +445,14 @@ function registerTools(server, ctx) {
389
445
  server.tool(
390
446
  "update-pod",
391
447
  {
392
- podId: import_zod.z.string().describe("ID of the pod to update"),
393
- name: import_zod.z.string().optional().describe("New name for the pod"),
394
- imageName: import_zod.z.string().optional().describe("New Docker image"),
395
- containerDiskInGb: import_zod.z.number().optional().describe("New container disk size in GB"),
396
- volumeInGb: import_zod.z.number().optional().describe("New volume size in GB"),
397
- volumeMountPath: import_zod.z.string().optional().describe("New path to mount the volume"),
398
- ports: import_zod.z.array(import_zod.z.string()).optional().describe("New ports to expose"),
399
- env: import_zod.z.record(import_zod.z.string()).optional().describe("New environment variables")
448
+ podId: import_zod2.z.string().describe("ID of the pod to update"),
449
+ name: import_zod2.z.string().optional().describe("New name for the pod"),
450
+ imageName: import_zod2.z.string().optional().describe("New Docker image"),
451
+ containerDiskInGb: import_zod2.z.number().optional().describe("New container disk size in GB"),
452
+ volumeInGb: import_zod2.z.number().optional().describe("New volume size in GB"),
453
+ volumeMountPath: import_zod2.z.string().optional().describe("New path to mount the volume"),
454
+ ports: import_zod2.z.array(import_zod2.z.string()).optional().describe("New ports to expose"),
455
+ env: import_zod2.z.record(import_zod2.z.string()).optional().describe("New environment variables")
400
456
  },
401
457
  async (params) => {
402
458
  const { podId, ...updateParams } = params;
@@ -418,7 +474,7 @@ function registerTools(server, ctx) {
418
474
  server.tool(
419
475
  "start-pod",
420
476
  {
421
- podId: import_zod.z.string().describe("ID of the pod to start")
477
+ podId: import_zod2.z.string().describe("ID of the pod to start")
422
478
  },
423
479
  async (params) => {
424
480
  const result = await runpodRequest(`/pods/${params.podId}/start`, "POST");
@@ -435,7 +491,7 @@ function registerTools(server, ctx) {
435
491
  server.tool(
436
492
  "stop-pod",
437
493
  {
438
- podId: import_zod.z.string().describe("ID of the pod to stop")
494
+ podId: import_zod2.z.string().describe("ID of the pod to stop")
439
495
  },
440
496
  async (params) => {
441
497
  const result = await runpodRequest(`/pods/${params.podId}/stop`, "POST");
@@ -452,7 +508,7 @@ function registerTools(server, ctx) {
452
508
  server.tool(
453
509
  "delete-pod",
454
510
  {
455
- podId: import_zod.z.string().describe("ID of the pod to delete")
511
+ podId: import_zod2.z.string().describe("ID of the pod to delete")
456
512
  },
457
513
  async (params) => {
458
514
  const result = await runpodRequest(`/pods/${params.podId}`, "DELETE");
@@ -469,8 +525,9 @@ function registerTools(server, ctx) {
469
525
  server.tool(
470
526
  "list-endpoints",
471
527
  {
472
- includeTemplate: import_zod.z.boolean().optional().describe("Include template information"),
473
- includeWorkers: import_zod.z.boolean().optional().describe("Include information about workers")
528
+ ...listPaginationParams,
529
+ includeTemplate: import_zod2.z.boolean().optional().describe("Include template information"),
530
+ includeWorkers: import_zod2.z.boolean().optional().describe("Include information about workers")
474
531
  },
475
532
  async (params) => {
476
533
  const queryParams = new URLSearchParams();
@@ -483,22 +540,18 @@ function registerTools(server, ctx) {
483
540
  queryParams.append("includeWorkers", params.includeWorkers.toString());
484
541
  const queryString = queryParams.toString() ? `?${queryParams.toString()}` : "";
485
542
  const result = await runpodRequest(`/endpoints${queryString}`);
486
- return {
487
- content: [
488
- {
489
- type: "text",
490
- text: JSON.stringify(result, null, 2)
491
- }
492
- ]
493
- };
543
+ return capListResult(result, {
544
+ limit: params.limit,
545
+ cursor: params.cursor
546
+ });
494
547
  }
495
548
  );
496
549
  server.tool(
497
550
  "get-endpoint",
498
551
  {
499
- endpointId: import_zod.z.string().describe("ID of the endpoint to retrieve"),
500
- includeTemplate: import_zod.z.boolean().optional().describe("Include template information"),
501
- includeWorkers: import_zod.z.boolean().optional().describe("Include information about workers")
552
+ endpointId: import_zod2.z.string().describe("ID of the endpoint to retrieve"),
553
+ includeTemplate: import_zod2.z.boolean().optional().describe("Include template information"),
554
+ includeWorkers: import_zod2.z.boolean().optional().describe("Include information about workers")
502
555
  },
503
556
  async (params) => {
504
557
  const queryParams = new URLSearchParams();
@@ -526,14 +579,14 @@ function registerTools(server, ctx) {
526
579
  server.tool(
527
580
  "create-endpoint",
528
581
  {
529
- name: import_zod.z.string().optional().describe("Name for the endpoint"),
530
- templateId: import_zod.z.string().describe("Template ID to use"),
531
- computeType: import_zod.z.enum(["GPU", "CPU"]).optional().describe("GPU or CPU endpoint"),
532
- gpuTypeIds: import_zod.z.array(import_zod.z.string()).optional().describe("List of acceptable GPU types"),
533
- gpuCount: import_zod.z.number().optional().describe("Number of GPUs per worker"),
534
- workersMin: import_zod.z.number().optional().describe("Minimum number of workers"),
535
- workersMax: import_zod.z.number().optional().describe("Maximum number of workers"),
536
- dataCenterIds: import_zod.z.array(import_zod.z.string()).optional().describe("List of data centers")
582
+ name: import_zod2.z.string().optional().describe("Name for the endpoint"),
583
+ templateId: import_zod2.z.string().describe("Template ID to use"),
584
+ computeType: import_zod2.z.enum(["GPU", "CPU"]).optional().describe("GPU or CPU endpoint"),
585
+ gpuTypeIds: import_zod2.z.array(import_zod2.z.string()).optional().describe("List of acceptable GPU types"),
586
+ gpuCount: import_zod2.z.number().optional().describe("Number of GPUs per worker"),
587
+ workersMin: import_zod2.z.number().optional().describe("Minimum number of workers"),
588
+ workersMax: import_zod2.z.number().optional().describe("Maximum number of workers"),
589
+ dataCenterIds: import_zod2.z.array(import_zod2.z.string()).optional().describe("List of data centers")
537
590
  },
538
591
  async (params) => {
539
592
  const result = await runpodRequest("/endpoints", "POST", params);
@@ -550,13 +603,13 @@ function registerTools(server, ctx) {
550
603
  server.tool(
551
604
  "update-endpoint",
552
605
  {
553
- endpointId: import_zod.z.string().describe("ID of the endpoint to update"),
554
- name: import_zod.z.string().optional().describe("New name for the endpoint"),
555
- workersMin: import_zod.z.number().optional().describe("New minimum number of workers"),
556
- workersMax: import_zod.z.number().optional().describe("New maximum number of workers"),
557
- idleTimeout: import_zod.z.number().optional().describe("New idle timeout in seconds"),
558
- scalerType: import_zod.z.enum(["QUEUE_DELAY", "REQUEST_COUNT"]).optional().describe("Scaler type"),
559
- scalerValue: import_zod.z.number().optional().describe("Scaler value")
606
+ endpointId: import_zod2.z.string().describe("ID of the endpoint to update"),
607
+ name: import_zod2.z.string().optional().describe("New name for the endpoint"),
608
+ workersMin: import_zod2.z.number().optional().describe("New minimum number of workers"),
609
+ workersMax: import_zod2.z.number().optional().describe("New maximum number of workers"),
610
+ idleTimeout: import_zod2.z.number().optional().describe("New idle timeout in seconds"),
611
+ scalerType: import_zod2.z.enum(["QUEUE_DELAY", "REQUEST_COUNT"]).optional().describe("Scaler type"),
612
+ scalerValue: import_zod2.z.number().optional().describe("Scaler value")
560
613
  },
561
614
  async (params) => {
562
615
  const { endpointId, ...updateParams } = params;
@@ -578,7 +631,7 @@ function registerTools(server, ctx) {
578
631
  server.tool(
579
632
  "delete-endpoint",
580
633
  {
581
- endpointId: import_zod.z.string().describe("ID of the endpoint to delete")
634
+ endpointId: import_zod2.z.string().describe("ID of the endpoint to delete")
582
635
  },
583
636
  async (params) => {
584
637
  const result = await runpodRequest(
@@ -595,24 +648,24 @@ function registerTools(server, ctx) {
595
648
  };
596
649
  }
597
650
  );
598
- const endpointIdSchema = import_zod.z.string().regex(/^[a-zA-Z0-9_-]+$/, "Invalid endpoint ID format");
599
- const jobIdSchema = import_zod.z.string().regex(/^[a-zA-Z0-9_-]+$/, "Invalid job ID format");
600
- const inputSchema = import_zod.z.record(import_zod.z.unknown()).describe(
651
+ const endpointIdSchema = import_zod2.z.string().regex(/^[a-zA-Z0-9_-]+$/, "Invalid endpoint ID format");
652
+ const jobIdSchema = import_zod2.z.string().regex(/^[a-zA-Z0-9_-]+$/, "Invalid job ID format");
653
+ const inputSchema = import_zod2.z.record(import_zod2.z.unknown()).describe(
601
654
  "Input payload for the worker handler. The expected fields depend on the deployed model or worker."
602
655
  );
603
- const webhookSchema = import_zod.z.string().url().optional().describe(
656
+ const webhookSchema = import_zod2.z.string().url().optional().describe(
604
657
  "Webhook URL to receive job completion notifications instead of polling"
605
658
  );
606
- const policySchema = import_zod.z.object({
607
- executionTimeout: import_zod.z.number().optional().describe("Maximum execution time in milliseconds"),
608
- lowPriority: import_zod.z.boolean().optional().describe("Submit as a low-priority job"),
609
- ttl: import_zod.z.number().optional().describe("Time-to-live for the job result in milliseconds")
659
+ const policySchema = import_zod2.z.object({
660
+ executionTimeout: import_zod2.z.number().optional().describe("Maximum execution time in milliseconds"),
661
+ lowPriority: import_zod2.z.boolean().optional().describe("Submit as a low-priority job"),
662
+ ttl: import_zod2.z.number().optional().describe("Time-to-live for the job result in milliseconds")
610
663
  }).optional().describe("Execution policy options");
611
- const s3ConfigSchema = import_zod.z.object({
612
- accessId: import_zod.z.string().describe("S3 access key ID"),
613
- accessSecret: import_zod.z.string().describe("S3 secret access key"),
614
- bucketName: import_zod.z.string().describe("S3 bucket name"),
615
- endpointUrl: import_zod.z.string().describe("S3 endpoint URL")
664
+ const s3ConfigSchema = import_zod2.z.object({
665
+ accessId: import_zod2.z.string().describe("S3 access key ID"),
666
+ accessSecret: import_zod2.z.string().describe("S3 secret access key"),
667
+ bucketName: import_zod2.z.string().describe("S3 bucket name"),
668
+ endpointUrl: import_zod2.z.string().describe("S3 endpoint URL")
616
669
  }).optional().describe("S3-compatible storage config for large outputs");
617
670
  server.tool(
618
671
  "run-endpoint",
@@ -652,7 +705,7 @@ function registerTools(server, ctx) {
652
705
  "ID of the Serverless endpoint to run synchronously"
653
706
  ),
654
707
  input: inputSchema,
655
- wait: import_zod.z.number().min(1e3).max(3e5).optional().describe(
708
+ wait: import_zod2.z.number().min(1e3).max(3e5).optional().describe(
656
709
  "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)."
657
710
  ),
658
711
  webhook: webhookSchema,
@@ -868,9 +921,10 @@ function registerTools(server, ctx) {
868
921
  "list-templates",
869
922
  `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.`,
870
923
  {
871
- includeRunpodTemplates: import_zod.z.boolean().optional().describe("Include official Runpod templates in the response"),
872
- includePublicTemplates: import_zod.z.boolean().optional().describe("Include community-made public templates in the response"),
873
- includeEndpointBoundTemplates: import_zod.z.boolean().optional().describe(
924
+ ...listPaginationParams,
925
+ includeRunpodTemplates: import_zod2.z.boolean().optional().describe("Include official Runpod templates in the response"),
926
+ includePublicTemplates: import_zod2.z.boolean().optional().describe("Include community-made public templates in the response"),
927
+ includeEndpointBoundTemplates: import_zod2.z.boolean().optional().describe(
874
928
  "Include templates bound to Serverless endpoints in the response"
875
929
  )
876
930
  },
@@ -886,20 +940,16 @@ function registerTools(server, ctx) {
886
940
  const result = await runpodRequest(
887
941
  `/templates${query ? `?${query}` : ""}`
888
942
  );
889
- return {
890
- content: [
891
- {
892
- type: "text",
893
- text: JSON.stringify(result, null, 2)
894
- }
895
- ]
896
- };
943
+ return capListResult(result, {
944
+ limit: params.limit,
945
+ cursor: params.cursor
946
+ });
897
947
  }
898
948
  );
899
949
  server.tool(
900
950
  "get-template",
901
951
  {
902
- templateId: import_zod.z.string().describe("ID of the template to retrieve")
952
+ templateId: import_zod2.z.string().describe("ID of the template to retrieve")
903
953
  },
904
954
  async (params) => {
905
955
  const result = await runpodRequest(`/templates/${params.templateId}`);
@@ -916,17 +966,20 @@ function registerTools(server, ctx) {
916
966
  server.tool(
917
967
  "create-template",
918
968
  {
919
- name: import_zod.z.string().describe("Name for the template"),
920
- imageName: import_zod.z.string().describe("Docker image to use"),
921
- isServerless: import_zod.z.boolean().optional().describe("Is this a serverless template"),
922
- ports: import_zod.z.array(import_zod.z.string()).optional().describe("Ports to expose"),
923
- dockerEntrypoint: import_zod.z.array(import_zod.z.string()).optional().describe("Docker entrypoint commands"),
924
- dockerStartCmd: import_zod.z.array(import_zod.z.string()).optional().describe("Docker start commands"),
925
- env: import_zod.z.record(import_zod.z.string()).optional().describe("Environment variables"),
926
- containerDiskInGb: import_zod.z.number().optional().describe("Container disk size in GB"),
927
- volumeInGb: import_zod.z.number().optional().describe("Volume size in GB"),
928
- volumeMountPath: import_zod.z.string().optional().describe("Path to mount the volume"),
929
- readme: import_zod.z.string().optional().describe("README content in markdown format")
969
+ name: import_zod2.z.string().describe("Name for the template"),
970
+ imageName: import_zod2.z.string().describe("Docker image to use"),
971
+ isServerless: import_zod2.z.boolean().optional().describe("Is this a serverless template"),
972
+ ports: import_zod2.z.array(import_zod2.z.string()).optional().describe("Ports to expose"),
973
+ dockerEntrypoint: import_zod2.z.array(import_zod2.z.string()).optional().describe("Docker entrypoint commands"),
974
+ dockerStartCmd: import_zod2.z.array(import_zod2.z.string()).optional().describe("Docker start commands"),
975
+ env: import_zod2.z.record(import_zod2.z.string()).optional().describe("Environment variables"),
976
+ containerDiskInGb: import_zod2.z.number().optional().describe("Container disk size in GB"),
977
+ volumeInGb: import_zod2.z.number().optional().describe("Volume size in GB"),
978
+ volumeMountPath: import_zod2.z.string().optional().describe("Path to mount the volume"),
979
+ readme: import_zod2.z.string().optional().describe("README content in markdown format"),
980
+ containerRegistryAuthId: import_zod2.z.string().optional().describe(
981
+ "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."
982
+ )
930
983
  },
931
984
  async (params) => {
932
985
  const result = await runpodRequest("/templates", "POST", params);
@@ -943,12 +996,15 @@ function registerTools(server, ctx) {
943
996
  server.tool(
944
997
  "update-template",
945
998
  {
946
- templateId: import_zod.z.string().describe("ID of the template to update"),
947
- name: import_zod.z.string().optional().describe("New name for the template"),
948
- imageName: import_zod.z.string().optional().describe("New Docker image"),
949
- ports: import_zod.z.array(import_zod.z.string()).optional().describe("New ports to expose"),
950
- env: import_zod.z.record(import_zod.z.string()).optional().describe("New environment variables"),
951
- readme: import_zod.z.string().optional().describe("New README content in markdown format")
999
+ templateId: import_zod2.z.string().describe("ID of the template to update"),
1000
+ name: import_zod2.z.string().optional().describe("New name for the template"),
1001
+ imageName: import_zod2.z.string().optional().describe("New Docker image"),
1002
+ ports: import_zod2.z.array(import_zod2.z.string()).optional().describe("New ports to expose"),
1003
+ env: import_zod2.z.record(import_zod2.z.string()).optional().describe("New environment variables"),
1004
+ readme: import_zod2.z.string().optional().describe("New README content in markdown format"),
1005
+ containerRegistryAuthId: import_zod2.z.string().optional().describe(
1006
+ "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."
1007
+ )
952
1008
  },
953
1009
  async (params) => {
954
1010
  const { templateId, ...updateParams } = params;
@@ -970,7 +1026,7 @@ function registerTools(server, ctx) {
970
1026
  server.tool(
971
1027
  "delete-template",
972
1028
  {
973
- templateId: import_zod.z.string().describe("ID of the template to delete")
1029
+ templateId: import_zod2.z.string().describe("ID of the template to delete")
974
1030
  },
975
1031
  async (params) => {
976
1032
  const result = await runpodRequest(
@@ -987,21 +1043,17 @@ function registerTools(server, ctx) {
987
1043
  };
988
1044
  }
989
1045
  );
990
- server.tool("list-network-volumes", {}, async () => {
1046
+ server.tool("list-network-volumes", listPaginationParams, async (params) => {
991
1047
  const result = await runpodRequest("/networkvolumes");
992
- return {
993
- content: [
994
- {
995
- type: "text",
996
- text: JSON.stringify(result, null, 2)
997
- }
998
- ]
999
- };
1048
+ return capListResult(result, {
1049
+ limit: params.limit,
1050
+ cursor: params.cursor
1051
+ });
1000
1052
  });
1001
1053
  server.tool(
1002
1054
  "get-network-volume",
1003
1055
  {
1004
- networkVolumeId: import_zod.z.string().describe("ID of the network volume to retrieve")
1056
+ networkVolumeId: import_zod2.z.string().describe("ID of the network volume to retrieve")
1005
1057
  },
1006
1058
  async (params) => {
1007
1059
  const result = await runpodRequest(
@@ -1020,9 +1072,9 @@ function registerTools(server, ctx) {
1020
1072
  server.tool(
1021
1073
  "create-network-volume",
1022
1074
  {
1023
- name: import_zod.z.string().describe("Name for the network volume"),
1024
- size: import_zod.z.number().describe("Size in GB (1-4000)"),
1025
- dataCenterId: import_zod.z.string().describe("Data center ID")
1075
+ name: import_zod2.z.string().describe("Name for the network volume"),
1076
+ size: import_zod2.z.number().describe("Size in GB (1-4000)"),
1077
+ dataCenterId: import_zod2.z.string().describe("Data center ID")
1026
1078
  },
1027
1079
  async (params) => {
1028
1080
  const result = await runpodRequest("/networkvolumes", "POST", params);
@@ -1039,9 +1091,9 @@ function registerTools(server, ctx) {
1039
1091
  server.tool(
1040
1092
  "update-network-volume",
1041
1093
  {
1042
- networkVolumeId: import_zod.z.string().describe("ID of the network volume to update"),
1043
- name: import_zod.z.string().optional().describe("New name for the network volume"),
1044
- size: import_zod.z.number().optional().describe("New size in GB (must be larger than current)")
1094
+ networkVolumeId: import_zod2.z.string().describe("ID of the network volume to update"),
1095
+ name: import_zod2.z.string().optional().describe("New name for the network volume"),
1096
+ size: import_zod2.z.number().optional().describe("New size in GB (must be larger than current)")
1045
1097
  },
1046
1098
  async (params) => {
1047
1099
  const { networkVolumeId, ...updateParams } = params;
@@ -1063,7 +1115,7 @@ function registerTools(server, ctx) {
1063
1115
  server.tool(
1064
1116
  "delete-network-volume",
1065
1117
  {
1066
- networkVolumeId: import_zod.z.string().describe("ID of the network volume to delete")
1118
+ networkVolumeId: import_zod2.z.string().describe("ID of the network volume to delete")
1067
1119
  },
1068
1120
  async (params) => {
1069
1121
  const result = await runpodRequest(
@@ -1080,21 +1132,21 @@ function registerTools(server, ctx) {
1080
1132
  };
1081
1133
  }
1082
1134
  );
1083
- server.tool("list-container-registry-auths", {}, async () => {
1084
- const result = await runpodRequest("/containerregistryauth");
1085
- return {
1086
- content: [
1087
- {
1088
- type: "text",
1089
- text: JSON.stringify(result, null, 2)
1090
- }
1091
- ]
1092
- };
1093
- });
1135
+ server.tool(
1136
+ "list-container-registry-auths",
1137
+ listPaginationParams,
1138
+ async (params) => {
1139
+ const result = await runpodRequest("/containerregistryauth");
1140
+ return capListResult(result, {
1141
+ limit: params.limit,
1142
+ cursor: params.cursor
1143
+ });
1144
+ }
1145
+ );
1094
1146
  server.tool(
1095
1147
  "get-container-registry-auth",
1096
1148
  {
1097
- containerRegistryAuthId: import_zod.z.string().describe("ID of the container registry auth to retrieve")
1149
+ containerRegistryAuthId: import_zod2.z.string().describe("ID of the container registry auth to retrieve")
1098
1150
  },
1099
1151
  async (params) => {
1100
1152
  const result = await runpodRequest(
@@ -1113,9 +1165,9 @@ function registerTools(server, ctx) {
1113
1165
  server.tool(
1114
1166
  "create-container-registry-auth",
1115
1167
  {
1116
- name: import_zod.z.string().describe("Name for the container registry auth"),
1117
- username: import_zod.z.string().describe("Registry username"),
1118
- password: import_zod.z.string().describe("Registry password")
1168
+ name: import_zod2.z.string().describe("Name for the container registry auth"),
1169
+ username: import_zod2.z.string().describe("Registry username"),
1170
+ password: import_zod2.z.string().describe("Registry password")
1119
1171
  },
1120
1172
  async (params) => {
1121
1173
  const result = await runpodRequest(
@@ -1136,7 +1188,7 @@ function registerTools(server, ctx) {
1136
1188
  server.tool(
1137
1189
  "delete-container-registry-auth",
1138
1190
  {
1139
- containerRegistryAuthId: import_zod.z.string().describe("ID of the container registry auth to delete")
1191
+ containerRegistryAuthId: import_zod2.z.string().describe("ID of the container registry auth to delete")
1140
1192
  },
1141
1193
  async (params) => {
1142
1194
  const result = await runpodRequest(