See README.md for safety warnings and disclaimer.
Self-contained guide for integrating bitmex-cli into AI agents, MCP clients, and automated pipelines.
Fast entry points:
- Runtime agent context:
CONTEXT.md - Full command contract:
agents/tool-catalog.json - Error routing contract:
agents/error-catalog.json - Workflow skills:
skills/
curl -sSfL https://raw.githubusercontent.com/BitMEX/bitmex-cli/master/install.sh | shDownloads a pre-built binary for your platform (macOS/Linux, x86_64/arm64), verifies the SHA256 checksum, and installs to /usr/local/bin. No Rust or build tools needed. Requires curl, tar, and sha256sum (or shasum). May prompt for sudo if /usr/local/bin is not writable.
# Install Rust if needed
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Clone and install
git clone https://github.com/BitMEX/bitmex-cli.git
cd bitmex-cli
cargo install --path .bitmex --versionPublic commands (market data, announcements) need no credentials. All other commands require a BitMEX API key.
If the user does not have a BitMEX account:
- Sign up at bitmex.com/register
- Complete identity verification (Settings → Verification)
- Deposit funds (Wallet → Deposit)
- Direct the user to bitmex.com/app/apiKeys (or testnet.bitmex.com/app/apiKeys for testnet).
- Create a key with Order and Account permissions (add Withdraw only if withdrawals/transfers are needed).
- Ask the user for the API key and secret.
- Store credentials:
bitmex auth set --api-key <KEY> --api-secret <SECRET>For testnet:
bitmex auth set --profile testnet --testnet --api-key <KEY> --api-secret <SECRET>- Verify:
bitmex account me -o jsonFor CI, Docker, or single-session use:
export BITMEX_API_KEY="..."
export BITMEX_API_SECRET="..."--api-key/--api-secretflagsBITMEX_API_KEY/BITMEX_API_SECRETenv vars--profile <name>flag → OS keychainBITMEX_PROFILE/ active profile in config → OS keychain- Plaintext fallback in config file (when keychain unavailable)
| Group | BitMEX API permissions |
|---|---|
| market, announce, chat (read) | None (public) |
| account, execution, position (read) | Order |
| order (place/cancel) | Order |
| wallet (read) | Account |
| wallet (withdraw/transfer) | Withdraw |
| staking, apikey, porl | Account |
bitmex <command-group> <subcommand> [args...] -o json 2>/dev/null- Always pass
-o jsonfor machine-readable output. - Redirect stderr (
2>/dev/null) to suppress diagnostic noise. - Check exit code:
0= success, non-zero = failure. - On failure, stdout contains a JSON error envelope.
All commands accept --testnet to target https://testnet.bitmex.com. Use testnet to validate agent workflows without risking real funds:
bitmex --testnet market instrument --active -o json
bitmex --testnet order buy XBTUSD 100 --price 50000 --validate -o jsonTestnet requires separate API keys from testnet.bitmex.com.
All commands return JSON on stdout. Arrays of objects are typical for list endpoints:
[
{
"symbol": "XBTUSD",
"lastPrice": 50000,
"markPrice": 49998,
"fundingRate": 0.0001,
...
}
]Error envelopes always contain error (stable category code) and message:
{ "error": "auth", "message": "Authentication failed: Invalid API Key." }| Category | Meaning | Retry? |
|---|---|---|
api |
Exchange rejected the request (4xx other than 429) | Depends on message |
auth |
Invalid key, bad signature, insufficient permissions | No |
network |
TCP connection failure or timeout | Yes |
rate_limit |
HTTP 429 or 503 (exchange overloaded) | Yes — wait for reset |
validation |
Bad CLI arguments | No |
config |
Missing or invalid configuration | No |
websocket |
WebSocket connection error | Yes |
io |
Local file I/O error | No |
parse |
Unexpected response format | No |
rate_limit errors include three extra fields added client-side (not from BitMEX):
{
"error": "rate_limit",
"message": "BitMEX rate limit exceeded: ... Retry after Unix timestamp 1713229600.",
"suggestion": "BitMEX allows 300 requests per 5 minutes. Back off and retry after x-ratelimit-reset.",
"retryable": true,
"docs_url": "https://www.bitmex.com/app/restAPI#Rate-Limits"
}messageincludes the Unix retry timestamp from thex-ratelimit-resetresponse headersuggestion/retryable/docs_urlare static hints for AI agent retry logic
- Never execute dangerous commands without explicit user approval. Check the
dangerousfield inagents/tool-catalog.json. - Validate orders first: always pass
--validatebefore submitting live orders. - Test on testnet: use
--testnetfor new strategies. - Confirm destructive actions: cancellations, withdrawals, transfers require
--yesflag or interactive confirmation. - Never log secrets: never print
BITMEX_API_SECRETin output.
All order placement, amendment, and cancellation commands. All withdrawal and transfer commands. Position isolation, leverage changes, margin transfers. See dangerous: true entries in agents/tool-catalog.json.
The built-in MCP server exposes bitmex-cli commands as tools directly to MCP clients:
bitmex mcp # market + account (safe defaults)
bitmex mcp -s all # all groups except streaming
bitmex mcp -s all --allow-dangerous # all commands including order placementClaude Desktop config (credentials from OS keychain):
{
"mcpServers": {
"bitmex": {
"command": "bitmex",
"args": ["mcp", "-s", "market,account,order,position,wallet"]
}
}
}For CI or environments without a keychain, pass credentials via environment variables:
{
"mcpServers": {
"bitmex": {
"command": "bitmex",
"args": ["mcp", "-s", "market,account,order,position,wallet"],
"env": {
"BITMEX_API_KEY": "your-key",
"BITMEX_API_SECRET": "your-secret"
}
}
}
}For real-time data, use bitmex ws instead of polling REST endpoints:
# Public — no auth needed
bitmex ws trade:XBTUSD
bitmex ws orderBookL2_25:XBTUSD instrument
# Private — requires --auth
bitmex ws --auth position order execution margin walletOutput is NDJSON (one JSON object per line) to stdout. Ctrl-C to stop.
Available public topics: trade, quote, instrument, orderBookL2_25, orderBook10, funding, liquidation, settlement, insurance, announcement, chat
Available private topics: order, execution, position, margin, wallet, transact, affiliate, privateNotifications
BitMEX allows 300 requests per 5 minutes for authenticated REST endpoints. Check response headers:
x-ratelimit-remaining— requests left in current windowx-ratelimit-reset— Unix timestamp when budget resets
When rate limited (error: "rate_limit"), wait until x-ratelimit-reset before retrying. Use WebSocket streaming for real-time data instead of polling.
bitmex market instrument --symbol XBTUSD -o json
bitmex market funding --symbol XBTUSD --count 3 --reverse -o json
bitmex market stats -o jsonbitmex position list -o json
bitmex execution trade-history --count 20 -o json
bitmex wallet balance -o jsonEvery instrument enforces a minimum price increment (tickSize) and minimum quantity increment (lotSize). Submitting a price or quantity that isn't a multiple of these will return a 400 Invalid price or 400 Invalid quantity error.
Fetch constraints before placing:
constraints=$(bitmex market instrument --symbol XBTUSD -o json | jq '.[0] | {tickSize, lotSize}')
tick_size=$(echo "$constraints" | jq -r '.tickSize')
lot_size=$(echo "$constraints" | jq -r '.lotSize')Round before submitting:
# round price to nearest tick
price=$(echo "$raw_price $tick_size" | awk '{printf "%g", int($1/$2+0.5)*$2}')
# round qty down to nearest lot
qty=$(echo "$raw_qty $lot_size" | awk '{printf "%g", int($1/$2)*$2}')# 1. Fetch tick/lot constraints and align price/qty before submitting
constraints=$(bitmex market instrument --symbol XBTUSD -o json | jq '.[0] | {tickSize, lotSize}')
# 2. Preview the constructed request body (local only — does not validate against exchange)
bitmex order buy XBTUSD 100 --price 50000 --validate -o json
# 3. Confirm with user, then execute (--yes skips interactive prompt for agent use)
bitmex order buy XBTUSD 100 --price 50000 --yes -o jsonbitmex ws trade:XBTUSD | jq -c '{time: .timestamp, price: .price, size: .size}'