Choose your preferred MCP client
Run this command in your terminal:
claude mcp add --transport http "fensory-health" https://mcp.fensory.com/mcp
Click the button below to add this MCP server to Cursor:
Open in CursorOr add manually: Settings → MCP → Add server
Click the button below to add this MCP server to VS Code:
Open in VS CodeOr add manually: Settings → MCP → Add server
Click the button below to add this MCP server to VS Code Insiders:
Open in VS Code InsidersOr add manually: Settings → MCP → Add server
get-my-walletsList the signed-in user's Fensory wallets, with their addresses and chains. The row with a `privy_wallet_id` is the user's EMBEDDED wallet — the one Fensory itself trades from, and the wallet address that identifies them on-chain. Use this whenever you need the user's address for any other lookup. If the user has no wallets, they need to register on the Fensory app (app.fensory.com).
get_marketGet live PERPETUAL FUTURES market data for one asset on Hyperliquid — mid/mark/oracle price, 24h change, hourly funding rate, open interest, 24h volume, max leverage — plus the trading constraints for that asset: `size_step` (the size precision Hyperliquid accepts) and `min_size` (the smallest order it will accept, because Hyperliquid rejects any order worth less than $10). CALL THIS BEFORE ANY SIZING DECISION OR PRICE QUESTION: never guess a price, a size precision or a minimum. Pass the Hyperliquid coin symbol, e.g. 'BTC', 'ETH', 'SOL'. THIS IS ALSO THE TOOL FOR TOKENIZED-STOCK / RWA PERPS (TSLA, NVDA, GOLD, and similar): they trade on Hyperliquid's HIP-3 builder dexes under a prefixed name like 'xyz:TSLA', and this tool searches those dexes automatically, so pass the bare ticker and use the full prefixed `asset` it returns for every follow-up call. Never answer an RWA or stock-perp question from a spot lookup — Hyperliquid also lists unrelated, illiquid HIP-1 spot tokens under lookalike tickers. Market data is public and global — it does not depend on the user's account or setup. READ THIS YOURSELF IF YOU CAN. Hyperliquid rate-limits per IP and every Fensory user shares this server's, so a read you make from your own environment always beats one made here. It is public data needing no credentials — NEVER send your Fensory token to Hyperliquid. POST to https://api.hyperliquid.xyz/info with `Content-Type: application/json` and: Send `{"type":"metaAndAssetCtxs"}` and look for the asset in `universe[]`; if it is not there it is a builder-dex (RWA) market, so send `{"type":"allPerpMetas"}` and search every `universe[]` for the name — each entry already carries its dex as the prefix (`xyz:TSLA`), so the prefix IS the dex and no separate dex lookup is needed — then `{"type":"metaAndAssetCtxs","dex":"<that prefix>"}` for the one you choose. Reading the response: it is a two-element array — `universe[i]` pairs with `ctxs[i]` BY INDEX, so find the index of the name and use the same index in the contexts. `markPx` is what Hyperliquid uses for PnL and liquidations, `midPx` is the book midpoint, `oraclePx` is the external index used for funding — they differ slightly and that is normal. `funding` is PER HOUR (Hyperliquid charges hourly, unlike venues on 8-hour periods); positive means longs pay shorts. A ticker is often listed on SEVERAL dexes with only one still alive: SKIP every entry with `isDelisted: true` (frozen mark, null mid, zero volume — TSLA has four dead copies and one live one on `xyz`), and if more than one live dex lists it, prefer the one with real `dayNtlVlm` and `openInterest` and say which you used. Match the EXACT ticker asked for: a similar name on another dex (`US500` vs `xyz:SP500` vs `flx:USA500`) is a DIFFERENT instrument, often at a different price scale — mention it as an aside if useful, never substitute it. `szDecimals` is the size precision every order must round to, and Hyperliquid rejects any order worth less than $10. A `dex:` prefix means a builder-deployed market, and that full prefixed name is what every follow-up call needs. A tokenized stock may ALSO exist as an illiquid HIP-1 spot token under a lookalike ticker — that is a different instrument, not this one. Then call this tool with its normal arguments plus `ack: true` so the read is recorded. FALLBACK — only if you genuinely cannot make an HTTP POST request: call it with `cannot_post: true` and the server reads for you, over a rate limit shared by every user.
get_all_marketsSnapshot EVERY Hyperliquid perps market in ONE call — price, 24h change, hourly funding, open interest and 24h volume for the whole universe. THIS IS THE SCREENING TOOL: use it for anything cross-sectional ('which markets are moving', 'highest funding', 'most liquid', 'rank by volume', building a basket) instead of calling get_market once per asset. The universe is 200+ perps, so results are SORTED and TRUNCATED — `sort_by` picks the ranking and `limit` the count, and `total_count` tells you how many exist beyond what was returned. Funding sorts by MAGNITUDE, since carry works in either direction. Once an asset is chosen, call get_market for its sizing rules (`size_step`, `min_size`) before ordering — those are deliberately not returned here. Set `dex` to reach tokenized-stock / RWA perps, which live on separate builder dexes. Public data: no account needed.
get_funding_historyHistorical funding rates for ONE perps market, oldest first. Funding is what longs and shorts pay each other every hour, so this is how a CARRY question gets answered: 'has this been paying shorts consistently', 'what did funding average last week', 'is the current rate unusual'. get_market gives the rate right now; this gives the series behind it, plus `average_annualized_pct` over the window. Pair it with get_all_markets sorted by funding to find candidates, then check here whether the rate has held or is a one-off spike. Public data — no account needed.
get_predicted_fundingsUpcoming funding rates for every coin across MULTIPLE venues (Hyperliquid, Binance, Bybit) with each venue's next funding time. Use it to see where Hyperliquid's funding sits versus the wider market: a rate far out of line with other venues is the interesting case. Rates are normalized to `funding_rate_hourly_pct` so venues on different schedules (Hyperliquid charges hourly, others every 4 or 8 hours) can actually be compared — never compare the raw `funding_rate` fields directly. IMPORTANT: Fensory only trades Hyperliquid, so a cross-venue difference is a SIGNAL, not an executable arbitrage — never describe it as a trade the user can take here. Public data — no account needed.
get_recent_tradesThe most recent PUBLIC trades on one Hyperliquid market — everyone's prints, not just the user's. Useful for a quick read on which side is hitting: are the last trades buys lifting the offer or sells hitting the bid, and at what sizes. IMPORTANT LIMIT: Hyperliquid returns only about the last TEN trades, so this is a small sample of the current moment, NOT a tape or trade history — never present it as complete, never compute volume or statistics from it, and use get_candles for anything about a period. For the user's own executions use get_fills. Public data — no account needed.
get_deposit_infoHow to fund a Hyperliquid account: the bridge address, which chain and token to send, and the minimum. Use it whenever the user asks how to deposit, add funds, or top up, and whenever a trade fails for insufficient balance — get_perps_status says they are short of collateral, this says what to do about it. THIS TOOL MOVES NO MONEY and neither does anything else on this server: the deposit is a transfer the USER makes from their own wallet, and the safe way to do it is the Fensory app, which builds the transaction for them. Send the wrong token, the wrong chain, or less than the minimum and THE FUNDS ARE LOST — Hyperliquid cannot recover them — so never abbreviate or reformat the address, and always state the chain and minimum alongside it. Static reference data: no account needed and nothing is read.
get_spot_metadataLook up Hyperliquid SPOT markets — HIP-1/HIP-2 tokens traded on Hyperliquid itself. THIS IS NOT THE TOOL FOR TOKENIZED STOCKS OR RWAs: those trade as PERPS on builder dexes and are resolved with get_market. Hyperliquid lists unrelated HIP-1 tokens under lookalike tickers (a stock ticker matched here is usually a near-worthless different token, not the stock), so never answer a stock or RWA question from this tool. Returns each market's `market_id`, base and quote token, size precision and lot step. CALL THIS BEFORE ANY SPOT ORDER: place_hl_spot_order and cancel_hl_spot_order take `market_id` (e.g. '@107' or 'PURR/USDC'), never a plain ticker like 'PURR' and never a perps symbol. Pass `query` to filter by token name — the full universe is hundreds of pairs and returning all of it is rarely useful. Public data: it does not depend on the user's account.
get_candlesGet historical OHLCV candlesticks for a Hyperliquid market — open, high, low, close, volume per interval, oldest first. Use it for anything about price HISTORY rather than the current price: 'how has BTC moved today', trend and volatility questions, where support or resistance sits, or checking whether a level was already touched. get_market gives one live price; this gives the shape that got it there. Works for perps coins ('BTC') and spot market ids ('@107'). Public data — no account needed. RETENTION IS LIMITED: Hyperliquid keeps only ~5000 candles per interval and the history is NOT pageable beyond that — roughly 3.5 days of 1m, 17 days of 5m, 52 days of 15m, 208 days of 1h, and ~2 years of 4h/1d. A window older than that returns nothing at all — it is impossible to fetch, not a paging problem, so tell the user the data does not exist rather than retrying. Note that any read of a chart is interpretation, not a prediction: say so when the user asks what happens next.
get_orderbookGet the live Hyperliquid order book for one market — the best bids and asks with the size resting at each price, plus the spread. Use it to judge whether a size can actually be filled near the current price before placing a MARKET order: get_market gives one mid price, but a large order eats through several levels and fills worse than that mid. Also answers 'how tight is the spread' and 'how much is resting at this level'. Works for perps coins ('BTC') and spot market ids ('@107'). Public data — no account needed.
get_perps_statusCheck whether the signed-in user's account is set up for PERPETUAL FUTURES trading on Hyperliquid, and show their perps balance. CALL THIS FIRST before any other perps tool, and again after any error that looks like a permissions or setup problem — it is the single check for 'is this account ready for perps at all'. Reports: the user's Hyperliquid account address (their Fensory embedded wallet), whether the account is funded, whether the trading agent is approved and unexpired, and whether the builder fee is approved. All three must be true before perps trading works. A missing piece is not an error — report what is missing and tell the user to complete it in the Fensory app (app.fensory.com); this server cannot fix any of it. This is also the gate for TRADING: `ready` must be true before any perps order tool is called, and `spot_ready` before any Hyperliquid-spot order (`spot_ready` is Hyperliquid spot — PURR, HYPE — not tokenized stocks). Both are top-level fields; when either is false, `setup_blockers` says exactly what is missing. The agent key and builder fee being fine is NOT enough — the agentic allow-list can exclude perps while both are true. READ THIS YOURSELF IF YOU CAN. Hyperliquid rate-limits per IP and every Fensory user shares this server's, so a read you make from your own environment always beats one made here. It is public data needing no credentials — NEVER send your Fensory token to Hyperliquid. POST to https://api.hyperliquid.xyz/info with `Content-Type: application/json` and: Send `{"type":"perpDexs"}` for the builder-dex list, then `{"type":"clearinghouseState","user":"<the user's embedded wallet address>"}` for the core dex plus one `{"type":"clearinghouseState","user":"<address>","dex":"<name>"}` per builder dex (positions live per dex — a dex you skip is a position you will not see), plus `{"type":"userAbstraction","user":"<address>"}` and `{"type":"spotClearinghouseState","user":"<address>"}`. Your `ack: true` call is the ONLY way to get the SETUP half — agent key, builder fee, `ready`, `spot_ready`, `setup_blockers` — because it lives in Fensory, not on Hyperliquid. The ack of this tool is NOT empty: it returns the SETUP half (agent key, builder fee, blockers), which lives in Fensory's database and only the server can read. YOU supply the FUNDING half from your own reads and combine the two — the account is ready for perps only when the agent is ready, the builder fee is approved, AND it is funded. THE FUNDING TRAP: if `userAbstraction` returns "unifiedAccount", Hyperliquid keeps the USDC in the SPOT balance and reports perps `accountValue` / `withdrawable` as 0 even though the account is funded — the USDC row of `spotClearinghouseState` is the real collateral, report THAT as the balance and never the perps zeros. It is the SAME money as the spot USDC, so never add the two. Any OTHER value ("default", "portfolioMargin", …) means the perps `accountValue` IS the real balance and spot USDC is separate money. Then call this tool with its normal arguments plus `ack: true` so the read is recorded. FALLBACK — only if you genuinely cannot make an HTTP POST request: call it with `cannot_post: true` and the server reads for you, over a rate limit shared by every user.
get_account_stateGet the signed-in user's PERPETUAL FUTURES account on Hyperliquid: every open position (coin, long/short, size, entry price, unrealized PnL, liquidation price, margin used, leverage) plus account value, free collateral and total margin used. This is the detailed read — get_perps_status returns only a balance summary. Use it for 'what are my positions', 'am I up or down', 'how close am I to liquidation'. Perps positions only — and that INCLUDES tokenized stocks and RWAs, which are perps on builder dexes (`xyz:TSLA`) and appear here under their prefixed name. For Hyperliquid spot token balances use get_spot_account_state. Returns an empty position list when nothing is open, which is not an error. READ THIS YOURSELF IF YOU CAN. Hyperliquid rate-limits per IP and every Fensory user shares this server's, so a read you make from your own environment always beats one made here. It is public data needing no credentials — NEVER send your Fensory token to Hyperliquid. POST to https://api.hyperliquid.xyz/info with `Content-Type: application/json` and: Send `{"type":"perpDexs"}` for the builder-dex list, then `{"type":"clearinghouseState","user":"<the user's embedded wallet address>"}` for the core dex plus one `{"type":"clearinghouseState","user":"<address>","dex":"<name>"}` per builder dex (positions live per dex — a dex you skip is a position you will not see), plus `{"type":"userAbstraction","user":"<address>"}` and `{"type":"spotClearinghouseState","user":"<address>"}`. Reading the response: THE FUNDING TRAP: if `userAbstraction` returns "unifiedAccount", Hyperliquid keeps the USDC in the SPOT balance and reports perps `accountValue` / `withdrawable` as 0 even though the account is funded — the USDC row of `spotClearinghouseState` is the real collateral, report THAT as the balance and never the perps zeros. It is the SAME money as the spot USDC, so never add the two. Any OTHER value ("default", "portfolioMargin", …) means the perps `accountValue` IS the real balance and spot USDC is separate money. `withdrawable` is FREE collateral, not the balance — it drops when an order rests because that margin is reserved, while `accountValue` stays the same; a lower `withdrawable` after placing an order is normal and NOT a loss. In each `assetPositions[].position`: `szi` is signed size (negative = short), `unrealizedPnl` is mark-to-market and moves every second — a snapshot, not a settled result; `liquidationPx: null` means Hyperliquid reports none; funding is charged HOURLY and `cumFunding.sinceOpen` is the running total already paid (positive) or received (negative). An empty `assetPositions` is not an error — a funded, fully set-up account can have nothing open. Then call this tool with its normal arguments plus `ack: true` so the read is recorded. FALLBACK — only if you genuinely cannot make an HTTP POST request: call it with `cannot_post: true` and the server reads for you, over a rate limit shared by every user.
get_open_ordersList the signed-in user's resting (unfilled) PERPETUAL FUTURES orders on Hyperliquid, including stop-loss and take-profit trigger orders. Each row carries its order id (`oid`), client order id (`cloid`), side, size, limit price, time-in-force and trigger details. Use it for 'what orders do I have open', or to check whether an order is still working before concluding it filled — an order that is NOT here either filled or was cancelled, and get_fills tells you which. Returns an empty list when nothing is resting, which is not an error. READ THIS YOURSELF IF YOU CAN. Hyperliquid rate-limits per IP and every Fensory user shares this server's, so a read you make from your own environment always beats one made here. It is public data needing no credentials — NEVER send your Fensory token to Hyperliquid. POST to https://api.hyperliquid.xyz/info with `Content-Type: application/json` and: Send `{"type":"perpDexs"}` for the list of builder dexes, then one `{"type":"frontendOpenOrders","user":"<the user's embedded wallet address>"}` for the core dex plus one `{"type":"frontendOpenOrders","user":"<address>","dex":"<name>"}` for each builder dex, and combine the lists. Orders rest per dex, so a dex you skip is an order you will not see. Reading the response: the CORE list (the one with no `dex`) also contains SPOT orders — a `coin` like `@1` or `PURR/USDC` is a spot order, not a perp, so never report it as a perps position. `sz` is what REMAINS unfilled and `origSz` is what was placed; a gap between them is a partial fill. Trigger orders (stop-loss / take-profit) come back with `isTrigger: true` and no meaningful `tif` — that is NORMAL, they are not resting on the book but waiting for `triggerPx`, and `isPositionTpsl: true` means the order is attached to a position and closes it. An empty array means nothing is resting, which is not an error. An order that is absent either filled or was cancelled — `{"type":"userFills","user":"<address>"}` tells you which. Then call this tool with its normal arguments plus `ack: true` so the read is recorded. FALLBACK — only if you genuinely cannot make an HTTP POST request: call it with `cannot_post: true` and the server reads for you, over a rate limit shared by every user.
get_portfolio_historyThe signed-in user's account value and PnL OVER TIME — the equity curve. This is the tool for 'how am I doing', 'am I up this month', 'show my performance', or any question about a trend rather than a moment: get_account_state is the snapshot right now, this is the history behind it. Pick the `period` that matches the question and set `perps_only` to separate perps performance from total account value. Points are thinned to keep the response readable, so describe the SHAPE of the curve and the start/end values rather than reciting rows. PnL here is Hyperliquid's own accounting over the window; it is not a per-trade breakdown — use get_fills for that.
get_funding_paymentsFunding the signed-in user has actually PAID or RECEIVED, per position. Perps charge funding every hour between longs and shorts, so a position held for days accrues a real cost or income that never appears in the entry/exit price — this is where it shows up. Use it for 'what has this position cost me to hold', 'am I earning funding on that short', or when explaining why realized PnL differs from the price move. Positive `usdc` means the user RECEIVED funding, negative means they PAID it. get_funding_history is the market-wide rate; this is the user's own money. Returns nothing for an account that has never held a position across a funding tick, which is normal and not an error.
get_fillsList the signed-in user's most recent PERPETUAL FUTURES fills (executed trades) on Hyperliquid — price, size, fee, realized PnL on closes, the order id (`oid`) and client order id (`cloid`) each fill came from. THIS IS HOW YOU VERIFY WHAT ACTUALLY HAPPENED: to check whether a specific order filled, look it up here by `cloid` or `oid` rather than trusting memory or what an earlier response said. Also use it for 'what did I trade', 'how much did I make on that', or realized PnL and fee questions. Newest first. Nothing is stored on Fensory's side — this is Hyperliquid's own record, and it covers perps only, not the tokenized-asset trades made elsewhere in the Fensory app. READ THIS YOURSELF IF YOU CAN. Hyperliquid rate-limits per IP and every Fensory user shares this server's, so a read you make from your own environment always beats one made here. It is public data needing no credentials — NEVER send your Fensory token to Hyperliquid. POST to https://api.hyperliquid.xyz/info with `Content-Type: application/json` and: Send `{"type":"userFills","user":"<the user's embedded wallet address>"}` — Hyperliquid returns up to 2,000 rows, newest first; keep only the first `limit`. The 2,000 is Hyperliquid's response size, NOT a value for this tool: `limit` here accepts at most 100. Reading the response: the list MIXES perps, SPOT (a `coin` like `@107` or `PURR/USDC`) and TWAP slice fills (`hash` of all zeros) — filter to what was asked. One order can produce SEVERAL fills at different prices, so group by `oid` before reporting an average, never read one fill as the whole order. `closedPnl` is realized PnL and is only meaningful when `dir` starts with "Close"; it is 0 on opens. `fee` is in `feeToken` and a NEGATIVE fee is a maker rebate the user was PAID, not a charge. `startPosition` is the position size before that fill. Only the most recent 2,000 fills exist — an empty list means no perps fills in that window, not an error. Then call this tool with its normal arguments plus `ack: true` so the read is recorded. FALLBACK — only if you genuinely cannot make an HTTP POST request: call it with `cannot_post: true` and the server reads for you, over a rate limit shared by every user.
get_spot_account_stateGet the signed-in user's Hyperliquid SPOT token balances — what they hold outright, what is reserved by resting spot orders, and what is therefore available to sell. This is a DIFFERENT account from perps: get_account_state shows perps collateral and positions, and the two do not share a balance. Use this before any spot sell (the user cannot sell more than `available`), for 'what tokens do I hold on Hyperliquid', or to confirm a spot buy actually landed. Spot has no positions, no leverage and no liquidation — a balance is simply owned.
get_order_statusLook up ONE Hyperliquid order by its id and get its current state — open, filled, cancelled or triggered — plus size, remaining size and prices. Use this when you know which order you care about: after placing an order, to check whether that specific order filled, pass the `cloid` (client order id) or `oid` from the place response rather than scanning get_fills. Use the `cloid` for an order you placed and have not modified. A modify REPLACES the order: the modify response carries a NEW `oid` which is the live handle, while the original `cloid` now resolves to the cancelled original — so after a modify, look the order up by its new `oid`, not the `cloid`. Works for perps and spot orders. An 'unknown' result means Hyperliquid no longer has the order in its recent history, which is normal for old orders and is not an error.
get_twap_statusList the signed-in user's TWAP schedules on Hyperliquid — running and past — with how much of each has actually executed so far. Use it before answering anything about a TWAP: whether one is still running, how far along it is, what it has cost, or to recover a `twap_id` that was lost (place_twap_order returns the id once and nothing stores it). Also use it BEFORE cancel_twap_order, so the user can be told how much has already filled — cancelling stops only the remainder and never unwinds what executed. A schedule with status 'activated' is still running and still spending; 'finished' completed in full; 'terminated' was cancelled or stopped early. Executed size is the truth about what happened — the requested total is only what was asked for.
get_user_feesGet the signed-in user's actual Hyperliquid trading fee rates — maker and taker, for perps and spot — and the rolling volume the tier is based on. Use it whenever the cost of a trade matters: 'what are my fees', 'is this trade worth it on a small size', or when explaining why a round trip costs what it does. Read the real rates rather than quoting a generic number: fee tiers vary per account and improve with volume. Note that Fensory's builder fee is charged ON TOP of these and is not included here.
place_perps_orderPlace a REAL perpetual futures order on Hyperliquid with the user's own money. Preflight, in this order, every time: (1) get_perps_status — the account must be ready; (2) get_market for this asset — the live price and its `min_size` / `size_step`, because Hyperliquid rejects anything worth under $10 and sizes must fit the asset's precision; (3) get_account_state — enough free collateral for the margin this order needs. A `market` order executes immediately at roughly the current mid (it is sent IOC with up to 5% slippage allowance) — you cannot know the exact fill price in advance, so tell the user it is approximate. A `limit` order requires `price` and rests on the book until filled or cancelled. Size and all prices are DECIMAL STRINGS in normal units (e.g. size '0.001' means 0.001 BTC) — never wei, never scientific notation. Optional `tpTriggerPx` / `slTriggerPx` attach take-profit / stop-loss orders that close the position when hit. `stop_market` and `stop_limit` rest as a TRIGGER that OPENS a position later, unattended, when the market reaches `triggerPx` — a buy stop must sit ABOVE the current price and a sell stop BELOW it, and the order can fire days later with nobody watching, so confirm the trigger, the size and the worst-case fill before sending. Set `reduce_only: true` to shrink an existing position without ever opening or growing one; unlike close_perps_position (which crosses the book immediately) it can rest at a price you choose, and Hyperliquid rejects it outright if it would increase the position. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
cancel_perps_orderCancel one resting perpetual futures order on Hyperliquid. Get the `oid` from get_open_orders immediately before calling — never from memory or from an earlier message, because order ids change and an order you saw before may already have filled. If the oid is not in get_open_orders, the order is already gone: check get_fills to see whether it filled rather than cancelling blindly. Cancelling is not free of consequence — the user loses their place in the queue, and a position left without its stop-loss is unprotected. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
batch_cancel_perps_ordersCancel MANY resting perpetual futures orders at once — by default EVERY one on the account, or narrowed with `asset` (one market) or `oids` (specific orders). ALWAYS call get_open_orders first and tell the user exactly what will be cancelled, with the count, before asking them to confirm: 'cancel my orders' is a request to see the list, not permission to wipe it. CRITICAL: stop-loss and take-profit orders are resting orders too, so an unnarrowed cancel REMOVES THE PROTECTION FROM OPEN POSITIONS and leaves them exposed to liquidation. If the list includes any order with `is_trigger: true` while a position is open, say so explicitly and make the user confirm that specific consequence — or narrow the call with `oids` so the protection survives. Nothing resting is a success, not an error. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
modify_perps_orderChange the size, price or trigger price of a resting perpetual futures order on Hyperliquid. Send ONLY the fields you are changing — everything omitted is carried forward from the existing order. TWO THINGS WILL SURPRISE YOU, and you must account for both: (1) a modify replaces the order and Hyperliquid issues a NEW `oid` — the old one is dead, so re-read get_open_orders afterwards and never reuse the id you passed in; (2) the modified order is forced to post-only (`Alo`), which means it is REJECTED outright rather than filling if its price would cross the book — that rejection comes back as a failure, so read the result rather than assuming the change took. If you are increasing `size`, this creates new exposure and is subject to the same per-order limit as a new order. IF THIS CALL TIMES OUT, do not guess and do not retry: look up the cloid of the order you were modifying with get_order_status. `canceled` means the modify DID apply — the replacement is live under a new oid, so find it in get_open_orders by the price and size you asked for. `open` means the modify did NOT apply and the original is still resting unchanged. Note the replacement does NOT inherit the cloid: after a successful modify, track the order by the new `oid` this returns. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
close_perps_positionClose an open perpetual futures position on Hyperliquid, fully or partially. Omit `size` to close the whole position — the backend reads the live size itself, so never compute it yourself or copy it from an earlier reading that may be stale. This sends a reduce-only market order (IOC at roughly the mid), so it executes immediately at approximately the current price and REALIZES the profit or loss. Before calling: read get_account_state and tell the user what they actually hold, the current unrealized PnL, and that closing turns that number into a realized gain or loss at a price that may differ slightly from the one you quote. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
place_twap_orderPlace a REAL TWAP (time-weighted average price) order on Hyperliquid with the user's own money: instead of executing at once, Hyperliquid splits the total size into slices and executes them AT MARKET across the window you set. Preflight, in this order, every time: (1) get_perps_status — the account must be ready; (2) get_market for this asset — the live price, `min_size` and `size_step`; (3) get_account_state — enough free collateral for the WHOLE schedule, not one slice. TWO THINGS WILL SURPRISE YOU. First, every slice is a MARKET order, so there is no limit price and no guarantee about the average fill — never promise the user a price. Second, execution begins IMMEDIATELY and money is spent gradually from that moment; cancelling later stops only the remainder, and slices already executed are real fills that are NOT unwound. `size` is the TOTAL across the whole schedule as a DECIMAL STRING in normal units (e.g. '0.01' means 0.01 BTC) — never wei, never scientific notation. `durationMinutes` is 5 to 1440 (24 hours). Hyperliquid REJECTS a TWAP worth under $100 — ten times the $10 floor on a normal order — so check the notional against get_market before calling, and if the user wants less than that, place a normal order instead rather than retrying. Capture the `twap_id` this returns: it is the ONLY handle for cancelling the schedule and nothing stores it for you. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
cancel_twap_orderStop a running TWAP schedule on Hyperliquid. This cancels only the REMAINDER: slices that have already executed are real fills spending REAL MONEY, and cancelling does NOT unwind them — the user is left holding whatever filled so far, which may be a partial position they did not ask for. Say that plainly before cancelling, and read get_twap_status first so you can tell them how much has already executed. Needs the `twapId` from place_twap_order; if it was lost, recover it with get_twap_status rather than guessing. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
set_perps_leverageSet the leverage and margin mode for one asset on Hyperliquid. Leverage decides how much margin a position of a given size requires — higher leverage means less margin and a LIQUIDATION PRICE CLOSER TO THE CURRENT PRICE. Check the asset's `max_leverage` with get_market first; anything above it is rejected. `isCross: true` shares collateral across all positions; `isCross: false` (isolated) ring-fences this asset's margin so a loss cannot consume the rest of the account. If the user already has an open position in this asset, raising leverage moves its liquidation price closer and increases the risk of being liquidated — say so explicitly before doing it. This does not place, close or change any order. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
update_perps_marginAdd or remove isolated margin on an existing Hyperliquid position. Adding margin moves the liquidation price FURTHER AWAY (safer); removing it moves the liquidation price CLOSER (riskier) and frees collateral. This only works on positions using ISOLATED margin — check `leverage_type` in get_account_state first, because on a cross-margin position there is no isolated margin to adjust. Amounts are in plain dollars: pass 25 to add $25, or -25 to remove $25. This does not open, close or resize any position. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
attach_position_tpslAttach a take-profit and/or stop-loss to a position the user ALREADY has open on Hyperliquid. Use this when a position exists without protection — place_perps_order can only attach TP/SL at the moment of entry, so a position opened earlier (or opened without them) needs this. The triggers are reduce-only, cover the WHOLE position and track it as it grows or shrinks. At least one of `tpTriggerPx` / `slTriggerPx` is required, and each must be on the correct side of the current price: for a LONG the take-profit is above and the stop-loss below; for a SHORT it is inverted. Read get_account_state first for the position's side, size and entry price, and get_market for the live price — a trigger on the wrong side is rejected. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
place_hl_spot_orderBuy or sell a token on Hyperliquid's SPOT market with the user's own money — outright ownership, no leverage, no liquidation, no position. This is NOT perps (place_perps_order), and NOT the tokenized-stock/RWA surface — those trade as perps on builder dexes. Preflight every time: (1) get_spot_metadata for the `market_id` and its lot step — a plain ticker or a perps symbol is rejected; (2) get_orderbook or get_candles for the live price; (3) get_spot_account_state — a SELL cannot exceed `available`, and a BUY spends the USDC spot balance. When get_perps_status reports `unified: true`, that is the SAME collateral margining open perps positions — a large spot buy reduces the margin behind them, so warn the user before a large buy while a position is open. `size` is always in the BASE token (0.5 PURR, never '$0.5 of PURR') and is floored to the lot step server-side. Spot trading needs its own authorisation ('hl-spot' in the agentic allow-list): a perps grant does not cover it, and get_perps_status says which the user has. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
cancel_hl_spot_orderCancel one resting Hyperliquid SPOT order. Get the `oid` from get_open_orders or the place response immediately before calling — never from memory, because the order may already have filled. If it is not open any more, check get_fills rather than cancelling blindly. This is the spot counterpart of cancel_perps_order; use that one for perpetual futures orders. Cancelling releases the balance the order was reserving, which reappears as `available` in get_spot_account_state. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
batch_cancel_hl_spot_ordersCancel MANY resting Hyperliquid SPOT orders at once — by default every one on the account, or narrowed with `asset` (a spot `market_id` from get_spot_metadata) or `oids`. Perps orders are never touched by this: use batch_cancel_perps_orders for those, and note the two are authorised separately, so this one needs `spot_ready` in get_perps_status. Call get_open_orders first and tell the user what will be cancelled, with the count, before asking them to confirm. Lower stakes than the perps version — spot orders carry no stop-losses and cancelling one only releases the balance it reserved, which returns to `available` — but it is still irreversible and loses queue position. Nothing resting is a success, not an error. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
place_hl_spot_twap_orderPlace a REAL TWAP on Hyperliquid's SPOT market with the user's own money: instead of buying or selling at once, Hyperliquid splits the total size into slices and executes them AT MARKET across the window you set. This is the SPOT counterpart of place_twap_order — outright ownership, no leverage, no position, and never reduce-only. Preflight every time: (1) get_perps_status — `spot_ready` must be true, and spot is authorised SEPARATELY from perps ('hl-spot' in the allow-list); (2) get_spot_metadata for the `market_id` and lot step — a bare ticker or a perps symbol is rejected; (3) get_spot_account_state — enough balance for the WHOLE schedule, not one slice (a sell cannot exceed `available`; a buy spends the USDC spot balance). THREE THINGS WILL SURPRISE YOU. First, every slice is a MARKET order, so there is no limit price and no guarantee about the average fill. Second, execution begins IMMEDIATELY and money is spent gradually from that moment; cancelling stops only the remainder and already-executed slices are real fills that are NOT unwound. Third, Hyperliquid REJECTS a TWAP whose notional is under $100, and it checks that against SIZE x PRICE, not against the balance — it will happily accept a schedule the account cannot afford and only discover that slice by slice, leaving a partial fill. So check the notional AND the balance before calling. `size` is the TOTAL across the schedule in the BASE token (0.5 PURR, never '$0.5 of PURR'), floored to the lot step. `durationMinutes` is 5 to 1440. Capture the `twap_id` this returns: it is the ONLY handle for cancelling and nothing stores it for you. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
cancel_hl_spot_twap_orderStop a running SPOT TWAP schedule on Hyperliquid. This cancels only the REMAINDER: slices that have already executed are real fills spending REAL MONEY, and cancelling does NOT unwind them — the user is left holding whatever filled so far, which may be a partial amount they did not ask for. Say that plainly before cancelling, and read get_twap_status first so you can tell them how much has already executed. This is the spot counterpart of cancel_twap_order; use that one for perps schedules. Needs the `twapId` from place_hl_spot_twap_order; if it was lost, recover it with get_twap_status rather than guessing. THIS SPENDS REAL MONEY AND CANNOT BE UNDONE. Before calling: state to the user, in plain units, exactly what will happen — asset, direction, size, price, resulting notional in dollars — and get their explicit confirmation for THIS specific action. A general instruction like 'trade for me' or 'manage my position' is NOT confirmation for an individual order. Call this AT MOST ONCE per confirmation: nothing here or on the backend deduplicates, so a second call is a second real action. If it returns an error, report it and STOP — do not call it again. Verify what actually happened with get_open_orders and get_fills instead.
ui://widget/fensory-wallets.htmlfensory-walletsThe signed-in user's Fensory wallets, with quick actions to ask for balances and spot holdings.