A command-line interface for Mapbox APIs. Commands are generated at build time from OpenAPI specs, so they always match the specs.
brew install mapbox/tap/mapbox
mapbox auth login
mapbox styles list- Install
- Authentication
- Commands
- For AI agents
- Global options
- Updates, history and logs
- Privacy
- Contributing
Homebrew covers macOS and Linux. On Windows, use the install script or download the archive.
On macOS or Linux:
brew install mapbox/tap/mapboxUpdate with brew upgrade mapbox. The formula also installs completions
for bash, zsh and fish, so there is nothing to set up under
Shell completion. The tap lives at
mapbox/homebrew-tap.
The script detects your platform, checks a SHA-256 checksum, and installs
mapbox into ~/.local/bin. No sudo, no admin rights:
curl -fsSL https://cli.mapbox.com/install.sh | shirm https://cli.mapbox.com/install.ps1 | iexRun it again to update. MAPBOX_CLI_VERSION pins a version instead of
taking the newest, with or without the leading v, so the version
mapbox --version prints can be pasted straight in:
curl -fsSL https://cli.mapbox.com/install.sh | MAPBOX_CLI_VERSION=0.3.0 sh$env:MAPBOX_CLI_VERSION = '0.3.0'; irm https://cli.mapbox.com/install.ps1 | iexMAPBOX_INSTALL_DIR chooses where the binary lands. The scripts' sources
are scripts/install.sh and
scripts/install.ps1.
If piping a script into a shell is not allowed where you work, the archives
are ordinary HTTP downloads, and manifest.json lists every target with its
checksum:
curl -fsSL https://cli.mapbox.com/latest/manifest.jsonSix targets are published: aarch64-apple-darwin, x86_64-apple-darwin,
aarch64-unknown-linux-musl, x86_64-unknown-linux-musl,
x86_64-pc-windows-msvc and aarch64-pc-windows-msvc. Pick yours, check it,
then extract:
version=v0.3.0
file=mapbox-${version}-aarch64-apple-darwin.tar.gz
curl -fsSLO "https://cli.mapbox.com/${version}/${file}"
curl -fsSL "https://cli.mapbox.com/${version}/SHA256SUMS" |
grep "$file" | shasum -a 256 -c -
tar -xzf "$file"
mv mapbox ~/.local/bin/On Windows the archive is a .zip, and PowerShell can read the manifest
directly:
$version = 'v0.3.0'
$target = 'x86_64-pc-windows-msvc'
$manifest = Invoke-RestMethod "https://cli.mapbox.com/$version/manifest.json"
$artifact = $manifest.artifacts.$target
Invoke-WebRequest "https://cli.mapbox.com/$version/$($artifact.file)" -OutFile $artifact.file
if ((Get-FileHash -Algorithm SHA256 $artifact.file).Hash -ine $artifact.sha256) {
throw 'checksum mismatch'
}
Expand-Archive $artifact.file -DestinationPath .This uses Invoke-WebRequest and Get-FileHash because Windows PowerShell
5.1, the edition that ships with Windows, aliases curl to
Invoke-WebRequest, and sha256sum isn't shipped outside WSL or Git Bash.
Use latest in place of the version for whatever is current. Each archive
holds one file, the mapbox executable.
The macOS builds are not code-signed with a Developer ID. curl attaches no
quarantine flag, which is why the commands above run, but a download through
a browser does, and Gatekeeper will refuse an unsigned binary that carries
one. Clear it with xattr -d com.apple.quarantine mapbox.
It needs Rust via rustup and nothing else: no second
repository, no token, and no network beyond crates.io. The OpenAPI specs the
commands are generated from are vendored in openapi/.
cargo build --release
./target/release/mapbox --helpmapbox uninstallRemoves only the mapbox binary. Credentials, profiles, and the separate
tilesets binary are untouched. Run
mapbox auth logout first if you
want those gone too. Asks for confirmation like any destructive command
(--yes/MAPBOX_YES skips it); --dry-run previews without deleting.
Installed with Homebrew? Use brew uninstall mapbox instead, so Homebrew
knows it is gone.
mapbox auth login # opens a browser (OAuth/PKCE)
mapbox auth whoami # reports which token the next command will use
mapbox auth logout # removes stored credentialsauth refresh and auth profiles complete the set; see
docs/commands.md.
Credentials live in ~/.mapbox as plain JSON with locked-down file
permissions. There is no OS keychain integration. Override them with
--token/--username or MAPBOX_ACCESS_TOKEN/MAPBOX_USERNAME, and set
MAPBOX_CONFIG_DIR to move the whole store, which a container usually
wants.
--profile <name> keeps a separate credential set per account:
mapbox auth login --profile android_app
mapbox --profile android_app styles list
mapbox auth profiles # which profiles are actually storedEach Mapbox API is a command group, with one subcommand per operation:
mapbox accounts <operation>
mapbox fonts <operation>
mapbox geocoder <operation>
mapbox search <operation>
mapbox sprites <operation>
mapbox static <operation>
mapbox styles <operation>
mapbox tilesets <operation>For example:
mapbox styles get <STYLE_ID>
mapbox styles create --data '{"name": "My Style", "version": 8, ...}'Groups are assigned per operation, not per spec file, so sprites and
tilesets each collect operations from several specs. A few nest one level
deeper where that reads better, as in mapbox styles draft get.
mapbox tilesets is unrelated to mapbox tilesets-cli.
docs/commands.md lists every command with its parameters and sample output.
Every request sends User-Agent: mapbox-cli/<version> and nothing else
about you or your machine. MAPBOX_CLI_NO_TELEMETRY=1 keeps even future
markers out of that header.
mapbox doctor # the token, proxies and settings the next command would use
mapbox usage # account usage per product, by day
mapbox config set update-check off # a setting that persists across shells
mapbox history list # recent runs, newest firstmapbox doctor is the first thing to run when a command behaves
unexpectedly. It makes no request unless you pass --verify. See
Doctor, Usage and
Config for details, and
Command history below.
Homebrew installs completions for you. Otherwise, mapbox completion
prints a script on stdout for you to put where your shell looks:
mapbox completion bash > ~/.local/share/bash-completion/completions/mapbox
mapbox completion zsh > ~/.zfunc/_mapbox # a directory on $fpath
mapbox completion fish > ~/.config/fish/completions/mapbox.fish
source <(mapbox completion bash) # this shell onlymapbox completion powershell >> $PROFILEIt completes commands, subcommands and flags from this binary's own command tree, so it always matches the build that printed it. Values such as style IDs are not completed, since that would mean an API request mid-keystroke.
mapbox tilesets-cli list <USERNAME>
mapbox tilesets-cli upload-source <USERNAME> <SOURCE_ID> data.geojson.ldForwards everything to the separately installed Tilesets CLI:
pipx install mapbox-tilesets # Python 3.10+It uses the same token as every other command. --output and --yes don't
apply here; tilesets has its own flags, so use --force/-f for its
prompts. If a tileset command answers for the wrong account,
mapbox auth whoami shows which token is in play.
Two commands, for two different jobs: agent-skills installs guidance on
using Mapbox, and generate-skills writes a skill describing this CLI.
mapbox agent-skills list # what's published, and what's installed here
mapbox agent-skills install # every skill, for whichever agents you have
mapbox agent-skills update # re-install what's here, report what changed
mapbox agent-skills uninstall <NAME>Installs the Mapbox Agent Skills: hand-written guidance for coding agents on cartography, token security, style quality, geospatial operations and the mobile and web SDKs. No token or Node needed.
By default it installs into this project for each supported agent it finds
on the machine, including Claude Code, Codex, Cursor and GitHub Copilot.
--agent picks one, --global writes to the agent's home directory, and
--dir writes to a path you name, for a Dockerfile or a CI job. update
rewrites only files that differ from what's published, including files you
edited. The full list of agents and flags is in
docs/commands.md.
mapbox generate-skillsWrites this CLI's whole command surface as an Agent
Skill, into the current project for
each agent it finds: .claude/skills for Claude Code, .agents/skills for
Codex. --agent, --global, --dir and --service narrow it, and
--dry-run lists the files first. To remove every copy it wrote:
mapbox agent-skills uninstall mapbox-cliThese apply to every command, not just the API ones.
Every mutating command takes --dry-run: it prints the request instead of
sending it, checking --data/--file along the way.
$ mapbox styles delete zz-clitest-style --dry-run
Dry run — nothing was sent.
DELETE https://api.mapbox.com/styles/v1/you/zz-clitest-style?access_token=<redacted>Goes after the operation name (mapbox styles delete ID --dry-run),
not before. A read-only command rejects it.
| Request | Budget |
|---|---|
A normal request (GET, or a typed --data body) |
60 seconds |
A --file upload, or a --data @<path> / @- body |
15 minutes |
--timeout <SECONDS> overrides either, MAPBOX_TIMEOUT sets it for a
whole shell.
MAPBOX_CLI_EXTRA_QUERY appends raw query parameters to every request this
process sends, in the same k1=v1&k2=v2 shape as a URL's own query string —
for an API parameter this CLI's specs don't declare a flag for. --debug
and --dry-run show it alongside everything else on the request.
HTTPS_PROXY, HTTP_PROXY, ALL_PROXY and NO_PROXY are all honored, so
a CLI behind a corporate proxy needs no configuration of its own.
Two things are easy to lose an afternoon to:
HTTP_PROXYalone does not carry Mapbox requests. Every Mapbox base URL ishttps, and that variable applies tohttpURLs only. SetHTTPS_PROXY(orALL_PROXY) instead.- A SOCKS proxy is not supported.
ALL_PROXY=socks5://…fails the request rather than being ignored, and the failure saysunsupported scheme socks5. If you see that, it is the proxy and not the network.
--output/-o (or MAPBOX_OUTPUT) picks the shape:
| Value | Result |
|---|---|
auto (default) |
text at a terminal, json when piped |
text |
Pretty-printed, readable |
json |
Everything on stdout is JSON: one compact document per command |
Every command prints one JSON document today. A command that streams would
print one per line (JSON Lines), which is why there is no -o jsonl.
Errors always go to stderr and never appear in stdout. Under json they're
one flat object: code, message, plus fix, next_actions and docs
where there is advice to give. See docs/commands.md
for the list of codes.
At a terminal, a run opens with a mapbox · v<version> line on stderr, and
tables, labels and tips are in color. Neither reaches a pipe or a file.
-q/--quiet (or MAPBOX_QUIET=1) hides the banner; NO_COLOR turns
color off.
mapbox <command> --schema describes a command as JSON instead of running
it: arguments, types, and the request it would make. Needs no token.
mapbox styles get --schema # one command
mapbox --schema # the whole CLIOnly DELETE commands ask for confirmation, and only at a terminal (both
stdin and stderr):
$ mapbox styles delete my-style
About to DELETE https://api.mapbox.com/styles/v1/me/my-style
Continue? [y/N] n--yes/-y/MAPBOX_YES=1 skips the question, which is what CI wants, or a
script deliberately run at a terminal. It does not apply to auth login,
which always needs a person.
mapbox can't update itself, so when a newer release exists it says so once
a day, on stderr, at a terminal:
A newer mapbox is available: 0.2.0 (this is 0.1.5).
Update: curl -fsSL https://cli.mapbox.com/install.sh | sh
Silence this: MAPBOX_NO_UPDATE_CHECK=1
The suggested command is the install script's. If you installed with
Homebrew, run brew upgrade mapbox instead.
This is the only request the CLI makes that you didn't ask for, so it is kept narrow:
| What it sends | A GET for the channel's latest/manifest.json, with no token, no account, no command, and nothing about you or your machine beyond User-Agent: mapbox-cli/<version> |
| When | At most once a day, and only when stderr is a terminal, so CI and piped runs never check and never print |
| Where | A detached background process. Your command never waits on it: offline, the timing is unchanged and nothing is printed |
| Off | MAPBOX_NO_UPDATE_CHECK=1, or MAPBOX_CLI_NO_TELEMETRY=1, which silences this too, for the shell session it's set in |
~/.mapbox/update-check.json (or $MAPBOX_CONFIG_DIR) holds the answer
between runs. A build that names no release channel never checks at all, and
cargo build produces one.
mapbox config set update-check off turns it off in every shell, not just
the one an environment variable is set in. See
Config.
Each run appends one line to ~/.mapbox/history/<UTC date>.jsonl (or under
$MAPBOX_CONFIG_DIR), kept for 30 days and at most 10 MB, oldest dropped
first: which command ran (its command path, like search forward), how it
ended, how long it took and the request ids support can look up. Argument values are never recorded — not what you
searched for, not a file path, not a token. The files are readable only by
you and never leave your machine.
mapbox history list # the most recent runs, newest first
mapbox history show # everything recorded about the newest run
mapbox history show be40d711 # or one run, by any prefix of its id--help, --version, completion, history itself and runs under sudo
are not recorded. mapbox config set history off turns history off for
good, and MAPBOX_HISTORY=0 for one shell; with it off, nothing is written
and no directory is created, but what was already recorded stays until you
delete ~/.mapbox/history. MAPBOX_CLI_NO_TELEMETRY does not affect it.
Off by default. mapbox config set log on (or MAPBOX_LOG=1 for one shell)
adds, for each run history records, a line of detail in
~/.mapbox/logs/<UTC date>.jsonl: the command line, each request's method,
URL, status, request id and timing, which token was used (where it came
from, its type and account, never the token itself) and the error message.
Tokens are replaced with <redacted> wherever they appear, and the files
never leave your machine.
mapbox history show includes a run's log, or says it was not captured
(logging was off) or is no longer available. Logs are kept up to 30 days and
100 MB in total; past that the oldest go first, and the run's history record
stays. A day of logs goes when that day of history does. Logging needs
history: with history off it never runs, and with the history setting off
config set log on refuses.
YOUR PRIVACY - COLLECTION OF TELEMETRY
Mapbox collects telemetry data from our CLIs to better understand how our tools are used and how to improve our products.
- What Telemetry Data We Collect: Usage metrics include installs, the
service a Mapbox API command belongs to (e.g.
stylesorgeocoder, never the operation or its arguments), CLI version, OS/architecture, whether stdin and stdout are attached to a terminal, an identifier for the detected AI coding agent (if any) running the command (based on signals such as the presence of theCLAUDECODEorCOPILOT_MODELenvironment variable; seeagent_detect.rsfor the complete, versioned list), and a boolean flag indicating whether the command was run in a CI environment. IP addresses necessarily accompany any request made to our server, but will not be retained and analyzed together with telemetry data. - Why We Collect It: For internal analytics by Mapbox to understand adoption, prioritize investments, and improve the reliability, performance, and developer experience of our CLIs.
- What We Do Not Collect: Code completion outputs, source code, project file names, directory contents, non-Mapbox API keys, or credentials.
- Who has Access: Telemetry data will not be disclosed to, or accessed by, third parties other than Mapbox affiliates and passive cloud storage and hosting providers necessary to maintain our infrastructure.
This also covers update notices above, since that check rides the same opt-out.
How to Opt Out: The collection of telemetry data is enabled by default. You can disable it at any time and without affecting the functionality of our CLIs by setting
MAPBOX_CLI_NO_TELEMETRY=1For additional information on our data processing activities and your related rights, please see our Mapbox Privacy Policy.
Running the tests, the lints they have to pass, versioning rules and how specs become commands are in CONTRIBUTING.md.