# mc — MinIO Client S3 CLI

LLMS index: [llms.txt](/en/llms.txt)

---

S3-compatible object storage is the default choice for buckets, backups, and static assets. When AWS CLI feels excessive and the web console is too clunky, MinIO Client (`mc`) fills the gap. This CLI tool works with any S3-compatible storage: MinIO, Yandex Cloud, AWS S3, Backblaze B2. Zero dependencies, works out of the box, configured in under a minute.

## Installation

Download the binary and make it executable:

```bash
curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc \
  -o /usr/local/bin/mc && chmod +x /usr/local/bin/mc
```

Verify the version:

```bash
mc --version
```

For macOS, use Homebrew:

```bash
brew install minio-stable/mc/mc
```

> [!NOTE]
> `mc` is a single static binary with no dependencies. Works perfectly in containers and minimal base images.

## Adding an Alias

An alias is a named connection to an S3 endpoint. Without it, every command requires the full URL.

```bash
mc alias set myminio https://minio.example.com \
  AKIAIOSFODNN7EXAMPLE \
  wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

After this, `myminio` replaces the URL in all commands. List existing aliases:

```bash
mc alias list
```

> [!TIP]
> In production, avoid storing keys in command history. Use environment variables: `mc alias set prod ${S3_ACCESS_KEY} ${S3_SECRET_KEY} --api API-S3v4` and substitute via `env`.

For S3-compatible services with self-signed certificates:

```bash
mc alias set myminio https://minio.example.com \
  minioadmin minioadmin --api S3v4 --insecure
```

## Browsing and Navigation

List buckets:

```bash
mc ls myminio
```

Recursive listing with contents:

```bash
mc ls --recursive myminio/backups/
```

Object metadata:

```bash
mc stat myminio/backups/db-2024-01.sql.gz
```

> [!WARNING]
> `mc ls` without `--recursive` shows only top-level buckets. Use prefixes to navigate folders inside a bucket.

## Working with Buckets

Create a bucket:

```bash
mc mb myminio/app-logs
```

If the bucket already exists, `mc` reports an error. The `--ignore-existing` flag suppresses it:

```bash
mc mb --ignore-existing myminio/app-logs
```

Remove an empty bucket:

```bash
mc rb myminio/app-logs
```

For non-empty buckets, use force:

```bash
mc rb --force myminio/app-logs
```

## Working with Objects

Print object contents to stdout without downloading:

```bash
mc cat myminio/config/latest.yaml
```

Remove an object:

```bash
mc rm myminio/backups/old.sql.gz
```

Recursive removal by pattern:

```bash
mc rm --recursive --force myminio/temp/*
```

> [!NOTE]
> `mc rm` without `--force` asks for confirmation. Always use `--force` in scripts.

Find objects by criteria:

```bash
mc find myminio --name "*.log" --older-than 30d
```

Combine with deletion:

```bash
mc find myminio --name "*.tmp" --exec "mc rm {path}" {}
```

## Uploading and Downloading

Copy a local file to a bucket:

```bash
mc cp /tmp/dump.sql myminio/backups/
```

Multiple upload:

```bash
mc cp ./uploads/* myminio/static/
```

Download an object locally:

```bash
mc cp myminio/backups/latest.tar.gz /tmp/
```

Copy between buckets (or across aliases):

```bash
mc cp myminio/archive/2024/ mys3/backup-2024/ --recursive
```

Flags for flow control:

| Flag | Purpose |
|------|---------|
| `--recursive` | Process directories recursively |
| `--force` | Overwrite without prompting |
| `--preserve` | Keep file attributes (mtime, ACL) |
| `--if-not-exists` | Skip already existing objects |
| `--disable-multipart` | Upload in a single PUT request |

## Mirroring

One-way directory synchronization:

```bash
mc mirror /data/myminio/uploads
```

Flags for production use:

```bash
mc mirror --overwrite --delete \
  /data/myminio/uploads
```

| Flag | Purpose |
|------|---------|
| `--overwrite` | Replace changed files |
| `--delete` | Remove files in destination missing from source |
| `--watch` | Monitor for changes in real time |
| `--md5` | Verify MD5 after upload |

> [!WARNING]
> `--delete` is dangerous: it removes files in the destination that don't exist in the source. Test with `--dry-run` or use `--preserve` for backup scenarios.

Dry-run — show what would happen without making changes:

```bash
mc mirror --overwrite --delete --dry-run \
  /data/myminio/uploads
```

## Access Policies

Set public access on a bucket:

```bash
mc anonymous set download myminio/public
```

Common policies:

```bash
# Read-only for everyone
mc anonymous set download myminio/public

# Fully public
mc anonymous set public myminio/public

# Private (keys only)
mc anonymous set private myminio/private

# No listing, allow downloads by exact link
mc anonymous set uploadOnly myminio/uploads
```

View current policy:

```bash
mc anonymous list myminio
```

Generate a presigned URL (works for private buckets too):

```bash
mc share download --expire 48h \
  myminio/backups/db-2024-01.sql.gz
```

Output contains the signed URL and expiration time.

## Useful Flags

Global flags working with any command:

| Flag | Purpose |
|------|---------|
| `--debug` | Verbose HTTP request/response output |
| `--json` | JSON output (easy to parse in scripts) |
| `--no-color` | Disable colored output |
| `--insecure` | Skip TLS certificate verification |
| `--config-dir` | Config path (default ~/.mc) |
| `--limit` | Rate limit (e.g., `--limit 10MiB/s`) |

JSON output for automation:

```bash
mc ls --json myminio | jq -r '.key'
```

Progress for large file copies:

```bash
mc cp --progress large.iso myminio/backups/
```

## Shell Completion

Bash/zsh autocompletion saves time:

```bash
# Bash
mc completion bash > /etc/bash_completion.d/mc

# Zsh
mc completion zsh > "${fpath[1]}/_mc"

# Fish
mc completion fish > ~/.config/fish/completions/mc.fish
```

After enabling, type `mc ` and press Tab twice to see available commands and aliases.

---

`mc` covers 90% of S3 tasks. For complex scenarios (versioning, lifecycle policies, encryption) — use the API or a Terraform provider. But basic bucket and object operations are faster with this tool than with any SDK.
