# Drive (/docs/drive)

Drive is a CoreSpeed-hosted capability: no third-party account to connect, and
the same `/mcp` seam as everything else, so identity, organization holds,
API-key caps, activity recording, and capability visibility all apply. It is
the one file system behind every other tool. An upload, a connector download,
a mail attachment and a media output are all Drive files, and every tool that
takes a file takes a Drive path or file id.

## Tools \[#tools]

| Tool                           | Use it for                                                                         |
| ------------------------------ | ---------------------------------------------------------------------------------- |
| `drive__put`                   | Store a file at a path, from another Drive file, a public URL, or inline text.     |
| `drive__get`                   | A file's facts and a 12-hour link to its bytes; small text files come back inline. |
| `drive__list`                  | The files and sub-folders of a folder, or everything under a prefix.               |
| `drive__move`                  | Rename or move a file. Moving out of `tmp/` keeps it.                              |
| `drive__delete`                | Delete a file and every version of it. Not reversible.                             |
| `drive__share`                 | Who can see a file: private, the organization, a secret link, or public.           |
| `drive__changes`               | The organization's change feed, in order, from a cursor.                           |
| `drive__create_upload`         | A one-use upload URL for a local file of any type.                                 |
| `drive__usage`                 | What the organization keeps against its plan, and what sits in `tmp/`.             |
| `drive__s3_credentials_create` | An S3 access key for rclone, the AWS CLI or a mount.                               |
| `drive__s3_credentials_list`   | Your access keys (never their secrets), and where a client points.                 |
| `drive__s3_credentials_revoke` | Revoke one of your access keys. Not reversible.                                    |

## Paths, `tmp/`, and keeping a file \[#paths-tmp-and-keeping-a-file]

A file lives at a path like `reports/q3.html`. Folders are implied by the
path; there is nothing to create first. Every file also has a stable
`file_id` (`drv_…`) that survives moves and new versions, and each version a
`version_id` (`dver_…`).

Anything under `tmp/` **expires after 7 days**. That is where the other doors
put what they take in:

| Path                  | What lands there                                                       |
| --------------------- | ---------------------------------------------------------------------- |
| `tmp/uploads/`        | A local file uploaded through `drive__create_upload` or the dashboard. |
| `tmp/media/<job_id>/` | Every output of a [Media](/docs/media) generation.                     |
| `tmp/mail/`           | An attachment stored by agent mail.                                    |
| `tmp/<connector>/`    | A file a connector downloaded, for example `tmp/google-drive/`.        |

To keep a file, `drive__move` it to any path outside `tmp/`, or `drive__put`
it to one with `source` set to its path or file id. A kept file stays until
you delete it. Moving a file into `tmp/` makes it expire.

Putting to an existing path writes a **new version**; the earlier version
stays readable through `drive__get` with its `version_id`, and still counts
against your quota until the file is deleted.

## Who can see a file \[#who-can-see-a-file]

A new file is **private**: only the member (or the agent acting as them) who
created it sees it. `drive__put` with `access: "org"` makes a new path visible
to every member; `drive__share` changes an existing file:

| Access    | Who                                                                                                                           |
| --------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `private` | Only you.                                                                                                                     |
| `org`     | Every member of the organization.                                                                                             |
| `link`    | Anyone holding the file's secret link, no sign-in. `rotate: true` issues a new secret and the old link stops working at once. |
| `public`  | Anyone with the file's URL, no sign-in.                                                                                       |

`link` and `public` publish the file outside the organization and answer a
lasting `share_url` that opens the file in the Drive viewer, with HTML,
markdown and plain text rendered as pages. Moving back to `org` or `private`
withdraws every outside link. Where a deployment has no Drive viewer
configured, sharing by link or publicly is refused with `drive_unavailable`.

Reads and listings only ever show the files you can see, and so does the
change feed. A `drive__get` link is good for 12 hours; pass the path or file
id, never a link, to other tools.

## Put and read \[#put-and-read]

`drive__put` takes exactly one of:

* `source` — another Drive path or file id, or a public `https` URL with an
  exact `Content-Length`, up to 2 GB;
* `text` — the content inline, for a text file up to 1 MiB: markdown, HTML,
  JSON, CSV.

`mime_type` defaults to the source's own type, or for text to one inferred
from the path's extension. The answer carries the path, `file_id`,
`version_id`, size, `sha256` and provenance.

`drive__get` reads by `path`, `file_id` or `version_id`. Text files up to
64 KiB (`text/*`, JSON, XML, YAML, SVG) come back inline in `content`. Every
file gets a 12-hour `url`; an HTML, markdown or plain-text file also a
`view_url` that opens it rendered, pinned to the version when you asked by
`version_id`.

## Upload a local file \[#upload-a-local-file]

Bytes never travel through tool arguments. For a file that only exists on
local disk:

1. Call `drive__create_upload` with the exact `mime_type` and `size_bytes`.
   The result includes `file_id`, `upload_url`, the `PUT` method, the headers
   to send — including `Authorization` — `expires_at`, and `lands_at`, the
   `tmp/uploads/` path the file will have.
2. `PUT` the raw bytes to `upload_url` with every returned header, within
   **10 minutes**. The ticket is one-use, and the declared type and size are
   bound to it.
3. Pass the path or `file_id` to any file-typed input, or `drive__move` it
   out of `tmp/` to keep it.

Files up to 2 GB are accepted. A deployment edge may still reject a very large
body with HTTP `413`; treat that as non-retryable for the deployment rather
than retrying the same upload. For many files or very large ones, mount the
Drive as S3 instead.

## Mount it as S3 \[#mount-it-as-s3]

`drive__s3_credentials_create` mints an access key for the organization's
Drive so rclone, the AWS CLI or an S3 mount can read and write it directly:
one bucket, `drive`, whose object keys are Drive paths, with the endpoint and
region in the answer and a ready rclone configuration. Large files go up as
resumable multipart uploads.

The credential acts as **you**: it sees your private files and the
organization's shared ones, files it writes are private to you, and its
writes are not held for approval. The secret is shown once, in the mint's
answer; you may hold at most ten live keys. `drive__s3_credentials_list` shows
your keys with when each was last used, and `drive__s3_credentials_revoke`
retires one at once.

## Quota \[#quota]

Kept bytes — every retained version of every file outside `tmp/` — count
against the organization's plan: **1 GiB** on the free plan, **20 GiB** on
Pro. A put to a kept path, or a move out of `tmp/`, is refused with
`drive_quota_exceeded` when it would pass the ceiling; expiries never touch
it. `tmp/` is bounded by the shared upload pool instead — **5 GB** and
**1,000** live files per organization — and expires. `drive__usage` reports
both, and the dashboard's Drive page shows the same numbers.

Drive calls are not charged credits: a file's cost is its place in your
quota, not the call that put it there. An organization billing hold or
suspension still stops a Drive write before it runs, as an `isError` result
with `payment_required` or `org_suspended`.

## Errors \[#errors]

| Code                                                 | Meaning                                                                                                           |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `invalid_path`                                       | The path breaks the Drive's naming rules; the message says which.                                                 |
| `file_not_found`                                     | No file at that path or id that you can see.                                                                      |
| `path_taken`                                         | `drive__move`: the destination already names a file.                                                              |
| `file_too_large`                                     | A file under `tmp/` is over the per-file limit; put it on a kept path.                                            |
| `drive_quota_exceeded`                               | The write would pass the plan's kept-bytes ceiling.                                                               |
| `upload_quota_exceeded`, `upload_capacity_exhausted` | The organization's `tmp/` pool, or the platform's, is full; uploads expire on their own.                          |
| `put_raced`, `precondition_failed`                   | Another write touched the path at the same moment (retryable).                                                    |
| `storage_error`, `drive_unavailable`                 | Storage or the index could not be reached (retryable), or sharing beyond the organization is not configured here. |

The upload `PUT` answers the same codes as HTTP problems; see the
[error reference](/docs/reference/errors).

## In the dashboard \[#in-the-dashboard]

[Dashboard → Drive](https://app.corespeed.io/drive) shows the organization's
tree as you see it: every folder, the `tmp/` inbox with when each file goes
unless kept, a file's details with its versions and links, sharing at the four
levels, drag-and-drop upload, and move, rename and delete. A member switches
the `drive__*` tools off for their agents on [Tools](/docs/capability-controls),
and an org admin sets the organization's ceiling; the page itself, and an
S3 key already minted, stay.