@runpod/mcp-server 4.3.0 → 4.5.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,40 @@
1
1
  # @runpod/mcp-server
2
2
 
3
+ ## 4.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 83bffb7: Hosted server: a new optional ALP tool, `report_how_user_found_runpod`, asks
8
+ the agent once per account how its user ended up on Runpod: the kind of
9
+ work (`useCase`) and why Runpod came up (`source`: `searched`,
10
+ `user_named`, `recommended`, `other`), or that it has no such context
11
+ (`noContext`). It collects categories and at most a short generic note,
12
+ never the user's own words. The ask rides in the `initialize` instructions; on each
13
+ `initialize` with a resolved account the server checks the storage sink and
14
+ omits the ask once the account has answered (a failed lookup keeps the ask),
15
+ and the sink keeps the first answer per account, with the server answering
16
+ `already_submitted` to any later one. Answers are stored with the
17
+ other ALP submissions under their own `referral` route, with the note capped at 200
18
+ characters, and scrubbed like every other submission. Absent on local stdio
19
+ and whenever the sink is not configured, like the other ALP tools.
20
+ - ff02fdb: Every tool now carries a human-readable `title` in tools/list (for example `List GPU types` for `list-gpu-types`), so hosts can show readable names and the server meets directory review requirements. Generated tools derive the title from their name, with overrides in `specgen/generator-config.yaml`; curated tools declare their own.
21
+
22
+ ### Patch Changes
23
+
24
+ - da524df: GraphQL errors that Runpod returns on an HTTP 200 now fail the tool call with a status taken from the error code (401, 403, 400 including Runpod's own `RUNPOD` input errors, otherwise 502) instead of 200, so agents get the matching recovery hint. A non-array `errors` field no longer crashes the call.
25
+ - d075b00: Network failures reaching the Runpod API (DNS, connection refused, unreachable host, TLS errors, or a connection dropped mid-request) now come back as tool errors with the underlying `cause` code and a recovery hint, instead of escaping as an opaque JSON-RPC `-32603 fetch failed`. Failures where the request never reached Runpod say a retry is safe; a dropped connection says a write may have been applied and to check with a get- or list- tool before calling again.
26
+ - 6a577ea: Update `@runpod/plugin-knowledge` from 1.7.4 to 1.8.0, so `list-guides` and `read-guide` serve the plugin's 1.8.0 skills and guides, including the new `runpod-build-template` skill.
27
+
28
+ ## 4.4.0
29
+
30
+ ### Minor Changes
31
+
32
+ - a58f9f1: New `search-docs` tool: searches Runpod documentation, curated support knowledge, the Runpod blog and runpod.io through the runpod-assistant knowledge index, and returns ranked passages with source URLs. The hosted server searches with its own service key and retries the index's capacity rejections with jittered backoff. Local installs call the hosted `POST /api/search` with the user's API key.
33
+
34
+ ### Patch Changes
35
+
36
+ - 4b53720: Hosted server: `tools/call` now answers as `application/json` too, so the CDN compresses tool results; only tools that hold their response open (`runsync-endpoint`, `get-job-status`, `stream-job`, `stream-pod-logs`, `stream-worker-logs`, `deploy-hub-repo`) keep SSE, declared with `CuratedTool.holdsResponse`.
37
+
3
38
  ## 4.3.0
4
39
 
5
40
  ### Minor Changes
package/README.md CHANGED
@@ -84,6 +84,22 @@ An OAuth-capable client starts the "Sign in with Runpod" flow automatically on f
84
84
 
85
85
  > 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.
86
86
 
87
+ ### If sign-in fails with HTTP 403
88
+
89
+ A `403 Forbidden` response with the header `X-Vercel-Mitigated: deny` means the hosted server's firewall has temporarily blocked your IP address, usually after a burst of unauthenticated requests from an MCP client. This happens most often with Codex, which sends many unauthenticated requests while it signs in. The block covers every path, including `/register` and requests that carry an API key, and lifts on its own within an hour. Wait for it to expire, then use one of these options so the next connection doesn't trip it again.
90
+
91
+ You can send your API key as a header instead of signing in with OAuth, as described above. Authenticated requests don't count toward the limit. In Codex, add the key to the server entry in `~/.codex/config.toml`:
92
+
93
+ ```toml
94
+ [mcp_servers.runpod]
95
+ url = "https://mcp.getrunpod.io/"
96
+ bearer_token_env_var = "RUNPOD_API_KEY"
97
+ ```
98
+
99
+ Then export `RUNPOD_API_KEY` in the shell that launches Codex.
100
+
101
+ You can also [run the server locally](#run-locally-with-npx). The local server calls the Runpod API directly, so the hosted firewall only affects its `search-docs` tool, which still searches through the hosted server.
102
+
87
103
  ### Usage analytics
88
104
 
89
105
  The hosted server records one anonymous event per tool call (tool name, status, duration, transport) and per guide resource read (guide URI, or `unknown` on a miss), plus one event when it starts blocking a 404 loop (tool name and block length). It never records your API key or any resource data, and drops tool arguments except on the guide and concept tools (`list-guides`, `read-guide`, `lookup-concept`, `search-concepts`), where it keeps the guide id, concept name or search words, plus the kind of guide read. 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.
@@ -16,11 +16,15 @@ function publicGraphqlBase(env) {
16
16
  function authedGraphqlBase(env) {
17
17
  return pick(env.RUNPOD_AUTHED_GRAPHQL_URL, "https://api.runpod.io/graphql");
18
18
  }
19
+ function hostedMcpBase(env) {
20
+ return pick(env.RUNPOD_MCP_URL, "https://mcp.getrunpod.io");
21
+ }
19
22
 
20
23
  export {
21
24
  sdkBase,
22
25
  serverlessBase,
23
26
  publicGraphqlBase,
24
- authedGraphqlBase
27
+ authedGraphqlBase,
28
+ hostedMcpBase
25
29
  };
26
- //# sourceMappingURL=chunk-DDX42UTT.mjs.map
30
+ //# sourceMappingURL=chunk-4GF3CMSH.mjs.map
@@ -1 +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":[]}
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/** The hosted MCP server: install target, and stdio's search-docs backend. */\nexport function hostedMcpBase(env: Env): string {\n return pick(env.RUNPOD_MCP_URL, 'https://mcp.getrunpod.io');\n}\n/** The runpod-assistant Convex site serving /v1/search. No default: unset\n * means search is not configured. */\nexport function knowledgeSearchBase(env: Env): string | undefined {\n return pick(env.KNOWLEDGE_SEARCH_URL, '') || undefined;\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;AAEO,SAAS,cAAc,KAAkB;AAC9C,SAAO,KAAK,IAAI,gBAAgB,0BAA0B;AAC5D;","names":[]}