CLI reference
One binary, two jobs: every subcommand is a thin client of a rusted server's admin API — and rusted serve is the server, if you'd rather run your own.
Where commands point
The CLI talks to the hosted service at https://rusted.sh unless told otherwise. Resolution order for the server: --admin <url> flag → RUSTED_ADMIN env var → the hosted default. For the key: --api-key → RUSTED_API_KEY → what rusted login stored. Add --json to any command for stable, script-friendly output.
# self-hosting? point the CLI at your own server once:
export RUSTED_ADMIN=http://127.0.0.1:7412
Developing
| command | what it does |
|---|---|
rusted new <name> | Scaffold a function directory: typed index.ts, rusted.d.ts, tsconfig, package.json. --js for plain JavaScript, --app for a web app scaffold, --mcp for an MCP server scaffold. |
rusted run <file> | Local dev server with hot reload — no server, database, or key. Bundles imports in-process; prints per-request outcomes, logs, and sourcemapped stacks. Flags: --port, --exec-ms, --outbound, --build '<cmd>'. |
rusted build <file> | Bundle to a single deployable file in dist/ (--sourcemap for a map). Refuses to write a bundle that wouldn't deploy. |
rusted verify <file> | Compile-check and read the declared surface without deploying. |
rusted types | Write rusted.d.ts — the runtime's exact type surface (no DOM, no Node). |
Deploying
| command | what it does |
|---|---|
rusted push <file> | Bundle and deploy. The file's own http/mcp export supplies name, methods, route, and access ("public" or "private" — see security); --name, --method, --path and --access override them. A file with no exports at all is a script (see the module reference) and takes its name and access from those flags — or skip the file: rusted push --script 'return 1 + 2' --name calc. |
rusted preview <file> | A temporary endpoint that expires on its own (--ttl seconds, default 120). |
rusted list | Your functions and live temporary runs. |
rusted pull <name> | Print (or -o save) the deployed source. |
rusted delete <name> | Remove the function. Durable state survives — see state purge. |
Operating
| command | what it does |
|---|---|
rusted invoke <name> | Run a deployed function without HTTP. --input takes JSON (checked locally, - reads stdin), --body sends raw text, --env picks the environment. Owner-only; returns the real error and logs, plus the status, content type, and headers the URL would have answered with. Exit codes tell outcomes apart: 0 success, 1 the function threw, 2 usage or connection trouble, 3 terminated by a limit, 4 not invocable this way (mcp kind, non-POST methods, or a route path — call its URL instead). |
rusted logs <name> | Recent invocations with outcome, HTTP status, timings, and console output. --errors filters to failures — including 4xx/5xx responses and refusals (rate limits, wrong methods) that never reached the handler. |
rusted state purge <name> | Permanently delete every durable-state key the function holds, across all environments. The one explicit way state goes away. |
rusted inbox new|get|list|rm | Throwaway URLs that accept POSTs from anyone — see inboxes. |
rusted login / logout | Device sign-in (approve once in a browser); forget the stored credential. |
Self-hosting
make db # postgres via docker compose
rusted serve # functions on :7411, admin API + console on :7412
Flags worth knowing: --require-auth demands an API key on every function endpoint (functions declaring access: "public" and OAuth-protected MCP functions are exempt), --debug prints per-invocation detail to stdout, and PUBLIC_URL sets the origin the console advertises. Migrations run at boot.
Deployed function URLs look like https://rusted.sh/f/<name> — and https://rusted.sh/f/@stage/<name> selects an environment.
rusted