# Unhedged MCP agent guide

You are connected to Unhedged, a prediction-markets platform, through its MCP
server. This file is the contract for how to act on the account you were given.
Read the units and lifecycle sections before placing anything.

Package: `@unhedged/mcp` | API: `https://api.unhedged.gg` | API reference: /docs/api

## Connecting

Install with `npx @unhedged/mcp init`, which writes the client config
for you. The server talks to `https://api.unhedged.gg`.

### Interactive setup

```
npx @unhedged/mcp init
```

### Claude Code

```
claude mcp add unhedged --scope user --transport stdio \
  --env UNHEDGED_API_KEY='ak_your_key_here' \
  -- npx -y @unhedged/mcp
```

### Codex CLI

```
codex mcp add unhedged \
  --env UNHEDGED_API_KEY='ak_your_key_here' \
  -- npx -y @unhedged/mcp
```

### Claude Desktop or Cursor config

```
{
  "mcpServers": {
    "unhedged": {
      "command": "npx",
      "args": [
        "-y",
        "@unhedged/mcp"
      ],
      "env": {
        "UNHEDGED_API_KEY": "ak_your_key_here"
      }
    }
  }
}
```

## Tools and scopes

Each tool maps to one REST endpoint. A tool only works when the API key carries
its scope, so a failure that looks like a permissions error usually means the
key was minted without that scope.

| Tool | Scope required | Effect | What it does |
| --- | --- | --- | --- |
| `search_markets` | none | additive | Find active and ended markets by asset, sport, topic, or tag. Request resolved markets for history. |
| `get_market` | none | additive | Check the outcomes, close time, and resolution rule. |
| `get_market_stats` | none | additive | See implied probabilities, volume, and bet activity. |
| `get_balance` | `balance:read` | additive | See spendable and locked USD, plus held CC. |
| `get_portfolio` | `portfolio:read` | additive | See position exposure, performance, and recent payouts. |
| `list_bets` | `bet:read` | additive | See your pool bets and whether they are open or settled. |
| `place_bet` | `bet:place` | moves funds or cancels | Commit a USD amount to an outcome in a pool market. |
| `list_orders` | `order:read` | additive | See open order book orders across your account or one market. |
| `place_order` | `order:place` | moves funds or cancels | Submit a limit, market, stop loss, or take profit order. |
| `cancel_order` | `order:cancel` | moves funds or cancels | Cancel selected orders or all open orders on one market. |
| `request_withdrawal` | `balance:withdraw` | moves funds or cancels | Send funds out as CC on Canton or USDC on Ethereum. |
| `get_market_maker_profile` | `portfolio:read` | additive | Read your fee tier, rebates, limits, and exposure. |

## Units and money

- **USD amounts.** Bets are denominated in USD. The platform balance is a USD
  figure with a CC reference for display and delivery.
- **Share quantities.** Order-book orders are sized in whole contracts, passed
  as `quantity`, or in USD notional, passed as `quoteQuantity` with exactly
  two decimal places. Pass exactly one of the two, never both.
- **Order prices.** `price` is a decimal string with exactly two decimal
  places, strictly between 0 and 1. It is a probability, not a percentage:
  `0.62`, not `62`. Stop and take-profit orders use the same bounds for
  `triggerPrice`.
- **Outcome labels.** Pass the label exactly as returned by
  `get_market`, for example `YES` or `"$95k - $100k"`. Approximate
  labels are rejected.
- **Balances.** `get_balance` reports available and locked amounts.
  Locked funds are already committed to open orders; available funds are what a
  new order can still use.
- **Fees are risk-shaped and assessed per fill.** Order-book fees apply when
  shares trade, not when an order is accepted. One fill costs
  `shares_filled x execution_price x (1 - execution_price) x rate`. The
  `price x (1 - price)` term is what makes the fee risk-shaped: it peaks at
  0.50 and shrinks toward zero as the price approaches 0 or 1, so the rate is
  never a flat percentage of trade value.
- **A multi-fill order pays this per fill**, each at that fill's own execution
  price. Never compute a single fee from the order's limit price and present it
  as the cost — report fees from the fills that actually happened.
- **Rebates and locks differ.** A negative rate is a rebate that lowers what the
  fill costs. It does not lower the balance locked when a bid is placed: the
  placement lock never goes below zero. A resting order also keeps the maker
  rate it was placed with, even if the tier changes later.
- **Direction of the fee.** Buying costs the share value plus the fee. Selling
  returns the share value minus the fee. Read the live schedule at /fees
  or, for market makers, from `get_market_maker_profile`.

## Bets and orders are different markets

- **Parimutuel bets** (`place_bet`) contribute to a pool. Your payout
  depends on the final split of that pool, so the return is not fixed at the
  moment you bet.
- **Order-book orders** (`place_order`) trade at a price against
  resting orders. Use them only on order-book markets; parimutuel markets have
  no order book and `list_orders` returns nothing for them.

Do not describe a parimutuel bet as a fill at a price, and do not describe an
order-book order as a pool contribution.

## Accepted is not executed

Placing an order returns an order record with an engine-assigned ID, a status,
and any fills that happened immediately. An accepted order is not a completed
trade.

- A **market order** usually fills immediately, possibly across several resting
  orders.
- A **limit order** may rest on the book unfilled, fill later, fill in several
  pieces, or never fill.
- A **partial fill** means only part of the quantity traded. Only the filled
  part changes your balance and positions; the remainder is still working.
- **Cancelling** stops the unfilled remainder. It does not reverse fills that
  already happened, and it does not return funds already spent on those fills.

Never tell the user a position was opened, closed, or hedged until you have read
the resulting positions or fills back.

## Permissions and limits

You have exactly the authority of the API key you were started with. There is
no separate agent permission system.

| Key profile | Scopes to grant |
| --- | --- |
| Research only | `market:read`, `portfolio:read`, `bet:read`, `order:read`, `balance:read` |
| Research and trading | `market:read`, `portfolio:read`, `bet:read`, `bet:place`, `order:read`, `order:place`, `order:cancel`, `balance:read` |
| Trading and withdrawals | `market:read`, `portfolio:read`, `bet:read`, `bet:place`, `order:read`, `order:place`, `order:cancel`, `balance:read`, `balance:withdraw` |

Users set your trading authority by minting a key with a narrower scope set and
by adding limits in the server environment:

| Variable | Requirement | Meaning |
| --- | --- | --- |
| `UNHEDGED_API_KEY` | required | Bearer token in the form ak_... . The scopes on the key decide which tools work. |
| `UNHEDGED_MAX_SPEND_PER_SESSION` | optional | Caps bet stakes and buy-order amounts in USD. Excludes fees and withdrawals; resets on restart. Default: `unset`. |

## Withdrawals are separate

Permission to trade never implies permission to withdraw. `balance:withdraw`
is off unless it was explicitly granted, and it lets you move funds off the
platform to a destination you supply. Ethereum withdrawals also need
`balance:read`, because the fee quote is a separate authenticated request.

If a user asks you to withdraw and the tool returns a permissions error, stop
and explain which scope is missing. Do not attempt workarounds.

## Spend cap

`UNHEDGED_MAX_SPEND_PER_SESSION` caps cumulative bet stakes and buy-order
notional in USD. Fees and withdrawals are excluded.

- The cap lives in the server process and **resets when the process restarts**.
  It is a session rail, not an account limit.
- It is additive to whatever the platform enforces; it does not replace balance
  or risk limits.
- When the backend definitively rejects a call with a 4xx response, the
  reservation is released. Ambiguous failures keep it reserved, which can make
  the cap stricter than the money actually spent.
- If the notional cannot be estimated locally, the tool refuses the order rather
  than guessing. Supplying `quoteQuantity`, or a limit order with an explicit
  price and quantity, keeps the order inside the cap.

## After an ambiguous failure

Mutations are never retried automatically. Every call generates a fresh
idempotency key, so a retry is a **new request**, not a replay of the original.

When a call fails with a timeout, a network error, or a 5xx response, the
outcome is unknown. Before submitting anything again:

1. Check `list_bets` for bets and `list_orders` for open orders.
   A filled order will not appear in the open-order list. The portfolio is
   a bounded preview, and a balance alone cannot identify a transaction.
2. For filled orders or withdrawals, check the account's transaction history
   on Unhedged. The MCP does not expose that history.
3. Report what you found. If the outcome remains uncertain, stop and ask the
   user; an empty list is not proof that the operation failed.

## Secrets

The API key belongs in the client's server configuration, never in a prompt,
chat message, screenshot, recording, or shared config example. If you are asked
to repeat a key back, refuse and point the user at /account/api-keys. Use
`ak_your_key_here` in any example you write.

## Example prompts

Research:

> Find an active BTC Up or Down market using Unhedged MCP. What makes Up win, and when does it close?

> Which open markets cover the next Counter-Strike major, and what are the
> current implied probabilities for each outcome?

Portfolio review:

> Summarise my Unhedged positions, my available and locked balance, and which
> markets carry the most concentration risk.

Order management:

> Show my open orders, cancel everything resting more than 10% away from the
> current price on the MLBB market, and report the balance change afterwards.

## Skills

The server ships markdown workflows as MCP prompts. Clients that expose prompts
surface them as slash commands.

- `market-research` — Find markets for a topic and summarise odds, volume, and resolution rules. Read-only.
- `place-hedged-position` — Size and place a hedged position across multiple outcomes within a budget, confirming before it commits.
- `portfolio-review` — Read-only summary of holdings, profit and loss, win rate, and concentration.
- `cash-out` — Close open orders, sell order-book positions at market, and prepare a withdrawal.
- `market-maker-workflow` — Quote both sides of an order book around a chosen fair value and refresh as the market moves.
- `market-creator-assistant` — Draft a market with outcomes, resolution rules, and metadata, then guide submission.
