# cs drive (/docs/cli/drive)

`cs drive` is the [Drive](/docs/drive) from a shell: the same `drive__*`
tools your agents call, with a local file on one end. Bytes never travel
through tool arguments, so an upload takes a one-use ticket and a `PUT`, and
a download follows the 12-hour link `drive__get` answers; these commands make
each of those one step. Every other Drive tool — the change feed, S3
credentials — is one [`cs mcp call`](/docs/cli/mcp) away.

## Usage \[#usage]

```bash
cs drive put <file> <path> [--mime <type>] [--access private|org]
cs drive get <path|file_id|version_id> [<file> | -]
cs drive ls [<prefix>] [--recursive] [--json]
cs drive mv <from> <to>
cs drive rm <path>
cs drive share <path> private|org|link|public [--rotate]
cs drive usage
```

```bash
cs drive put ./q3.pdf reports/q3.pdf
cs drive get reports/q3.pdf ~/Downloads/
cs drive ls reports/
```

## put \[#put]

`cs drive put <file> <path>` stores a local file at a Drive path. The path
is the file's place in the organization's tree, like `reports/q3.pdf`;
folders are implied, and nothing has to exist first. The stored type comes
from the file's extension (`.pdf`, `.png`, `.md`, …; `application/octet-stream`
when the extension is unknown); `--mime <type>` names it instead. A new path
is private to you; `--access org` shows it to every member. Putting to a path
that already names a file writes a **new version** of it, and the file keeps
its access; change that with `share`.

```bash
cs drive put ./q3.pdf reports/q3.pdf
cs drive put ./deck.key decks/launch.key --mime application/vnd.apple.keynote
cs drive put ./README.md docs/readme.md --access org
```

The result is the file as `drive__put` answers it:

```json title="Output"
{
  "path": "reports/q3.pdf",
  "file_id": "drv_01HZX…",
  "version_id": "dver_01HZX…",
  "mime_type": "application/pdf",
  "size_bytes": 184233,
  "sha256": "9f2c…",
  "access": "private",
  …
}
```

Behind it: `drive__create_upload` reserves a ticket, the bytes go up with
one `PUT`, `drive__put` stores them at your path from the uploaded copy, and
that copy under `tmp/uploads/` is removed. Files up to 2 GB are accepted. For
many files or a whole folder, mount the Drive as S3 instead
([`drive__s3_credentials_create`](/docs/drive#mount-it-as-s3)).

A put an organization's policy routes to a human exits `6` with the
`manage__approval_wait` command to run, like any [`cs mcp call`](/docs/cli/mcp#call);
the uploaded bytes wait for the decision.

## get \[#get]

`cs drive get <reference> [<file> | -]` downloads a file. The reference is a
path, a `drv_…` file id, or a `dver_…` version id — an earlier version a put
replaced stays readable by its id. With no destination the file is written
under its own name in the current directory; a directory takes the file's
name; `-` streams the bytes to stdout and prints the facts on stderr, so the
output pipes.

```bash
cs drive get reports/q3.pdf                    # ./q3.pdf
cs drive get reports/q3.pdf ~/Downloads/       # ~/Downloads/q3.pdf
cs drive get dver_01HZX… ./q3-before.pdf       # an earlier version
cs drive get notes/todo.md - | head
```

```text title="Output"
Saved reports/q3.pdf to ./q3.pdf (179.9 KB, application/pdf)
```

The bytes land in a temporary file beside the destination and take its name
only once every byte has arrived, so a download that is refused, dropped or
stops short exits `5` and leaves a file already at that name as it was; retry
it. For a file's facts without its bytes — its link, who can see it, its
versions — call [`drive__get`](/docs/drive#put-and-read) directly.

## ls \[#ls]

`cs drive ls [<prefix>]` lists a folder: its sub-folders first, then its
files, one line each with the size, who can see it, when it last changed,
and the path. `--recursive` lists every file under the prefix instead;
`--json` prints the folders and entries exactly as `drive__list` declares
them. The root is listed when no prefix is given. Only the files you can see
are listed: your own, and the organization's shared ones.

```text title="Output"
        -  folder               reports/2025/
   2.0 KB  org      2026-10-20  reports/a.pdf
     12 B  private  2026-10-21  reports/b.md
```

## mv \[#mv]

`cs drive mv <from> <to>` renames or moves a file. The bytes and the file id
stay. Moving a file out of `tmp/` keeps it; moving one into `tmp/` makes it
expire after 7 days. A destination that already names a file is refused with
`path_taken`.

## rm \[#rm]

`cs drive rm <path>` deletes a file: the path and every version of it. Not
reversible, and the command does not ask.

## share \[#share]

`cs drive share <path> <access>` sets who can see a file: `private` (only
you), `org` (every member), `link` (anyone holding its secret link, no
sign-in) or `public` (anyone with its URL). `link` and `public` answer a
lasting `share_url`; `--rotate` issues a new secret link to a file already at
`link`, and the old one stops working at once.

```bash
cs drive share reports/q3.pdf org
cs drive share reports/q3.pdf link
cs drive share reports/q3.pdf link --rotate
```

## usage \[#usage-1]

`cs drive usage` prints what the organization keeps against its plan and what
sits under `tmp/`, as [`drive__usage`](/docs/drive#quota) answers it.

## Exit codes \[#exit-codes]

The commands end as [`cs mcp call`](/docs/cli/mcp#call) does: `0` when the
tool did what it was asked, `1` when it refused (`file_not_found`,
`path_taken`, `drive_quota_exceeded`, a bad path), `4` when the organization's
standing stopped it, `5` when CoreSpeed could not be reached or the bytes did
not arrive whole, `6` when a write waits for a human's approval. A local file
that does not exist or cannot be written is `1`. The reason is on `stderr`;
the [Drive](/docs/drive#errors) page lists the codes.