Fast MCP server for interacting with Upbit. Provides public market data tools and optional private trading tools.
- Node.js 18+
- pnpm 8+
pnpm install
Copy and edit .env
:
cp .env.example .env
.env.example
:
UPBIT_SERVER_URL=https://api.upbit.com
UPBIT_ACCESS_KEY=
UPBIT_SECRET_KEY=
UPBIT_ENABLE_TRADING=false
Private tools require UPBIT_ACCESS_KEY
, UPBIT_SECRET_KEY
, and UPBIT_ENABLE_TRADING=true
.
- Keep your
UPBIT_SECRET_KEY
private and IP-allowlist your server in Upbit. - Set
UPBIT_ENABLE_TRADING=true
only when you intend to place/cancel orders or create withdrawals/deposit addresses. - Upbit permission mapping (high-level):
- Orders: create/cancel → 주문하기, query/list → 주문조회
- Accounts/balances → 자산조회
- Withdrawals: create/cancel → 출금하기, query/list/address list → 출금조회
- Deposits: create deposit address → 입금하기, query/list/chance/address read → 입금조회
- Auth follows Upbit JWT with
query_hash
(sorted URL-encoded params). POSTs send JSON bodies and are signed based on that body. - See docs: 인증, 주문 생성, 출금/입금 레퍼런스
- Auth: docs.upbit.com/kr/reference/auth
- Orders: docs.upbit.com/kr/reference/new-order
- Withdrawals: list-withdrawal-addresses, withdraw
- Deposits: available-deposit-information, create-deposit-address
Before you begin, you need to get your Upbit API keys:
- Create an account on Upbit if you don't already have one
- Go to the Upbit Developer Center
- Create a new API key
- Make sure to set appropriate permissions (read, trade, withdraw as needed)
- Store your API keys(
UPBIT_ACCESS_KEY
,UPBIT_SECRET_KEY
) in the.env
file (see Installation section) setUPBIT_ENABLE_TRADING=true
to enable private tools.
pnpm run build
pnpm run start
For easier testing use this (in project root):
pnpm run build
npx @modelcontextprotocol/inspector node dist/index.js
If installed globally or via npx, you can also run the bin:
mcp-upbit-server
Runs over stdio for MCP clients.
Public:
GET_TICKER
— latest ticker for a market. Params:{ "market": "KRW-BTC" }
GET_ORDERBOOK
— orderbook snapshot. Params:{ "market": "KRW-BTC" }
GET_TRADES
— recent trades. Params:{ "market": "KRW-BTC" }
Private (requires env and enable flag):
GET_ACCOUNTS
GET_ORDERS
—{ market?, state?, page?, limit? }
GET_ORDER
—{ uuid? , identifier? }
CREATE_ORDER
—{ market, side, ord_type, volume?, price? }
CANCEL_ORDER
—{ uuid }
LIST_WITHDRAWAL_ADDRESSES
CREATE_WITHDRAWAL
—{ currency, amount, address, net_type, secondary_address? , transaction_type? }
GET_WITHDRAWAL
—{ uuid }
LIST_WITHDRAWALS
—{ currency?, state?, page?, limit? }
CANCEL_WITHDRAWAL
—{ uuid }
GET_DEPOSIT_CHANCE
—{ currency, net_type? }
CREATE_DEPOSIT_ADDRESS
—{ currency, net_type }
GET_DEPOSIT_ADDRESS
—{ currency, net_type }
LIST_DEPOSIT_ADDRESSES
GET_DEPOSIT
—{ uuid }
LIST_DEPOSITS
—{ currency?, state?, page?, limit? }
All tool outputs are JSON strings for easy display.
// CREATE_ORDER (market buy 10,000 KRW)
{
"name": "CREATE_ORDER",
"arguments": {
"market": "KRW-BTC",
"side": "bid",
"ord_type": "price",
"price": "10000"
}
}
// CREATE_ORDER (limit sell with post_only)
{
"name": "CREATE_ORDER",
"arguments": {
"market": "KRW-BTC",
"side": "ask",
"ord_type": "limit",
"volume": "0.01",
"price": "100000000",
"time_in_force": "post_only",
"identifier": "my-unique-id-001"
}
}
// LIST_WITHDRAWALS (page 1, 50 items)
{
"name": "LIST_WITHDRAWALS",
"arguments": { "page": 1, "limit": 50 }
}
// GET_DEPOSIT_CHANCE
{
"name": "GET_DEPOSIT_CHANCE",
"arguments": { "currency": "BTC" }
}
MIT