Skip to main content

langchain-cleave

LangChain tools for Cleave, a DEX aggregator on Ethereum, Arbitrum, Base, BNB Chain, Polygon and Optimism, with split routing and one-step cross-chain swaps.

The package gives a LangChain agent the four tools of Cleave's MCP server, with the same names, inputs and answers. They call the keyless Agent REST API. No API key is needed.

The tools return unsigned calls for the user's wallet to sign and send. They never take a private key. They sign nothing; the only thing they send is a gas order the wallet has signed, and only when the gas relay is turned on (it is off by default; see Gas top-ups).

Installation

pip install -U langchain-cleave
uv add langchain-cleave

Python 3.10 or later.

Tools

Tool Class What it does
cleave_plan_swap CleavePlanSwap Plans a swap on one chain, a cross-chain swap or a bridge, and returns unsigned calls in signing order
cleave_track_swap CleaveTrackSwap Reports the state of a sent plan or a gas order, and what arrived
cleave_find_token CleaveFindToken Finds a token by symbol or address and flags look-alikes
cleave_get_gas CleaveGetGas Offers native gas for USDC; with the relay turned on, passes the order the wallet signed to Cleave's relayer

CleaveToolkit().get_tools() returns all four.

Every input field is the same as the MCP tool's: chain ids are integers (1, 10, 56, 137, 8453, 42161), amounts are decimal strings in token units, and tokens are listed symbols or contract addresses.

Use with an agent

This example also needs langchain and a chat model package:

pip install -U langchain-cleave langchain "langchain[anthropic]"
from langchain.agents import create_agent
from langchain_cleave import CleaveToolkit

agent = create_agent(
    model="claude-sonnet-4-6",
    tools=CleaveToolkit().get_tools(),
)

agent.invoke(
    {
        "messages": [
            {
                "role": "user",
                "content": (
                    "Plan a swap of 25 USDC to WETH on Base for wallet "
                    "0x00000000000000000000000000000000000A11cE"
                ),
            }
        ]
    }
)

Call a tool directly

from langchain_cleave import CleaveFindToken, CleavePlanSwap

CleaveFindToken().invoke({"chainId": 42161, "query": "USDC"})

plan = CleavePlanSwap().invoke(
    {
        "fromChainId": 8453,
        "sellToken": "USDC",
        "buyToken": "WETH",
        "amount": "25",
        "wallet": "0x00000000000000000000000000000000000A11cE",
    }
)

A plan is a dict. Read it in this order:

  1. blocked and notices: a block notice means calls is empty.
  2. requiresConfirmation: set by a warn notice or a recipient other than the wallet. Show the plan to the user before signing.
  3. route.outcomeKind and receive: what arrives, the minimum, and the fallback or refund.
  4. fees: costs charged by others, such as a bridge fee. Cleave's fees are included in the price. Network gas is not listed.
  5. validUntil: sign and send calls in order before this unix time.

Before anything is signed

  • Do not act on a blocked plan.
  • Show the user the warnings, the recipient, the amounts and the slippage, and get their confirmation before any wallet signs. The cleave_plan_swap description tells the model the same, and not to raise slippage above the default 50 bps without the user's consent.
  • Never change the recipient or raise slippage to get past a refusal or a warning.
  • blocked, requiresConfirmation and the notices are advisory. They bind only if your application, or the signer it uses, enforces them.

Signing and tracking

  • calls are in signing order. Any approval calls come first; the last call is the swap or transfer itself.
  • Each approval must be mined and succeed before the next call is sent.
  • If validUntil passes before the last call is sent, plan again and sign the new calls.
  • Track the mined hash of the last call, the execution transaction, with cleave_track_swap, passing chainId, txHash and the plan's requestId. Do not track an approval's hash: a refusal on an approval hash, such as not_a_cleave_tx, says nothing about the swap.
  • Track before sending a plan again: a plan still in flight that is sent twice can pay twice.

Finding tokens

cleave_find_token returns up to ten candidates. When a symbol is shared by many tokens, the one the user means may not be among them: prefer a verified contract address. A search by symbol or name is limited to 48 characters after normalization, although the input schema accepts 64.

Gas top-ups

cleave_get_gas takes two calls with separate fields; fields from one call are refused in the other.

  1. Offer: payChainId, chainId, recipient, amount (USDC), wallet and optionally refundTo. It returns the offer, the fee, the minimum native amount, the deadline, the order and, only when wallet is given, typedData: the USDC authorization to sign.
  2. Submit: offer, signature and wallet. It passes the order the wallet signed to Cleave's relayer, which executes it, and returns a requestId for cleave_track_swap.
from langchain_cleave import CleaveGetGas

offer = CleaveGetGas().invoke(
    {
        "payChainId": 8453,
        "chainId": 8453,
        "recipient": "0x00000000000000000000000000000000000A11cE",
        "amount": "5",
        "wallet": "0x00000000000000000000000000000000000A11cE",
    }
)

The refund address in the order is refundTo if given, else wallet, else the recipient for an order on one chain. An order paid on another chain needs wallet or refundTo. Adding wallet only at submission does not change the refund address of the order already offered. Review both the recipient and the refund address in order before signing.

Check Value
Amount USDC, at most 6 decimals
Smallest order 2 USDC, or 5 USDC when the gas is delivered on Ethereum
Largest order 50 USDC
USDC paid on Ethereum, Arbitrum, Base, Optimism, Polygon
  • An authorization that is never submitted never debits the wallet.
  • Once an order is funded, its outcome is whatever cleave_track_swap reports for g:<payChainId>:<orderHash>. Do not assume a refund because a deadline passed; track until the status shows it.
  • See x402 gas top-up.

The relay is off by default

The submit call is off by default: the tool returns offers, and a call with offer or signature comes back as a refusal with code relay_disabled, without a request. Turn it on in code, not from the agent:

from langchain_cleave import CleaveGetGas, CleaveToolkit

tools = CleaveToolkit(include_gas_relay=True).get_tools()
gas = CleaveGetGas(allow_relay=True)

With the relay on, an agent can keep a person in the loop before each signed order is sent. HumanInTheLoopMiddleware pauses on that tool; the agent needs a checkpointer:

from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    model="claude-sonnet-4-6",
    tools=CleaveToolkit(include_gas_relay=True).get_tools(),
    middleware=[HumanInTheLoopMiddleware(interrupt_on={"cleave_get_gas": True})],
    checkpointer=InMemorySaver(),
)

When a submission fails

A submission that times out, loses its connection, or gets a server error or an unreadable answer may still have been accepted. The tool then returns outcome_unknown, which is not retryable. When the tool returned the offer itself, the body carries payChainId, orderHash and trackRequestId.

  • Track g:<payChainId>:<orderHash> with cleave_track_swap before signing a new offer. Do not sign a replacement until the original shows its outcome: two signed orders can both be paid.
  • Cancelling the call, or the agent run, does not cancel an order the relayer already accepted.
  • A later authorization_used or offer_expired refusal does not prove that an earlier submission failed. Track the order.

Errors

What a tool returns depends on how it is called:

Call Success Refusal
tool.invoke({...}) a dict a JSON string
tool.invoke(tool_call) a ToolMessage a ToolMessage with status="error"

A refusal from the API carries the API's JSON body, as over MCP: {"apiVersion", "requestId", "error": {"code", "reason", "message", "retryable", ...}}. Refusals made by the package itself have only error:

  • network_error: the request did not complete (retryable).
  • invalid_param: the input breaks the schema, such as an unsupported or boolean chain id, a malformed address or an explicit null. No request is sent; detail names each field. Omit an optional field instead of sending null.
  • relay_disabled and outcome_unknown: see Gas top-ups.

To raise instead, pass handle_tool_error=False. The tool then raises CleaveAPIError, a ToolException with status, code, reason, retryable and the full body. Pass handle_validation_error=False to raise a pydantic ValidationError for schema violations.

Configuration

import httpx
from langchain_cleave import CleaveAPIWrapper, CleaveToolkit

api = CleaveAPIWrapper(
    base_url="https://api.cleave.fi",
    timeout=60.0,
    client=httpx.Client(timeout=60.0),
)
tools = CleaveToolkit(api_wrapper=api).get_tools()
  • base_url: defaults to https://api.cleave.fi.
  • timeout: the httpx timeout in seconds, applied to each phase of a request (connect, read, write and pool), 60 by default. It is passed on every request, also with your own client.
  • client, async_client: optional httpx clients, for proxies or reuse. The package sets its own authentication on each request: an Authorization header or auth set on your client is never sent.
  • api_key: optional partner key, of the form cq_live_<key>. It is sent as Authorization: Bearer cq_live_<key>. Keyless use needs none.
    • When the argument is omitted, the key is read from CLEAVE_API_KEY.
    • api_key=None means keyless, even when CLEAVE_API_KEY is set.
    • A set key replaces keyless use: every call is checked against that key, and a bad or revoked key fails every call. There is no fallback to keyless.

Call the API from a server, bot or agent process. Requests that carry an Origin header, as browsers send, are refused.

Limits

  • Without a key, each caller's address can make 40 requests per 10 seconds and 120 per minute, and all keyless agents share one planning capacity. When it is busy, the refusal is rate_limited with a short retryAfterSec.
  • The token to receive must be on Cleave's token list.
  • A cross-chain plan from one token to another refuses maxSlippageBps: 0.
  • The schema lists six chains, but a deployment can turn a chain off; a plan on it is then refused with unsupported_chain.

Terms

Use of the API is subject to Cleave's Terms of Use and Privacy Policy.

License

MIT

Metadata

Release files for langchain-cleave 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for langchain-cleave 0.1.0
File Size Uploaded Provenance Actions
langchain_cleave-0.1.0.tar.gz 21.5 kB With provenance Details for langchain_cleave-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for langchain-cleave 0.1.0
File Interpreter ABI Platform Actions
langchain_cleave-0.1.0-py3-none-any.whl Python 3 none any Details for langchain_cleave-0.1.0-py3-none-any.whl

Total release size: 36.4 kB

Release files / langchain_cleave-0.1.0.tar.gz

Download URL langchain_cleave-0.1.0.tar.gz
Size 21.5 kB
Tags Source
SHA-256 checksum
How to use checksums
3a44604a24f733117a2bd2c20f8e80748ca4da4b9ddf30b83041c53c09bfd8e9
BLAKE2b-256 checksum
How to use checksums
7af1afbf8430eb123dc2b5e40f6a6de72fce99f32f10df99b1cbc84ebe6fb318
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Release files / langchain_cleave-0.1.0-py3-none-any.whl

Download URL langchain_cleave-0.1.0-py3-none-any.whl
Size 14.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9320f1d186e8b58bb4a6748378deb9ceb421d4a5fe54110a203e657cd27f9045
BLAKE2b-256 checksum
How to use checksums
f99dc18dc4da6c8a8d52aa364cbab78ef861ce146bfa0517df979d2dfa01ab41
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Security for langchain-cleave 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for langchain_cleave-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page