@runpod/mcp-server 1.2.0 → 1.3.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 +29 -0
- package/README.md +154 -93
- package/dist/chunk-CRHHCQRI.mjs +1108 -0
- package/dist/chunk-CRHHCQRI.mjs.map +1 -0
- package/dist/http.cjs +1224 -0
- package/dist/http.cjs.map +1 -0
- package/dist/http.d.cts +18 -0
- package/dist/http.d.ts +18 -0
- package/dist/http.mjs +88 -0
- package/dist/http.mjs.map +1 -0
- package/dist/stdio.cjs +1158 -0
- package/dist/stdio.cjs.map +1 -0
- package/dist/stdio.d.cts +2 -0
- package/dist/stdio.d.ts +2 -0
- package/dist/stdio.mjs +1135 -0
- package/dist/stdio.mjs.map +1 -0
- package/dist/tools.cjs +1142 -0
- package/dist/tools.cjs.map +1 -0
- package/dist/tools.d.cts +21 -0
- package/dist/tools.d.ts +21 -0
- package/dist/tools.mjs +7 -0
- package/dist/tools.mjs.map +1 -0
- package/package.json +28 -13
- package/dist/index.d.cts +0 -3
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -1136
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -1102
- package/dist/index.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @runpod/mcp-server
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 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.
|
|
8
|
+
- 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`.
|
|
9
|
+
- 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`.
|
|
10
|
+
- 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).
|
|
11
|
+
- 3e6dedf: Address hosted OAuth review feedback:
|
|
12
|
+
- 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).
|
|
13
|
+
- 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.
|
|
14
|
+
- `/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.
|
|
15
|
+
- 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`).
|
|
16
|
+
- Stop advertising PKCE (`S256`) since it isn't enforced server-side; security rests on the `redirect_uri` allowlist and the single-use flash approval.
|
|
17
|
+
- 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.
|
|
18
|
+
|
|
19
|
+
- 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.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 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.
|
|
24
|
+
- 3e6dedf: Address low-severity review nits on the hosted HTTP / OAuth path:
|
|
25
|
+
- Make the public discovery GraphQL host configurable via `RUNPOD_PUBLIC_GRAPHQL_URL` (was hardcoded to prod, so a dev deploy hit prod GraphQL).
|
|
26
|
+
- 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`).
|
|
27
|
+
- Gate OAuth request-id / handoff-URL logging behind `MCP_VERBOSE_LOGS` (request ids are live, single-use auth codes).
|
|
28
|
+
- `stream-job` now surfaces the most recent polling error in its timeout payload instead of discarding it.
|
|
29
|
+
- 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.
|
|
30
|
+
- 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.
|
|
31
|
+
|
|
3
32
|
## 1.2.0
|
|
4
33
|
|
|
5
34
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,46 +1,48 @@
|
|
|
1
1
|
# Runpod MCP server
|
|
2
|
+
|
|
2
3
|
[](https://smithery.ai/server/@runpod/runpod-mcp-ts)
|
|
3
4
|
|
|
4
|
-
This Model Context Protocol (MCP) server
|
|
5
|
+
This is the official Runpod Model Context Protocol (MCP) server, published to npm as `@runpod/mcp-server`.
|
|
5
6
|
|
|
6
|
-
|
|
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.
|
|
7
11
|
|
|
8
|
-
|
|
12
|
+
The server never holds a credential of its own and never shares one across users.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
9
15
|
|
|
10
16
|
- Node.js 18 or higher.
|
|
11
|
-
- A Runpod account and API key
|
|
17
|
+
- A Runpod account and API key: https://www.runpod.io/console/user/settings
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
## Quick start
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
### Run locally with `npx`
|
|
16
22
|
|
|
17
23
|
```bash
|
|
18
|
-
RUNPOD_API_KEY=YOUR_API_KEY npx @runpod/mcp-server@latest
|
|
24
|
+
RUNPOD_API_KEY=YOUR_API_KEY npx -y @runpod/mcp-server@latest
|
|
19
25
|
```
|
|
20
26
|
|
|
21
|
-
###
|
|
22
|
-
|
|
23
|
-
To install for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@runpod/runpod-mcp-ts):
|
|
27
|
+
### Install via Smithery
|
|
24
28
|
|
|
25
29
|
```bash
|
|
26
30
|
npx -y @smithery/cli install @runpod/runpod-mcp-ts --client claude
|
|
27
31
|
```
|
|
28
32
|
|
|
29
|
-
##
|
|
33
|
+
## Local MCP clients
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
Local MCP clients should use the default package entrypoint, which is the `stdio` server.
|
|
32
36
|
|
|
33
37
|
### Claude Code
|
|
34
38
|
|
|
35
|
-
Add the MCP server globally so it's available across all your projects:
|
|
36
|
-
|
|
37
39
|
```bash
|
|
38
40
|
claude mcp add runpod -s user \
|
|
39
41
|
-e RUNPOD_API_KEY=YOUR_API_KEY \
|
|
40
42
|
-- npx -y @runpod/mcp-server@latest
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
For a project-local server:
|
|
44
46
|
|
|
45
47
|
```bash
|
|
46
48
|
claude mcp add runpod -s project \
|
|
@@ -48,11 +50,19 @@ claude mcp add runpod -s project \
|
|
|
48
50
|
-- npx -y @runpod/mcp-server@latest
|
|
49
51
|
```
|
|
50
52
|
|
|
51
|
-
Verify
|
|
53
|
+
Verify with `claude mcp list`. In an active session, use `/mcp` to reconnect.
|
|
52
54
|
|
|
53
55
|
### Claude Desktop
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
Local MCP servers in Claude Desktop still use `claude_desktop_config.json`.
|
|
58
|
+
|
|
59
|
+
macOS:
|
|
60
|
+
|
|
61
|
+
`~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
62
|
+
|
|
63
|
+
Windows:
|
|
64
|
+
|
|
65
|
+
`%APPDATA%\\Claude\\claude_desktop_config.json`
|
|
56
66
|
|
|
57
67
|
```json
|
|
58
68
|
{
|
|
@@ -72,7 +82,7 @@ Restart Claude Desktop after saving.
|
|
|
72
82
|
|
|
73
83
|
### Cursor
|
|
74
84
|
|
|
75
|
-
Add
|
|
85
|
+
Add this to `.cursor/mcp.json` in your project or `~/.cursor/mcp.json` globally:
|
|
76
86
|
|
|
77
87
|
```json
|
|
78
88
|
{
|
|
@@ -88,73 +98,105 @@ Add the following to `.cursor/mcp.json` in your project directory, or `~/.cursor
|
|
|
88
98
|
}
|
|
89
99
|
```
|
|
90
100
|
|
|
91
|
-
### Windsurf
|
|
101
|
+
### VS Code, Windsurf, Cline, JetBrains, and other local clients
|
|
92
102
|
|
|
93
|
-
|
|
103
|
+
Use the same pattern:
|
|
94
104
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
```
|
|
105
|
+
- command: `npx`
|
|
106
|
+
- args: `["-y", "@runpod/mcp-server@latest"]`
|
|
107
|
+
- env: `RUNPOD_API_KEY=YOUR_API_KEY`
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
For a broader list of MCP clients, see https://modelcontextprotocol.io/clients
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
## Hosted HTTP deployment
|
|
112
112
|
|
|
113
|
-
|
|
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
|
-
```
|
|
113
|
+
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
114
|
|
|
127
|
-
|
|
115
|
+
The hosted transport is stateless:
|
|
128
116
|
|
|
129
|
-
|
|
117
|
+
- Each request creates a fresh MCP server instance.
|
|
118
|
+
- The caller must send `Authorization: Bearer <token>`.
|
|
119
|
+
- No credentials are cached or shared server-side.
|
|
130
120
|
|
|
131
|
-
|
|
121
|
+
### Hosted auth
|
|
132
122
|
|
|
133
|
-
|
|
123
|
+
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
124
|
|
|
135
|
-
|
|
125
|
+
The token can be either:
|
|
136
126
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
127
|
+
- a Runpod API key the caller configured manually, or
|
|
128
|
+
- a Runpod API key obtained through the OAuth "Sign in with Runpod" flow (see below).
|
|
129
|
+
|
|
130
|
+
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.
|
|
131
|
+
|
|
132
|
+
### Sign in with Runpod (authorize flow)
|
|
133
|
+
|
|
134
|
+
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`.
|
|
135
|
+
|
|
136
|
+
The flow reuses the Runpod flash auth backend and mints a real Runpod API key:
|
|
137
|
+
|
|
138
|
+
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.
|
|
139
|
+
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`.
|
|
140
|
+
3. The user logs in and approves the request in the console. On approval the backend mints a Runpod API key for the request.
|
|
141
|
+
4. The console returns the browser to the client's `redirect_uri` with `code=<request id>`.
|
|
142
|
+
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.
|
|
143
|
+
|
|
144
|
+
This flow uses these environment variables:
|
|
145
|
+
|
|
146
|
+
- `RUNPOD_GRAPHQL_URL`: flash auth backend endpoint (default `https://api.runpod.io/graphql`).
|
|
147
|
+
- `CONSOLE_BASE_URL`: base URL of the console that hosts the handoff login page (default `https://console.runpod.io`).
|
|
148
|
+
- `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.
|
|
149
|
+
- `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).
|
|
150
|
+
- `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.
|
|
151
|
+
|
|
152
|
+
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).
|
|
153
|
+
|
|
154
|
+
Notes and current limitations:
|
|
155
|
+
|
|
156
|
+
- 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.
|
|
157
|
+
- 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=""`.
|
|
158
|
+
|
|
159
|
+
### Vercel
|
|
160
|
+
|
|
161
|
+
This repo already contains `vercel.json` and the Vercel handler.
|
|
162
|
+
|
|
163
|
+
Deploy with the Vercel CLI:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
vercel
|
|
167
|
+
vercel --prod
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
After deploy, test the endpoint:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
curl -i https://YOUR-DEPLOYMENT.vercel.app/
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Unauthenticated requests should return `401`.
|
|
177
|
+
|
|
178
|
+
### Hosted smoke test
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
MCP_SERVER_URL=https://YOUR-DEPLOYMENT.vercel.app \
|
|
182
|
+
RUNPOD_API_KEY=YOUR_API_KEY \
|
|
183
|
+
pnpm smoke:http
|
|
149
184
|
```
|
|
150
185
|
|
|
151
|
-
|
|
186
|
+
This validates:
|
|
187
|
+
|
|
188
|
+
- MCP initialization.
|
|
189
|
+
- `tools/list`.
|
|
190
|
+
- A public GraphQL-backed tool call.
|
|
191
|
+
- An authenticated REST-backed tool call.
|
|
192
|
+
|
|
193
|
+
## Claude Desktop and hosted MCP
|
|
152
194
|
|
|
153
|
-
|
|
195
|
+
Use the local `stdio` integration for Claude Desktop today.
|
|
154
196
|
|
|
155
|
-
|
|
197
|
+
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
198
|
|
|
157
|
-
|
|
199
|
+
## Local development
|
|
158
200
|
|
|
159
201
|
```bash
|
|
160
202
|
git clone https://github.com/runpod/runpod-mcp.git
|
|
@@ -163,28 +205,42 @@ pnpm install
|
|
|
163
205
|
pnpm build
|
|
164
206
|
```
|
|
165
207
|
|
|
166
|
-
|
|
208
|
+
Run the local build directly:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
RUNPOD_API_KEY=YOUR_API_KEY node dist/stdio.mjs
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Or point a client at your local build:
|
|
167
215
|
|
|
168
216
|
```json
|
|
169
217
|
{
|
|
170
218
|
"command": "node",
|
|
171
|
-
"args": ["/absolute/path/to/runpod-mcp/dist/
|
|
219
|
+
"args": ["/absolute/path/to/runpod-mcp/dist/stdio.mjs"],
|
|
220
|
+
"env": {
|
|
221
|
+
"RUNPOD_API_KEY": "YOUR_API_KEY"
|
|
222
|
+
}
|
|
172
223
|
}
|
|
173
224
|
```
|
|
174
225
|
|
|
175
|
-
|
|
226
|
+
### Local smoke test
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
RUNPOD_API_KEY=YOUR_API_KEY pnpm build
|
|
230
|
+
RUNPOD_API_KEY=YOUR_API_KEY pnpm smoke:stdio
|
|
231
|
+
```
|
|
176
232
|
|
|
177
233
|
## Usage examples
|
|
178
234
|
|
|
179
235
|
### List all Pods
|
|
180
236
|
|
|
181
|
-
```
|
|
237
|
+
```text
|
|
182
238
|
Can you list all my Runpod Pods?
|
|
183
239
|
```
|
|
184
240
|
|
|
185
241
|
### Create a new Pod
|
|
186
242
|
|
|
187
|
-
```
|
|
243
|
+
```text
|
|
188
244
|
Create a new Runpod Pod with the following specifications:
|
|
189
245
|
- Name: test-pod
|
|
190
246
|
- Image: runpod/pytorch:2.1.0-py3.10-cuda11.8.0-devel-ubuntu22.04
|
|
@@ -194,7 +250,7 @@ Create a new Runpod Pod with the following specifications:
|
|
|
194
250
|
|
|
195
251
|
### Create a Serverless endpoint
|
|
196
252
|
|
|
197
|
-
```
|
|
253
|
+
```text
|
|
198
254
|
Create a Runpod Serverless endpoint with the following configuration:
|
|
199
255
|
- Name: my-endpoint
|
|
200
256
|
- Template ID: 30zmvf89kd
|
|
@@ -204,36 +260,41 @@ Create a Runpod Serverless endpoint with the following configuration:
|
|
|
204
260
|
|
|
205
261
|
## Contributing
|
|
206
262
|
|
|
207
|
-
|
|
263
|
+
The source is now split by responsibility:
|
|
264
|
+
|
|
265
|
+
- `src/stdio.ts`: local `stdio` entrypoint.
|
|
266
|
+
- `src/http.ts`: bearer-token extraction and the per-request MCP session for the Streamable HTTP transport.
|
|
267
|
+
- `src/tools.ts`: all Runpod MCP tools.
|
|
268
|
+
- `src/server.ts`: shared server metadata and construction.
|
|
269
|
+
- `api/index.ts`: Vercel adapter and the OAuth authorization-server routes (`/.well-known/*`, `/register`, `/authorize`, `/token`).
|
|
270
|
+
|
|
271
|
+
After changes:
|
|
208
272
|
|
|
209
273
|
```bash
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
pnpm install
|
|
274
|
+
pnpm type-check
|
|
275
|
+
pnpm lint
|
|
213
276
|
pnpm build
|
|
214
277
|
```
|
|
215
278
|
|
|
216
|
-
|
|
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`:
|
|
279
|
+
For transport validation:
|
|
221
280
|
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
Description of what changed and why.
|
|
281
|
+
```bash
|
|
282
|
+
pnpm smoke:stdio
|
|
283
|
+
pnpm smoke:http
|
|
228
284
|
```
|
|
229
285
|
|
|
230
|
-
|
|
286
|
+
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
287
|
|
|
232
|
-
See
|
|
288
|
+
See `CLAUDE.md` and `docs/context.md` for contributor guidance.
|
|
233
289
|
|
|
234
290
|
## Security considerations
|
|
235
291
|
|
|
236
|
-
This server
|
|
292
|
+
This server acts with the full permissions of the supplied `RUNPOD_API_KEY`.
|
|
293
|
+
|
|
294
|
+
- Never share your API key.
|
|
295
|
+
- Be deliberate about destructive tools.
|
|
296
|
+
- Treat hosted deployments as sensitive infrastructure.
|
|
297
|
+
- Each request authenticates with its own caller-supplied token, which is forwarded to the Runpod API and never persisted server-side.
|
|
237
298
|
|
|
238
299
|
## License
|
|
239
300
|
|