explore_dex_pools
Browse and filter concentrated liquidity pools on Meteora, Raydium, and Uniswap V3. Compare yields, TVL, and volume, then get detailed pool information by address.
Instructions
Explore DeFi CLMM pools — discover pools, compare yields, and get pool details.
Supports CLMM DEX connectors (Meteora, Raydium, Uniswap V3) for concentrated liquidity.
- list_pools: Browse available CLMM pools with filtering and sorting
- get_pool_info: Get detailed information about a specific pool (requires network + pool_address)
To manage LP positions, use `manage_executors` with `lp_executor` type.
To check on-chain positions, use `get_portfolio_overview` with `include_lp_positions=True`.
Args:
action: Action to perform on CLMM pools.
connector: CLMM connector name (e.g., 'meteora', 'raydium', 'uniswap'). Required.
network: Network ID in 'chain-network' format (e.g., 'solana-mainnet-beta'). Required for get_pool_info.
pool_address: Pool contract address (required for get_pool_info).
page: Page number for list_pools (default: 0).
limit: Results per page for list_pools (default: 50, max: 100).
search_term: Search term to filter pools by token symbols (e.g., 'SOL', 'USDC').
sort_key: Sort by field for list_pools (volume, tvl, feetvlratio, etc.).
order_by: Sort order for list_pools ('asc' or 'desc').
include_unknown: Include pools with unverified tokens (default: True).
detailed: Return detailed table with more columns for list_pools (default: False).Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | ||
| connector | No | ||
| network | No | ||
| pool_address | No | ||
| page | No | ||
| limit | No | ||
| search_term | No | ||
| sort_key | No | volume | |
| order_by | No | desc | |
| include_unknown | No | ||
| detailed | No |
Implementation Reference
- Core handler function that executes the explore_dex_pools logic. Calls gateway_clmm.get_pools for list_pools action and gateway_clmm.get_pool_info for get_pool_info action, returning formatted results with pool tables.
async def explore_gateway_clmm_pools(client: Any, request: GatewayCLMMRequest) -> dict[str, Any]: """ Explore Gateway CLMM pools: list pools and get pool information. Actions: - list_pools: Get list of available CLMM pools with filtering and sorting - get_pool_info: Get detailed information about a specific pool Supported CLMM Connectors: - meteora (Solana): DLMM pools - raydium (Solana): CLMM pools - uniswap (Ethereum/EVM): V3 pools """ # ============================================ # LIST POOLS - Browse available pools # ============================================ if request.action == "list_pools": result = await client.gateway_clmm.get_pools( connector=request.connector, page=request.page, limit=request.limit, search_term=request.search_term, sort_key=request.sort_key, order_by=request.order_by, include_unknown=request.include_unknown ) pools = result.get("pools", []) # Format as detailed table if detailed mode is enabled if request.detailed: formatted_table = format_pools_as_detailed_table(pools) else: # Otherwise format as simplified table formatted_table = format_pools_as_table(pools) return { "action": "list_pools", "connector": request.connector, "filters": { "search_term": request.search_term, "sort_key": request.sort_key, "order_by": request.order_by, "include_unknown": request.include_unknown }, "pagination": { "page": request.page, "limit": request.limit, "total": result.get("total", 0) }, "pools_table": formatted_table } # ============================================ # GET POOL INFO - Get detailed pool information # ============================================ elif request.action == "get_pool_info": # Validate required parameters if not request.network: raise ToolError("network is required for get_pool_info action") if not request.pool_address: raise ToolError("pool_address is required for get_pool_info action") result = await client.gateway_clmm.get_pool_info( connector=request.connector, network=request.network, pool_address=request.pool_address ) return { "action": "get_pool_info", "connector": request.connector, "network": request.network, "pool_address": request.pool_address, "result": result } else: raise ToolError(f"Unknown action: {request.action}") - hummingbot_mcp/server.py:766-821 (registration)MCP tool registration decorated with @mcp.tool(). Defines the tool's name (explore_dex_pools), its parameters with Literal types and defaults, docstring, and delegates to explore_gateway_clmm_pools_impl.
@mcp.tool() @handle_errors("explore DEX pools", GATEWAY_LOG_HINT) async def explore_dex_pools( action: Literal["list_pools", "get_pool_info"], connector: str | None = None, network: str | None = None, pool_address: str | None = None, page: int = 0, limit: int = 50, search_term: str | None = None, sort_key: str | None = "volume", order_by: str | None = "desc", include_unknown: bool = True, detailed: bool = False, ) -> str: """Explore DeFi CLMM pools — discover pools, compare yields, and get pool details. Supports CLMM DEX connectors (Meteora, Raydium, Uniswap V3) for concentrated liquidity. - list_pools: Browse available CLMM pools with filtering and sorting - get_pool_info: Get detailed information about a specific pool (requires network + pool_address) To manage LP positions, use `manage_executors` with `lp_executor` type. To check on-chain positions, use `get_portfolio_overview` with `include_lp_positions=True`. Args: action: Action to perform on CLMM pools. connector: CLMM connector name (e.g., 'meteora', 'raydium', 'uniswap'). Required. network: Network ID in 'chain-network' format (e.g., 'solana-mainnet-beta'). Required for get_pool_info. pool_address: Pool contract address (required for get_pool_info). page: Page number for list_pools (default: 0). limit: Results per page for list_pools (default: 50, max: 100). search_term: Search term to filter pools by token symbols (e.g., 'SOL', 'USDC'). sort_key: Sort by field for list_pools (volume, tvl, feetvlratio, etc.). order_by: Sort order for list_pools ('asc' or 'desc'). include_unknown: Include pools with unverified tokens (default: True). detailed: Return detailed table with more columns for list_pools (default: False). """ request = GatewayCLMMRequest( action=action, connector=connector, network=network, pool_address=pool_address, page=page, limit=limit, search_term=search_term, sort_key=sort_key, order_by=order_by, include_unknown=include_unknown, detailed=detailed, ) client = await hummingbot_client.get_client() result = await explore_gateway_clmm_pools_impl(client, request) return format_gateway_clmm_pool_result(action, result) - hummingbot_mcp/schemas.py:605-676 (schema)Pydantic schema for the explore_dex_pools request, defining all input parameters with validation (e.g., page >= 0, limit 1-100, Literal action types).
class GatewayCLMMRequest(BaseModel): """Request model for Gateway CLMM pool discovery. This model supports DeFi data exploration: Pool Exploration: - list_pools: Get list of available CLMM pools with filtering/sorting - get_pool_info: Get detailed information about a specific pool To manage LP positions, use `manage_executors` with `lp_executor` type. To check on-chain positions, use `get_portfolio_overview` with `include_lp_positions=True`. """ action: Literal["list_pools", "get_pool_info"] = Field( description="Action to perform on CLMM pools" ) # Common parameters connector: str | None = Field( default=None, description="CLMM connector name (required). Examples: 'meteora', 'raydium', 'uniswap'" ) network: str | None = Field( default=None, description="Network ID in 'chain-network' format (required for get_pool_info). Examples: 'solana-mainnet-beta', 'ethereum-mainnet'" ) pool_address: str | None = Field( default=None, description="Pool contract address (required for get_pool_info)" ) # Pool listing parameters page: int = Field( default=0, ge=0, description="Page number for list_pools (default: 0)" ) limit: int = Field( default=50, ge=1, le=100, description="Results per page for list_pools (default: 50, max: 100)" ) search_term: str | None = Field( default=None, description="Search term to filter pools by token symbols (e.g., 'SOL', 'USDC')" ) sort_key: str | None = Field( default="volume", description="Sort by field (volume, tvl, feetvlratio, etc.)" ) order_by: str | None = Field( default="desc", description="Sort order: 'asc' or 'desc'" ) include_unknown: bool = Field( default=True, description="Include pools with unverified tokens (default: True)" ) detailed: bool = Field( default=False, description="Return detailed table with more columns (default: False)" ) - Helper function that formats a list of pool dictionaries into a simplified human-readable table string with columns for address, trading_pair, bin_step, current_price, liquidity, fees, APY, volume, and fees_24h.
def format_pools_as_table(pools: list[dict[str, Any]]) -> str: """ Format pool data as a simplified table string. Columns: address | trading_pair | bin_step | current_price | liquidity | base_fee_percentage | apy | volume_24h | fees_24h """ if not pools: return "No pools found." # Header - simplified columns header = "address | trading_pair | bin_step | current_price | liquidity | base_fee_percentage | apy | volume_24h | fees_24h" separator = "-" * 200 # Format each pool as a row rows = [] for pool in pools: row = ( f"{get_field(pool, 'address', default='N/A')} | " f"{get_field(pool, 'trading_pair', default='N/A')} | " f"{get_field(pool, 'bin_step', default='N/A')} | " f"{format_number(get_field(pool, 'current_price', default=None))} | " f"{format_number(get_field(pool, 'liquidity', default=None))} | " f"{format_number(get_field(pool, 'base_fee_percentage', default=None))} | " f"{format_number(get_field(pool, 'apy', default=None))} | " f"{format_number(get_field(pool, 'volume_24h', default=None))} | " f"{format_number(get_field(pool, 'fees_24h', default=None))}" ) rows.append(row) return f"{header}\n{separator}\n" + "\n".join(rows) - Formatter that wraps the raw result dictionary into a final human-readable string with connector info, pagination, filters, and the pool table for display to the user.
def format_gateway_clmm_pool_result(action: str, result: dict[str, Any]) -> str: """Format gateway CLMM pool exploration results into a human-readable string.""" if action == "list_pools" and "pools_table" in result: return ( f"Gateway CLMM Pool Exploration Result:\n" f"Connector: {result['connector']}\n" f"Total Pools: {result['pagination']['total']}\n" f"Page: {result['pagination']['page']}, Limit: {result['pagination']['limit']}\n" f"Filters: {result['filters']}\n\n" f"{result['pools_table']}" ) return f"Gateway CLMM Pool Exploration Result: {result}"