Skip to main content
Glama
Typus-Lab

typus-perp-mcp

Official
by Typus-Lab
README.md
# 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

A3.8/5.0

Scored across 19 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count4/5

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.

Completeness4/5

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.

Maintenance

ActivityInactive
ResponsivenessNo issues