libre-mcp 32 tools
Tools for the Libre blockchain — a no-fee orderbook DEX and permissionless
BTC-collateralized borrowing — for AI agents and any HTTP client. This server holds
no keys and signs nothing.
Connect
Over MCP (Claude Desktop, or any MCP client):
{ "mcpServers": { "libre": {
"type": "streamable-http",
"url": "https://mcp.libre.org/mcp"
} } }
Or over plain HTTP — one path per tool, arguments as a JSON body:
curl -X POST https://mcp.libre.org/v1/tools/get_btc_price \
-H 'content-type: application/json' -d '{}'
curl -X POST https://mcp.libre.org/v1/tools/get_orderbook \
-H 'content-type: application/json' -d '{"pair":"btcusdt"}'
Machine-readable: OpenAPI 3.1 ·
llms.txt · health
What this protocol is good for
Libre is an Antelope chain with two things an autonomous agent can use directly, with
keys it controls.
- An orderbook DEX with no protocol trading fee.
dex.libre
charges nothing per trade — its entire config is a pause flag. No listing process, no KYC,
no whitelist. Blocks are 0.5s, so orders land sub-second. (Full irreversibility takes about
three minutes — that matters for settlement claims, not for quoting.)
- Permissionless BTC-collateralized borrowing. Lock BTC in a vault only
your loan can draw on, borrow USDT against it up to 60% LTV, repay whenever. Nobody
approves you. The rate floats with pool utilization — 3% when the pool is idle, 20% when
it is fully lent out.
Collateral and execution live on the same chain, so borrowing and trading compose inside
a single agent.
Things worth building
- Market making
- The btcusdt book is currently wide — often several percent between best bid and best
ask. With no protocol fee, quoting inside that spread is the most obvious opportunity on
the chain.
get_orderbook → place_order both sides →
get_orders → cancel_order as the oracle price moves.
- Collateral health monitoring
get_loans plus get_btc_price gives you every position's LTV.
Liquidation starts at 80% and clears only below 70%, so an agent that tops up collateral or
repays before the 72-hour timer expires is doing real work.
- Leveraged BTC exposure
- Deposit BTC → borrow USDT → buy BTC → redeposit. At 60% max LTV that tops out near
2.5× in theory, closer to 1.5–2× before you're sitting on the liquidation
threshold. Check
get_orderbook first: a wide book can cost more per loop than
the borrow rate does.
- Rate watching
- The borrow rate is a pure function of utilization (
get_pool_stats). Cheap
to borrow when the pool is idle; lending pays best when it's busy.
All of it is read tools + compose tools + your own signature. The server
holds no key, so an agent here operates its own account — not one somebody custodies for it.
The BTC price
BTC/USD comes from the on-chain oracle contract: the
average of a round of at least three independent feeders that agree within 10% (otherwise
the round is skipped and the last price stands). It is the same price the loan contract
uses for LTV and liquidation. Call get_btc_price.
Do not quote an external exchange price for Libre collateral
math, and do not use a feed the tool marks stale — the loan contract itself
rejects anything older than 5 minutes.
Bot quickstart
A bot signs locally with its own key; this server never sees it. Compose here, sign
there, relay back:
npm i @wharfkit/session @wharfkit/wallet-plugin-privatekey
import { Session } from '@wharfkit/session';
import { WalletPluginPrivateKey } from '@wharfkit/wallet-plugin-privatekey';
const info = await (await fetch('https://api.libre.cryptobloks.io/v1/chain/get_info',
{ method: 'POST', body: '{}' })).json();
const session = new Session({
chain: { id: info.chain_id, url: 'https://api.libre.cryptobloks.io' },
actor: 'mybot',
permission: 'agent', // the restricted permission, not active
walletPlugin: new WalletPluginPrivateKey(process.env.AGENT_KEY),
});
// 1. compose — unsigned, no key involved
const res = await fetch('https://mcp.libre.org/v1/tools/place_order', {
method: 'POST', headers: { 'content-type': 'application/json' },
body: JSON.stringify({ account: 'mybot', pair: 'btcusdt', side: 'buy',
price: '80000', amount: '0.0001', permission: 'agent' }),
});
const { actions } = await res.json();
// 2. sign and push — WharfKit fetches the ref block and ABIs and serializes for you
const result = await session.transact({ actions });
That is the whole loop: read, compose, transact, repeat. Get the key onto a restricted
permission first at tools.libre.org/bot-account.
Two things that will bite you. The permission you pass
to a compose tool must match the one your session signs with, or the chain rejects the
transaction. And a signature is bound to one chain id — a mainnet signature is meaningless
on testnet, so pass network explicitly rather than relying on the default.
Prefer to build the transaction yourself? push_transaction
takes a packed transaction directly, and scripts/e2e-testnet.mjs in the repo is a
worked example using @wharfkit/antelope. You don't need it to write a bot.
Signing model
Compose tools return an unsigned {actions, esr, expires} proposal. You then
either:
- Bot: sign
actions with your own key (WharfKit) and relay
with push_transaction. Use a linkauth-restricted child permission
scoped to the actions your bot needs — never the account's owner or active key.
- Human: open the
esr link in Bitcoin Libre or Anchor,
review it there, and sign.
Networks
Every tool takes an optional network: "mainnet" (default, real
funds) or "testnet".
Rate limits
Per source IP: read tools 300/min, compose tools 60/min, push_transaction and
request_account 10/min. Over the limit returns 429.
Tools
Read — market & price
Free, no key, no signature.
get_btc_price- Authoritative BTC/USD price from the on-chain oracle contract — the average of a round of independent feeders (at least 3, agreeing within 10%, or the round is skipped and the previous price stands), and the price the loan contract uses for LTV and liquidation. Prefer this over any external exchange price. A feed older than 5 minutes is marked stale and must not be used for collateral math.
get_orderbook- dex.libre orderbook for a pair: bids/asks sorted best-first, best prices and spread. truncated:true means the book exceeded the 500-row page read and the depth shown is partial.
get_trades- Recent dex.libre trades for a pair, newest first. truncated:true means the history exceeded the 500-row page read, so older trades for this pair are not included.
get_orders- Open dex.libre orders for an account (optionally one pair). truncated:true means a book exceeded the 500-row page read and orders may be missing.
get_pool_stats- Lending pool state (available/outstanding USDT per pool), interest-rate curve config, and oracle BTC/USD.
Read — accounts & loans
Account state, vaults, and loan positions.
get_account- Balances (BTC, USDT, LIBRE, TPF, CBTC), permissions, resources, and whether the account key is on the Ill Bloom affected-set (compromised) list. Refuse to operate from an account with affected_set=true; if affected_set_checked=false the gate was unavailable and affected_set=false means unknown, not safe.
get_vault- Collateral vault for an account: vault name, CBTC collateral balance, and the BTC address to fund it.
get_loans- Active and queued loans (optionally one account); include_completed adds history.
get_redemption_queue- Queued lender redemptions (TPF → USDT waiting for liquidity), optionally one account.
get_deposit_address- The account's personal BTC deposit (bridge peg-in) address. BTC sent here arrives as BTC on Libre after confirmation.
get_chain_info- Chain id, head block and time for the selected network.
get_table_rows- Raw get_table_rows escape hatch for any Libre contract table.
Compose — trading
Return unsigned actions plus an ESR link. Nothing is signed or sent.
place_order- Compose a dex.libre limit order. amount is in the base token (BTC for btcusdt), price in quote per base (USDT; BTC with 10 decimals for librebtc). Buys lock amount*price of quote; sells lock amount of base.
cancel_order- Compose cancellation of an open dex.libre order (see get_orders for ids).
transfer- Compose a token transfer on Libre (unsigned). Returns actions + esr.
setup_deposit_address- Compose registration with a bridge so the account is assigned its own Bitcoin address, which is how an agent funds itself. Sign this, then poll get_deposit_address: the bridge signers assign the address a short time later (about a minute on testnet), so it is NOT available immediately. bridge "btc" (x.libre, default) is the wallet balance used for trading; "vault" (v.libre) is loan collateral, and setup_vault already handles that path for borrowing. Fails if an address already exists.
withdraw_btc- Compose a BTC withdrawal (bridge peg-out) from Libre to a Bitcoin address. Bridge fee applies (x.libre feeconfig table).
Compose — lending & borrowing
Also unsigned. Testnet only until the oracle-cutover loan build ships to mainnet.
setup_vault- Compose collateral-vault creation (createvault + genaddr). The vault sub-account name is generated here and returned as vault_name. Afterwards get_vault returns the BTC address to fund.
borrow- Compose a variable-rate USDT loan against vault collateral. Minimum loan is 0.001 BTC worth of USDT (~$80 at current prices; the floor is BTC-denominated so the USDT figure moves). max_apr_bps is a slippage cap on the interest rate, compared against the APR AFTER this loan is disbursed — your own borrowing raises utilization, so the post-disbursement rate is higher than the one get_pool_stats shows now. A request over the cap is not rejected: it stays in the loan queue and opens if the rate later falls. Send the pool curve max (2000 bps) to accept any rate; cancel a queued request with cancel_loan_request.
repay- Compose a USDT repayment toward the account's loan.
withdraw_collateral- Compose a collateral withdrawal (CBTC → BTC to an address). Fails on-chain if it would breach LTV. The v.libre bridge charges 50 bps on the way out, capped at 0.005 CBTC, with a 0.0008 CBTC minimum withdrawal; funding a vault is free.
lend- Compose a USDT deposit into the lending pool (mints TPF shares).
redeem- Compose redemption of TPF shares for USDT (queued if liquidity is out on loan).
cancel_redeem- Compose cancellation of a queued redemption by id (see get_redemption_queue).
cancel_loan_request- Compose cancellation of a queued (unfilled) loan request.
Submit & onboard
Relay a transaction you signed yourself; request a new account.
push_transaction- Broadcast a transaction you signed yourself (WharfKit packed format). Only agent-whitelisted actions with ≤10 min expiry are relayed.
request_account- Paid account creation. NOT ENABLED — Libre accounts are free at https://accounts.libre.org, so this exists only as a proxy if a paid registrar is ever deployed. Calling it returns instructions, not an account.
get_account_request- Status of a request_account payment/creation.
Invoices
Trust-based agent-to-agent invoicing: no escrow, no signing, no storage. Terms are canonicalised bytes you sign yourself.
draft_invoice- Build invoice terms with a staged payment schedule and return the canonical bytes and digest for the seller to sign. Settlement is trust-based: there is no escrow and the final tranche is not enforced. This server stores nothing — keep the returned terms and signatures yourself.
verify_invoice- Check that the seller (and, once approved, the buyer) signed exactly these terms. Proves the terms were agreed; it does NOT prove anything was paid.
compose_invoice_payment- Compose the (unsigned) transfer paying one tranche of an invoice, with the standard pay:<invoice_id>#<seq> memo. Use this rather than typing the memo by hand: a transfer whose memo does not parse cannot be attributed to an invoice.
reconcile_invoice- Match confirmed transfers against invoice terms: which tranches are paid, what is still owed, what arrived twice, and which transfers could not be attributed. Replays credit nothing twice. Set cancelled=true to report a withdrawn invoice: nothing further is due and any tranche already paid reads refund_due — a refund the seller owes, tracked here but not enforced, since this server moves no funds.