hashlock-mcp
OfficialServer Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| HASHLOCK_ENDPOINT | No | GraphQL endpoint override (rarely needed) | https://hashlock.markets/api/graphql |
| HASHLOCK_ACCESS_TOKEN | Yes | 7-day SIWE JWT from hashlock.markets/sign/login |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| create_htlcA | Trustless atomic settlement — delivery vs payment (DVP) guarantee. Both sides receive their asset OR both get refunded; zero counterparty risk, zero slippage, no custodian. Records the on-chain HTLC lock tx hash to advance the settlement state machine. USE WHEN: a trade is accepted and the user has just broadcast the lock transaction on-chain (EVM, Bitcoin, or Sui). DO NOT USE WHEN: the trade is not yet accepted, or the lock tx has not been broadcast yet — submit the on-chain tx first, then call this tool. PARAM NOTES: |
| withdraw_htlcA | Atomic claim — reveals the 32-byte preimage to unlock both legs of the swap simultaneously. Trustless cross-chain finality: no intermediary holds funds at any point. USE WHEN: counterparty has confirmed their lock on-chain and the user wants to claim their side of the swap. DO NOT USE WHEN: counterparty lock is not yet confirmed on-chain, OR the timelock has already expired — use refund_htlc instead. PARAM NOTES: |
| refund_htlcA | Trustless unwind — recover locked funds after the HTLC timelock expires. Non-custodial refund guarantee: if the swap does not complete, the original sender reclaims their asset with zero counterparty risk. USE WHEN: the timelock deadline has passed AND the counterparty never locked their side (or the swap otherwise failed to complete). DO NOT USE WHEN: counterparty HAS locked and the swap can still complete — use withdraw_htlc instead. Only the original lock sender can call refund, and only after the deadline. PARAM NOTES: |
| get_htlcA | Real-time trade observability — per-leg HTLC settlement state for a trade: which legs are locked, on which chain, with what timelock, and whether the preimage has been revealed. Read-only, safe to call at any time. Returns an ARRAY of HTLC legs (one entry per locked leg, typically the initiator leg and the counterparty leg). An empty array means no HTLC has been recorded for this tradeId yet (or the tradeId does not exist) — treat empty as "nothing locked", not an error. USE WHEN: showing trade/settlement status to the user, deciding the next settlement action (lock / claim / refund), polling for the counterparty leg, or rebuilding state after losing context. DO NOT USE WHEN: you need RFQ/quote status (this is settlement-leg state only) — use list_my_trades or list_open_rfqs instead. INTERPRETING THE RESULT (per leg): |
| create_rfqA | Trustless price discovery for OTC trades — sealed-bid auction with zero information leakage, no front-running, no MEV. Non-custodial, cross-chain (ETH/BTC/SUI). Agent-friendly: works with any MCP runtime. Create a Request for Quote (RFQ) for an OTC swap — broadcast to market makers for sealed-bid quotes. USE WHEN: user wants competitive quotes (not AMM curve fill) for size ≥ $10k, cross-chain swaps, privacy-sensitive orders, or expressed a "negotiate" / "best execution" / "large block" / "institutional" intent. DO NOT USE WHEN: sub-second execution is required, or pair is a long-tail memecoin with no market-maker coverage (prefer DEX aggregator). ═══ SUPPORTED CHAIN-QUALIFIED PAIRS ═══ ETH/sepolia, ETH/ethereum, BTC/bitcoin-signet, BTC/bitcoin, USDC/sepolia, USDC/ethereum, USDT/ethereum, WBTC/ethereum, WETH/ethereum, SUI/sui, SUI/sui-testnet. Cross-chain RFQs (e.g. SUI/sui ↔ ETH/sepolia) are first-class — set baseChain and quoteChain explicitly so the backend can disambiguate same-symbol-different-chain pairs. ═══ INTENT → PARAMS MAPPING ═══ Translate the user free-text intent into params using these rules. The user will rarely give a structured form; you are the compiler. side: • "sell X / swap X for Y / exchange X to Y / liquidate X / convert X to Y / cash out X" → side=SELL, baseToken=X, quoteToken=Y • "buy X with Y / acquire X / pay Y for X / get X using Y" → side=BUY, baseToken=X, quoteToken=Y • Turkish: "sat / çıkar / boşalt" → SELL, "al / topla" → BUY, "X karşılığı Y" → SELL with X=base. baseChain / quoteChain (CHAIN INFERENCE): • If the user names the chain explicitly ("Sepolia", "mainnet", "Sui testnet", "signet"), use it. • Otherwise apply per-token mainnet defaults: ETH/USDC/USDT/WBTC/WETH → "ethereum"; BTC → "bitcoin"; SUI → "sui". • If the user says "test" / "testnet" / "demo" / "test mode" / "sınama" globally, switch every leg to its testnet variant: ETH→sepolia, BTC→bitcoin-signet, SUI→sui-testnet, USDC→sepolia. • Cross-environment is allowed and common — if only ONE leg is qualified with a testnet hint (e.g. "sell SUI for Sepolia ETH"), keep the other leg on its mainnet default. Do NOT silently testnet-ify the unqualified leg. • If the chain is genuinely ambiguous after all rules (e.g. "sell ETH for USDC" — both could be mainnet or both Sepolia depending on user intent), ASK before calling. Do not gamble on real funds. amount: • Pass the raw decimal string the user typed ("0.1", "1.5", "10"). Do NOT pre-convert to wei / satoshis / smallest unit — the backend handles decimals via the token registry. • If the user gives a USD-denominated value ("worth $10k of SUI"), do NOT call the tool — ask for the base-token amount or compute and confirm before submitting. expiresIn (seconds): • Default 300 (5 min) when unspecified. • "Quick / urgent / hızlı / acele" → 60–120. • "Leave open / take your time / uzun süre" → 600–1800. • Hard cap 86400 (24 h). isBlind (Ghost Auction mode): • Default false. Zero slippage: quote equals fill, regardless of mode. • Set true on intent words: "ghost", "blind", "anonymous", "hide identity", "private auction", "gizli", "kimliğimi gizle". ═══ REQUIRED BEFORE CALLING ═══
═══ EXAMPLES ═══ User: "Hashlock'ta 0.1 SUI'mi Sepolia ETH'e karşı sat, 5 dakika" → { side: "SELL", baseToken: "SUI", baseChain: "sui", quoteToken: "ETH", quoteChain: "sepolia", amount: "0.1", expiresIn: 300, isBlind: false } User: "sell 2 ETH for USDC, ghost auction" → { side: "SELL", baseToken: "ETH", baseChain: "ethereum", quoteToken: "USDC", quoteChain: "ethereum", amount: "2", isBlind: true } User: "buy 0.05 BTC with USDT, take your time" → { side: "BUY", baseToken: "BTC", baseChain: "bitcoin", quoteToken: "USDT", quoteChain: "ethereum", amount: "0.05", expiresIn: 1200 } User: "test mode — swap 1 SUI to ETH" → { side: "SELL", baseToken: "SUI", baseChain: "sui-testnet", quoteToken: "ETH", quoteChain: "sepolia", amount: "1" } |
| list_supported_pairsA | List the chain-qualified token pairs Hashlock supports for RFQ/swap. Read-only, no auth side effects. USE WHEN: before create_rfq if unsure a token/chain is supported, or to show the user available markets instead of guessing. DO NOT USE WHEN: you already know the pair is supported — this is discovery, not a precondition. Each entry is SYMBOL/chain. Same symbol on different chains (e.g. SUI/sui vs SUI/sui-testnet) are distinct markets — pass baseChain/quoteChain explicitly to create_rfq. |
| respond_rfqA | Market-maker tool — submit a sealed-bid price quote to compete on an open RFQ. Quotes are private: other makers cannot see your price, and losing bids are never revealed. No funds are locked until the requester accepts a quote. USE WHEN: the MCP client is acting as a market maker and has decided to quote on a specific open RFQ (obtained via list_open_rfqs). DO NOT USE WHEN: acting as an end-user buyer or seller who wants to receive quotes — use create_rfq instead. This is the market-maker side only; sealed bids, not open negotiation. PARAM NOTES: |
| list_open_rfqsA | List currently open (ACTIVE) RFQs awaiting market-maker quotes. Read-only. USE WHEN: acting as a market-maker agent deciding what to quote on, or showing the user live demand. DO NOT USE WHEN: you want your own trade history (use list_my_trades). Returns a page of RFQs (id, baseToken, quoteToken, side, amount, isBlind, status, expiresAt). To quote, call respond_rfq with the rfqId. |
| list_my_tradesA | List the caller's trades (active + historical). Read-only. Primary tool for rebuilding state after losing conversation context. USE WHEN: an agent restarted/lost context and must resync in-flight settlements, or showing the user their trade history. DO NOT USE WHEN: you need open market demand (use list_open_rfqs) or per-leg HTLC detail for one trade (use get_htlc). Optional status filter narrows the page. For settlement-leg detail on a specific trade, follow up with get_htlc(tradeId). |
| swap_quoteA | One-call OTC swap intake for agents — opens a sealed-bid Ghost Auction under the hood and waits briefly for the first private market-maker bids, then hands back a swap_handle + the best bid so far. Async by design: there is NO public synchronous price (that is the privacy guarantee). Zero slippage: the bid you execute is the fill. USE WHEN: an agent/user wants to "just swap X for Y" and have the facade manage quote collection + best-bid selection + a price guard. Privacy-sensitive or large flow. DO NOT USE WHEN: the caller wants explicit market-maker-aware RFQ control and will pick/accept quotes itself — use create_rfq. Sub-second DEX fills — use a DEX aggregator. PARAM NOTES: |
| swap_statusA | Re-poll an open swap by its swap_handle — returns the current best sealed bid + how many bids are in. Read-only, stateless: the primary way to resume a swap after losing context (only the swap_handle is needed). USE WHEN: letting maker competition build before executing, or rebuilding an in-flight swap after a context reset. DO NOT USE WHEN: you need settlement-leg detail (use get_htlc) or your trade history (use list_my_trades). PARAM NOTES: returns best_bid (or null), bids_seen, still_open and rfq_status. When best_bid is present, swap_execute with the same limit_price (or best_bid.quote_id) to take it. |
| swap_executeA | Accept the winning sealed bid for a swap and create the trade. Real funds. Provide EITHER limit_price (auto-takes the best bid only if it meets your bound) OR quote_id (the exact bid you saw via swap_status). With neither, this refuses (CONFIRMATION_REQUIRED) rather than guess — restate the price to the user first. USE WHEN: a swap has an acceptable bid and the user confirmed. DO NOT USE WHEN: you have not surfaced the price to the user, or you want maker-side quoting (use respond_rfq). PARAM NOTES: |
| swap_cancelA | Abort an open swap before it executes (cancels the underlying RFQ). No funds were locked. Use when the limit never meets, the user changed their mind, or to clean up a stale swap_handle. USE WHEN: backing out of a swap_quote that has not been executed. DO NOT USE WHEN: the swap already executed (a trade exists) — settlement is governed by the HTLC timelock, not this tool. PARAM NOTES: idempotent within a session via client_request_id. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Hashlock-Tech/hashlock-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server