# The Shipyard CLI A tool to manage Ephemeral Environments on the Shipyard platform. Using an AI assistant? The CLI includes an MCP server: see [Use Shipyard from an AI assistant](#use-shipyard-from-an-ai-assistant-mcp). ## Installation - **Linux and macOS** ``` curl https://www.shipyard.sh/install.sh | bash ``` It installs to `/usr/local/bin`, using `sudo` only if it can't write there. To install somewhere else, such as a directory you own, set `SHIPYARD_INSTALL_DIR`: ``` curl https://www.shipyard.sh/install.sh | SHIPYARD_INSTALL_DIR="$HOME/.local/bin" bash ``` - **Windows** Navigate to the [releases page](https://github.com/shipyard/shipyard-cli/releases) and download the executable for Windows. - **Homebrew** ``` brew tap shipyard/tap brew install shipyard ``` ### Verifying a download Every release publishes a `checksums.txt` with the SHA-256 of each binary. The install script checks the binary against it and refuses to install on a mismatch. To check a binary you downloaded yourself: ```bash grep " shipyard-darwin-arm64$" checksums.txt | shasum -a 256 -c - ``` `checksums.txt` comes from the same release as the binary, so it catches a corrupted or truncated download, not a release whose files were replaced. The attestation below is the check that the binary was built by this repo's release workflow. In releases after 1.9.0, each binary also has a signed build provenance attestation, showing which workflow run, commit and tag built it, and an SPDX SBOM (`shipyard--.sbom.json`; `.exe.sbom.json` on Windows) listing what it was built from. Verify the attestation with the [GitHub CLI](https://cli.github.com), naming the release you downloaded (here v1.10.0): ```bash gh attestation verify shipyard-darwin-arm64 -R shipyard/shipyard-cli \ --signer-workflow shipyard/shipyard-cli/.github/workflows/release.yaml \ --source-ref refs/tags/v1.10.0 ``` Keep `--source-ref`: without it, the check passes for anything a copy of the workflow signed on any branch, not just that release's tag build. The check names the tag, not its commit. A withdrawn release's attestations aren't deleted, so if a version is ever released again under the same tag, its withdrawn binaries still pass. To pin the commit as well, add `--source-digest ` with the commit the tag points to. ## Upgrading ```bash shipyard upgrade ``` `shipyard update` does the same thing. It installs the latest release and shows its release notes. A Homebrew install is upgraded with `brew upgrade shipyard`; any other install downloads the release binary, verifies it against the release's `checksums.txt`, and replaces the running binary. If that binary is in a directory you can't write to, such as `/usr/local/bin`, run `sudo shipyard upgrade`. Add `--prerelease` to include pre-releases, or `--force` to reinstall the current release (for a Homebrew install, use `brew reinstall shipyard` instead). ### Upgrading from 1.9.0 or earlier The `shipyard update` in 1.9.0 and earlier compares versions as text, so it reports 1.10.0 and later as older than what you have. Upgrade once the way you installed, and `shipyard upgrade` works from then on: - **Linux and macOS:** `curl https://www.shipyard.sh/install.sh | bash` - **Windows:** download the executable from the [releases page](https://github.com/shipyard/shipyard-cli/releases) - **Homebrew:** `brew upgrade shipyard` ### Update notices When a new release is out, the CLI tells you after a command finishes, at most once a day: ``` A new version of shipyard is available: 1.9.0 → 1.10.0 Run `shipyard upgrade` to install it. Release notes: https://github.com/shipyard/shipyard-cli/releases/tag/v1.10.0 ``` It never asks anything or waits for input. The check runs in the background while your command runs; if it hasn't finished when the command does, the CLI waits at most a second for it. That only happens when it's asking GitHub, about once a day or to fetch release notes you missed. The first run after an upgrade made any other way, such as `brew upgrade`, shows those notes. The message goes to stderr, and only when stderr is a terminal. It's never shown in CI, inside AI coding agents that identify themselves (Claude Code, Codex, Cursor's agent, Gemini CLI), or for `shipyard mcp serve`. To turn it off, set `SHIPYARD_NO_UPDATE_CHECK=1` or add `update_check: false` to `~/.shipyard/config.yaml`. ## Login Run `shipyard login` to initialize the CLI. This will prompt you to log in to Shipyard in the browser. The CLI will then save your API token in a local config. You're ready to start running commands. ### Or Set Your Token Manually Set your Shipyard API token as the value of the `SHIPYARD_API_TOKEN` environment variable. You can get it by going to [your profile page](https://shipyard.build/profile). You can get in touch with us at [support@shipyard.build](mailto:support@shipyard.build) if you would like to enable API access for your org. If you have any other questions, feel free to join our community [Slack](https://join.slack.com/t/shipyardcommunity/shared_invite/zt-x830cx39-BuiQKZwvhG7zGRTXAvojVQ). ```bash shipyard set token ``` Alternatively, you can use a configuration file stored in `$HOME/.shipyard/config.yaml` by default. When you run the CLI for the first time, it will create a default empty config that you can then edit. You can also specify a non-default config path with the `--config {path}` flag added to any command. Add any configuration values in your config and ensure the file follows YAML syntax. For example: ```yaml api_token: org: ``` The values of your environment variables override their corresponding values in the config. ## Basic usage ### Get all orgs you are a member of ```bash shipyard get orgs ``` ### Set the global default org ```bash shipyard set org {org-name} ``` ### Get the currently configured org ```bash shipyard get org ``` ### List all environments ```bash shipyard get environments ``` Available flags: | Name | Description | Type | Default Value | |---------------------|------------------------------------------------------|---------|------------------| | branch | Filter by branch name | string | | | deleted | Return deleted environments | boolean | false | | json | Print the complete JSON output | boolean | false | | name | Filter by name of the application | string | | | org-name | Filter by org name, if you are part of multiple orgs | string | your default org | | page | Page number requested | int | 1 | | page-size | Page size requested | int | 20 | | pull-request-number | Filter by pull request number | string | | | repo-name | Filter by repo name | string | | **Examples:** - List all environments running the repo `flask-backend` on branch `main`: ```bash shipyard get environments --repo-name flask-backend --branch main ``` - List all deleted environments: ```bash shipyard get environments --deleted ``` ### Get details for a specifc environment by its UUID ```bash shipyard get environment {environment_uuid} ``` Available flags: | Name | Description | Type | Default Value | |----------|------------------------------------------------------|---------|------------------| | json | Print the complete JSON output | boolean | false | | org | Org of the environment, if you are part of multiple orgs | string | your default org | | bypass-token | Print only the environment's bypass token, for scripts | boolean | false | `--bypass-token` lets a script use the token without anyone typing or printing it: ```bash SHIPYARD_TOKEN=$(shipyard get environment {environment_uuid} --bypass-token) && \ export SHIPYARD_TOKEN && curl -b "shipyard_token=$SHIPYARD_TOKEN" https://your-environment-url/ ``` ### Stop a running environment ```bash shipyard stop environment {environment_uuid} ``` ### Restart a stopped environment ```bash shipyard restart environment {environment_uuid} ``` ### Cancel ongoing build for an environment ```bash shipyard cancel environment {environment_uuid} ``` ### Rebuild an environment ```bash shipyard rebuild environment {environment_uuid} ``` ### Revive a deleted environment ```bash shipyard revive environment {environment_uuid} ``` ### Deploy a detached environment Create a new, independent ("detached") environment by cloning an existing application build. Requires detached environments to be enabled for your org. ```bash shipyard detached deploy {application_build_uuid} --name my-detached-env ``` Override branches per-repo and control whether the detached environment rebuilds on new commits: ```bash # Override the branch for a repo, and never rebuild on new commits shipyard detached deploy {application_build_uuid} --name my-detached-env --branch web=feature-x --build-on-commit never # Per-repo build-on-commit settings (always | inherit | never) shipyard detached deploy {application_build_uuid} --build-on-commit-for web=always --build-on-commit-for api=never ``` ### Get all services and exposed ports for an environment ```bash shipyard get services --env {environment_uuid} ``` ### Exec into a running environment's service Execute any command with any arguments and flags in a given service for a **running** environment. Pass any command arguments after a double slash. ```bash shipyard exec --env {environment_uuid} --service {service_name} -- bash ``` ### Port forward a running environment's service's port ```bash shipyard port-forward --env {environment_uuid} --service {service_name} --ports {local_port}:{service_container_port} ``` ### Get logs for a running environment's service ```bash shipyard logs --env {environment_uuid} --service {service_name} ``` ### Visit an environment ```bash shipyard visit {environment_uuid} ``` Available flags: | Name | Description | Type | Default Value | |--------|-------------------------------|---------|---------------| | follow | Follow the logs output | boolean | false | | tail | # of recent log lines to show | int | 3000 | ## Work with volumes ### List all volumes in an environment ```bash shipyard get volumes --env {environment_uuid} ``` ### List all volume snapshots in an environment ```bash shipyard get snapshots --env {environment_uuid} ``` ### Reset a volume in an environment ```bash shipyard reset volume --env {environment_uuid} ``` ### Create a snapshot in an environment ```bash shipyard create snapshot --env {environment_uuid} ``` ### Load a volume snapshot in an environment ```bash shipyard load snapshot --env {environment_uuid} --sequence-number {n} ``` ### Upload a file to a volume in an environment ```bash shipyard upload volume --env {environment_uuid} --volume {volume} --file {filepath.bz2} ``` ### Call the REST API directly ```bash shipyard api /api/v1/environment shipyard api -X PUT /api/v1/environment/{environment_uuid}/env-vars --input body.json ``` Paths must start with `/api/v1` or `/api/v2`; your token and org are added for you. `bypass_token` and kubeconfig credentials are redacted unless you pass `--include-secrets`. ### Connect to telepresence ```bash shipyard telepresence connect --env {environment_uuid} ``` From there, you'll be able to communicate directly with all pods in the namespace. You _may_ have to use the namespace hostname to communicate with services, which you can get via `telepresence status` under the Namespace field. For example, to communicate with redis, you'd use redis.shipyard-app-build-{uuid} ## Build executable from code: You can make an executable by running the following command: ```bash make ``` To run this new executable: ```bash ./shipyard ``` ## Enable Autocompletion ### Bash This script depends on the `bash-completion` package. If it is not installed already, you can install it via your OS's package manager. To load completions in your current shell session: ``` source <(shipyard completion bash) ``` To load completions for every new session, execute the following once. On Linux: ``` shipyard completion bash > /etc/bash_completion.d/shipyard ``` On macOS: ``` shipyard completion bash > $(brew --prefix)/etc/bash_completion.d/shipyard ``` ### Zsh If shell completion is not already enabled in your environment, you will need to enable it. You can execute the following once: ``` echo "autoload -U compinit; compinit" >> ~/.zshrc ``` To load completions in your current shell session: ``` source <(shipyard completion zsh); compdef _shipyard shipyard ``` To load completions for every new session, execute the following once. On Linux: ``` shipyard completion zsh > "${fpath[1]}/_shipyard" ``` On macOS: ``` shipyard completion zsh > $(brew --prefix)/share/zsh/site-functions/_shipyard ``` You will need to start a new shell for this setup to take effect. ### Fish To load completions in your current shell session: ``` $ shipyard completion fish | source ``` To load completions for each session, execute once: ``` shipyard completion fish > ~/.config/fish/completions/shipyard.fish ``` ### PowerShell To load completions in your current shell session: ``` shipyard completion powershell | Out-String | Invoke-Expression ``` To load completions for every new session, run: ``` shipyard completion powershell > shipyard.ps1 ``` and source this file from your PowerShell profile. ## Use Shipyard from an AI assistant (MCP) `shipyard mcp serve` runs a [Model Context Protocol](https://modelcontextprotocol.io) server, so an assistant such as Claude Code, Claude Desktop, Cursor or Codex can list, inspect, rebuild and configure your environments, read service logs, manage volumes, and verify a pushed change against its environment. With the CLI logged in, add it to Claude Code: ```bash claude mcp add shipyard -- shipyard mcp serve ``` Then ask things like: - "Which environments are running for the `web` repo?" - "Show me the `api` service's logs on my branch's environment." - "Why did the latest build of this environment fail?" - "Set `FEATURE_FLAGS=beta` on this environment and restart the `worker` service." - "I just pushed. Verify the change against its environment." (or `/mcp__shipyard__verify`) See the **[MCP guide](docs/mcp.md)** for setting it up in other clients, configuration, the full tool list, the `verify` prompt, and troubleshooting.