Skip to content

mc — MinIO Client S3 CLI

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:

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:

mc --version

For macOS, use Homebrew:

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.

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

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

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:

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

Browsing and Navigation

List buckets:

mc ls myminio

Recursive listing with contents:

mc ls --recursive myminio/backups/

Object metadata:

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:

mc mb myminio/app-logs

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

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

Remove an empty bucket:

mc rb myminio/app-logs

For non-empty buckets, use force:

mc rb --force myminio/app-logs

Working with Objects

Print object contents to stdout without downloading:

mc cat myminio/config/latest.yaml

Remove an object:

mc rm myminio/backups/old.sql.gz

Recursive removal by pattern:

mc rm --recursive --force myminio/temp/*
Note

mc rm without --force asks for confirmation. Always use --force in scripts.

Find objects by criteria:

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

Combine with deletion:

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

Uploading and Downloading

Copy a local file to a bucket:

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

Multiple upload:

mc cp ./uploads/* myminio/static/

Download an object locally:

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

Copy between buckets (or across aliases):

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

Flags for flow control:

FlagPurpose
--recursiveProcess directories recursively
--forceOverwrite without prompting
--preserveKeep file attributes (mtime, ACL)
--if-not-existsSkip already existing objects
--disable-multipartUpload in a single PUT request

Mirroring

One-way directory synchronization:

mc mirror /data/myminio/uploads

Flags for production use:

mc mirror --overwrite --delete \
  /data/myminio/uploads
FlagPurpose
--overwriteReplace changed files
--deleteRemove files in destination missing from source
--watchMonitor for changes in real time
--md5Verify 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:

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

Access Policies

Set public access on a bucket:

mc anonymous set download myminio/public

Common policies:

# 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:

mc anonymous list myminio

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

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:

FlagPurpose
--debugVerbose HTTP request/response output
--jsonJSON output (easy to parse in scripts)
--no-colorDisable colored output
--insecureSkip TLS certificate verification
--config-dirConfig path (default ~/.mc)
--limitRate limit (e.g., --limit 10MiB/s)

JSON output for automation:

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

Progress for large file copies:

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

Shell Completion

Bash/zsh autocompletion saves time:

# 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.