typus-perp-mcp
Official# typus-perp-mcp
MCP (Model Context Protocol) server for [Typus Perp](https://typus.finance) — lets Claude and other AI agents query markets, manage positions, and execute trades on the Typus Perp DEX on Sui.
---
## Prerequisites
- Node.js >= 18
- A Sui wallet (required for trading and liquidity tools)
- [Claude Desktop](https://claude.ai/download) or [Claude Code](https://claude.ai/code)
---
## Installation
```bash
git clone https://github.com/xingyen0613/typus-perp-mcp
cd typus-perp-mcp
npm install
cp .env.example .env # then edit .env to add your PRIVATE_KEY
npm run build
```
---
## Private Key Setup
Trading and liquidity tools require a private key. The private key is stored locally in a `.env` file and never leaves your machine.
**1. Copy the example file:**
```bash
cp .env.example .env
```
**2. Edit `.env` and fill in your private key:**
```env
NETWORK=MAINNET
SUI_RPC_URL=https://fullnode.mainnet.sui.io:443
PRIVATE_KEY=<your-private-key>
```
> Both Bech32 format (`suiprivkey1...`) and Base64 format are supported.
> The `.env` file is listed in `.gitignore` and will never be committed to Git.
> If you only need read-only tools (query markets, positions, etc.), you can leave `PRIVATE_KEY` empty.
---
## Enable in Claude
> **Setup order**: Installation → Private Key Setup → add to Claude config below → restart Claude.
### Claude Code
Add to `~/.claude/settings.json`:
```json
{
"mcpServers": {
"typus-perp": {
"command": "node",
"args": ["/absolute/path/to/typus-perp-mcp/dist/index.js"]
}
}
}
```
### Claude Desktop
**macOS** — add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"typus-perp": {
"command": "node",
"args": ["/absolute/path/to/typus-perp-mcp/dist/index.js"]
}
}
}
```
**Windows** — add to `%APPDATA%\Claude\claude_desktop_config.json`:
```json
{
"mcpServers": {
"typus-perp": {
"command": "node",
"args": ["C:\\Users\\username\\typus-perp-mcp\\dist\\index.js"]
}
}
}
```
> Replace the path in `args` with the actual location where you cloned this repo.
> `PRIVATE_KEY` and other settings are loaded from the `.env` file in the project root — no need to repeat them here.
> After editing the config, restart Claude to load the new MCP server.
---
## Tools
### Query Tools (read-only, no wallet required)
---
#### `get_markets`
Get all active trading markets and their configurations.
No parameters required.
**Returns:** Market list including leverage limits, trading fees, funding rates, open interest per symbol.
---
#### `get_lp_pools`
Get TLP liquidity pool information.
No parameters required.
**Returns:** TVL, per-token liquidity amounts and USD values, LP token info.
---
#### `get_stake_pools`
Get TLP staking pool information.
No parameters required.
**Returns:** Current TLP price snapshot, total staked shares.
---
#### `get_positions`
Get all open positions for a wallet address.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `address` | Yes | Sui wallet address (`0x...`) |
**Returns:** Open positions including size, collateral, entry price, liquidation price, unrealized PnL, funding fee, borrow fee, close fee.
---
#### `get_orders`
Get all pending orders for a wallet address.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `address` | Yes | Sui wallet address (`0x...`) |
**Returns:** Pending orders including size, trigger price, leverage, order type, linked position.
---
#### `get_user_stake`
Get a user's TLP staking positions and pending rewards.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `address` | Yes | Sui wallet address (`0x...`) |
**Returns:** Staked shares, active/deactivating shares, claimable rewards, unlock timestamps.
> Use this to check your cooldown status after `unstake` or `unstake_redeem`. The `deactivating_shares[].unlocked_ts_ms` field shows the Unix timestamp (ms) when the cooldown ends and `claim` becomes available.
---
### Trading Tools (requires `PRIVATE_KEY`)
---
#### `create_order`
Create a trading order on Typus Perp.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `tradingToken` | Yes | The base token to trade. See [Supported Tokens](#supported-tokens). |
| `collateralToken` | Yes | Token used as collateral. Supported: `USDC`, `SUI` |
| `size` | Yes | Position size as a raw integer (`amount × 10^size_decimal`). Use `get_markets` to find `size_decimal` for the token. |
| `triggerPrice` | Yes | Order trigger price as a raw integer (`USD price × 10^8`). e.g. $65,000 = `6500000000000` |
| `isLong` | Yes | `true` = Long position, `false` = Short position |
| `collateralAmount` | Yes | Collateral amount as a raw integer. USDC has 6 decimals (10 USDC = `10000000`), SUI has 9 decimals (5 SUI = `5000000000`). |
| `isStopOrder` | No | `true` = stop order attached to an existing position. `false` = regular open/limit order. Default: `false` |
| `reduceOnly` | No | `true` = can only reduce an existing position. `false` = can open or increase. Default: `false` |
| `linkedPositionId` | No | Position ID to attach this order to. **Required when `isStopOrder` is `true`**. Use `get_positions` to find position IDs. |
| `dryRun` | No | `true` = simulate without submitting. Default: `false` |
> The perp market and pool index are determined automatically based on `tradingToken` (TYPUS uses index 1, all others use index 0).
---
#### `cancel_order`
Cancel a pending trading order.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `orderId` | Yes | The order ID to cancel. Use `get_orders` to find order IDs. |
| `marketIndex` | Yes | The market index the order belongs to. Use `get_orders` to find the `marketIndex` for each order. |
---
#### `increase_collateral`
Add more collateral to an existing position.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `positionId` | Yes | The position ID to add collateral to. Use `get_positions` to find position IDs. |
| `amount` | Yes | Collateral amount as a raw integer (token units × 10^decimals). |
| `marketIndex` | Yes | The market index the position belongs to. Use `get_positions` to find the `marketIndex` for each position. |
---
#### `release_collateral`
Withdraw excess collateral from an existing position.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `positionId` | Yes | The position ID to release collateral from. Use `get_positions` to find position IDs. |
| `amount` | Yes | Amount to release as a raw integer (token units × 10^decimals). |
| `marketIndex` | Yes | The market index the position belongs to. Use `get_positions` to find the `marketIndex` for each position. |
---
#### `collect_funding_fee`
Collect accumulated funding fees for a position.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `positionId` | Yes | The position ID to collect funding fees from. Use `get_positions` to find position IDs. |
| `marketIndex` | Yes | The market index the position belongs to. Use `get_positions` to find the `marketIndex` for each position. |
---
### Liquidity Tools (requires `PRIVATE_KEY`)
---
#### `mint_stake_lp`
Deposit tokens into the TLP liquidity pool to mint TLP, with optional staking.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `collateralToken` | Yes | Token to deposit. e.g. `USDC`, `SUI` |
| `amount` | Yes | Amount to deposit as a raw integer (token units × 10^decimals). |
| `poolIndex` | Yes | LP pool index. `0` = mTLP pool (accepts SUI, USDC), `1` = iTLP pool (accepts USDC, for TYPUS market). |
| `stakePoolIndex` | Yes | Stake pool index. `0` = mTLP stake pool, `1` = iTLP stake pool. Must match `poolIndex`. |
| `stake` | Yes | `true` = automatically stake the minted TLP after deposit. `false` = receive TLP without staking. |
| `isAutoCompound` | Yes | `true` = enable auto-compounding of staking rewards. `false` = rewards accumulate without compounding. |
---
#### `stake_lp`
Stake existing TLP tokens to earn rewards.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `amount` | Yes | Amount of TLP to stake as a raw integer (TLP units × 10^9). |
| `stakePoolIndex` | Yes | Stake pool index. `0` = mTLP stake pool, `1` = iTLP stake pool. |
---
#### `unstake`
Begin unstaking TLP. This starts an unlock countdown — you must wait for the cooldown period to complete before calling `redeem_tlp` → `claim`. The cooldown duration is subject to change; check the [official Typus documentation](https://typus.finance) for the current value.
> To check when your cooldown ends, call `get_user_stake` and look at `deactivating_shares[].unlocked_ts_ms`.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `stakePoolIndex` | Yes | Stake pool index. `0` = mTLP stake pool, `1` = iTLP stake pool. |
| `poolIndex` | Yes | LP pool index. `0` = mTLP pool, `1` = iTLP pool. Must match `stakePoolIndex`. |
| `share` | No | Amount of shares to unstake as a raw integer. Omit to unstake all. |
---
#### `unstake_redeem`
Combine unstake and redeem into a single transaction. Note that the cooldown period still applies — you must wait for it to complete before calling `claim`. The cooldown duration is subject to change; check the [official Typus documentation](https://typus.finance) for the current value.
> ⚠️ This does **not** return tokens to your wallet directly — you must wait for the cooldown period, then call `claim` to receive the underlying collateral.
> To check when your cooldown ends, call `get_user_stake` and look at `deactivating_shares[].unlocked_ts_ms`.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `stakePoolIndex` | Yes | Stake pool index. `0` = mTLP stake pool, `1` = iTLP stake pool. |
| `poolIndex` | Yes | LP pool index. `0` = mTLP pool, `1` = iTLP pool. Must match `stakePoolIndex`. |
| `share` | No | Amount of shares to unstake and redeem as a raw integer. Omit to unstake and redeem all. |
---
#### `redeem_tlp`
Redeem TLP tokens for underlying assets. Use this when:
- TLP is already in your wallet (minted with `stake=false`), or
- You have completed the `unstake` cooldown period
> ⚠️ This does **not** return tokens to your wallet directly — you must call `claim` afterwards. Full flow: `unstake → (wait cooldown) → redeem_tlp → claim`.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `poolIndex` | Yes | LP pool index. `0` = mTLP pool, `1` = iTLP pool. |
| `share` | No | Amount of TLP shares to redeem as a raw integer. Omit to redeem all. |
---
#### `claim`
Claim redeemed TLP tokens back as underlying collateral. This is the **final step** after `unstake_redeem` or `redeem_tlp`.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `collateralToken` | Yes | The collateral token to receive. e.g. `SUI`, `USDC` |
| `poolIndex` | Yes | LP pool index. `0` = mTLP pool, `1` = iTLP pool. |
| `stakePoolIndex` | Yes | Stake pool index. `0` = mTLP stake pool, `1` = iTLP stake pool. Must match `poolIndex`. |
> Claim does not require an amount — it automatically transfers all redeemed collateral to your wallet.
---
#### `harvest_reward`
Harvest pending staking reward tokens.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `stakePoolIndex` | Yes | Stake pool index. `0` = mTLP stake pool, `1` = iTLP stake pool. |
---
#### `swap`
Swap tokens using the Typus Perp liquidity pool.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `fromToken` | Yes | Token to swap from. e.g. `USDC`, `SUI` |
| `toToken` | Yes | Token to swap to. e.g. `SUI`, `USDC` |
| `amount` | Yes | Amount to swap as a raw integer (fromToken units × 10^decimals). |
| `perpIndex` | Yes | Perp market index. `0` = main market (SUI, BTC, ETH, etc.), `1` = TYPUS market. |
---
## Reference
### Pool Index
| Index | LP Pool | Stake Pool | Accepted Collateral | Markets |
|-------|---------|------------|---------------------|---------|
| `0` | mTLP | mTLP stake | SUI, USDC | All markets except TYPUS |
| `1` | iTLP | iTLP stake | USDC | TYPUS market only |
### Supported Tokens
| Token | Symbol to use | Decimals |
|-------|--------------|----------|
| SUI | `SUI` | 9 |
| Bitcoin | `WBTC` | 8 |
| Ethereum | `wETH` | 8 |
| Solana | `wSOL` | 8 |
| Aptos | `wAPT` | 8 |
| DEEP | `DEEP` | 6 |
| WAL | `WAL` | 9 |
| DOGE | `DOGE` | 8 |
| HYPE | `HYPE` | 8 |
| XRP | `XRP` | 8 |
| Japanese Yen | `JPY` | 9 |
| Gold | `XAU` | 9 |
| Silver | `XAG` | 9 |
| US Oil | `USOIL` | 9 |
| QQQ (ETF) | `QQQX` | 9 |
| S&P 500 (ETF) | `SPYX` | 9 |
| TYPUS | `TYPUS` | 9 |
| USDC (collateral) | `USDC` | 6 |
### Raw Integer Conversion
All amount parameters use raw integers (on-chain representation):
| Value | Formula | Example |
|-------|---------|---------|
| Token amount | `amount × 10^decimals` | 10 USDC = `10000000` (6 decimals) |
| Position size | `amount × 10^size_decimal` | Use `get_markets` to find `size_decimal` |
---
## Workflow Examples
### Open a Long with TP/SL
```
# 1. Open Long position
create_order: tradingToken="SUI", collateralToken="SUI", size="10000000000",
triggerPrice="10000000000", isLong=true, collateralAmount="3000000000"
# 2. Get positionId
get_positions: address="0x..."
# 3. Set Take-Profit (TP)
create_order: tradingToken="SUI", collateralToken="SUI", size="10000000000",
triggerPrice="500000000", isLong=false, reduceOnly=true,
collateralAmount="0", linkedPositionId="<positionId>"
# 4. Set Stop-Loss (SL) — set BELOW current market price to avoid immediate trigger
create_order: tradingToken="SUI", collateralToken="SUI", size="10000000000",
triggerPrice="50000000", isLong=false, isStopOrder=true, reduceOnly=true,
collateralAmount="0", linkedPositionId="<positionId>"
# 5. Close position at market price
create_order: tradingToken="SUI", collateralToken="SUI", size="10000000000",
triggerPrice="1", isLong=false, reduceOnly=true,
collateralAmount="0", linkedPositionId="<positionId>"
```
### Deposit and Withdraw Liquidity
```
# Deposit and stake
mint_stake_lp: collateralToken="SUI", amount="10000000000",
poolIndex="0", stakePoolIndex="0", stake=true, isAutoCompound=false
# Withdraw — Option A: single transaction (cooldown still applies)
unstake_redeem: stakePoolIndex="0", poolIndex="0" # Step 1: unstake + redeem
# ... wait for cooldown period ...
claim: collateralToken="SUI", poolIndex="0", stakePoolIndex="0" # Step 2: receive tokens
# Withdraw — Option B: two transactions
unstake: stakePoolIndex="0", poolIndex="0" # Step 1: start cooldown
# ... wait for cooldown period ...
redeem_tlp: poolIndex="0" # Step 2: redeem
claim: collateralToken="SUI", poolIndex="0", stakePoolIndex="0" # Step 3: receive tokens
```
---
## Important Notes
- **Minimum deposit**: mTLP pool requires at least ~10 SUI (or equivalent USDC). Smaller amounts will fail with `deposit_amount_insufficient`.
- **`reduceOnly` orders require `linkedPositionId`**: When closing or reducing a position with `reduceOnly=true`, you must provide `linkedPositionId`. Omitting it will fail with `position_id_needed_with_reduce_only_order`.
- **Stop-Loss price**: Set SL **below** your entry price for longs (above for shorts). Setting SL above the current market price will trigger it immediately and close your position.
- **Withdrawal flow**: `unstake_redeem` or `redeem_tlp` alone does **not** return tokens to your wallet. Always call `claim` as the final step to receive the underlying collateral.
---
## Development
```bash
npm run build # Compile TypeScript → dist/index.js
npm run typecheck # Type check without building
npm start # Run the server directly
```
---
## Security
- `PRIVATE_KEY` is stored locally and never transmitted outside your machine
- Store it in `.env` or the MCP config's `env` block — never commit it to Git
- `.env` is listed in `.gitignore`
- For read-only use, leave `PRIVATE_KEY` empty — all query tools work without it
TDQS
Scored across 19 tools
Each tool targets a distinct resource and action: user staking vs pool info, order creation vs cancellation, collateral management, and the multi-step unstake/redeem/claim flow are all clearly separated. Even similar-sounding tools like unstake and unstake_redeem have explicit descriptions that delineate their purposes.
Most tools follow a verb_noun snake_case pattern (get_markets, create_order, increase_collateral), but a few are bare verbs (unstake, claim, swap) or compound verbs (mint_stake_lp, unstake_redeem). This is a minor deviation from the otherwise consistent convention.
With 19 tools, the set is slightly heavy but each tool earns its place given the dual domains of perpetuals trading and TLP staking/LP management. The count is justifiable for the breadth of operations covered.
Core workflows are well-covered: order lifecycle, position collateral management, staking/unstaking/redeeming/claiming, and swaps. Minor gaps exist, such as no explicit wallet balance tool to check free TLP or token holdings, but these can be worked around via user-supplied information or external chain queries.