@runpod/mcp-server 1.2.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 CHANGED
@@ -1,5 +1,52 @@
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
+
21
+ ## 1.3.0
22
+
23
+ ### Minor Changes
24
+
25
+ - 3e6dedf: Add HTTP transport for hosted MCP server deployments. The package now exports three entrypoints: `@runpod/mcp-server` (stdio, unchanged), `@runpod/mcp-server/http` (streamable HTTP with per-request auth), and `@runpod/mcp-server/tools` (shared tool definitions). This enables deploying the MCP server on Vercel or any HTTP-capable host where each request carries its own RunPod API key via the Authorization header. Existing stdio users are unaffected.
26
+ - 3e6dedf: Add a "Sign in with Runpod" OAuth flow to the hosted HTTP server so it can act as the authorization server for Claude's MCP connector. When `MCP_OAUTH_ENABLED=true`, the server advertises itself in the OAuth discovery metadata and exposes `GET /authorize` and `POST /token`. The flow reuses the Runpod flash auth backend: `/authorize` creates a guest `createFlashAuthRequest` and hands off to the Runpod console for approval, and `/token` polls `flashAuthRequestStatus` and returns the minted Runpod API key as the access token, which the server then forwards to the Runpod API. The backend endpoint and console base URL are configurable via `RUNPOD_GRAPHQL_URL` and `CONSOLE_BASE_URL`.
27
+ - 3e6dedf: Complete the hosted OAuth flow for real MCP clients. Add an OAuth 2.0 Dynamic Client Registration endpoint (`POST /register`, RFC 7591) and advertise it as `registration_endpoint`, so clients like Claude can register before signing in. Make the Runpod REST and Serverless API hosts configurable via `RUNPOD_REST_API_URL` and `RUNPOD_SERVERLESS_API_URL` so a deployment authenticating with non-production keys can target the matching environment. The console handoff path is `/integrations/mcp/login`.
28
+ - 3e6dedf: Validate the OAuth `redirect_uri` against an allowlist. Because the authorization code redeems into a real Runpod API key, `/authorize` and `/token` now reject any `redirect_uri` that is not an allowlisted client callback, preventing an attacker from crafting an authorize link that delivers the code (and key) to a host they control. Loopback addresses (`http://localhost` / `127.0.0.1` / `::1`, any port) are always allowed per RFC 8252; the hosted client callbacks default to Claude's, and the list is extendable via `MCP_ALLOWED_REDIRECT_URIS` (comma-separated).
29
+ - 3e6dedf: Address hosted OAuth review feedback:
30
+ - Remove the `MCP_OAUTH_ENABLED` flag — the hosted HTTP server always advertises the OAuth sign-in challenge. Callers that bring their own Runpod API key as the bearer token are unaffected (they never hit the challenge).
31
+ - Default `CONSOLE_BASE_URL` to the production console (`https://console.runpod.io`) so a deploy that forgets to set it doesn't silently redirect users to localhost.
32
+ - `/token` now polls for most of the function budget (~45s) instead of returning a non-retryable `authorization_pending` after ~10s, avoiding a dead-end when console→backend approval propagation lags.
33
+ - Caller-tracking falls back to the inbound HTTP `User-Agent` on the stateless HTTP transport, where the per-request server never sees the MCP `initialize` `clientInfo` (previously reported `client=unknown`).
34
+ - Stop advertising PKCE (`S256`) since it isn't enforced server-side; security rests on the `redirect_uri` allowlist and the single-use flash approval.
35
+ - Default the minted key name to `runpod-mcp` (`RUNPOD_API_KEY_NAME`), so hosted keys are identifiable/revocable. Set `RUNPOD_API_KEY_NAME=""` to suppress it for a backend that has not shipped the `apiKeyName` argument.
36
+
37
+ - 3e6dedf: Simplify hosted HTTP auth to pure token passthrough. The server now forwards the caller's Bearer token directly to the Runpod API and holds no credential of its own — there is no shared server-side key and no token translation. When `MCP_OAUTH_ENABLED=true`, unauthenticated requests return a `WWW-Authenticate` challenge so OAuth-capable clients start the "Sign in with Runpod" flow. Removes the `RUNPOD_HTTP_SHARED_API_KEY` environment variable and the `jose` dependency.
38
+
39
+ ### Patch Changes
40
+
41
+ - 3e6dedf: Support naming the minted Runpod API key in the OAuth flow. Set `RUNPOD_API_KEY_NAME` (e.g. `runpod-mcp`) to pass `apiKeyName` through to the flash backend's `createFlashAuthRequest`, so the key shows up under that name in the user's dashboard. It is omitted by default for compatibility with backends that don't yet support the argument.
42
+ - 3e6dedf: Address low-severity review nits on the hosted HTTP / OAuth path:
43
+ - Make the public discovery GraphQL host configurable via `RUNPOD_PUBLIC_GRAPHQL_URL` (was hardcoded to prod, so a dev deploy hit prod GraphQL).
44
+ - Report the real package version in the hosted server's outbound `User-Agent` (read from package.json at runtime, since tsup's build-time define doesn't run when Vercel compiles `api/index.ts`).
45
+ - Gate OAuth request-id / handoff-URL logging behind `MCP_VERBOSE_LOGS` (request ids are live, single-use auth codes).
46
+ - `stream-job` now surfaces the most recent polling error in its timeout payload instead of discarding it.
47
+ - Pass the parsed request body to the MCP transport explicitly; dispose the per-request server/transport on response close; guard `getBaseUrl` against a missing `Host`; handle a `Buffer` request body in the token endpoint.
48
+ - Single CORS source of truth (handler, not `vercel.json`); stop serving the whole repo as static assets; add an `oauth-e2e` npm script and `engines.pnpm`; fix docs that misattributed the OAuth routes and listed the new env vars.
49
+
3
50
  ## 1.2.0
4
51
 
5
52
  ### Minor Changes
package/README.md CHANGED
@@ -1,46 +1,58 @@
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)
3
4
 
4
- This Model Context Protocol (MCP) server lets you manage Runpod infrastructure through any MCP-compatible client. It provides tools for working with Pods, Serverless endpoints, templates, network volumes, and container registry authentications.
5
+ This is the official Runpod Model Context Protocol (MCP) server, published to npm as `@runpod/mcp-server`.
5
6
 
6
- ## Quick start
7
+ It supports two deployment modes:
8
+
9
+ - Local `stdio` for Claude Desktop, Claude Code, Cursor, VS Code, and other MCP clients that launch a local process. The caller sets `RUNPOD_API_KEY` in the environment.
10
+ - Hosted Streamable HTTP for Vercel or other HTTP-capable platforms. Each request carries its own `Authorization: Bearer <token>`, which the server forwards directly to the Runpod API. The token can be a Runpod API key or one obtained through the OAuth "Sign in with Runpod" flow.
11
+
12
+ The server never holds a credential of its own and never shares one across users.
7
13
 
8
- ### Requirements
14
+ ## Requirements
9
15
 
10
16
  - Node.js 18 or higher.
11
- - A Runpod account and API key ([get your API key](https://www.runpod.io/console/user/settings)).
17
+ - A Runpod account and API key: https://www.runpod.io/console/user/settings
12
18
 
13
- ### Running with npx
19
+ ## Quick start
20
+
21
+ ### Guided install
14
22
 
15
- You can run the server directly without installation:
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:
16
24
 
17
25
  ```bash
18
- RUNPOD_API_KEY=YOUR_API_KEY npx @runpod/mcp-server@latest
26
+ npx @runpod/mcp-server@latest add
19
27
  ```
20
28
 
21
- ### Installing via Smithery
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`.
22
30
 
23
- To install for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@runpod/runpod-mcp-ts):
31
+ ### Run locally with `npx`
32
+
33
+ ```bash
34
+ RUNPOD_API_KEY=YOUR_API_KEY npx -y @runpod/mcp-server@latest
35
+ ```
36
+
37
+ ### Install via Smithery
24
38
 
25
39
  ```bash
26
40
  npx -y @smithery/cli install @runpod/runpod-mcp-ts --client claude
27
41
  ```
28
42
 
29
- ## Setting up with your client
43
+ ## Local MCP clients
30
44
 
31
- Most MCP clients use a JSON configuration file with the same general structure. The examples below show the npx approach (recommended for most users) and the local build approach (for development). Replace `YOUR_API_KEY` with your actual Runpod API key.
45
+ Local MCP clients should use the default package entrypoint, which is the `stdio` server.
32
46
 
33
47
  ### Claude Code
34
48
 
35
- Add the MCP server globally so it's available across all your projects:
36
-
37
49
  ```bash
38
50
  claude mcp add runpod -s user \
39
51
  -e RUNPOD_API_KEY=YOUR_API_KEY \
40
52
  -- npx -y @runpod/mcp-server@latest
41
53
  ```
42
54
 
43
- Or add it to a specific project (creates a `.mcp.json` file you can commit):
55
+ For a project-local server:
44
56
 
45
57
  ```bash
46
58
  claude mcp add runpod -s project \
@@ -48,11 +60,19 @@ claude mcp add runpod -s project \
48
60
  -- npx -y @runpod/mcp-server@latest
49
61
  ```
50
62
 
51
- Verify the server is connected with `claude mcp list`. If you're in an active session, type `/mcp` to reconnect without restarting.
63
+ Verify with `claude mcp list`. In an active session, use `/mcp` to reconnect.
52
64
 
53
65
  ### Claude Desktop
54
66
 
55
- Edit the config file at `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
67
+ Local MCP servers in Claude Desktop still use `claude_desktop_config.json`.
68
+
69
+ macOS:
70
+
71
+ `~/Library/Application Support/Claude/claude_desktop_config.json`
72
+
73
+ Windows:
74
+
75
+ `%APPDATA%\\Claude\\claude_desktop_config.json`
56
76
 
57
77
  ```json
58
78
  {
@@ -72,7 +92,7 @@ Restart Claude Desktop after saving.
72
92
 
73
93
  ### Cursor
74
94
 
75
- Add the following to `.cursor/mcp.json` in your project directory, or `~/.cursor/mcp.json` for global access:
95
+ Add this to `.cursor/mcp.json` in your project or `~/.cursor/mcp.json` globally:
76
96
 
77
97
  ```json
78
98
  {
@@ -88,73 +108,105 @@ Add the following to `.cursor/mcp.json` in your project directory, or `~/.cursor
88
108
  }
89
109
  ```
90
110
 
91
- ### Windsurf
111
+ ### VS Code, Windsurf, Cline, JetBrains, and other local clients
92
112
 
93
- Open Windsurf settings (Cmd+Shift+P → "Open Windsurf Settings"), navigate to the Cascade section, and enable MCP. Then edit `~/.codeium/windsurf/mcp_config.json`:
113
+ Use the same pattern:
94
114
 
95
- ```json
96
- {
97
- "mcpServers": {
98
- "runpod": {
99
- "command": "npx",
100
- "args": ["-y", "@runpod/mcp-server@latest"],
101
- "env": {
102
- "RUNPOD_API_KEY": "YOUR_API_KEY"
103
- }
104
- }
105
- }
106
- }
107
- ```
115
+ - command: `npx`
116
+ - args: `["-y", "@runpod/mcp-server@latest"]`
117
+ - env: `RUNPOD_API_KEY=YOUR_API_KEY`
108
118
 
109
- ### VS Code (GitHub Copilot)
119
+ For a broader list of MCP clients, see https://modelcontextprotocol.io/clients
110
120
 
111
- MCP works in VS Code's agent mode (requires VS Code 1.101+). Add the following to `.vscode/mcp.json` in your workspace:
121
+ ## Hosted HTTP deployment
112
122
 
113
- ```json
114
- {
115
- "mcpServers": {
116
- "runpod": {
117
- "command": "npx",
118
- "args": ["-y", "@runpod/mcp-server@latest"],
119
- "env": {
120
- "RUNPOD_API_KEY": "YOUR_API_KEY"
121
- }
122
- }
123
- }
124
- }
125
- ```
123
+ The package also exports a Streamable HTTP entrypoint at `@runpod/mcp-server/http`, and this repo includes a Vercel function in `api/index.ts`.
126
124
 
127
- Click the "Start" button next to the server entry to connect.
125
+ The hosted transport is stateless:
128
126
 
129
- ### Cline
127
+ - Each request creates a fresh MCP server instance.
128
+ - The caller must send `Authorization: Bearer <token>`.
129
+ - No credentials are cached or shared server-side.
130
130
 
131
- Open Cline in VS Code, click the hamburger menu (☰), and go to MCP Servers. You can add servers through the marketplace or manually configure in Cline's settings using the same JSON structure shown above.
131
+ ### Hosted auth
132
132
 
133
- ### JetBrains IDEs
133
+ The server forwards the caller's Bearer token directly to the Runpod API as the credential for that request. There is no server-side or shared key.
134
134
 
135
- Create a `mcp.json` file at `~/.junie/mcp.json` (global) or `.junie/mcp/` in your project:
135
+ The token can be either:
136
136
 
137
- ```json
138
- {
139
- "mcpServers": {
140
- "runpod": {
141
- "command": "npx",
142
- "args": ["-y", "@runpod/mcp-server@latest"],
143
- "env": {
144
- "RUNPOD_API_KEY": "YOUR_API_KEY"
145
- }
146
- }
147
- }
148
- }
137
+ - a Runpod API key the caller configured manually, or
138
+ - a Runpod API key obtained through the OAuth "Sign in with Runpod" flow (see below).
139
+
140
+ An unauthenticated request receives a `401` with a `WWW-Authenticate` header pointing at the protected-resource metadata, which tells an OAuth-capable client (such as Claude) to start the sign-in flow. A caller that brings its own API key as the bearer token never hits that path.
141
+
142
+ ### Sign in with Runpod (authorize flow)
143
+
144
+ In OAuth mode the hosted server is itself the authorization server for Claude's connector. It advertises itself in `/.well-known/oauth-protected-resource` and `/.well-known/oauth-authorization-server`, pointing `authorization_endpoint` at its own `GET /authorize`, `token_endpoint` at its own `POST /token`, and `registration_endpoint` at its own `POST /register`.
145
+
146
+ The flow reuses the Runpod flash auth backend and mints a real Runpod API key:
147
+
148
+ 1. The client registers via `POST /register` (OAuth Dynamic Client Registration, RFC 7591) to obtain a `client_id`. This is a public client; no client secret is used.
149
+ 2. `GET /authorize` calls the guest `createFlashAuthRequest` mutation to get a request id (which serves as the OAuth authorization code), then `302`-redirects the browser to the console handoff page (`/integrations/mcp/login`), carrying the request id plus the client's `redirect_uri` and `state`.
150
+ 3. The user logs in and approves the request in the console. On approval the backend mints a Runpod API key for the request.
151
+ 4. The console returns the browser to the client's `redirect_uri` with `code=<request id>`.
152
+ 5. `POST /token` polls the guest `flashAuthRequestStatus` query for that id; once `APPROVED`, it returns the minted `apiKey` as the `access_token`. The client then sends that key as its bearer token on every MCP request, and the server forwards it to the Runpod API.
153
+
154
+ This flow uses these environment variables:
155
+
156
+ - `RUNPOD_GRAPHQL_URL`: flash auth backend endpoint (default `https://api.runpod.io/graphql`).
157
+ - `CONSOLE_BASE_URL`: base URL of the console that hosts the handoff login page (default `https://console.runpod.io`).
158
+ - `RUNPOD_REST_API_URL` / `RUNPOD_SERVERLESS_API_URL`: override the REST and Serverless API hosts so a deployment authenticating with non-production keys can target the matching environment.
159
+ - `RUNPOD_API_KEY_NAME`: name for the minted key as shown in the user's dashboard. Defaults to `runpod-mcp`. Set it to `""` to omit the name for a backend that does not support the `apiKeyName` argument (such backends reject the request when it is sent).
160
+ - `MCP_ALLOWED_REDIRECT_URIS`: comma-separated extra `redirect_uri` values to allow, in addition to the built-in Claude callbacks. Loopback addresses (`localhost`/`127.0.0.1`/`::1`, any port) are always allowed. `/authorize` and `/token` reject any `redirect_uri` not on this list, since the authorization code redeems into a real API key.
161
+
162
+ You can verify the entire flow end to end with `MCP_SERVER_URL=<deployment-url> npx tsx scripts/oauth-e2e.ts` (the harness uses a loopback callback).
163
+
164
+ Notes and current limitations:
165
+
166
+ - PKCE is not supported: `code_challenge` is neither advertised nor enforced (the flash flow has no place to bind it). Security relies on the `redirect_uri` allowlist and the single-use, short-lived flash approval.
167
+ - The minted key is named via `RUNPOD_API_KEY_NAME` (default `runpod-mcp`), which requires a flash backend that supports the `apiKeyName` argument. Against a backend without it, set `RUNPOD_API_KEY_NAME=""`.
168
+
169
+ ### Vercel
170
+
171
+ This repo already contains `vercel.json` and the Vercel handler.
172
+
173
+ Deploy with the Vercel CLI:
174
+
175
+ ```bash
176
+ vercel
177
+ vercel --prod
178
+ ```
179
+
180
+ After deploy, test the endpoint:
181
+
182
+ ```bash
183
+ curl -i https://YOUR-DEPLOYMENT.vercel.app/
184
+ ```
185
+
186
+ Unauthenticated requests should return `401`.
187
+
188
+ ### Hosted smoke test
189
+
190
+ ```bash
191
+ MCP_SERVER_URL=https://YOUR-DEPLOYMENT.vercel.app \
192
+ RUNPOD_API_KEY=YOUR_API_KEY \
193
+ pnpm smoke:http
149
194
  ```
150
195
 
151
- ### Other clients
196
+ This validates:
197
+
198
+ - MCP initialization.
199
+ - `tools/list`.
200
+ - A public GraphQL-backed tool call.
201
+ - An authenticated REST-backed tool call.
202
+
203
+ ## Claude Desktop and hosted MCP
152
204
 
153
- This server uses stdio transport and works with any MCP-compatible client. The configuration pattern is the same across all clients — point the command to `npx` with `@runpod/mcp-server@latest` as the argument, and set `RUNPOD_API_KEY` in the environment. For a full list of MCP clients, see the [official MCP clients page](https://modelcontextprotocol.io/clients).
205
+ Use the local `stdio` integration for Claude Desktop today.
154
206
 
155
- ## Using a local build
207
+ For remote clients such as Claude's connector, deploy the hosted HTTP server. The client then runs the OAuth "Sign in with Runpod" flow, and the resulting Runpod API key is forwarded to the Runpod API on each request.
156
208
 
157
- If you want to run from a local clone of the repo (for development or to test unreleased changes):
209
+ ## Local development
158
210
 
159
211
  ```bash
160
212
  git clone https://github.com/runpod/runpod-mcp.git
@@ -163,28 +215,42 @@ pnpm install
163
215
  pnpm build
164
216
  ```
165
217
 
166
- Then replace the `command` and `args` in any of the configurations above with:
218
+ Run the local build directly:
219
+
220
+ ```bash
221
+ RUNPOD_API_KEY=YOUR_API_KEY node dist/stdio.mjs
222
+ ```
223
+
224
+ Or point a client at your local build:
167
225
 
168
226
  ```json
169
227
  {
170
228
  "command": "node",
171
- "args": ["/absolute/path/to/runpod-mcp/dist/index.mjs"]
229
+ "args": ["/absolute/path/to/runpod-mcp/dist/stdio.mjs"],
230
+ "env": {
231
+ "RUNPOD_API_KEY": "YOUR_API_KEY"
232
+ }
172
233
  }
173
234
  ```
174
235
 
175
- After making changes to the source, re-run `pnpm build` and restart or reconnect the MCP server for changes to take effect.
236
+ ### Local smoke test
237
+
238
+ ```bash
239
+ RUNPOD_API_KEY=YOUR_API_KEY pnpm build
240
+ RUNPOD_API_KEY=YOUR_API_KEY pnpm smoke:stdio
241
+ ```
176
242
 
177
243
  ## Usage examples
178
244
 
179
245
  ### List all Pods
180
246
 
181
- ```
247
+ ```text
182
248
  Can you list all my Runpod Pods?
183
249
  ```
184
250
 
185
251
  ### Create a new Pod
186
252
 
187
- ```
253
+ ```text
188
254
  Create a new Runpod Pod with the following specifications:
189
255
  - Name: test-pod
190
256
  - Image: runpod/pytorch:2.1.0-py3.10-cuda11.8.0-devel-ubuntu22.04
@@ -194,7 +260,7 @@ Create a new Runpod Pod with the following specifications:
194
260
 
195
261
  ### Create a Serverless endpoint
196
262
 
197
- ```
263
+ ```text
198
264
  Create a Runpod Serverless endpoint with the following configuration:
199
265
  - Name: my-endpoint
200
266
  - Template ID: 30zmvf89kd
@@ -204,36 +270,41 @@ Create a Runpod Serverless endpoint with the following configuration:
204
270
 
205
271
  ## Contributing
206
272
 
207
- To get started with local development, clone the repo and build:
273
+ The source is now split by responsibility:
274
+
275
+ - `src/stdio.ts`: local `stdio` entrypoint.
276
+ - `src/http.ts`: bearer-token extraction and the per-request MCP session for the Streamable HTTP transport.
277
+ - `src/tools.ts`: all Runpod MCP tools.
278
+ - `src/server.ts`: shared server metadata and construction.
279
+ - `api/index.ts`: Vercel adapter and the OAuth authorization-server routes (`/.well-known/*`, `/register`, `/authorize`, `/token`).
280
+
281
+ After changes:
208
282
 
209
283
  ```bash
210
- git clone https://github.com/runpod/runpod-mcp.git
211
- cd runpod-mcp
212
- pnpm install
284
+ pnpm type-check
285
+ pnpm lint
213
286
  pnpm build
214
287
  ```
215
288
 
216
- After making changes, rebuild with `pnpm build`. In Claude Code, type `/mcp` to reconnect to the updated server without restarting your session. You can also use `pnpm build:watch` for auto-rebuilding during development.
217
-
218
- All tools live in `src/index.ts`. The server uses two backends: the REST API (`runpodRequest()`) for authenticated CRUD operations, and the GraphQL API (`graphqlRequest()`) for public read-only queries like GPU types and data centers. Follow existing patterns when adding new tools — kebab-case names, Zod schemas with `.describe()`, and JSON stringified responses.
219
-
220
- This project uses [changesets](https://github.com/changesets/changesets) for versioning and npm publishing. Every PR with user-facing changes needs a changeset file at `.changeset/DESCRIPTIVE_NAME.md`:
289
+ For transport validation:
221
290
 
222
- ```markdown
223
- ---
224
- "@runpod/mcp-server": minor
225
- ---
226
-
227
- Description of what changed and why.
291
+ ```bash
292
+ pnpm smoke:stdio
293
+ pnpm smoke:http
228
294
  ```
229
295
 
230
- Use `patch` for bug fixes, `minor` for new tools or features, and `major` for breaking changes. The `.changeset/` directory is gitignored, so use `git add -f` to stage changeset files.
296
+ This project uses [changesets](https://github.com/changesets/changesets) for versioning and npm publishing. Every PR with user-facing changes needs a changeset file at `.changeset/DESCRIPTIVE_NAME.md`.
231
297
 
232
- See [CLAUDE.md](./CLAUDE.md) for the full development guide including architecture details, tool conventions, and known issues.
298
+ See `CLAUDE.md` and `docs/context.md` for contributor guidance.
233
299
 
234
300
  ## Security considerations
235
301
 
236
- This server requires your Runpod API key, which grants full access to your Runpod account. Never share your API key. Be cautious about what operations you perform, and consider setting up a separate API key with limited permissions. Do not use this in a production environment without proper security measures.
302
+ This server acts with the full permissions of the supplied `RUNPOD_API_KEY`.
303
+
304
+ - Never share your API key.
305
+ - Be deliberate about destructive tools.
306
+ - Treat hosted deployments as sensitive infrastructure.
307
+ - Each request authenticates with its own caller-supplied token, which is forwarded to the Runpod API and never persisted server-side.
237
308
 
238
309
  ## License
239
310