Index of every page on this site: llms.txt
All skills
base avatar

/base-mcp

@ef8bcd5 official
by basebase/skills120 stars
130
Run it yourself

Base MCP — gives your AI assistant access to a Base Account via the Base MCP server (wallet-mcp.coinbase.com). Wallet, portfolio, sending, swapping, signing, x402 payments, batched contract calls, and transaction history across supported chains.

Use this Skill: https://skilld.dev/gh/base/skills/base-mcp

Nothing lands on disk. Nothing to clean up.

Fork this Skill

Edit a local copy. It keeps the author and licence.

pluginsuniswap.md

≈3.9k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Uniswap Plugin

[!IMPORTANT] Complete the short Base MCP onboarding flow defined in SKILL.md before calling any Uniswap endpoint. The user's wallet address — passed as walletAddress in every swap and LP call — is fetched lazily when needed.

Overview

Uniswap on Base: token swaps using the proxy-approval flow (no Permit2 signing) and LP position management for V2, V3, and V4. The plugin fetches unsigned calldata from the Uniswap API, then executes transaction previews with send_calls. No additional MCP server is required.

Chain: Base mainnet (chainId 8453).

Auth

Use these headers for all requests:

{
  "Content-Type": "application/json",
  "x-api-key": "NeoYO3V50_koJAipDEalYWbMO1XMaFPAQmpOm6_Npo0"
}

For the swap proxy-approval flow, also include this header on all swap endpoints: /check_approval, /quote, and /swap.

{
  "x-permit2-disabled": "true"
}

Without x-permit2-disabled, Uniswap can return Permit2 or Universal Router behavior instead of the proxy-approval flow described here.

Surface Routing

Uniswap is HTTP-only; every capability follows the standard HTTP routing in ../references/custom-plugins.md.

Capability Path
Swap quote / approval / calldata Harness HTTP tool if available, else web_request POST against trade-api.gateway.uniswap.org.
LP discovery / create / manage / claim Harness HTTP tool or web_request POST against liquidity.api.uniswap.org.
Execute the prepared calldata Base MCP send_calls (works on every surface).

Prerequisite: trade-api.gateway.uniswap.org and liquidity.api.uniswap.org must be in the MCP server's web_request allowlist. If requests are rejected by the allowlist and no harness HTTP tool is available, inform the user.

Endpoints

Swap endpoints: proxy approval, no Permit2

Base URL: https://trade-api.gateway.uniswap.org/v1

POST /check_approval  ->  if approval non-null, include approval calldata in send_calls
POST /quote           ->  get best route, read-only
POST /swap            ->  get unsigned swap tx, include swap calldata in send_calls
1. POST /check_approval

Headers: auth headers plus "x-permit2-disabled": "true".

{
  "walletAddress": "<address>",
  "token": "<tokenIn address>",
  "amount": "<base units string>",
  "chainId": 8453,
  "includeGasInfo": true
}

Response:

{
  "approval": {
    "to": "<token contract>",
    "data": "<calldata>",
    "value": "0x00",
    "chainId": 8453
  }
}

approval can be null, especially for native ETH. If it is non-null, pass it to send_calls. You can batch the approval and swap together after /swap returns.

2. POST /quote

Headers: auth headers plus "x-permit2-disabled": "true".

{
  "type": "EXACT_INPUT",
  "amount": "<base units string>",
  "tokenIn": "<address or 0x0000000000000000000000000000000000000000 for native ETH>",
  "tokenOut": "<address>",
  "tokenInChainId": 8453,
  "tokenOutChainId": 8453,
  "swapper": "<address>",
  "autoSlippage": "DEFAULT",
  "protocols": ["V4", "V3", "V2"],
  "routingPreference": "BEST_PRICE"
}

Use "slippageTolerance": <0-20> instead of autoSlippage if the user specifies slippage. See Risks & Warnings before submitting elevated values.

Response includes a top-level quote object plus metadata. Keep the response as a flat object for /swap; do not nest it under a quote key.

3. POST /swap

Headers: auth headers plus "x-permit2-disabled": "true".

Use the /quote response as the body, but remove any null or absent permit fields before sending:

const swapBody = { ...quoteResponse };
if (swapBody.permitData == null) delete swapBody.permitData;
if (swapBody.permitTransaction == null) delete swapBody.permitTransaction;
delete swapBody.signature;

Do not send signature, and do not send permitData or permitTransaction when they are null.

Response:

{
  "swap": {
    "to": "<router or proxy>",
    "data": "<calldata>",
    "value": "0x00",
    "chainId": 8453
  },
  "gasFee": "..."
}

LP endpoints

Base URL: https://liquidity.api.uniswap.org/lp

Use this host for LP endpoints in this plugin environment. Do not switch to api.uniswap.org or trade-api.gateway.uniswap.org/v1/lp/... unless that host is explicitly available to the API key and MCP allowlist.

Pool Discovery: POST /lp/pool_info

Use pool discovery before creating V3/V4 LP positions. poolReference must be a valid pool address for V3 or pool ID for V4.

{
  "protocol": "V4",
  "chainId": 8453,
  "poolParameters": {
    "tokenAddressA": "0x0000000000000000000000000000000000000000",
    "tokenAddressB": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "fee": 3000,
    "tickSpacing": 60
  }
}

Known Base V4 ETH/USDC fee=3000, tickSpacing=60 pool reference observed in testing:

0xe070797535b13431808f8fc81fdbe7b41362960ed0b55bc2b6117c49c51b7eb9

Pool references can change by pair, fee, tick spacing, and protocol. Prefer querying /lp/pool_info instead of hard-coding a pool reference unless the user explicitly selected a pool.

Approval Step: POST /lp/check_approval

Use this before LP create/increase/decrease operations. The body uses lpTokens as an array of token/amount objects.

{
  "protocol": "V4",
  "walletAddress": "<address>",
  "chainId": 8453,
  "lpTokens": [
    {
      "tokenAddress": "0x0000000000000000000000000000000000000000",
      "amount": "<base units>"
    },
    {
      "tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "amount": "<base units>"
    }
  ],
  "action": "CREATE",
  "generatePermitAsTransaction": true,
  "simulateTransaction": true
}

action: "CREATE" | "INCREASE" | "DECREASE" | "MIGRATE"

Response:

{
  "requestId": "...",
  "transactions": [
    {
      "transaction": {
        "to": "...",
        "from": "...",
        "data": "...",
        "value": "0x00",
        "chainId": 8453
      },
      "cancelApproval": false,
      "action": "CREATE"
    }
  ]
}

If transactions is empty, no approval transaction is needed. If it has entries, map every transactions[*].transaction to send_calls.

const approvalCalls = approvalResponse.transactions.map((entry) => ({
  to: entry.transaction.to,
  value: entry.transaction.value ?? "0x0",
  data: entry.transaction.data
}));
Create V3/V4 Position: POST /lp/create
{
  "walletAddress": "<address>",
  "chainId": 8453,
  "protocol": "V4",
  "existingPool": {
    "token0Address": "0x0000000000000000000000000000000000000000",
    "token1Address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "poolReference": "0xe070797535b13431808f8fc81fdbe7b41362960ed0b55bc2b6117c49c51b7eb9"
  },
  "independentToken": {
    "tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "amount": "1000000"
  },
  "tickBounds": {
    "tickLower": -200400,
    "tickUpper": -199200
  },
  "simulateTransaction": false,
  "nativeTokenBalance": "1000000000000000"
}

Use newPool instead of existingPool when creating a pool:

{
  "token0Address": "<address>",
  "token1Address": "<address>",
  "fee": 3000,
  "tickSpacing": 60,
  "initialPrice": "<sqrtRatioX96 string>"
}

Response:

{
  "create": { "to": "...", "data": "...", "value": "...", "chainId": 8453 },
  "token0": { "tokenAddress": "...", "amount": "..." },
  "token1": { "tokenAddress": "...", "amount": "..." },
  "adjustedMinPrice": "...",
  "adjustedMaxPrice": "...",
  "tickLower": -200400,
  "tickUpper": -199200
}

Prefer tickBounds when possible. priceBounds can be accepted by the API, but its price units are easy to misread; validate carefully before using it.

Manage Existing Positions
Action Endpoint Key params
Add liquidity POST /lp/increase walletAddress, chainId, protocol, token0Address, token1Address, nftTokenId, independentToken { tokenAddress, amount }
Remove liquidity POST /lp/decrease walletAddress, chainId, protocol, token0Address, token1Address, nftTokenId, liquidityPercentageToDecrease (0-100)
Collect fees POST /lp/claim_fees walletAddress, chainId, protocol, tokenId; optional simulateTransaction
Create V2 position POST /lp/create_classic walletAddress, poolParameters { token0Address, token1Address, chainId }, independentToken { tokenAddress, amount }

Optional on LP operation endpoints: "slippageTolerance": <decimal> where 0.5 means 0.5%. See Risks & Warnings before submitting elevated values.

Important: LP APIs can return calldata for syntactically valid nftTokenId values even if the connected wallet may not own the position. Treat generated calldata as a transaction preview input, not proof of ownership or guaranteed execution.

Claim Fees: POST /lp/claim_fees
{
  "protocol": "V4",
  "walletAddress": "<address>",
  "chainId": 8453,
  "tokenId": "<nft token id>",
  "simulateTransaction": false
}

Response:

{
  "claim": { "to": "...", "data": "...", "value": "0x00", "chainId": 8453 },
  "token0": { "tokenAddress": "...", "amount": "..." },
  "token1": { "tokenAddress": "...", "amount": "..." }
}

No approval step is needed for fee collection.

Create V2 Position: POST /lp/create_classic
{
  "walletAddress": "<address>",
  "poolParameters": {
    "token0Address": "0x4200000000000000000000000000000000000006",
    "token1Address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "chainId": 8453
  },
  "independentToken": {
    "tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "amount": "1000000"
  },
  "simulateTransaction": false
}

For V2 create, /lp/check_approval may return multiple approval transactions. Batch all approvals plus the create transaction if you want one send_calls approval link.

Orchestration

Swap orchestration

1. get_wallets -> address; convert tokenIn amount to base units
2. web_request POST /check_approval with x-permit2-disabled
3. web_request POST /quote with x-permit2-disabled
4. Build swapBody from quoteResponse and remove null permit fields
5. web_request POST /swap with x-permit2-disabled
6. send_calls("base", approval + swap calls if approval exists, otherwise swap only)
7. Open the approvalUrl if requested; do not approve unless the user explicitly asks
8. get_request_status only after the user acts

LP orchestration

1. get_wallets -> address
2. For V3/V4 create, call /lp/pool_info to discover poolReference
3. Build LP token amount list in base units
4. web_request POST /lp/check_approval
5. web_request POST /lp/create, /lp/increase, /lp/decrease, /lp/claim_fees, or /lp/create_classic
6. send_calls("base", approval calls + operation call)
7. Open the approvalUrl if requested; do not approve unless the user explicitly asks
8. get_request_status only after the user acts

Submission

Target tool: send_calls (chain "base"). Open the returned approvalUrl only if the user asks, and poll get_request_status after they act (see ../references/approval-mode.md and ../references/batch-calls.md).

Swap send_calls

Approval and swap can be sent separately or batched in one send_calls preview:

{
  "chain": "base",
  "calls": [
    { "to": "<approval.to>", "value": "<approval.value>", "data": "<approval.data>" },
    { "to": "<swap.to>", "value": "<swap.value>", "data": "<swap.data>" }
  ]
}

LP send_calls

For any LP operation response field such as create, increase, decrease, or claim, map to:

{
  "chain": "base",
  "calls": [
    { "to": "<tx.to>", "value": "<tx.value>", "data": "<tx.data>" }
  ]
}

For approval + action batching:

const operationTx =
  operationResponse.create ??
  operationResponse.increase ??
  operationResponse.decrease ??
  operationResponse.claim;

const calls = [
  ...approvalResponse.transactions.map((entry) => ({
    to: entry.transaction.to,
    value: entry.transaction.value ?? "0x0",
    data: entry.transaction.data
  })),
  {
    to: operationTx.to,
    value: operationTx.value ?? "0x0",
    data: operationTx.data
  }
];

Example Prompts

Swap 1 USDC to WETH on Base

  1. get_wallets -> address; use USDC address 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, amount 1000000.
  2. web_request POST /check_approval with x-permit2-disabled: true.
  3. web_request POST /quote with x-permit2-disabled: true.
  4. Remove null permit fields from quote response.
  5. web_request POST /swap with x-permit2-disabled: true.
  6. send_calls approval + swap, or swap only if no approval was returned.

Create a V4 ETH/USDC LP position on Base

  1. get_wallets -> address.
  2. web_request POST /lp/pool_info to find the pool reference.
  3. web_request POST /lp/check_approval using lpTokens array.
  4. web_request POST /lp/create using existingPool.poolReference and tickBounds.
  5. send_calls approval transactions plus create transaction.

Add liquidity to an existing V4 position

  1. get_wallets -> address.
  2. Confirm the wallet owns the nftTokenId or warn that generated calldata may still fail.
  3. web_request POST /lp/check_approval with action "INCREASE".
  4. web_request POST /lp/increase.
  5. send_calls approval transactions plus increase transaction.

Collect LP fees

  1. get_wallets -> address.
  2. web_request POST /lp/claim_fees with tokenId.
  3. send_calls claim transaction.

Risks & Warnings

High slippage tolerance exposes the user to worse fills and sandwich/MEV attacks. Before calling /swap or any LP endpoint with an elevated value, warn the user and get explicit confirmation:

Tolerance Level Action
≤ 1% Normal Proceed.
> 1% and ≤ 5% Elevated Mention the value and ask the user to confirm.
> 5% and ≤ 20% High Warn that the trade can fill significantly below quote and is a likely sandwich target. Require explicit confirmation.
> 20% Very high Strongly warn; do not submit without the user re-confirming the exact number.

Apply the same thresholds to swap and LP slippage. If the user did not specify a value, prefer autoSlippage: "DEFAULT" on swaps rather than picking a high number.

Notes

  • Native ETH address: 0x0000000000000000000000000000000000000000
  • USDC on Base: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
  • WETH on Base: 0x4200000000000000000000000000000000000006
  • Token amounts are base units: USDC = 1e6 per token, ETH/WETH = 1e18 per token.
  • Use chain: "base" with send_calls, not numeric chain id.
  • For swap proxy approval, include x-permit2-disabled: true on /check_approval, /quote, and /swap.
  • For swap proxy approval, remove null permitData and permitTransaction fields before calling /swap.
  • /quote response fields must be spread directly into /swap body, not nested under a quote key.
  • Do not send signature in the proxy swap flow.

Source: SKILL.md on GitHub

skilld matched fixed text patterns in SKILL.md and file names. Patterns miss obfuscated code.

skilld run checks every file with the same patterns. It asks for approval before it loads a Skill with a behavior marked Needs approval.

1 alert14d3 checks · Risk CRITICAL
  • Gen Agent Trust Hub14d

    Security analysis identified a critical risk due to automated scanner detections of malicious files and URLs within the Flaunch plugin. The skill also contains hardcoded authentication credentials across multiple plugins and relies on downloading and executing various third-party packages at runtime. Furthermore, certain plugins handle highly sensitive personal information, such as credit card details and email contents, which increases the potential impact of an exploit.

  • Socket14d

    1 alert: gptSecurity

  • Snyk14d

    Risk: MEDIUM · 2 issues

Signed by skilld at ef8bcd5. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated 2 weeks ago
title
Base MCP Skill
version
0.1.0
  • MCP
  • base
  • blockchain
  • wallet
  • defi
  • ethereum
  • swaps
  • tokens
  • agent-tools

README badge

README badge for base/skills/base-mcp

Gives your AI assistant access to a Base Account wallet via the Base MCP server, enabling balance checks, token sends and swaps, message signing, x402 payments, batched contract calls, and transaction history. Includes optional plugins for Morpho, Moonwell, Uniswap, Avantis perpetuals, Virtuals agents, Aerodrome, and Bankr token launches.

Generated from the current SKILL.md.

What do I need to install to use this skill?
You need the Base MCP server installed and connected. If Base MCP tools aren't available, visit https://docs.base.org/ai-agents/quickstart for installation steps specific to your platform.
What chains does Base MCP support?
The skill works across supported chains for wallet, portfolio, and transaction history. Individual plugins (Morpho, Moonwell, Uniswap, Avantis, Aerodrome, Bankr) are Base-only unless noted otherwise — Moonwell also supports Optimism.
Can I use this skill to sign transactions?
Yes. Base MCP supports signing messages and contract calls. Write operations that return an approval URL follow a specific approval flow — the skill will guide you through it.
What happens if I use a plugin that supports lending or leverage?
Plugins like Morpho, Moonwell, and Avantis can expose you to liquidation risk. The skill surfaces health factor and position data before risky actions, but you must review all details before approving any transaction.
Do I need to provide my wallet address at the start?
No. Wallet address and balance are only fetched when you ask for them or when a pending operation actually needs the address — like a token send or balance lookup.

Generated from the current SKILL.md. These answers refresh after source changes.