Skip to main content
Glama

REMOVE_COLLATERAL

Withdraw collateral from a BAMM position by providing the BAMM contract address and the amount to remove.

Instructions

Remove collateral from your BAMM position

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
bammAddressYesThe address of the BAMM contract
amountYesThe amount of collateral to remove
collateralTokenNoThe address of the collateral token
collateralTokenSymbolNoThe symbol of the collateral token (e.g., 'IQT')

Implementation Reference

  • The RemoveCollateralService class with the execute() method that handles the core logic: resolves collateral token address, validates token against BAMM, checks balance, constructs the action struct with negative token amounts (removal), simulates and writes the executeActions contract call on the BAMM contract.
    export class RemoveCollateralService {
    	constructor(private walletService: WalletService) {}
    
    	async execute(params: RemoveCollateralParams): Promise<{ txHash: string }> {
    		let { bammAddress, collateralToken, collateralTokenSymbol, amount } =
    			params;
    		if (!collateralToken && !collateralTokenSymbol) {
    			throw new Error(
    				"Either collateralToken or collateralTokenSymbol is required",
    			);
    		}
    		const publicClient = this.walletService.getPublicClient();
    		const walletClient = this.walletService.getWalletClient();
    
    		if (!walletClient || !walletClient.account) {
    			throw new Error("Wallet client is not initialized");
    		}
    
    		const userAddress = walletClient.account.address;
    		const removeAmountWei = -BigInt(Math.floor(Number(amount) * 1e18));
    
    		try {
    			if (collateralTokenSymbol) {
    				collateralToken = await getTokenAddressFromSymbol(
    					collateralTokenSymbol,
    				);
    			}
    
    			if (!collateralToken) {
    				throw new Error("Could not resolve collateral token address");
    			}
    
    			const tokenValidation = await validateTokenAgainstBAMM(
    				bammAddress,
    				collateralToken,
    				publicClient,
    			);
    			await checkTokenBalance(
    				collateralToken,
    				userAddress,
    				removeAmountWei,
    				publicClient,
    			);
    
    			const currentTime = Math.floor(Date.now() / 1000);
    			const deadline = BigInt(currentTime + 300);
    
    			const action = {
    				token0Amount: tokenValidation.isToken0 ? removeAmountWei : 0n,
    				token1Amount: tokenValidation.isToken1 ? removeAmountWei : 0n,
    				rent: 0n,
    				to: userAddress,
    				token0AmountMin: 0n,
    				token1AmountMin: 0n,
    				closePosition: false,
    				approveMax: false,
    				v: 0,
    				r: "0x0000000000000000000000000000000000000000000000000000000000000000" as `0x${string}`,
    				s: "0x0000000000000000000000000000000000000000000000000000000000000000" as `0x${string}`,
    				deadline,
    			};
    
    			const { request: executeRequest } = await publicClient.simulateContract({
    				address: bammAddress,
    				abi: BAMM_ABI,
    				functionName: "executeActions",
    				args: [action],
    				account: walletClient.account,
    			});
    			const txHash = await walletClient.writeContract(executeRequest);
    			await publicClient.waitForTransactionReceipt({ hash: txHash });
    			return { txHash };
    		} catch (error) {
    			console.error("Error executing remove-collateral", error);
    			throw Error("Error executing remove-collateral");
    		}
    	}
    }
  • Zod schema (removeCollateralToolParams) defining the input parameters for REMOVE_COLLATERAL: bammAddress (hex address), amount (string), collateralToken (optional hex address), collateralTokenSymbol (optional string).
    const removeCollateralToolParams = z.object({
    	bammAddress: z
    		.string()
    		.regex(/^0x[a-fA-F0-9]{40}$/)
    		.describe("The address of the BAMM contract"),
    	amount: z.string().min(1).describe("The amount of collateral to remove"),
    	collateralToken: z
    		.string()
    		.regex(/^0x[a-fA-F0-9]{40}$/)
    		.optional()
    		.describe("The address of the collateral token"),
    	collateralTokenSymbol: z
    		.string()
    		.optional()
    		.describe("The symbol of the collateral token (e.g., 'IQT')"),
    });
    
    export type RemoveCollateralToolParams = z.infer<
    	typeof removeCollateralToolParams
    >;
  • The Tool object named 'REMOVE_COLLATERAL' with description 'Remove collateral from your BAMM position', parameters, and the execute handler that instantiates WalletService and RemoveCollateralService.
    export const removeCollateralTool: Tool<
    	FastMCPSessionAuth,
    	typeof removeCollateralToolParams
    > = {
    	name: "REMOVE_COLLATERAL",
    	description: "Remove collateral from your BAMM position",
    	parameters: removeCollateralToolParams,
    	execute: async (params, _context) => {
    		try {
    			if (!params.collateralToken && !params.collateralTokenSymbol) {
    				return "Error: Either collateralToken address or collateralTokenSymbol is required";
    			}
    
    			const privateKey = process.env.WALLET_PRIVATE_KEY;
    			if (!privateKey) {
    				return "Error: WALLET_PRIVATE_KEY environment variable is not set. Please set it with your wallet's private key (without 0x prefix).";
    			}
    
    			const walletService = new WalletService(privateKey);
    			const removeCollateralService = new RemoveCollateralService(
    				walletService,
    			);
    
    			const result = await removeCollateralService.execute({
    				bammAddress: params.bammAddress as Address,
    				collateralToken: params.collateralToken as Address | undefined,
    				collateralTokenSymbol: params.collateralTokenSymbol,
    				amount: params.amount,
    			});
    
    			return dedent`
            ✅ Collateral Removal Successful
    
            🌐 BAMM Address: ${params.bammAddress}
            🔓 Amount: ${formatNumber(Number(params.amount))}
            💰 Token: ${params.collateralTokenSymbol ?? params.collateralToken}
            🔗 Transaction: ${result.txHash}
    
            Collateral has been removed from your BAMM position.
          `;
    		} catch (error) {
    			if (error instanceof Error) {
    				return dedent`
              ❌ Collateral Removal Failed
    
              Error: ${error.message}
    
              Please verify your inputs and try again.
            `;
    			}
    			return "An unknown error occurred while removing collateral";
    		}
    	},
    };
  • src/index.ts:8-24 (registration)
    Import and registration of the removeCollateralTool via server.addTool(removeCollateralTool) in the main server entry point.
    import { removeCollateralTool } from "./tools/remove-collateral.js";
    import { repayTool } from "./tools/repay.js";
    
    async function main() {
    	console.log("🚀 Initializing BAMM MCP Server...");
    
    	const server = new FastMCP({
    		name: "BAMM MCP Server",
    		version: "0.0.1",
    	});
    
    	server.addTool(addCollateralTool);
    	server.addTool(borrowTool);
    	server.addTool(getPositionsTool);
    	server.addTool(lendTool);
    	server.addTool(poolStatsTool);
    	server.addTool(removeCollateralTool);
  • The REMOVE_COLLATERAL_TEMPLATE string, a prompt template for LLM extraction of 'collateral withdrawal' parameters using the TOKEN_OPERATION_TEMPLATE.
    export const REMOVE_COLLATERAL_TEMPLATE = TOKEN_OPERATION_TEMPLATE.replace(
    	/{{operation}}/g,
    	"collateral withdrawal",
    ).replace(/{{tokenType}}/g, "collateralToken");
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, and the description does not disclose behavioral traits such as effects on position state, authentication requirements, or reversibility, leaving the agent to infer from the name alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that efficiently states the tool's purpose, though it omits necessary details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of output schema and annotations, the description is incomplete; it does not explain return values, prerequisites, or the impact on the BAMM position, which is critical for a mutation tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage for all 4 parameters, so the description adds no extra meaning beyond the schema. Baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Remove' and the resource 'collateral from your BAMM position', which distinguishes it from the sibling tool ADD_COLLATERAL.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives like REPAY or how to ensure the position has sufficient collateral to remove.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/IQAIcom/mcp-bamm'

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