Limits it can't argue with
Position size, leverage, daily loss, a market allowlist, and a cap on what one trade may lose if its stop fills. There is no tool that changes them, so no prompt or clever reasoning gets past them.
Reins sits between your agent and Hyperliquid. Position size, leverage, daily loss, which markets it may touch and a stop on every position are enforced outside the model, and every decision is written down with the reason the agent gave for it.
$ npx @r2rlabs/reins init
Position size, leverage, daily loss, a market allowlist, and a cap on what one trade may lose if its stop fills. There is no tool that changes them, so no prompt or clever reasoning gets past them.
Paper trading on live Hyperliquid prices with realistic fills and fees, using the same tools and the same limits as live. Nothing is signed, and no key is needed.
Each order, refusal, wait and stop-out is stored with the reason given for it. When something strange happens at 3am, you can read exactly what it thought it was doing.
Agents speak to Reins over MCP. Everything else speaks HTTP: swap “send this order to the exchange” for “send it to Reins”, and inherit the limits and the log without changing anything else.
$ npx @r2rlabs/reins http --port 8787 $ curl -H "Authorization: Bearer $TOKEN" \ -d '{"symbol":"ETH","side":"buy","sizeUsd":1000,"stopLoss":2620,"reason":"Breakout retest"}' \ http://127.0.0.1:8787/orders 400 BLOCKED (TRADE_RISK_TOO_LARGE): Stopping out would lose $50.99, over the $30 allowed on one trade. Move the stop closer or send a smaller order.
Routes for limits, positions, book, candles, orders, stops, cancels, closes and the log itself. It binds to your own machine and needs a token; a refused order comes back with the limit that stopped it.
Most Hyperliquid bots are Python, so there is a client rather than a snippet — pip install reins-client, no dependencies. A refused order raises Refused carrying the code, and size_for_risk() is the same arithmetic the engine checks, so an order can be sized into the per-trade limit instead of being refused by it.
An agent's explanation of its own trading is testimony, not fact. Reins stores the reason and the outcome side by side, so the two can be compared.
In a five-day paper run, the log caught the agent misreporting its own trade twice. Once it wrote that it was exiting at 81,021 “rather than wait for the 81,060 stop”. It filled at 81,063, worse than the stop it meant to beat.
| $17.08 | Worst single trade, 0.17% of the account |
| 0 | Positions left without a stop, and 0 orders that breached a limit |
| 7 of 10 | Trades closed by a stop the exchange held, several while the agent slept |
| 141 | Records written, including the 72 times it decided not to trade |
Paper trading costs nothing and needs no key. Point Claude, Cursor, or your own bot at it and watch what it does.
$ npx @r2rlabs/reins init
On your own machine, free and open source. Connect Claude Desktop, Claude Code or Cursor and the model trades behind limits it cannot change.
The same engine hosted: keys in a KMS, orders over your threshold held for your approval, a kill switch only your login resets, and alerts on your phone.