Releases: kychee-com/run402
v1.43.0 — deployDir helper + optional wallet on projects.list
Two developer-experience improvements for agents and Node SDK callers.
Highlights
sites.deployDir({ dir }) — directory in, URL out
A new helper on the Node SDK (@run402/sdk/node), MCP server, and CLI that takes a local directory path and does the walking, binary detection, base64 encoding, and manifest assembly for you. Agents no longer reimplement dir-walk boilerplate before every deploy.
- SDK:
r402.sites.deployDir({ project, dir, inherit?, target? }) - MCP tool:
deploy_site_dir(shares the Zod schema shape withdeploy_site) - CLI:
run402 sites deploy-dir <path> --project <id>
The walk skips .git/, node_modules/, .DS_Store at every depth, auto-detects UTF-8 vs. binary content, POSIX-normalizes paths, rejects symlinks, and errors out on empty directories before issuing a request. Inherits the existing /deployments/v1 inline-payload ceiling (~100 MB) — blob-backed large files come on a future rung.
projects.list(wallet?) — wallet now optional in Node
Following the precedent set by allowance.faucet(address?), projects.list() on the Node SDK now falls back to credentials.readAllowance()?.address when the wallet argument is omitted. Collapses the common "what are my projects?" call to a single line. Explicit-wallet callers (including sandbox providers that lack readAllowance) are unchanged.
Clear error messages point to both escape hatches when the fallback can't resolve: pass an explicit wallet, or use @run402/sdk/node with a configured allowance. Closes #113.
Package versions
- `run402-mcp@1.43.0` — https://www.npmjs.com/package/run402-mcp
- `run402@1.43.0` — https://www.npmjs.com/package/run402
- `@run402/sdk@1.43.0` — https://www.npmjs.com/package/@run402/sdk
All three must stay in sync per the monorepo's publish contract.
Compatibility
Both changes are additive. Existing sites.deploy(files) calls, existing deploy_site tool invocations, and existing projects.list(wallet) calls all continue to work unchanged.
v1.42.0
Breaking changes
sites.deploy signature aligned with the rest of the SDK
Every other method in @run402/sdk takes (projectId, opts) with payload inside opts. sites.deploy was the only outlier at (project, files, opts). Aligning it now since the SDK is still at 1.x and this is the cheap moment.
Before:
await r.sites.deploy(projectId, files, { target, inherit });After:
await r.sites.deploy(projectId, { files, target, inherit });Impact: any code that calls @run402/sdk's sites.deploy directly needs to move files into the options object. The run402 site deploy CLI command and the deploy_site MCP tool are unchanged for end users.
Install reliability
@x402/evm, @x402/fetch, mppx, and viem moved from optionalDependencies to dependencies in @run402/sdk. The x402 payment layer lives behind dynamic import() calls, and optional deps can fail silently on fresh installs (e.g. npm ci --omit=optional, broken mirrors, platform mismatches). When that happened, run402() looked healthy but the first paid request returned PaymentRequired instead of auto-paying — a very confusing failure. Hard deps fail loudly at install time instead.
Packages
run402-mcp@1.42.0— https://www.npmjs.com/package/run402-mcprun402@1.42.0— https://www.npmjs.com/package/run402@run402/sdk@1.42.0— https://www.npmjs.com/package/@run402/sdk
v1.41.0
Agent-UX polish for CLI, MCP, and SDK
Breaking
run402 allowance statusoutput field rename:funded→faucet_used. The old field was set totruewhenever the faucet had ever been invoked and couldn't be used as a "can this account pay now" check. The new name matches the actual semantic. The on-diskallowance.jsonschema is unchanged; only the CLI/SDK output field was renamed. A newconfiguredfield is also surfaced for "local allowance file exists." For real pay-readiness, userun402 allowance balance. (closes GH-109)
Fixes
-
Tier help text now reflects real prototype pricing.
run402 tier --help, MCPprovision_postgres_projecttier description, and both SKILL.md files advertised prototype as "free/testnet, 7d" while the server charged $0.10 USDC. Help now reads$0.10/7d, free with testnet faucetand the long-form note referencesrun402 allowance fund. (closes GH-110) -
projects pinnow documented as admin-only. CLI help, MCP tool description, and SDK JSDoc now make clear thatpinrequires run402 platform admin auth — project owners will always receive 403. The command is retained (admins still use it). (closes GH-103)
Links
v1.40.2 — packaging hotfix for v1.40.1
Hotfix
v1.40.1 was broken on install. Both run402 and run402-mcp imported the SDK via a monorepo-relative path that resolves to nowhere once the package is installed from npm — every command threw ERR_MODULE_NOT_FOUND before doing anything. Upgrade to v1.40.2 immediately.
Root cause
The SDK was extracted into its own package (@run402/sdk) in v1.40.0, but the MCP server (src/sdk.ts) and CLI (cli/lib/sdk.mjs) continued importing it via monorepo-relative paths (../sdk/dist/node/index.js and ../../sdk/dist/node/index.js). Those paths worked in the checked-out repo but pointed outside the tarball after npm install.
Fix
Bundle the already-built SDK tree into each tarball, mirroring the existing core/dist pattern:
run402-mcpnow shipssdk/distandsdk/core-distalongsidedistandcore/dist.run402(CLI) now shipssdk/(populated by theprepackstep) and rewrites its import to../sdk/dist/node/index.js.@run402/sdkitself is unchanged in content; version bumped to 1.40.2 to keep the three packages in sync.
@run402/sdk@1.40.1 (standalone SDK consumers) was not affected — only the two wrappers were broken.
Verified
npm pack both tarballs, extract, install, run — passes on v1.40.2.
v1.40.1 — chain-picking bugfix
Bug fix
@run402/sdk / run402 CLI / run402-mcp: the x402 chain-picking policy in sdk/src/node/paid-fetch.ts filtered 402 payment requirements on balance > 0, not balance >= amount.
When dust sat on one Base chain (mainnet or Sepolia) and the funds needed to cover the request sat on the other, x402Client would pick the dust chain and fail silently at settlement. The filter now compares each balance against the requested amount, so the funded chain always wins.
No API changes; drop-in upgrade.
v1.40.0 — Typed TypeScript SDK
Highlights
@run402/sdk — the whole run402 API as a typed TypeScript client
A new npm package, @run402/sdk, exposes every run402 endpoint as a typed method across 17 resource namespaces. The SDK is now the kernel — run402-mcp and run402 CLI are both thin shims over it.
import { run402 } from "@run402/sdk/node";
const r = run402();
const project = await r.projects.provision({ tier: "prototype" });
await r.blobs.put(project.project_id, "hello.txt", { content: "hi" });
await r.functions.deploy(project.project_id, { name: "api", code: "..." });
await r.sites.deploy(project.project_id, [{ file: "index.html", data: "<h1>hi</h1>" }]);Two entry points:
@run402/sdk— isomorphic (Node, Deno, Bun, V8 isolates). No filesystem access. Bring your ownCredentialsProvider.@run402/sdk/node— Node defaults. Reads your local keystore + allowance, auto-handles x402 payments via@x402/fetch.
Typed error hierarchy: PaymentRequired, ProjectNotFound, Unauthorized, ApiError, NetworkError — all extending Run402Error. No process.exit; exceptions only.
17 namespaces, ~90 methods
projects · blobs · functions · secrets · subdomains · domains · sites · service · tier · allowance · ai (+ image) · auth · senderDomain · billing · apps · email (+ webhooks) · contracts · admin
Why this matters
- Call run402 from anywhere JavaScript runs. User-deployed
deploy_functioncode, custom agents, CI scripts, future code-mode sandboxes. - Typed autocomplete + compile-time errors across the entire API surface — no more hand-rolled
fetch. - MCP tool and CLI output is byte-identical to 1.39.x — your existing scripts and agent prompts keep working. The SDK is the implementation, not a new surface users have to learn.
- Foundation for code-mode MCP. The SDK is designed to run inside a V8 isolate with a session-bound
CredentialsProvider— see the design doc for the sandbox sketch.
Under the hood
- Single source of truth for the HTTP kernel: lives in
sdk/src/kernel.ts, used by MCP, CLI, and OpenClaw - Shared credentials interface (
CredentialsProvider) with pluggable providers — the Node default wraps the existing keystore + allowance - Sync test extended to enforce MCP ↔ CLI ↔ OpenClaw ↔ SDK consistency: every tool maps to an SDK method; every SDK method is referenced by a tool
- Deleted legacy
src/paid-fetch.ts+cli/lib/paid-fetch.mjs(canonical location is nowsdk/src/node/paid-fetch.ts) - All three packages —
run402-mcp,run402,@run402/sdk— now publish in lockstep at the same version
Install
npm install -g run402@1.40.0 # CLI
npx run402-mcp@1.40.0 # MCP server
npm install @run402/sdk@1.40.0 # SDK275/275 tests pass. See openspec/changes/add-run402-sdk/ for the full design, specs, and 58-task implementation plan.
v1.39.0 — expose manifest
Declarative authorization manifest (supersedes RLS setup)
New MCP tools and CLI subcommands that replace the legacy /rls flow with a single convergent manifest describing the full authorization surface of a project (tables, views, RPCs).
What's new
apply_expose(MCP) /run402 projects apply-expose(CLI) — POST a manifest to/projects/v1/admin/:id/expose. Applying the same manifest twice is a no-op; items removed between applies have their policies, grants, triggers, and views dropped. Supportsuser_owns_rows,public_read_authenticated_write,public_read_write_UNRESTRICTED, and acustomescape hatch. Views and RPCs can be declared in the same manifest.get_expose(MCP) /run402 projects get-expose(CLI) — GET the current manifest. Returnssource: \"applied\"frominternal.project_manifest, orsource: \"introspected\"regenerated from live DB state if no manifest has ever been applied.- Dark by default — tables created via
run402 projects sqlare NOT readable by anon or authenticated until declared withexpose: true. Pre-v1.31 tables on Pod 01 are grandfathered.
Deprecated (sunset 2026-05-23)
setup_rlsMCP tool — useapply_expose.run402 projects rlsCLI — userun402 projects apply-expose.- Bundle deploys that embed an
rlsblock are auto-translated to an expose manifest during the deprecation window; after the sunset the/rlsendpoint returns410 Gone.
Docs
cli/llms-cli.txtRLS section rewritten around the manifest format, with the dark-by-default contract and migration path spelled out.setup_rlstool description and success output both flag the sunset date and point atapply_expose.
Closes #105.
v1.37.0 — email CLI/MCP: delete, reply, pagination, info, --vars
Fills six feature gaps in the email CLI + MCP relative to the already-shipped backend.
What's new
email delete [<mailbox_id>] --confirm(+delete_mailboxMCP tool) — drop a project's mailbox. Destructive, requires explicit confirm, clears the cached mailbox_id locally on success.email reply <message_id> --html "..."— threaded replies. The CLI fetches the original message, derives the reply-to address and default subject (`Re: `), and POSTs a new message with `in_reply_to` so the server can set RFC-822 `In-Reply-To` / `References` headers. Override with `--subject` or `--from-name`.email list --limit <n> --after <cursor>(+ matching `list_emails` MCP params) — pagination. Server caps at 200.email info— the preferred name for mailbox-info. `email status` is kept as a backward-compat alias.email sendraw-mode validation (CLI + MCP) — raw mode now requires BOTH `--subject` AND `--html`. Previously, either-alone was silently accepted and the server rejected the incomplete body.email send --vars '<json>'— one JSON object instead of N `--var key=value` repetitions. `--var` still works and overrides keys from `--vars`.
Also: `send_email` MCP tool now accepts an optional `in_reply_to` for threading new messages under an existing one.
Notes
- No server changes required — all endpoints existed.
- Closes #87.
Install
- MCP: `npm install -g run402-mcp@1.37.0`
- CLI: `npm install -g run402@1.37.0`
v1.36.1
Bug fix release — six CLI fixes across auth, projects, tier, init, and service.
Fixes
- auth set-password now attaches the required
apikeyheader (previously 401 Missing apikey). (#90) - projects subcommands (
info,keys,usage,schema,sql,rest,rls,delete,pin,promote-user,demote-user) now respect the active-project default promised in help — pass a project id or omit it and the active one is used. (#102) - projects provision and tier status no longer crash with a raw Node SyntaxError stack when the gateway returns a non-JSON (HTML 502/504) response — they emit a structured JSON error and exit non-zero. (#83, #84)
- service health and service status now exit non-zero on a non-2xx response (previously exited 0 even on a 503 degraded health response, breaking script piping). (#85)
- init mpp --json now polls the Tempo faucet for balance propagation (matching the x402 rail) and reports
allowance.funded: truein the JSON summary after a successful faucet top-up (previously the summary was stale from before the faucet ran). (#81)
Install
- MCP: `npm install -g run402-mcp@1.36.1`
- CLI: `npm install -g run402@1.36.1`
v1.36.0 — RLS template rename
Breaking change: RLS template rename
Aligns MCP tool schemas, CLI, and agent docs with the gateway's 2026-04-21 security-hardening rename. The new names are the security messaging — the old names downplayed what the templates actually do.
Template renames
| Before | After |
|---|---|
public_read |
public_read_authenticated_write |
public_read_write |
public_read_write_UNRESTRICTED (requires i_understand_this_is_unrestricted: true) |
user_owns_rows |
(unchanged — gateway now uses type-aware predicates + auto-index) |
What this means for you
- If you use
setup_rlsorbundle_deployvia MCP with the old names, the MCP Zod schema now rejects them at the tool boundary. The error lists the three valid templates. - If you use
run402 deploywith a manifest that includes anrlsblock with the old names, the gateway will reject it with HTTP 400. Update the manifest. - If you want the fully-open template, your request body (or manifest
rlsblock) must include"i_understand_this_is_unrestricted": true. The MCP schema enforces this locally via superRefine — you get a fast error before the network call.
Why
The old public_read_write name hid that it granted anon_key full INSERT/UPDATE/DELETE on the table. An LLM picking that template for a user-scoped todos table would silently create an open-to-the-internet table. The new names + explicit ACK force the caller to see and acknowledge what they're applying.
Also in this release
- New guidance: the docs now lead with "prefer
user_owns_rowsfor anything user-scoped" across SKILL.md, openclaw/SKILL.md, and cli/llms-cli.txt. - CLI
--helpforrun402 deployandrun402 projects rlsnow includes per-template safety notes. - 14 new unit tests covering enum rejection, ACK refinement, and request-body wiring.
- Full OpenSpec change artifacts under
openspec/changes/rls-template-rename/.
Packages: