{
  "markdown": "# paladin-swap-mcp\n\n**Open client and API spec for [PaladinFi Swap](https://paladinfi.com/swap/)** — a competitive multi-aggregator swap router for AI agents on Base. This repository contains the public REST and MCP API specification, working code examples, and thin client wrappers. The hosted backend at `swap.paladinfi.com` is proprietary.\n\n> **Routing scope.** PaladinFi Swap queries integrated upstream aggregators (currently 0x and Velora) in parallel and returns whichever delivers the higher post-fee buy amount. We do not represent any returned route as the best available, lowest-cost, or optimal across the broader DeFi market. Phrases like \"best execution\" are reserved-meaning terms in U.S. securities law and are deliberately not used here.\n\n[![Status](https://img.shields.io/badge/status-live-3fb950)](https://swap.paladinfi.com/health)\n[![Chain](https://img.shields.io/badge/chain-Base%208453-2563eb)](https://basescan.org/)\n[![Backend](https://img.shields.io/badge/backend-0x%20%2B%20Velora-555)](https://paladinfi.com/swap/)\n[![Fee](https://img.shields.io/badge/fee-10%20bps-b64cef)](#fees)\n[![MCP](https://img.shields.io/badge/MCP-Streamable%20HTTP-7c3aed)](https://modelcontextprotocol.io)\n[![CI](https://github.com/paladinfi/paladin-swap-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/paladinfi/paladin-swap-mcp/actions/workflows/ci.yml)\n[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n[![paladinfi/paladin-swap-mcp MCP server](https://glama.ai/mcp/servers/paladinfi/paladin-swap-mcp/badges/score.svg)](https://glama.ai/mcp/servers/paladinfi/paladin-swap-mcp)\n\n---\n\n## What is PaladinFi Swap?\n\nA swap router built for **AI agents** that need to execute on-chain swaps. Your agent calls a single tool; the service returns ready-to-execute calldata your wallet signs and submits:\n\n- **Router address** to send the transaction to\n- **Calldata** with all routing pre-baked\n- **Min buy amount** (slippage protection enforced on-chain)\n- **Affiliate fee already injected** — no separate accounting on your side\n\nAgents skip writing aggregator glue, slippage handling, and fee logic. One call, ready bytes.\n\nThe Service is **non-custodial**: PaladinFi never holds, signs, or moves user funds. Every transaction is signed and submitted by the user's own wallet (or their agent acting on their behalf).\n\n## Install (MCP)\n\nFor [Claude Code](https://claude.com/claude-code) or any MCP-compatible client supporting Streamable-HTTP transport:\n\n```bash\nclaude mcp add --transport http --scope user paladin-swap https://swap.paladinfi.com/mcp\n```\n\nRestart your client. Three tools become available:\n\n- `swap_quote(sellToken, buyToken, sellAmount, taker, chainId?, slippageBps?)` — competitive route across 0x and Velora (highest post-fee buy amount); returns ready-to-execute calldata.\n- `trust_check_preview(address, chainId?)` — **sample-fixture preview** of the trust gate. Returns `_real: false`, every factor is `real: false`, and the recommendation is prefixed `sample-` (e.g., `sample-allow`). **Do not use the preview verdict to gate real swaps**, signing, or any production agent decision. For production trust evaluation, POST to `/v1/trust-check` (paid, $0.001 USDC/call via x402) or use the npm plugins `@paladinfi/eliza-plugin-trust` / `@paladinfi/agentkit-actions`.\n- `swap_health()` — liveness, fee config, per-source counters, decimals-cache state, last Velora startup-canary verdict, selector-enforcement state.\n\nSee [`mcp-tools.json`](mcp-tools.json) for the full tool schemas.\n## MCP standards compliance\n\n| Requirement | Status |\n|---|---|\n| Tool `title` + `annotations` (readOnlyHint, openWorldHint, idempotentHint, destructiveHint) | ✓ since v0.11.74; verify via the MCP `tools/list` method |\n| Tool name ≤64 chars | ✓ longest is `trust_check_preview` (19 chars) |\n| Streamable HTTP transport | ✓ at `https://swap.paladinfi.com/mcp` |\n| Public OpenAPI 3.0 schema | ✓ at [`/openapi.yaml`](https://swap.paladinfi.com/openapi.yaml) |\n| Documented rate limits | ✓ at [paladinfi.com/swap](https://paladinfi.com/swap) (5 r/s + burst 30 on `/v1/quote`; 10 r/s + burst 30 on `/mcp`; 5 concurrent connections per IP) |\n| x402 paid-tool challenge | ✓ on the `/v1/trust-check` paid endpoint. The MCP `trust_check_preview` tool is gated to sample-fixture output with explicit misuse banners (`_real: false`, `_HUMAN_DO_NOT_USE_AS_REAL_VERDICT`, `sample-` recommendation prefix) — preview by design, never a real verdict |\n| Tool descriptions narrow + accurate | ✓ see [`mcp-tools.json`](mcp-tools.json) for exact schemas |\n| Browser-origin clients (CORS) | ✓ since v0.11.75 on `/v1/quote`; allowlist is `paladinfi.com` + `www.paladinfi.com` only — other origins blocked at preflight |\n| Free real-data on-ramp endpoint | ✓ since v0.11.77 — `POST /v1/trust-check/ofac` runs the OFAC SDN wallet-screen leg only (anonymous, 1 r/s rate-limit + burst 3, daily Treasury XML refresh). Response includes `_paid_endpoint_info` upgrade hint to the full multi-source composition at `/v1/trust-check`. Wallet-OFAC scope (token-contract sanctions list planned for future versions). |\n| MCP Registry listing | ✓ this package is listed as [`io.github.paladinfi/paladin-swap`](https://registry.modelcontextprotocol.io/v0/servers?search=paladinfi). The §4.A-clean trust-check-only variant (no payment surface, no calldata, no transaction execution) ships separately as [`com.paladinfi/trust-check-mcp`](https://registry.modelcontextprotocol.io/v0/servers?search=paladinfi) — Streamable HTTP at [`trust.paladinfi.com/mcp`](https://trust.paladinfi.com/mcp). Use the trust-check variant when payment-surface adjacency would be a deployment blocker. |\n\nPer [MCP `ToolAnnotations`](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool-annotations):\n\n- **`swap_quote`** — title `\"Get Swap Quote\"`; `readOnlyHint: true` (returns calldata, never mutates server state), `openWorldHint: true` (calls upstream aggregators 0x AllowanceHolder + Velora Augustus v6.2 on Base)\n- **`trust_check_preview`** — title `\"Token Trust Check (Preview)\"`; `readOnlyHint: true`, `idempotentHint: true` (deterministic sample fixture per address), `openWorldHint: true` (paid-mode upstream factor sources cross the process boundary; defensive contract-violation handlers exist for shape drift)\n- **`swap_health`** — title `\"Swap Service Health\"`; `readOnlyHint: true`, `openWorldHint: false` (introspection of our own service state only)\n\n\n## Agent usage walkthrough\n\nA representative call chain when an MCP-aware agent (e.g., Claude Code) handles a swap intent. Specific tool-call formatting varies by client; the key point is that the swap router returns ready-to-execute calldata so the agent never composes routing logic itself.\n\n**User:** *\"Swap 100 USDC for WETH on Base.\"*\n\n**1. Optional pre-trade trust check** (free, sample-fixture only). Before composing the swap, the agent may call `trust_check_preview` to inspect the buy-token contract's risk shape.\n\n```json\n// Tool call\n{\n  \"tool\": \"trust_check_preview\",\n  \"arguments\": {\n    \"address\": \"0x4200000000000000000000000000000000000006\",\n    \"chainId\": 8453\n  }\n}\n```\n\n```json\n// Response (truncated)\n{\n  \"_real\": false,\n  \"_HUMAN_DO_NOT_USE_AS_REAL_VERDICT\": \"Preview-only fixture. See README.\",\n  \"trust\": {\n    \"recommendation\": \"sample-allow\",\n    \"_preview\": true,\n    \"factors\": [\n      { \"real\": false, \"source\": \"ofac\",      \"signal\": \"clear\" },\n      { \"real\": false, \"source\": \"goplus\",    \"signal\": \"clear\" },\n      { \"real\": false, \"source\": \"etherscan\", \"signal\": \"verified-contract\" }\n    ]\n  }\n}\n```\n\nThe preview is **sample-fixture only** — agents must check `_real === true` before consuming a verdict. For production gating, call `/v1/trust-check` (paid, $0.001 USDC/call via x402) or use the npm plugins [`@paladinfi/eliza-plugin-trust`](https://www.npmjs.com/package/@paladinfi/eliza-plugin-trust) / [`@paladinfi/agentkit-actions`](https://www.npmjs.com/package/@paladinfi/agentkit-actions).\n\n**2. Competitive quote with calldata.** The agent calls `swap_quote` to get the route + ready-to-execute transaction.\n\n```json\n// Tool call\n{\n  \"tool\": \"swap_quote\",\n  \"arguments\": {\n    \"sellToken\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n    \"buyToken\":  \"0x4200000000000000000000000000000000000006\",\n    \"sellAmount\": \"100000000\",\n    \"taker\":      \"0xUserAgentWallet\",\n    \"chainId\":    8453,\n    \"slippageBps\": 50\n  }\n}\n```\n\n```json\n// Response (illustrative; values depend on live pool state)\n{\n  \"source\":           \"velora\",\n  \"chainId\":          8453,\n  \"router\":           \"0x6a000f20005980200259b80c5102003040001068\",\n  \"calldata\":         \"0xe3ead59e000000000000000000000000...\",\n  \"buyAmount\":        \"43200000000000000\",\n  \"minBuyAmount\":     \"42984000000000000\",\n  \"sellAmount\":       \"100000000\",\n  \"gas\":              \"318707\",\n  \"ourFeeBps\":        10,\n  \"ourFeeRecipient\":  \"0xeA8C33d018760D034384e92D1B2a7cf0338834b4\"\n}\n```\n\n`source` indicates whichever upstream aggregator (0x or Velora) delivered the higher post-fee buy amount for this pair. The 10 bps fee is already injected into the calldata; the `buyAmount` you see is the user's net (post-fee, pre-slippage). `minBuyAmount` reflects the requested 50 bps slippage tolerance.\n\n**3. Sign + submit.** The agent surfaces the transaction shape to the user's wallet for signing — `to=router, data=calldata, value=0` (for ERC20 → ERC20). PaladinFi never sees the signature; the wallet broadcasts the transaction directly to Base.\n\n**4. Confirm.** Slippage is enforced on-chain: the swap reverts if the actual fill would deliver less than `minBuyAmount`. The agent reports the transaction hash; the user's wallet shows the settled buy amount on Base. The 10 bps fee transfers to the published treasury address (`/health`) atomically as part of the same transaction — no second on-chain step.\n\n**Non-custodial end-to-end.** At no point does PaladinFi hold, sign, or move funds. The MCP server returns metadata; the wallet executes. A compromised swap router could only return calldata; even malicious calldata is bounded by the v0.11.71 outer-router + selector + 0x Settler-target allowlist (see Roadmap below) and the user's own wallet-side approval limits.\n\n## Install (REST)\n\nNo MCP needed — hit the endpoint directly:\n\n```bash\ncurl -sS https://swap.paladinfi.com/v1/quote \\\n  -H 'content-type: application/json' \\\n  -d '{\n    \"chainId\": 8453,\n    \"sellToken\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n    \"buyToken\":  \"0x4200000000000000000000000000000000000006\",\n    \"sellAmount\": \"5000000\",\n    \"taker\": \"0xYOUR_AGENT_WALLET\"\n  }'\n```\n\nFull REST spec in [`openapi.yaml`](openapi.yaml).\n\nFor free OFAC SDN wallet screening (no MCP, no key, no signup), see the drop-in cURL + React hook walkthrough at [paladinfi.com/docs/screen-wallets/](https://paladinfi.com/docs/screen-wallets/) — `POST /v1/trust-check/ofac` returns an `allow` or `block` verdict, anonymous, rate-limited at 1 r/s + burst 3.\n\n## Endpoints\n\n| Method | Path | Purpose | Pricing |\n|--------|------|---------|---------|\n| `GET` | `/health` | Liveness, fee config, per-source counters, decimals-cache state, last Velora canary verdict, selector-enforcement state | Free |\n| `POST` | `/v1/quote` | Competitive route quote with calldata — highest post-fee buy amount across 0x and Velora | Free |\n| `POST` | `/v1/trust-check` | Live token-contract trust evaluation (OFAC SDN, GoPlus, Etherscan, anomaly heuristics) | $0.001 USDC/call via x402 |\n| `POST` | `/v1/trust-check/preview` | Sample-fixture preview of the trust-check response shape (no live data sources evaluated) | Free |\n| `POST` | `/mcp` | MCP Streamable-HTTP transport (3 tools — see `mcp-tools.json`) | Free |\n\n## Response shape (abridged)\n\n```json\n{\n  \"source\": \"velora\",\n  \"chainId\": 8453,\n  \"router\": \"0x6a000f20005980200259b80c5102003040001068\",\n  \"calldata\": \"0x...\",\n  \"buyAmount\": \"2160000000000000\",\n  \"minBuyAmount\": \"2138000000000000\",\n  \"sellAmount\": \"5000000\",\n  \"gas\": \"318707\",\n  \"ourFeeBps\": 10,\n  \"ourFeeRecipient\": \"0xeA8C33d018760D034384e92D1B2a7cf0338834b4\",\n  \"estimatedOurFeeAmount\": \"2160000000000\",\n  \"estimatedOurFeeToken\": \"0x4200000000000000000000000000000000000006\"\n}\n```\n\n`source` is the upstream aggregator that won this quote (`\"0x\"` or `\"velora\"`). Submit the transaction as `to=router, data=calldata, value=0` (for ERC20→ERC20) from `taker`.\n\n## Examples\n\n- [`examples/python/quote_and_swap.py`](examples/python/quote_and_swap.py) — Python with web3.py\n- [`examples/typescript/quote_and_swap.ts`](examples/typescript/quote_and_swap.ts) — TypeScript with viem\n\n## Fees\n\nA flat **10 basis points (0.1%)** is taken on the **buy token**. The fee is calculated against the *actual* fill amount, not the quoted estimate, so you never pay more than expected even if the pool moves between quote and fill. PaladinFi's 10 bps is taken from the buy-token side via the upstream aggregator's integrator-fee mechanism (0x's `swapFeeBps` / Velora's `partnerFeeBps`), so the `buyAmount` you see in the response already reflects both any upstream protocol fee and our 10 bps — no additional deduction at fill time.\n\nFees route directly to the PaladinFi treasury — no on-chain receipt step on your side. The fee recipient address is published in `/health` so it's auditable on-chain. The `/v1/quote` endpoint stays free to query, with no per-call charges or spread on top. (`/v1/trust-check` is the only paid endpoint, at $0.001 USDC/call via x402.)\n\n## Supported assets\n\n- **Chain:** Base (8453). Ethereum mainnet, Arbitrum, Optimism, BNB are on the roadmap.\n- **Tokens:** Any ERC20 supported by either 0x or Velora on Base. Coverage is the union of both aggregators — canonical pairs (USDC, WETH, cbBTC, USDT, DAI, AERO) are routable on both; long-tail tokens often route on only one of the two.\n\n## Trust Check data sources\n\nThe paid `/v1/trust-check` endpoint evaluates a token contract against a defined set of public data sources and returns a single `recommendation: \"allow\" | \"warn\" | \"block\"` verdict alongside per-source breakdown. Sources currently consulted, with verifiability pointers:\n\n| Source | What it screens | Verifiability |\n|--------|----------------|---------------|\n| **OFAC SDN list** (U.S. Department of the Treasury) | Sanctioned addresses (the contract itself, deployer, and known associated wallets) | List refreshed daily on the hosted backend from the Treasury Sanctions List Service feed at `https://sanctionslistservice.ofac.treas.gov/api/PublicationPreview/exports/SDN_ADVANCED.XML`. The address dataset extracted is the union of `Feature[@FeatureTypeID=\"345\"]/FeatureVersion/VersionDetail[@DetailTypeID=\"1432\"]` entries (FeatureTypeID 345 = ETH/EVM addresses; DetailTypeID 1432 = Digital Currency Address Detail). Loaded count as of last verification: **87 ETH addresses** (2026-04-30). The underlying Treasury feed is publicly downloadable so any client can independently re-derive the dataset and verify a positive match. |\n| **GoPlus Token Security API** | Honeypot patterns, mint authority, ownership renouncement, transfer pause, blacklist function, anti-whale, hidden owners, slippage modifiers | Queried per-call via `https://api.gopluslabs.io/api/v1/token_security/8453?contract_addresses=<address>`. We normalize the GoPlus response into the `factors` array we surface; the full GoPlus response is publicly queryable so buyers can independently audit any signal. |\n| **Etherscan / BaseScan source verification** (via the unified Etherscan v2 API) | Verified-source presence and proxy-pattern detection (via `Proxy` / `Implementation` fields in the `getSourceCode` response) | Queried per-call via `https://api.etherscan.io/v2/api?chainid=8453&module=contract&action=getsourcecode&address=<address>`. Public source code (when verified) is independently inspectable on basescan.org. |\n| **Anomaly heuristics** (PaladinFi-internal) | Contract age windows (under 1h / 24h / 7d), address-kind classification (contract vs. EOA via `eth_getCode`), and no-outbound transaction history (nonce=0 check) | Heuristic logic runs in the hosted backend module `address_anomaly.py`; each emitted signal (`contract_age_under_*`, `address_kind_*`, `no_outbound_history`) is surfaced in the response so a buyer can reproduce or override the conclusion via direct RPC calls. |\n\n**Preview vs paid distinction.** `/v1/trust-check/preview` (free) returns a static fixture with `_real: false` markers — none of the live data sources above are queried. `/v1/trust-check` (paid, $0.001 USDC via x402) consults all four. The preview exists so integrators can validate request shape and inspect the response schema without paying; agents must check the top-level `_real` field is `true` before consuming a verdict.\n\n**Request logging.** Per call, PaladinFi retains a request log entry containing timestamp, the queried address, source IP, and billing/rate-limit reference. This is used for revenue accounting, rate-limit enforcement, and abuse detection — not for analytics or resale. PaladinFi does not maintain a separate database of evaluated tokens or buyer query history.\n\n## Roadmap\n\n- [x] 0x Settler routing on Base\n- [x] **Highest-of-two routing across 0x and Velora on Base** (v0.11.66+, 2026-05-04)\n- [x] MCP Streamable-HTTP transport with `swap_quote`, `swap_health`, and `trust_check_preview` tools\n- [x] `/v1/trust-check` paid endpoint via x402 ($0.001 USDC/call)\n- [x] Per-source 4-byte calldata selector + Settler-target allowlist (v0.11.71 — defense in depth against router-substitution / dispatcher-hijack attacks)\n- [ ] Ethereum mainnet, Arbitrum, BNB, Optimism — planned\n- [ ] Permit2-native flow (skip the approve tx) — planned\n\n## Status\n\nProduction. The endpoint is live, monitored, and verified end-to-end with on-chain test transactions on Base. See [`/health`](https://swap.paladinfi.com/health) for current fee config, version, and per-source counters.\n\n## What's in this repository\n\n| File / folder | Purpose |\n|---------------|---------|\n| [`README.md`](README.md) | This file |\n| [`LICENSE`](LICENSE) | MIT — covers everything in this repo |\n| [`SECURITY.md`](SECURITY.md) | Vulnerability disclosure path + scope |\n| [`openapi.yaml`](openapi.yaml) | OpenAPI 3.0 spec for the public REST API |\n| [`mcp-tools.json`](mcp-tools.json) | MCP tool schemas |\n| [`examples/`](examples) | Working code examples (Python, TypeScript) |\n| [`.github/workflows/ci.yml`](.github/workflows/ci.yml) | CI: YAML/JSON syntax + OpenAPI 3.0 schema validation on push/PR |\n\n**Not in this repository:** the hosted backend (proprietary). This repo is the public client surface — install instructions, schemas, and integration code samples.\n\n## Contact\n\n- Email: [dev@paladinfi.com](mailto:dev@paladinfi.com)\n- Marketing: [paladinfi.com](https://paladinfi.com)\n- API: [swap.paladinfi.com/health](https://swap.paladinfi.com/health)\n- Landing: [paladinfi.com/swap/](https://paladinfi.com/swap/)\n\n## Legal\n\nOperated by **Malcontent Games LLC**, doing business as **PaladinFi**, a Michigan limited liability company. The Service routes quotes through third-party aggregators (currently 0x and Velora). You retain custody — your agent signs every transaction. PaladinFi never holds user funds.\n\nUse of the hosted Service is subject to the [PaladinFi Terms of Service](https://paladinfi.com/terms/) and [Privacy Policy](https://paladinfi.com/privacy/).\n\n## License\n\nThe contents of this repository are released under the [MIT License](LICENSE). The hosted backend is proprietary and not covered.\n",
  "bytes": 19537,
  "sha": "83e92cc2c218efd105d418f8c0b7e55ef78aa56413d3ea0e714001d84be4cffd",
  "repo_slug": "paladinfi/paladin-swap-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_paladinfi_paladin_swap_b1f84bdc/readme"
}