Skip to main content
Glama

pancakeRemovePosition

Withdraw liquidity from PancakeSwap positions using the BSC MCP Server. Specify the position ID and percentage to remove, ensuring precise control over your DeFi transactions on Binance Smart Chain.

Instructions

remove liquidity position on panceke

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
percentYes
positionIdYes

Implementation Reference

  • MCP tool handler: executes remove liquidity by calling removeLiquidityV3, handles success/error with transaction URL
    async ({ positionId, percent }) => { let txHash = undefined; try { const account = await getAccount(); txHash = await removeLiquidityV3(account, BigInt(positionId), percent); const txUrl = await checkTransactionHash(txHash) return { content: [ { type: "text", text: `remove liquidity position on panceke successfully. ${txUrl}`, url: txUrl, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); const txUrl = buildTxUrl(txHash); return { content: [ { type: "text", text: `transaction failed: ${errorMessage}`, url: txUrl, }, ], isError: true, }; } }
  • Input schema for the tool: positionId (string), percent (number between 1 and 100)
    positionId: z.string(), percent: z.number().max(100).min(1), },
  • Registration function that defines and registers the 'Remove_PancakeSwap_Liquidity' tool on the MCP server
    export function registerPancakeRemovePosition(server: McpServer) { server.tool("Remove_PancakeSwap_Liquidity", "🔄Withdraw your liquidity from PancakeSwap pools", { positionId: z.string(), percent: z.number().max(100).min(1), }, async ({ positionId, percent }) => { let txHash = undefined; try { const account = await getAccount(); txHash = await removeLiquidityV3(account, BigInt(positionId), percent); const txUrl = await checkTransactionHash(txHash) return { content: [ { type: "text", text: `remove liquidity position on panceke successfully. ${txUrl}`, url: txUrl, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); const txUrl = buildTxUrl(txHash); return { content: [ { type: "text", text: `transaction failed: ${errorMessage}`, url: txUrl, }, ], isError: true, }; } } ); }
  • src/main.ts:35-35 (registration)
    Site-wide registration of the pancakeRemovePosition tool in the main server setup
    registerPancakeRemovePosition(server);
  • Core helper function implementing the V3 liquidity removal logic via multicall to PositionManager
    export const removeLiquidityV3 = async (account: PrivateKeyAccount, tokenId: BigInt, percent: number) => { const calldatas: Hex[] = [] const client = walletClient(account).extend(publicActions) const positionInfo = await publicClient.readContract({ address: POSITION_MANAGER_ADDRESS, abi: positionManagerABI, functionName: 'positions', args: [tokenId] }) as any[] const bnb = Native.onChain(ChainId.BSC) const liquidity: bigint = new Percent(percent!, 100).multiply(positionInfo[7]).quotient // remove liquidity calldatas.push(encodeFunctionData({ abi: positionManagerABI, functionName: 'decreaseLiquidity', args: [ { tokenId, liquidity, amount0Min: BigInt(1), amount1Min: BigInt(1), deadline: Math.floor(Date.now() / 1000) + 1200, }, ], })) const involvesETH = getAddress(bnb.wrapped.address) === getAddress(positionInfo[2]) || getAddress(bnb.wrapped.address) === getAddress(positionInfo[3]) calldatas.push(encodeFunctionData({ abi: positionManagerABI, functionName: 'collect', args: [ { tokenId, recipient: involvesETH ? zeroAddress : account.address, amount0Max: maxUint128, amount1Max: maxUint128, }, ], })) if (involvesETH) { const poolAddrs = await client.readContract({ address: FACTORY_ADDRESS, abi: FACTORY_ABI, functionName: 'getPool', args: [ positionInfo[2] as Address, positionInfo[3] as Address, positionInfo[4] ] }) const slot0 = await client.readContract({ address: poolAddrs as Address, abi: POOL_ABI, functionName: 'slot0', }) const token0Amount = PositionMath.getToken0Amount( slot0[1], positionInfo[5], positionInfo[6], slot0[0], positionInfo[7], ) const discountedAmount0 = new Percent(percent!, 100).multiply(token0Amount).quotient const token1Amount = PositionMath.getToken1Amount( slot0[1], positionInfo[5], positionInfo[6], slot0[0], positionInfo[7], ) const discountedAmount1 = new Percent(percent!, 100).multiply(token1Amount).quotient const ethAmount = getAddress(bnb.wrapped.address) === getAddress(positionInfo[2]) ? discountedAmount0 : discountedAmount1 const token = getAddress(bnb.wrapped.address) === getAddress(positionInfo[2]) ? positionInfo[3] : positionInfo[2] const tokenAmount = getAddress(bnb.wrapped.address) === getAddress(positionInfo[2]) ? discountedAmount1 : discountedAmount0 calldatas.push(encodeFunctionData({ abi: Payments_ABI, functionName: 'unwrapWETH9', args: [ethAmount, account.address], })) calldatas.push(encodeFunctionData({ abi: Payments_ABI, functionName: 'sweepToken', args: [token, tokenAmount, account.address], })) } const data = Multicall.encodeMulticall(calldatas) const tx = await client.sendTransaction({ to: POSITION_MANAGER_ADDRESS, data: data, value: BigInt(0), account: account, chain: client.chain as any, }) return tx }

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/TermiX-official/bsc-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server