@leashmarket/mcp is the agent-first surface of Leash. It runs as a Model Context Protocol server over STDIO, so any MCP-compatible host (Cursor, Claude Desktop, Cline, Continue, ChatGPT-MCP, …) can let its agent mint, pay, withdraw, discover, and earn on Solana — without a browser or the chat product in the loop.

Install

// In Cursor → Settings → MCP, or your MCP host's equivalent:
{
  "mcpServers": {
    "leash": {
      "command": "npx",
      "args": ["-y", "@leashmarket/mcp"],
    },
  },
}
That’s the entire setup. leash_register_agent provisions an agent in two steps:
  1. Generate (or import) a Solana keypair, persist it to ~/.config/leash/agent.json, and tell you to send ~0.01 SOL to the printed address — this is the agent’s owner / executive.
  2. After you fund it, call leash_register_agent again. The MCP mints the MPL Core agent asset, sets an unlimited USDC delegation from the treasury PDA to the executive (the default; tighten, revoke, or extend to USDT / USDG via leash_set_spend_limit), records the asset on the Leash API, and hot-swaps the in-memory host so subsequent tool calls (leash_pay_payment_link, leash_check_treasury_balance, etc.) work without a restart.
The cluster (devnet vs mainnet) comes from LEASH_NETWORK — same flow either way, since rent + gas are paid by the user’s executive on both.

Other MCP hosts

The same JSON entry works (sometimes under a slightly different file path) in:
  • Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.json
  • Cline — VS Code extension settings → “Cline: MCP Servers”
  • Continue~/.continue/config.json under mcpServers
  • ChatGPT Desktop (MCP) — Settings → Connectors → Add MCP server
After editing the config, restart the host so it re-spawns the STDIO process.

Configure (optional)

If you already have an agent (minted from the chat product, the CLI, or another MCP host), point at it via env vars:
envexample
LEASH_AGENT_MINTAgnt7XQ...
LEASH_EXECUTIVE_KEY5Jz... (base58) or [12,34,...] (JSON arr)
LEASH_NETWORKsolana-mainnet (default) / solana-devnet
LEASH_API_URLhttps://api.leash.market (default)
LEASH_RPC_URLstrongly recommended — see below
LEASH_EXPLORER_URLhttps://explorer.leash.market (default)
LEASH_API_KEYbearer for legacy /v1/payment-links flow
Or paste a JSON config into ~/.config/leash/agent.json (chmod 600). The CLI subcommands leash-mcp export / leash-mcp import round-trip that file so an agent can move between hosts in one command.
The default RPCs (api.devnet.solana.com, api.mainnet-beta.solana.com) are public, rate-limited, and slow. x402 settlement makes 3-5 RPC calls per leash_pay_payment_link (getLatestBlockhash, getAccountInfo, simulateTransaction, sendTransaction, getSignatureStatuses) — on a public endpoint that’s a 4-8s payment, sometimes a 429. With a private RPC it’s typically under one second.
Set LEASH_RPC_URL to a paid or self-hosted endpoint:
# Helius (free tier handles devnet + light mainnet)
LEASH_RPC_URL=https://devnet.helius-rpc.com/?api-key=YOUR_KEY

# Triton, QuickNode, Alchemy — any RPC that speaks the standard
# JSON-RPC interface works.
Or persist it in ~/.config/leash/agent.json:
{
  "version": 1,
  "agent_mint": "Agnt7XQ...",
  "executive_keypair": "5Jz...",
  "network": "solana-devnet",
  "rpc_url": "https://devnet.helius-rpc.com/?api-key=YOUR_KEY",
}
The same advice applies to the CLI — leash and leash-mcp share the config file.

Tools

The MCP exposes 17 canonical tools. Each is also available through the Claude Agent SDK in the chat product (same names, same shapes — shared definitions).
ToolWhat it does
leash_register_agentTwo-step onboarding. First call returns funding instructions; second call mints + delegates + records + hot-swaps.
leash_get_identitySelf-introspection — what agent am I, on which network, what’s my treasury PDA.
leash_resolve_identityResolve another agent by mint, handle, or verified domain. Returns public profile, verified domains, public capability cards, public claims, and reputation summary.
leash_verify_identityVerify that a mint, handle, or domain resolves to a live Leash identity. Add intent/capability/thresholds to get an allow/warn/deny trust verdict before paying, trusting a claim, or calling a capability.
leash_check_treasury_balanceRead SOL + USDC/USDG/USDT balances on the agent treasury PDA.
leash_pay_payment_linkProbe an x402 link, sign + settle the SPL transfer locally, return the receipt.
leash_create_payment_linkMint an x402 paywall the user can share.
leash_withdraw_treasuryOwner-driven withdrawal of SOL or an SPL stable to any wallet (mpl-core::Execute).
leash_set_spend_limitOwner-driven update of the SPL Approve delegation. Tighten / revoke / restore the executive’s spend authority for an SPL stable.
leash_get_spend_limitInspect the active SPL delegation (delegate pubkey, remaining cap, treasury balance) for an SPL stable.
leash_receiptsPaginated receipts feed for the active agent.
leash_get_receiptFetch a single ReceiptV1 by receipt_hash — the same canonical JSON the explorer renders at /receipt/{hash}.
leash_transaction_historyList every earn + spend receipt in the last N days (default 7) plus running totals (sent_usd, received_usd, net_usd).
leash_daily_transactionsBin the same window into per-day buckets ({ date, sent_usd, received_usd, net_usd, sent_count, received_count }).
leash_discoverSearch paid services by capability + price across two catalogues: the Leash marketplace and the Solana Foundation pay-skills registry (~75 stablecoin-gated APIs). Each item carries a source: 'leash' | 'pay-skills' tag. Public, no agent needed.
leash_pay_skills_endpointsExpand a pay-skills discover item (where source === 'pay-skills') into its paid endpoint list — { method, url, pricing, protocol, supported_usd, probe_status }. Mirrors pay skills endpoints <fqn> from the pay.sh CLI. Use as the second hop in leash_discover → leash_pay_skills_endpoints → leash_pay_payment_link.
leash_reputationLive reputation snapshot for any on-chain agent — settled-call volume, dispute rate, normalised rating in [0,1].

Verify it works

Once the host is running, ask the agent:
“List the Leash MCP tools.”
You should see all 17 leash_* tools. If you don’t, check the host’s MCP logs (in Cursor: ~/Library/Application Support/Cursor/logs/.../MCP Logs.log) — most failures are wrong path, missing network access, or a stale cached npx install (clear with npx clear-npx-cache). You can also smoke-test outside any host using the in-memory transport:
leash-mcp doctor
Prints config path, derived executive pubkey, network, RPC + API reachability — useful first stop for any “why isn’t this working” question.

Onboarding flow

leash_register_agent walks the LLM through two calls. Either or both can be initiated by the user (you) or the agent (Cursor / Claude Desktop / etc.): Step 1 — choose an executive keypair + fill in agent metadata. Default is mode: "generate" — the MCP creates a fresh ed25519 keypair locally and persists it to ~/.config/leash/agent.json under pending_register (chmod 600). To bring your own (e.g. an existing solana-keygen keypair), pass mode: "import" + executive_secret_base58. While you’re at it, supply the agent’s public profile so it lands in the on-chain MPL Core metadata + the off-chain EIP-8004 RegistrationV1 doc on the very first mint:
ArgNotes
nameFriendly label (recorded on-chain).
descriptionFree-text description.
image_urlPublic URL of the agent avatar.
servicesEIP-8004 service entries other agents and humans use to discover the agent — [{ name, endpoint }, …]. Do not include receipts; the protocol auto-injects one.
These fields are persisted alongside the keypair in pending_register.meta so Step 2 picks them up automatically — you do not have to re-supply them after funding.
// Step 1 example tool call
{
  "name": "Plexpert",
  "description": "Onchain accountant for indie operators.",
  "image_url": "https://plexpert.xyz/avatar.png",
  "services": [
    { "name": "web", "endpoint": "https://plexpert.xyz" },
    { "name": "api", "endpoint": "https://api.plexpert.xyz" },
  ],
}
The tool returns:
{
  "kind": "register_agent",
  "status": "funding_required",
  "network": "solana-devnet", // or solana-mainnet, from LEASH_NETWORK
  "executive_pubkey": "947dU4Nk8HsdkFcrVip5Zt9XLnfFF5iJSvepEArdr5Ma",
  "required_sol": "0.01",
  "balance_sol": "0.0",
  "instructions": [
    "Send at least 0.01 SOL on devnet to 947dU4Nk8...",
    "Devnet SOL is free — request it via `solana airdrop 1 947dU4Nk8... --url https://api.devnet.solana.com`",
    "Once funded, call `leash_register_agent` again WITH NO ARGUMENTS",
    "...",
  ],
}
Step 2 — fund the executive, then re-run. On devnet, solana airdrop 1 <executive_pubkey> --url https://api.devnet.solana.com or any free faucet (faucet.solana.com, quicknode.com/faucet/sol) works. On mainnet, send SOL from any wallet you control. ~0.01 SOL is enough — covers the agent asset rent (~0.0034 SOL), one ATA creation rent (~0.00203 SOL), and tx fees with comfortable buffer. Calling leash_register_agent a second time (no arguments) makes the MCP:
  1. Read the persisted pending_register block.
  2. Re-check the executive’s SOL balance via RPC.
  3. Mint the MPL Core agent asset (createAgent).
  4. Set unlimited USDC spend delegation from the treasury PDA to the executive (setSpendDelegation / SPL Approve capped at u64::MAX). Add USDT / USDG delegations later with leash_set_spend_limit({ symbol: 'USDT' | 'USDG', mode: 'unlimited' | 'amount', amount? }) — the cap is per-mint.
  5. POST /v1/agents/record so the Leash API has a row for receipts
    • discovery + reputation.
  6. Promote the pending block to a full agent.json and hot-swap the in-memory host.
The result blob contains mint, treasury_address, both tx signatures, and the path to the persisted config. From this point forward the agent can pay, earn, withdraw, and be discovered just like one minted via the chat product.

Demo flow (90 seconds)

  1. Add the MCP entry to your host config and restart.
  2. Ask the agent: “register me a Leash agent” → first call returns funding_required + a printed pubkey.
  3. solana airdrop 1 <pubkey> --url https://api.devnet.solana.com (or paste the pubkey into your devnet faucet of choice).
  4. Ask the agent again: “continue registering my Leash agent” → second call mints + delegates + records + hot-swaps.
  5. Ask: “what’s my balance?”leash_check_treasury_balance.
  6. Ask: “find me an OCR service under 10c”leash_discover.
  7. Ask: “pay this link”leash_pay_payment_link. Returns a real tx_signature + receipt_hash on devnet.
  8. Ask: “withdraw 50c USDC to YOUR_WALLET_ADDRESS”leash_withdraw_treasury. Real on-chain transfer via mpl-core::Execute.
The whole demo runs against live devnet infrastructure — the only manual step is funding the executive in step 3.

Troubleshooting

SymptomLikely cause + fix
Tools list is empty / host can’t connectWrong path or stale cache. Run npx clear-npx-cache, restart the host, check the host’s MCP logs.
leash_register_agent returns funding_requiredExpected — that’s step 1. Send the printed SOL amount to the printed pubkey, then call the tool again with no args.
leash_register_agent returns error: ... not visible on RPC within 20sRPC propagation. Try again in 5s — the second call resumes from pending_register and will pick up the just-confirmed mint.
leash_register_agent returns mode: "import" requires executive_secret_base58You passed mode: "import" but no secret. Either drop mode (defaults to generate) or include the base58-encoded 64-byte secret.
leash_pay_payment_link is slow (5–10s) or 429sYou’re on the public RPC. Set LEASH_RPC_URL to a paid endpoint — see Bring your own RPC above.
leash_pay_payment_link returns wrong_networkThe link is on the other cluster. The MCP does not pay across networks — confirm the link’s network and your LEASH_NETWORK.
tx_signature returned but explorer shows nothingRPC propagation delay (~2-3s on devnet). Refresh in 5s.
leash_create_payment_link returns errorToday this tool calls back to the API with a legacy bearer token. Set LEASH_API_KEY until X-Leash-Sig auth lands here.
leash_set_spend_limit returns no_agentNo agent configured. Run leash_register_agent first.
leash_set_spend_limit mode: "amount" returns erroramount was missing or ≤ 0. Pass a positive decimal number (e.g. amount: 100 = $100 USDC).
leash_get_spend_limit shows delegate_matches_executive: falseThe delegation was set by a different keypair (e.g. previously rotated). Re-run leash_set_spend_limit to re-write the cap.

Source