chore: version packages - #80
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
github-actions
Bot
force-pushed
the
changeset-release/main
branch
3 times, most recently
from
August 7, 2026 19:30
da8d1d2 to
9a64ea7
Compare
justinwlin
self-requested a review
August 7, 2026 19:30
justinwlin
approved these changes
Aug 7, 2026
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
August 10, 2026 14:28
9a64ea7 to
6f965da
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
August 14, 2026 22:57
6f965da to
ea0acfe
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@runpod/mcp-server@3.3.0
Minor Changes
a62a663:
list-gpu-typesandget-gpu-typenow always sendproductwith theirinclude=AVAILABILITYcatalog requests, via a new optionalproductparameter (POD|CLUSTER|SERVERLESS, defaultPOD). Availability is product-specific — the same GPU can be scarce for Pods and plentiful for Serverless — and the next v2 API release makesproductrequired with availability (400 without it), so this keeps the availability lookups working and lets agents ask for the context they actually deploy to: passSERVERLESSwhen picking a GPU for an endpoint,CLUSTERfor Instant Clusters. WhenincludeAvailabilityis false,productis not sent (the API also rejectsproductwithoutinclude=AVAILABILITY). The CPU catalog tools never request availability, so they are unaffected.7074c87: Add an
sshPublicKeyparameter tocreate-podfor full SSH access (create-pod should expose SSH terminal access and inject account public keys #73), and fix v2 GPU pod creation failing without an explicitgpuCount.The REST API has no SSH switch yet (the console and runpodctl set it via GraphQL
startSsh), so Pods created through the MCP got a valid-looking port-22 mapping but no authorized key — direct SSH, SCP, SFTP, and rsync all failed. PassingsshPublicKeynow merges the key into thePUBLIC_KEYenvironment variable and ensures22/tcpis exposed, which any image honoring thePUBLIC_KEYconvention (all runpod/* official images) turns into a running sshd with the key installed. Template deploys extend the template's ports and env rather than replacing them, and an existingPUBLIC_KEYis appended to rather than overwritten.The key is validated before the Pod is created, because an unusable value would otherwise produce a Pod that looks SSH-ready and is not:
22/tcpexposed, junk inPUBLIC_KEY, and a reply reporting SSH as configured. Rejected with a 400: a private key in any format (PEM in any case, or a PuTTY.ppk, which contains neither the words "private key" nor a public key line), a file path or SHA256 fingerprint passed instead of the.pubfile's contents, a bare base64 blob with no key type, and an empty or whitespace-only value (omit the parameter to create a Pod without SSH). Accepted keys are normalized to one key per line with CRLF stripped, since a stray carriage return corrupts theauthorized_keysentry it lands on. Error messages never echo the rejected value, which may itself be secret.create-podalso now rejects agpuCountbelow 1 or with a fractional part, which the v2 API answers with an opaque 422.Separately, the v2 pod-create mapper omitted
gpu.countwhen the caller passed nogpuCount, trusting the spec's documented server-side default of 1. In practice the scheduler matches zero machines without it and every create fails with a misleading "no instances available" error (verified live against both v2 hosts). The mapper now always emitscount, defaulting to 1.9176c78: Clamp long-poll tool budgets on the hosted HTTP server, which runs behind a 60-second Vercel function limit.
runsync-endpointwaited 90 seconds by default (300 viawait) andstream-jobpolled for up to 5 minutes, so for a slow job the function was reaped mid-flight: the caller got a bare 504 and every chunk collected so far was discarded.Over HTTP,
runsync-endpointnow sends awaitcapped at 45000 ms — a job that outlives it comes back as a job ID plus a non-terminal status to poll withget-job-status.stream-jobstops after 45 seconds over HTTP and returns what it has withpollingTimedOut: true;/streamdrains what it hands out, so calling again resumes rather than replaying. Its HTTP polls also sendwait=1000, since the server otherwise holds an empty response for 10 seconds and the budget is only checked between polls. Both tool descriptions are now written per transport, so a caller is told the one budget that applies to them and where to go for more —run-endpoint+get-job-status, or the runtime API directly. The stdio server has no deadline and is unchanged.f20d987: Give every outbound request a client-side deadline — every tool call, the OAuth handshake on the hosted server, and the install wizard's key check. node-fetch applies no timeout of its own, so a Runpod host that accepted the connection and then went silent — a wedged worker, a load balancer holding the socket — left a tool call pending forever, and on the hosted server that ended as a bare 504 when Vercel reaped the function at its 60s limit.
Requests now abort after 30 seconds with a named
RequestTimeoutErrornaming the API that went quiet, the deadline it was given, and what to do next.runsync-endpointis the one call that legitimately asks the server to hold a connection open, so it derives its deadline from thewaitit requested (the server's own 90-second default whenwaitis omitted) rather than being truncated. Successful tool output is unchanged.On the hosted transport the cap is a single budget for the whole invocation rather than a fresh allowance per request, because several tools make more than one call —
get-job-statusadds a queued-job diagnosis,deploy-hub-repoandset-endpoint-gpusread before they write,update-endpointreads the current scaler before patching it — and two full deadlines back to back outlived the platform even with each one bounded. Each request is clamped to what is left, so a stall anywhere in a handler surfaces as the named error instead of a 504. The queued-job diagnosis, which only decorates a status that is already in hand, is bounded at 5 seconds so it cannot spend a budget the reply itself needs.stream-jobbounds each poll by the wait the server was asked to hold rather than by its whole budget. A deadline set to the budget meant one wedged socket consumed the entire run in a single attempt — 45 seconds on the hosted server, five minutes on stdio — so the loop's retry path never ran and a stall returned nothing at all. Each poll now gets the hold plus a round trip, which both clears a reply already in flight and leaves the budget room to reconnect; a run that ends on the budget reportspollingTimedOutwith the last error rather than discarding it.The hosted OAuth routes are bounded too.
/tokenpolls the flash backend for an approval, and one silent socket there hung the whole handshake until the platform reaped it — the worst place for a blank error, since the user has no credential yet to retry with. Each backend call now has its own 10-second deadline (override withMCP_FLASH_TIMEOUT_MS), never exceeding what is left of a 45-second poll budget, and a stall is reported as a named error naming the operation, the host and the deadline. Therunpod-mcp installwizard's key verification gets the same treatment, so it can no longer sit at "Verifying…" indefinitely.A timed-out GraphQL read is also no longer described as a possible write. The advice keys off the HTTP method and GraphQL is always POST on the wire, so
list-gpu-typestiming out used to tell the agent the call may have landed and to "check with the matching list-/get- tool first" — which is the tool that just failed. Only actual mutations carry that warning now.Patch Changes
2b6480d: Refuse the standalone GET SSE stream with 405. The HTTP server is stateless and never sends server-initiated messages, so the GET "listen" stream has nothing to carry — but the SDK accepted it anyway and held the response open with nothing to send until the platform's maxDuration killed it, at which point every connected client immediately re-opened it. On the hosted deployment that loop was ~1.1M hung requests per day (90% of all traffic), each ending in a 60-second timeout, and it dominated the serverless bill. GET now gets the spec's answer for a server without an SSE stream: 405 Method Not Allowed with an
Allow: POST, DELETEheader and a JSON-RPC error body, before any auth work — a 401 there would send OAuth clients into a pointless re-auth flow. Clients per the MCP spec treat the 405 as "no server-initiated messages offered" and continue POST-only; tool calls are unaffected.674fa2c: Fix Claude Code detection and registration in the install wizard on Windows (Bug: Install wizard never detects Claude Code on Windows, even when it's installed and working #56).
Detection used the POSIX-only
command -v claudeplus three POSIX install paths, soClaude Code was undetectable on a standard Windows install. Windows now probes
%USERPROFILE%\.local\bin\claude.exe(native installer) and%APPDATA%\npm\claude.cmd(global npm), and registration resolves the real entrypoint from the installed package
manifest instead of running the
.cmdshim throughcmd.exe. Candidates arecanonicalized and confined to their standard install roots, a PATH result resolving into
the current project is rejected, and Claude Code is spawned with
PATH,COMSPEC,PATHEXT,NODE_OPTIONS, andNODE_PATHsanitized, so nothing a project directory canplant receives your API key. Custom npm prefixes and redirected roaming profiles are
still not auto-detected; when Claude Code is not found, the wizard now prints the exact
claude mcpcommand to register or remove the entry yourself.Claude Code add and remove are now verified against its own
.claude.jsonrather thanthe CLI exit code, which reports success for writes it never made. Re-running the wizard
over an existing entry now says the entry was left unchanged instead of printing a bare
success, since the CLI does not update it and a rotated API key would otherwise look
applied. An entry shadowed by a local-scope one is called out with the command to clear
it.
For the clients that own a JSON config, an edit that would leave the file unparseable —
or land in a duplicated server block the client does not read — now fails with the
original file untouched instead of reporting success, and validity is judged by the
parser each client actually ships (Claude Desktop is strict JSON, Cursor and VS Code
accept JSONC, Windsurf's tolerance is unverified and disclosed rather than assumed).
Claude Desktop on Linux and VS Code now honour
XDG_CONFIG_HOMEinstead of writingwhere those clients never read, an empty or relative
APPDATA/XDG_CONFIG_HOMEnolonger resolves a config path against the current directory, configs this wizard creates
are
0600because they hold a plaintext API key, and a key taken from the environment istrimmed.