Skip to main content
Glama

get_token_price_estimate

Calculate real-time token swap price estimates on Paloma DEX across multiple EVM chains to inform trading decisions before execution.

Instructions

Get real-time price estimate for token swap.

Args:
    chain_id: Chain ID (1, 10, 56, 100, 137, 8453, 42161)
    input_token_address: Address of token to trade from
    output_token_address: Address of token to trade to
    input_amount: Amount of input token in wei format

Returns:
    JSON string with price estimate and trading information.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chain_idYes
input_token_addressYes
output_token_addressYes
input_amountYes

Implementation Reference

  • Main handler function decorated with @mcp.tool(). Computes token swap price estimates using PalomaDEXAPI.get_token_estimate and AMM utilities, returning formatted JSON with exchange rates, price impact, etc.
    async def get_token_price_estimate(ctx: Context, chain_id: str, input_token_address: str, output_token_address: str, input_amount: str) -> str:
        """Get real-time price estimate for token swap.
        
        Args:
            chain_id: Chain ID (1, 10, 56, 100, 137, 8453, 42161)
            input_token_address: Address of token to trade from
            output_token_address: Address of token to trade to
            input_amount: Amount of input token in wei format
        
        Returns:
            JSON string with price estimate and trading information.
        """
        try:
            paloma_ctx = ctx.request_context.lifespan_context
            
            if chain_id not in CHAIN_CONFIGS:
                return f"Error: Unsupported chain ID {chain_id}"
            
            config = CHAIN_CONFIGS[chain_id]
            chain_name = get_chain_name_for_api(chain_id)
            
            if not chain_name:
                return f"Error: Chain name mapping not found for chain ID {chain_id}"
            
            # Validate addresses
            if not Web3.is_address(input_token_address):
                return f"Error: Invalid input token address: {input_token_address}"
            
            if not Web3.is_address(output_token_address):
                return f"Error: Invalid output token address: {output_token_address}"
            
            try:
                input_amount_int = int(input_amount)
                if input_amount_int <= 0:
                    raise ValueError("Amount must be positive")
            except ValueError:
                return f"Error: Invalid input amount: {input_amount}"
            
            # Use our Paloma-based API implementation
            try:
                estimate_data = await paloma_ctx.palomadex_api.get_token_estimate(
                    input_token_address, output_token_address, chain_id, input_amount
                )
                
                if not estimate_data.get('exist', False):
                    return f"Error: Trading pair does not exist for these tokens"
                
                if estimate_data.get('empty', True):
                    return f"Error: Pool has no liquidity for this trading pair"
                
                # Get token information from blockchain
                web3 = paloma_ctx.web3_clients.get(chain_id)
                if web3:
                    try:
                        input_contract = web3.eth.contract(address=input_token_address, abi=ERC20_ABI)
                        output_contract = web3.eth.contract(address=output_token_address, abi=ERC20_ABI)
                        
                        input_symbol = input_contract.functions.symbol().call()
                        output_symbol = output_contract.functions.symbol().call()
                        input_decimals = input_contract.functions.decimals().call()
                        output_decimals = output_contract.functions.decimals().call()
                        
                        # Convert amounts for display
                        input_amount_display = float(input_amount_int) / (10 ** input_decimals)
                        output_amount_wei = int(estimate_data.get('estimated_amount', '0'))
                        output_amount_display = float(output_amount_wei) / (10 ** output_decimals)
                        
                        # Calculate exchange rate and price impact
                        exchange_rate = output_amount_display / input_amount_display if input_amount_display > 0 else 0
                        
                        # Calculate price impact using AMM math
                        price_impact = AMM.calculate_price_impact(
                            input_amount_int, 
                            1000000 * 10**input_decimals,  # Mock reserve
                            1000000 * 10**output_decimals   # Mock reserve
                        )
                        
                    except Exception as e:
                        logger.warning(f"Failed to get token info from blockchain: {e}")
                        input_symbol = "Unknown"
                        output_symbol = "Unknown"
                        input_decimals = 18
                        output_decimals = 18
                        input_amount_display = float(input_amount_int) / 1e18
                        output_amount_display = float(estimate_data.get('estimated_amount', '0')) / 1e18
                        exchange_rate = 0
                        price_impact = 0
                else:
                    input_symbol = "Unknown"
                    output_symbol = "Unknown"
                    input_amount_display = float(input_amount_int) / 1e18
                    output_amount_display = float(estimate_data.get('estimated_amount', '0')) / 1e18
                    exchange_rate = 0
                    price_impact = 0
                
                result = {
                    "chain": config.name,
                    "chain_id": config.chain_id,
                    "input_token": {
                        "address": input_token_address,
                        "symbol": input_symbol,
                        "amount_wei": input_amount,
                        "amount_display": str(input_amount_display)
                    },
                    "output_token": {
                        "address": output_token_address,
                        "symbol": output_symbol,
                        "estimated_amount_wei": estimate_data.get('estimated_amount', '0'),
                        "estimated_amount_display": str(output_amount_display)
                    },
                    "trading_info": {
                        "exchange_rate": f"1 {input_symbol} = {exchange_rate:.6f} {output_symbol}",
                        "price_impact": f"{price_impact:.2f}%",
                        "trading_fee": "0.3%"
                    },
                    "pool_exists": estimate_data.get('exist', False),
                    "has_liquidity": not estimate_data.get('empty', True),
                    "data_source": "paloma_amm_calculation",
                    "raw_api_response": estimate_data
                }
                
                return json.dumps(result, indent=2)
                
            except Exception as api_error:
                logger.error(f"Price estimation failed: {api_error}")
                return f"Error: Failed to get price estimate: {str(api_error)}"
                    
        except Exception as e:
            logger.error(f"Error getting token price estimate: {e}")
            return f"Error getting token price estimate: {str(e)}"
  • PalomaDEXAPI.get_token_estimate: Core helper that performs the actual AMM swap calculation using mock pool reserves and returns estimation data used by the main handler.
    async def get_token_estimate(self, input_token_address: str, output_token_address: str, 
                               chain_id: str, input_amount: str) -> Dict:
        """Get token swap estimation using AMM math."""
        try:
            # Create token denoms for Paloma
            input_denom = create_token_denom(chain_id, input_token_address, "input")
            output_denom = create_token_denom(chain_id, output_token_address, "output")
            
            if not input_denom or not output_denom:
                return {"exist": False, "empty": True, "estimated_amount": "0"}
            
            # Mock pool reserves (in real implementation, query from Paloma)
            input_reserve = 1000000 * 10**18  # 1M tokens
            output_reserve = 1000000 * 10**18  # 1M tokens
            
            input_amount_int = int(input_amount)
            
            # Calculate swap output using AMM
            estimated_output = AMM.calculate_swap_output(
                input_amount_int, input_reserve, output_reserve
            )
            
            return {
                "amount0": str(input_amount),
                "amount1": str(estimated_output),
                "estimated_amount": str(estimated_output),
                "exist": True,
                "empty": False
            }
            
        except Exception as e:
            logger.error(f"Error in token estimation: {e}")
            return {"exist": False, "empty": True, "estimated_amount": "0"}
  • AMM utility class providing calculate_swap_output and calculate_price_impact functions used in token price estimation.
    class AMM:
        """AMM calculation utilities."""
        
        @staticmethod
        def calculate_swap_output(input_amount: int, input_reserve: int, output_reserve: int, fee_rate: float = 0.003) -> int:
            """Calculate swap output using constant product formula."""
            if input_reserve <= 0 or output_reserve <= 0:
                return 0
            
            # Apply fee to input amount
            input_amount_with_fee = int(input_amount * (1 - fee_rate))
            
            # Constant product formula: (x + dx) * (y - dy) = x * y
            # dy = (y * dx) / (x + dx)
            numerator = output_reserve * input_amount_with_fee
            denominator = input_reserve + input_amount_with_fee
            
            if denominator <= 0:
                return 0
            
            return numerator // denominator
        
        @staticmethod
        def calculate_price_impact(input_amount: int, input_reserve: int, output_reserve: int) -> float:
            """Calculate price impact percentage."""
            if input_reserve <= 0 or output_reserve <= 0:
                return 0.0
            
            # Current price (before swap)
            current_price = output_reserve / input_reserve
            
            # Price after swap
            output_amount = AMM.calculate_swap_output(input_amount, input_reserve, output_reserve)
            if input_amount <= 0:
                return 0.0
            
            new_price = output_amount / input_amount
            
            # Price impact as percentage
            if current_price <= 0:
                return 0.0
            
            price_impact = (current_price - new_price) / current_price * 100
            return max(0.0, price_impact)
        
        @staticmethod
        def apply_slippage_tolerance(amount: int, slippage_tolerance: float) -> int:
            """Apply slippage tolerance to get minimum received amount."""
            return int(amount * (1 - slippage_tolerance / 100))
  • padex.py:1351-1351 (registration)
    @mcp.tool() decorator registers the get_token_price_estimate function with the FastMCP server.
    async def get_token_price_estimate(ctx: Context, chain_id: str, input_token_address: str, output_token_address: str, input_amount: str) -> str:
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions 'real-time price estimate' and returns 'JSON string with price estimate and trading information,' but fails to disclose critical behaviors such as rate limits, authentication requirements, error conditions, or whether the estimate is guaranteed or approximate. For a financial tool with zero annotation coverage, this leaves significant gaps in understanding its operational characteristics.

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

Conciseness5/5

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

The description is efficiently structured with a clear purpose statement followed by bullet-point-style sections for Args and Returns. Every sentence adds value without redundancy, and it is appropriately sized for a tool with four parameters. The front-loaded purpose statement immediately conveys the tool's function.

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

Completeness3/5

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

Given the tool's complexity (financial estimation with 4 parameters), no annotations, and no output schema, the description is moderately complete. It covers the basic purpose and parameters but lacks details on behavioral traits, error handling, and output structure beyond 'JSON string.' For a tool in this context, more information on reliability, latency, or example outputs would enhance completeness.

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

Parameters4/5

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

The description adds meaningful semantics beyond the input schema, which has 0% description coverage. It clarifies that chain_id uses specific numeric values (1, 10, 56, etc.), input_amount is in 'wei format,' and parameters relate to token addresses for trading. This compensates well for the schema's lack of descriptions, though it could elaborate on format details like address validation or wei conversion examples.

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 specific action ('Get real-time price estimate') and resource ('for token swap'), distinguishing it from sibling tools like execute_token_swap (which performs the swap) and get_etf_price (which focuses on ETF tokens). It precisely communicates the tool's function without being vague or tautological.

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

Usage Guidelines3/5

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

The description implies usage for obtaining price estimates before executing swaps, but does not explicitly state when to use this tool versus alternatives like execute_token_swap or validate_trade_quote. It provides basic context (real-time estimates) but lacks explicit guidance on prerequisites, exclusions, or comparisons to sibling tools.

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/VolumeFi/mcpPADEX'

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