The Railway CLI lets you interact with your Railway projects from the command line. Read the CLI documentation.
Install the Railway CLI with agent support configured in one step (macOS, Linux, Windows via WSL):
bash <(curl -fsSL railway.com/install.sh) --agents -yThis installs the CLI to ~/.railway/bin and runs railway setup agent to configure detected agent tools.
To install the CLI without agent configuration:
bash <(curl -fsSL railway.com/install.sh) -yUninstall the CLI:
bash <(curl -fsSL cli.new) -rOther installation methods are available in the CLI documentation: Homebrew, npm, Scoop, pre-built binaries, and source builds.
Before using the CLI, authenticate with your Railway account:
railway loginFor environments without a browser, such as SSH sessions, use browserless login:
railway login --browserlessFor CI/CD pipelines, set environment variables instead of using interactive login:
- Project token: Set
RAILWAY_TOKENfor project-level actions. - Account or workspace token: Set
RAILWAY_API_TOKENfor account-level or workspace-level actions.
RAILWAY_TOKEN=xxx railway upSee Tokens for more information.
Configure Railway agent support for AI coding tools:
railway setup agent -yThis installs Railway skills and configures the remote Railway MCP server (mcp.railway.com via railway mcp proxy, authenticated with your CLI login) for detected tools such as Claude Code, Cursor, Codex, OpenCode, GitHub Copilot, and Factory Droid.
Use the focused commands when you only need one part of the setup:
railway mcp install --agent cursor
railway skills --agent claude-codeWith automatic updates enabled, CLI-managed skills update silently in the background,
including on the first normal command after a CLI version change (whether upgraded
with railway upgrade or a package manager). Locally modified or deleted skills are
skipped, and user-added files are preserved. Restart your coding tool to load updated
skills. Use railway skills update to review skipped updates, or add --force to
overwrite local changes explicitly.
railway autoupdate disable (or RAILWAY_NO_AUTO_UPDATE=1) disables automatic CLI
and skill updates and their update notices. Explicit railway upgrade,
railway check-updates, and railway skills update commands remain available.
Opt into the local GraphQL-backed MCP server instead:
railway setup agent -y --local
# or
railway mcp install --local --agent cursorrailway upgrade presents CLI installation and managed skill synchronization as
one flow. Stages advance as work completes, and the final summary says whether
the new version is active or will be used on the next command. This explicit
command also synchronizes managed skills when automatic updates are disabled.
Automatic discovery and downloads run quietly. After the new CLI is active and its skill sync has finished, an interactive command shows one completion receipt per CLI version. Preserved local edits are reported neutrally; a skill-sync failure is reported separately from a successful CLI install. Commands using JSON, piped output, help, and version output do not show or consume receipts. Install methods that require manual upgrades get one availability notice per release instead.
Run railway autoupdate status to inspect the running and recorded installed
versions, staged/in-progress CLI updates, skill-sync results, and unmanaged
skills. Use railway skills update for detailed skill results or to retry a sync.
Prepare an authenticated server on a cloud agent and open your local client:
railway code --opencode
railway code --opencode2
railway code --opencode2 --newWhen the matching OpenCode Desktop edition has an existing settings file or
desktop database, Railway automatically saves the server URL, credentials,
default server, and project in it. The final output confirms that configuration
was updated; open Railway: <agent-name> in Desktop's server picker. Both JSON
settings and SQLite renderer state are supported, with backups of previous settings.
You may need to restart OpenCode Desktop to load the updated configuration.
Configuration failures are non-fatal and reported alongside the connection
details; rerun the command to retry.
The CLI also prints the server URL, username, password, and project directory
for manual setup, plus a Railway reconnect command:
railway code --opencode connect <agent> (or --opencode2 for Beta).
After successful setup in an interactive terminal, it clears the setup messages
and shows the connection details, with the Desktop update confirmation inside
the result panel. Failed setup keeps its diagnostic output visible.
Press Enter to launch the matching local terminal client. If that client is
missing, Railway offers to install it first. Declining, Esc, or Ctrl+C at
either prompt leaves the server running and prints the connection details.
Standard and Beta clients are detected and installed separately.
New OpenCode agents are named oc-railg-3ed (standard) or oc2-railg-3ed
(Beta); Codex uses codex-railg-3ed: the first five letters/digits of the project
name, lowercase, plus a random three-character suffix. When using your default
cloud agents project, the label comes from the local repository or directory
instead. Existing names are checked before creation; --name overrides the
generated name. The same naming applies to remote and railway ca desktop.
Reconnect to an existing server using your local client:
railway code --opencode connect
railway code --opencode2 connect my-boxconnect discovers running servers of the selected edition on agents you own.
One match connects directly; multiple matches show a workspace/project/agent
picker. A name or ID targets an agent directly and can wake a saved server.
Connecting also refreshes the detected Desktop edition's configuration.
Connecting never creates a new agent or installs a server on an unrelated box.
In noninteractive terminals, the CLI still attempts Desktop configuration and
prints connection details instead of prompting, installing software, or
launching a terminal client; multiple matches require a name or ID.
To run both client and server inside the cloud agent, in Railway CA:
railway code --opencode remote
railway code --opencode2 remote --new--new creates a fresh VM; --agent <name-or-id> targets an existing one.
For the local-client setup, --dir selects the remote project directory
(default /app). Beta uses its server's startup directory, so switching it
requires a fresh agent. Setup uses the same generated credentials, HTTPS
checks, provider sign-in behavior, skills, and MCP sync as Desktop. It saves
settings in detected Desktop installations and prints them for manual entry.
A running server and its password are reused. Use railway ca sleep <name>
when finished.
Put harness-specific arguments after --, for example:
railway code --opencode2 -- run --standalone "explain this project".
Run the native Codex terminal UI on your computer, connected to Codex App Server on a persistent Railway cloud agent:
railway code --codex --new
railway code --codex --agent my-box --dir /app
railway code --codex connect my-box
railway code --codex connectNew Codex agents use the same naming rules as OpenCode, with a codex- prefix
(for example, codex-railg-3ed). The generated name works with connect,
get-config, and cloud-agent lifecycle commands; --name sets a custom name.
For a Desktop-only workflow:
railway code --codex desktop-only --new
railway code --codex desktop-only --agent my-box --dir /appThis prepares the VM, starts or reuses the authenticated backend App Server, verifies its public endpoint, registers SSH, and saves the remote project for Codex Desktop to import at its next startup. It then exits, leaving the backend running. It never prompts to install or launch a local terminal client. The results panel shows backend credentials, the SSH configuration file location, the Desktop project name, and commands to reconnect or retrieve the configuration.
Terminal setup carries your available local Codex sign-in and configured
skills/MCP sync, starts App Server on port 8080, verifies its public WebSocket
handshake, and offers to launch the local client. Tools, files, and threads live
on the VM. Use /resume in Codex to reopen a remote thread. connect discovers
running Codex servers; an explicit agent also wakes and restarts a previously
configured server as needed.
The remote terminal client uses a separate, persistent CODEX_HOME under
~/.railway/codex-client/<backend-id>/. The VM owns its tools and sessions;
local-only MCP servers, plugins, and hooks must not participate in remote
startup. This also keeps the terminal's busy indicator and cancellation state
consistent with the backend. Ctrl+C interrupts active work and exits when idle;
Ctrl+D on an empty prompt detaches even during startup.
The terminal connection uses wss:// through the agent's public domain. Its
bearer token is passed to the local client through an environment variable.
The remote server's token, PID, version, directory, and logs live under
~/.railway/codex/. Repeated setup reuses the server and token. An occupied port
or a different running project directory requires another agent (--new).
Setup and connect also register and verify the agent's SSH host in
~/.ssh/config as railway-<agent-name>, using the same registration as
railway ca desktop --codex. Reconnecting upgrades the previous
railway-agent-<agent-name> default in both SSH and Codex Desktop's saved config.
They merge the connection and remote project into
~/.codex/codex-app/config.json ($CODEX_HOME/codex-app/config.json when set)
in the background. Setup never launches or activates Codex Desktop; the app
imports the saved configuration when you next start it.
Find Railway: <name> in Codex Desktop's project sidebar. An existing custom SSH
alias and project label are preserved. connect imports the server's actual
working directory. You can use the same VM from the terminal and Desktop.
The VM must have a Codex release with --ws-auth and --ws-token-file support.
Terminal mode uses a local client with the same version as the server. If needed,
it offers to install that official @openai/codex version with npm into
~/.railway/runtimes/codex-client/<version>/.
For scripts, --connection-json returns a single JSON object containing
schemaVersion, agent identity, and connection url, token, directory,
version, and reused. Progress goes to stderr.
railway code --codex --connection-json connect my-box
railway code --codex remote # run the UI inside Railway CA
railway code --codex -- exec "run tests" # execute inside the VMClosing the local client leaves the server running. Use railway ca sleep my-box
to stop compute, then railway code --codex connect my-box to wake and reconnect.
Codex currently marks its remote App Server transport experimental.
railway code get-config # most recently saved connection
railway code get-config my-box # a specific agent by name
railway code get-config codex-railg-3ed # generated names work too
railway code get-config <agent-id> # use an ID if names are ambiguous
railway code get-config my-box --jsonCodex terminal setup, connect, and desktop-only (including its
railway ca desktop --codex alias) save the verified backend connection and
Desktop configuration outcome. OpenCode/OpenCode2 setup and reconnect also save
their server details; ordinary cloud-terminal launches save SSH details.
get-config works from any directory, using local snapshots without login,
network access, waking a VM, launching a client, or applying Desktop configuration.
Its human-readable output uses the same concise results panel as creation and
reconnect.
--json includes the saved agent/SSH metadata and the harness-specific codex
or opencode object, including credentials and Desktop status. These are saved
details, rather than a live health check; rerun setup/connect to refresh them.
Railway retains the latest snapshot per agent in ~/.railway/code-configs.json
and continues writing ~/.railway/last-code-config.json for compatibility with
existing CLI versions. Existing latest snapshots are retained when the archive
is first written. Named lookup requires a connection previously saved on this
computer; unknown names report an error, and duplicate names list their IDs.
The files are private and atomically updated under a lock. railway logout
removes both saved-configuration files.
Prepare a cloud agent for Claude Code Desktop, Codex, or OpenCode Desktop:
railway ca desktop --claude
railway ca desktop --codex
railway ca desktop --opencode --agent my-box
railway ca desktop --opencode --new
railway ca desktop --opencode2 --newWith Codex selected alone, railway ca desktop --codex is a compatibility alias
for railway code --codex desktop-only. It uses the same backend startup and
Desktop import flow, forwarding --agent, --new, --dir, project/environment,
and its SSH alias/config/verification options. The existing --dry-run,
--remove, and multi-app setup commands remain available.
App flags can be combined to prepare the same agent for several apps. Setup
carries available local sign-ins, applies your skills/MCP sync preferences,
and writes the agent's SSH configuration. --dry-run previews the local files
without creating or waking an agent or starting a connection. Existing agents
are reused and woken as needed; if none exists in the target environment, setup
creates one. --new always creates a fresh agent, including when several app
flags are combined. It cannot be combined with --agent or --remove.
Codex setup registers the SSH host and named remote project using Codex Desktop's
version-1 app configuration, entirely in the background. It never launches or
activates the app. Codex Desktop imports the configuration on its next startup.
Existing connections and retry/timeout preferences
are retained; changed configuration is backed up to config.json.railway-backup.
--dry-run previews the merged config. --remove removes the SSH
block and that alias's import declaration; remove already-imported connections
and projects inside Codex, since its import mechanism does not delete them.
OpenCode Desktop connects directly to the agent's existing HTTPS address.
The CLI starts password-protected opencode serve
in the background on port 8080, checks its public endpoint, and saves the URL,
username, password, default server, and remote project in Desktop's settings.
--opencode configures only standard OpenCode (ai.opencode.desktop).
--opencode2 configures only OpenCode2 Beta
(ai.opencode.desktop.beta), using its compatible server runtime. These two
flags cannot be combined. JSON server settings and SQLite renderer state are
supported; a drafts-only database does not change where settings are saved.
For Beta, the CLI seeds an opencode2 shim on the agent. Each new process checks
the latest official Beta release, downloads the Linux Desktop package for the
agent's architecture, verifies its published SHA-256, and extracts just the CLI
executable. The first start can take several minutes. A verified cached version
is reused until the release changes; running sessions keep their executable.
A failed update reports an error and preserves the previous runtime.
Use railway ca --opencode2 for a terminal session. In the new-session picker,
highlight OpenCode and press Tab to switch to OpenCode2 [Beta]. Tab also
switches editions in the prompt footer; Shift+Tab cycles harnesses.
Setup also prints the connection details and a reminder that you may need to
restart OpenCode Desktop to load the updated configuration.
Private .railway-backup files preserve the previous settings and server state.
You can close the terminal after setup; there is no local tunnel to keep running.
Press Cmd+B (Ctrl+B on Windows/Linux) to open Home. Under Projects, find
Railway: <agent-name> and /app (or your --dir), then use that project's
menu → New session. Setting a default server
does not move existing chats. Standard OpenCode provider sign-ins from auth.json are copied
when available. OpenCode2 imports the active account for each provider from your local
Beta credential database, preserving accounts already configured on the cloud agent.
Legacy auth.json is used only when no Beta credential store exists. Credentials are
sent over SSH and the temporary transfer file is removed after import. If there is
no local sign-in to copy, connect the provider in the remote server's settings.
OpenCode uses the agent's public app port (8080). Setup refuses to take over
an occupied port; stop the other process or use --new for a fresh agent.
Rerunning railway ca desktop --opencode --agent my-box reuses the running
server and its credentials, or starts it again after a sleep/wake or restart.
The remote credential and process state are stored privately under
~/.railway/desktop/opencode/; startup logs are in server.log there.
railway ca desktop --opencode --agent my-box --remove (or --opencode2
for Beta) stops the managed
OpenCode process on a running agent and removes the shared SSH block and the
Desktop connection/project saved by setup. It does not wake a sleeping agent.
The agent remains; railway ca sleep my-box stops its compute bill.
See CONTRIBUTING.md for information on setting up this repository locally.
Share feedback and suggestions on Central Station.