@runpod/mcp-server 3.4.0 → 4.1.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 CHANGED
@@ -1,5 +1,59 @@
1
1
  # @runpod/mcp-server
2
2
 
3
+ ## 4.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1d049b6: Serve the official Runpod plugin's guides and concept graph: `list-guides`, `read-guide`, `lookup-concept` and `search-concepts`, plus each guide as a `runpod://guides/` resource, from the `@runpod/plugin-knowledge` package.
8
+ - 09a565a: `list-templates` now returns 20 templates per page by default instead of the
9
+ full list. Follow `nextCursor` to see the rest.
10
+
11
+ Resync the vendored v2 OpenAPI spec with production. Adds five account-secret
12
+ tools (`list-secrets`, `get-secret`, `create-secret`, `update-secret`,
13
+ `delete-secret`) and refreshes the schemas for pods, endpoints, templates,
14
+ registries, and clusters — most visibly the `cursor`/`limit` query parameters
15
+ and `pagination` response block the API now serves on its list endpoints.
16
+
17
+ `list-endpoints` and `list-templates` now page on the server: `limit` and
18
+ `cursor` go to the API, and `pagination` returns its `nextCursor` and
19
+ `hasNextPage` plus `returned`. `list-endpoints` drops the old client-side
20
+ `total`, `offset`, and `truncated` fields, which only counted one server page.
21
+ Requires `@runpod/typescript-api-sdk` 0.2.0.
22
+
23
+ ### Patch Changes
24
+
25
+ - 531ecb0: Serve MCP tool annotations. Every tool now advertises `readOnlyHint`,
26
+ `destructiveHint`, `idempotentHint`, and `openWorldHint` in `tools/list`:
27
+ generated tools derive them from the HTTP method they wrap, so they cannot
28
+ drift from the spec, with generator-config overrides for operations that delete
29
+ through a POST or PUT (`pod-action`, `update-ssh-keys`), and the curated
30
+ overlay declares them per tool. Hosts can
31
+ auto-approve reads and gate deletions, cancels, and queue purges on a human.
32
+
33
+ ## 4.0.0
34
+
35
+ ### Major Changes
36
+
37
+ - 57b3973: Require Node.js 20 or newer and add the published Runpod TypeScript API SDK as the REST client foundation. Share deadline enforcement across REST, runtime, GraphQL, and log readers; preserve per-caller credentials and bounded polling. Update GPU selection with a sparse REST PATCH and isolate queued-job diagnostics by caller.
38
+
39
+ Pin the bundled TypeScript API SDK to 0.1.1. Reject null required arguments and invalid endpoint IDs before issuing requests.
40
+
41
+ - 57b3973: Serve the same REST v2 generated tools and skill resources over HTTP and stdio. Remove the legacy v1 fallback, hand-written tool surface, and package tools export. See specgen/old-mcp-tools.yaml for renamed tools and pod-action replacements. Include argument checks, compact lists, bounded log snapshots, upstream retry guidance, caller tracking, and opt-in hosted analytics. The REST SDK is bundled into both entrypoints.
42
+
43
+ Remove the repository Dockerfile, Smithery manifest/install instructions, and bundled Cursor configuration. Use the hosted MCP URL or the published npm CLI, configured in your MCP client, instead. The install wizard verifies keys against REST v2 and honors RUNPOD_API_BASE_URL; retired REST host variables no longer disable credential preflight.
44
+
45
+ ### Minor Changes
46
+
47
+ - 57b3973: Add hosted-only feedback, question, and private journal tools when a storage sink is configured. Contributions are optional and scrubbed for secrets. Scope journal reads to the authenticated account, bound reads, verify storage confirmation, and reject malformed storage requests. Local stdio does not advertise these tools.
48
+
49
+ Redact nested YAML/Compose secrets, Hugging Face tokens, and URL query credentials. Clarify that journals are not published to other accounts and Runpod stores submissions for review.
50
+
51
+ ### Patch Changes
52
+
53
+ - 57b3973: Fix two secret-redaction leaks in ALP submission scrubbing, and replace the config-assignment regex with an explicit scan.
54
+
55
+ `password: p&ss#word123` and `password=abc&def` were truncated at the `&` and everything after it was stored in plaintext. A sensitive assignment nested inside a non-sensitive value was skipped entirely, so `https://host/?password=secret` passed through untouched. Values now keep `&` and `#` unless the key sits in a URL query string, where those characters really do bound the value, and the scan resumes inside a non-sensitive value instead of past it. Unbalanced and unterminated quotes no longer disable redaction. Scrub version is now 5.
56
+
3
57
  ## 3.4.0
4
58
 
5
59
  ### Minor Changes
@@ -92,7 +146,7 @@
92
146
 
93
147
  - 259241d: Enforce PKCE (S256) in every hosted OAuth flow. `/authorize` rejects missing, malformed, or non-S256 challenges before issuing a code and forwards a valid challenge to the flash backend. `/token` requires a valid, matching `code_verifier` before returning the minted key; missing PKCE state, `plain`, and non-matching verifiers are rejected.
94
148
 
95
- Requires the backend `codeChallenge` / `codeChallengeMethod` fields on `createFlashAuthRequest` / `flashAuthRequestStatus` (runpod/RunPod, DR-1398) to be deployed.
149
+ Requires the backend `codeChallenge` / `codeChallengeMethod` fields on `createFlashAuthRequest` / `flashAuthRequestStatus` to be deployed.
96
150
 
97
151
  - f6208cd: Diagnose stuck queued jobs instead of leaving them ambiguous. A job that stays IN_QUEUE has two very different causes that its status alone cannot distinguish: no host has the endpoint's GPU available (capacity), or a worker spun up and is crash-looping — the platform marks it UNHEALTHY while the job stays queued indefinitely, and agents reliably misread that as a capacity shortage. `get-job-status` now best-effort attaches the endpoint's worker summary (`workerHealth`) and a plain-language `hint` whenever the job is IN_QUEUE (v2 only; the extra lookup never fails the status call, and the diagnosis is cached ~15s per endpoint so polling loops do not amplify into repeated worker-list fetches): UNHEALTHY workers → crash-loop guidance naming the worker ids to inspect with `stream-worker-logs`; zero workers → capacity guidance; throttled/initializing → wait guidance. The `get-job-status`, `endpoint-health`, `list-endpoint-workers`, and `stream-worker-logs` descriptions now cross-reference each other so agents are routed from a stuck job to the worker logs without prior knowledge of the platform's queueing behavior.
98
152
  - f36f191: Send the reshaped v2 Serverless write schema, and support load-balancing endpoints.
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2025 RunPod, Inc.
1
+ Copyright 2025 Runpod, Inc.
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
package/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # Runpod MCP server
2
2
 
3
- [![smithery badge](https://smithery.ai/badge/@runpod/runpod-mcp-ts)](https://smithery.ai/server/@runpod/runpod-mcp-ts)
4
-
5
3
  The official Runpod Model Context Protocol (MCP) server. It lets MCP clients such as Claude Code, Claude Desktop, Cursor, Windsurf, and VS Code manage your Runpod Pods, Serverless endpoints, templates, network volumes, and more.
6
4
 
7
5
  **We host it for you at [`https://mcp.getrunpod.io/`](https://mcp.getrunpod.io/)** — point your client at that URL and sign in with Runpod. Nothing to install, no API key on disk. Or run it locally from npm as [`@runpod/mcp-server`](https://www.npmjs.com/package/@runpod/mcp-server).
@@ -44,7 +42,7 @@ In **Claude Code**, the native plugin route also wires up the hosted MCP server
44
42
 
45
43
  ### Requirements
46
44
 
47
- - Node.js 18 or higher.
45
+ - Node.js 20 or higher.
48
46
  - A Runpod account and [API key](https://www.runpod.io/console/user/settings).
49
47
 
50
48
  ## Connect to the hosted server
@@ -71,8 +69,14 @@ claude mcp add --transport http runpod -s user https://mcp.getrunpod.io/
71
69
 
72
70
  An OAuth-capable client starts the "Sign in with Runpod" flow automatically on first connect: it opens a browser, you log in to the Runpod console and approve, and the server obtains a Runpod API key scoped to your session. Nothing is stored on disk.
73
71
 
72
+ > **Which account does OAuth pick?** The key is minted for whichever account or team profile your browser's console session has selected when you approve. If you belong to multiple teams, switch to the right profile in the [console](https://console.runpod.io) first (or check afterwards — the resources the tools return are that profile's). To change it later, switch profiles in the console and re-authenticate from your MCP client.
73
+
74
74
  > Prefer your own API key over OAuth? Append `--header "Authorization: Bearer YOUR_API_KEY"` to the `claude mcp add` command (or add a `headers` block in the JSON). The server forwards that key to the Runpod API directly.
75
75
 
76
+ ### Usage analytics
77
+
78
+ The hosted server records one anonymous event per tool call (tool name, status, duration, transport — never your API key, arguments, or any resource data; your identity is an irreversible salted hash). To opt out, send the header `X-Runpod-Analytics: off` — e.g. append `--header "X-Runpod-Analytics: off"` to the `claude mcp add` command. Running locally, nothing is ever sent.
79
+
76
80
  ## Run locally with `npx`
77
81
 
78
82
  Run the server as a local `stdio` process with your own API key:
@@ -81,12 +85,6 @@ Run the server as a local `stdio` process with your own API key:
81
85
  RUNPOD_API_KEY=YOUR_API_KEY npx -y @runpod/mcp-server@latest
82
86
  ```
83
87
 
84
- Or install via [Smithery](https://smithery.ai/server/@runpod/runpod-mcp-ts):
85
-
86
- ```bash
87
- npx -y @smithery/cli install @runpod/runpod-mcp-ts --client claude
88
- ```
89
-
90
88
  ### Local client setup
91
89
 
92
90
  Local clients launch the `stdio` server and set `RUNPOD_API_KEY` in the environment.
@@ -138,16 +136,25 @@ Create a Serverless endpoint named my-endpoint with image
138
136
  runpod/test-output:0.0.1, GPU pool AMPERE_80, 0 min workers, 3 max workers.
139
137
  ```
140
138
 
141
- On the v2 API (the default), endpoints are image-based — pass an image and a GPU pool (a `pool` value from `list-gpu-types`), not a template.
139
+ Endpoints are image-based — pass an image and a GPU pool (a `pool` value from `list-gpu-types`), not a template.
140
+
141
+ See [`docs/configuration.md`](docs/configuration.md) for host overrides, private image pull (registry credentials vs ECR delegation), and large-output handling.
142
+
143
+ ## Upgrading from 3.x
142
144
 
143
- See [`docs/configuration.md`](docs/configuration.md) for REST v1/v2 selection and the `templateId` migration note, private image pull (registry credentials vs ECR delegation), and large-output handling.
145
+ Eight tools follow their spec operationIds (e.g.
146
+ `create-container-registry-auth` → `create-registry`, `get-billing` →
147
+ `list-billing`) and `start-pod`/`stop-pod`/`restart-pod` fold into
148
+ `pod-action` with an `action` argument. The full old→new map is
149
+ [`specgen/old-mcp-tools.yaml`](specgen/old-mcp-tools.yaml). The server is
150
+ v2-only; `RUNPOD_REST_VERSION` and the v1 fallback are retired.
144
151
 
145
152
  ## Security
146
153
 
147
154
  This server acts with the full permissions of the supplied API key.
148
155
 
149
156
  - Never share your API key.
150
- - Be deliberate with destructive tools.
157
+ - Be deliberate with destructive tools. Every tool carries MCP annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`) derived from the operation it wraps, so a host can auto-approve reads and gate `delete-pod` or `purge-endpoint-queue` on a human.
151
158
  - Each request authenticates with its own caller-supplied token, which is forwarded to the Runpod API and **never persisted server-side**. The server never holds a credential of its own and never shares one across users.
152
159
 
153
160
  ## Local development
@@ -174,8 +181,19 @@ pnpm test # offline unit suite — no network or API key required
174
181
  pnpm build
175
182
  ```
176
183
 
184
+ Tools are generated from the vendored v2 OpenAPI spec rather than hand-written: see [specgen/DESIGN.md](specgen/DESIGN.md) for the walkthrough and [specgen/README.md](specgen/README.md) for the regeneration workflow and drift gates.
185
+
177
186
  This project uses [changesets](https://github.com/changesets/changesets) for versioning and npm publishing; every PR with user-facing changes needs a changeset. See `CLAUDE.md` and `docs/context.md` for full contributor guidance, architecture, and the test suite.
178
187
 
179
188
  ## License
180
189
 
181
190
  Apache-2.0
191
+
192
+ ### JavaScript API migration
193
+
194
+ This major release removes the `@runpod/mcp-server/tools` package export and
195
+ its `registerTools` API. The legacy registration API is not compatible with
196
+ the new generated surface. Applications should connect to the server through
197
+ MCP using the `runpod-mcp` CLI, or use `handleMcpRequest` from
198
+ `@runpod/mcp-server/http` when embedding the HTTP handler. The HTTP entry point
199
+ also no longer re-exports the legacy `registerTools` or `ToolContext`.
@@ -0,0 +1,73 @@
1
+ Bundled Runpod REST API v2 TypeScript SDK
2
+ =======================================
3
+
4
+ MIT License
5
+
6
+ Copyright (c) 2026 RunPod, Inc.
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
25
+
26
+
27
+ This package bundles openapi-fetch (https://github.com/openapi-ts/openapi-typescript).
28
+
29
+ MIT License
30
+
31
+ Copyright (c) 2023 Drew Powers
32
+
33
+ Permission is hereby granted, free of charge, to any person obtaining a copy
34
+ of this software and associated documentation files (the "Software"), to deal
35
+ in the Software without restriction, including without limitation the rights
36
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
37
+ copies of the Software, and to permit persons to whom the Software is
38
+ furnished to do so, subject to the following conditions:
39
+
40
+ The above copyright notice and this permission notice shall be included in all
41
+ copies or substantial portions of the Software.
42
+
43
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
46
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
48
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
49
+ SOFTWARE.
50
+
51
+ This package also bundles structured-headers (https://github.com/evert/structured-headers).
52
+
53
+ MIT License
54
+
55
+ Copyright (c) 2018-2026 Evert Pot
56
+
57
+ Permission is hereby granted, free of charge, to any person obtaining a copy
58
+ of this software and associated documentation files (the "Software"), to deal
59
+ in the Software without restriction, including without limitation the rights
60
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
61
+ copies of the Software, and to permit persons to whom the Software is
62
+ furnished to do so, subject to the following conditions:
63
+
64
+ The above copyright notice and this permission notice shall be included in all
65
+ copies or substantial portions of the Software.
66
+
67
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
70
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
71
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
72
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
73
+ SOFTWARE.
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/_shared/hosts.ts
4
+ function pick(value, fallback) {
5
+ return value?.trim().replace(/\/+$/, "") || fallback;
6
+ }
7
+ function sdkBase(env) {
8
+ return pick(env.RUNPOD_API_BASE_URL, "https://api.runpod.io");
9
+ }
10
+ function serverlessBase(env) {
11
+ return pick(env.RUNPOD_SERVERLESS_API_URL, "https://api.runpod.ai/v2");
12
+ }
13
+ function publicGraphqlBase(env) {
14
+ return pick(env.RUNPOD_PUBLIC_GRAPHQL_URL, "https://api.runpod.io/graphql");
15
+ }
16
+ function authedGraphqlBase(env) {
17
+ return pick(env.RUNPOD_AUTHED_GRAPHQL_URL, "https://api.runpod.io/graphql");
18
+ }
19
+
20
+ export {
21
+ sdkBase,
22
+ serverlessBase,
23
+ publicGraphqlBase,
24
+ authedGraphqlBase
25
+ };
26
+ //# sourceMappingURL=chunk-DDX42UTT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/_shared/hosts.ts"],"sourcesContent":["// Env-resolved API base URLs, extracted from the retired dual-version backend\n// resolver (backend.ts) when the spec-generated surface became the only one.\n// The credential preflight compares only active SDK and runtime destinations.\n\nexport type Env = Record<string, string | undefined>;\n\n// '' reads as unset everywhere: the wrong-environment guard already strips\n// empty vars before comparing, and every consumer (the credential checker's\n// probe URL, the GraphQL/log clients) must resolve identically or the\n// guard's \"checker and guard cannot disagree\" invariant breaks.\nfunction pick(value: string | undefined, fallback: string): string {\n return value?.trim().replace(/\\/+$/, '') || fallback;\n}\n\n// Generated paths include /v2, so the SDK base is the API origin.\nexport function sdkBase(env: Env): string {\n return pick(env.RUNPOD_API_BASE_URL, 'https://api.runpod.io');\n}\nexport function serverlessBase(env: Env): string {\n return pick(env.RUNPOD_SERVERLESS_API_URL, 'https://api.runpod.ai/v2');\n}\nexport function publicGraphqlBase(env: Env): string {\n return pick(env.RUNPOD_PUBLIC_GRAPHQL_URL, 'https://api.runpod.io/graphql');\n}\n// A separate var from publicGraphqlBase despite the identical default:\n// RUNPOD_PUBLIC_GRAPHQL_URL is the documented credential-free discovery\n// override and gets pointed at stubs freely, so routing authed calls through it\n// would turn \"point this anywhere\" into \"send the caller's API key there\".\nexport function authedGraphqlBase(env: Env): string {\n return pick(env.RUNPOD_AUTHED_GRAPHQL_URL, 'https://api.runpod.io/graphql');\n}\n"],"mappings":";;;AAUA,SAAS,KAAK,OAA2B,UAA0B;AACjE,SAAO,OAAO,KAAK,EAAE,QAAQ,QAAQ,EAAE,KAAK;AAC9C;AAGO,SAAS,QAAQ,KAAkB;AACxC,SAAO,KAAK,IAAI,qBAAqB,uBAAuB;AAC9D;AACO,SAAS,eAAe,KAAkB;AAC/C,SAAO,KAAK,IAAI,2BAA2B,0BAA0B;AACvE;AACO,SAAS,kBAAkB,KAAkB;AAClD,SAAO,KAAK,IAAI,2BAA2B,+BAA+B;AAC5E;AAKO,SAAS,kBAAkB,KAAkB;AAClD,SAAO,KAAK,IAAI,2BAA2B,+BAA+B;AAC5E;","names":[]}