discover_pools
Find Cardano DEX liquidity pools for specific native tokens using Iris API data to analyze trading opportunities.
Instructions
Discover Cardano DEX liquidity pools for a native token via Iris API
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| symbol | Yes | Cardano token symbol (INDY, SNEK, MIN, NIGHT) |
Implementation Reference
- src/tools/cardano.ts:197-243 (handler)The main handler implementation of the discover_pools tool. It fetches liquidity pools from the Iris API for a given Cardano token symbol, filters pools matching the token's policy ID, sorts by TVL, and returns pool details including DEX name, TVL, reserves, price, and active status.
server.tool( 'discover_pools', 'Discover Cardano DEX liquidity pools for a native token via Iris API', { symbol: z.string().describe('Cardano token symbol (INDY, SNEK, MIN, NIGHT)'), }, async ({ symbol }) => { const upper = symbol.toUpperCase(); const token = SUPPORTED_TOKENS[upper]; if (!token) { throw new Error( `Unsupported token: ${symbol}. Supported: ${Object.keys(SUPPORTED_TOKENS).join(', ')}` ); } const allPools = await fetchIrisPools(); const tokenPools = allPools .filter((p: any) => matchesToken(p, token.policyId)) .sort((a: any, b: any) => (b.state?.tvl || 0) - (a.state?.tvl || 0)); return { content: [ { type: 'text' as const, text: JSON.stringify( { symbol: upper, totalPools: tokenPools.length, pools: tokenPools.map((p: any) => ({ identifier: p.identifier, dex: p.dex || 'unknown', tvl: p.state?.tvl || 0, reserveA: p.state?.reserveA || 0, reserveB: p.state?.reserveB || 0, price: p.state?.price || null, isActive: p.isActive !== false, })), timestamp: new Date().toISOString(), }, null, 2 ), }, ], }; } ); - src/tools/cardano.ts:79-89 (helper)Helper function fetchIrisPools() that fetches liquidity pools data from the Iris API endpoint. Used by discover_pools to retrieve all available pools.
async function fetchIrisPools(): Promise<any[]> { const resp = await fetch(`${IRIS_BASE_URL}/api/liquidity-pools`, { headers: { 'User-Agent': 'OpenMM-MCP-Agent/1.0' }, signal: AbortSignal.timeout(10000), }); if (!resp.ok) { throw new Error(`Iris API error: ${resp.status}`); } const data = await resp.json(); return data?.data || data || []; } - src/tools/cardano.ts:108-112 (helper)Helper function matchesToken() that checks if a pool contains a token with a specific policy ID. Used by discover_pools to filter pools for the requested token.
function matchesToken(pool: any, policyId: string): boolean { const tokenA = pool.pair?.tokenA || pool.tokenA; const tokenB = pool.pair?.tokenB || pool.tokenB; return tokenA?.policyId === policyId || tokenB?.policyId === policyId; } - src/tools/cardano.ts:114-244 (registration)The registerCardanoTools function that registers both get_cardano_price and discover_pools tools with the MCP server. The discover_pools tool is registered starting at line 198.
export function registerCardanoTools(server: McpServer): void { server.tool( 'get_cardano_price', 'Get aggregated price for a Cardano native token from DEX liquidity pools (TOKEN/USDT via ADA bridge)', { symbol: z.string().describe('Cardano token symbol (INDY, SNEK, MIN, NIGHT)'), }, async ({ symbol }) => { const upper = symbol.toUpperCase(); const token = SUPPORTED_TOKENS[upper]; if (!token) { throw new Error( `Unsupported token: ${symbol}. Supported: ${Object.keys(SUPPORTED_TOKENS).join(', ')}` ); } const [adaPrice, allPools] = await Promise.all([fetchADAUSDT(), fetchIrisPools()]); const tokenPools = allPools .filter((p: any) => matchesToken(p, token.policyId)) .filter((p: any) => (p.state?.tvl || 0) >= token.minLiquidity) .sort((a: any, b: any) => (b.state?.tvl || 0) - (a.state?.tvl || 0)) .slice(0, 3); if (tokenPools.length === 0) { throw new Error(`No liquidity pools found for ${upper} above minimum TVL threshold`); } const identifiers = tokenPools.map((p: any) => p.identifier).filter(Boolean); let tokenAdaPrice: number; if (identifiers.length > 0) { const prices = await fetchIrisPrices(identifiers); if (prices.length > 0) { const totalTvl = tokenPools.reduce((sum: number, p: any) => sum + (p.state?.tvl || 0), 0); tokenAdaPrice = tokenPools.reduce((sum: number, p: any, i: number) => { const weight = (p.state?.tvl || 0) / totalTvl; return sum + (prices[i] || 0) * weight; }, 0); } else { tokenAdaPrice = tokenPools.reduce((sum: number, p: any) => sum + (p.state?.price || 0), 0) / tokenPools.length; } } else { tokenAdaPrice = tokenPools.reduce((sum: number, p: any) => sum + (p.state?.price || 0), 0) / tokenPools.length; } const tokenUsdtPrice = tokenAdaPrice * adaPrice.price; const confidence = Math.min(tokenPools.length / 3, 1); return { content: [ { type: 'text' as const, text: JSON.stringify( { symbol: `${upper}/USDT`, price: tokenUsdtPrice, tokenAdaPrice, adaUsdtPrice: adaPrice.price, confidence, poolsUsed: tokenPools.length, sources: { ada: adaPrice.sources, pools: tokenPools.map((p: any) => ({ dex: p.dex || 'unknown', tvl: p.state?.tvl, })), }, timestamp: new Date().toISOString(), }, null, 2 ), }, ], }; } ); server.tool( 'discover_pools', 'Discover Cardano DEX liquidity pools for a native token via Iris API', { symbol: z.string().describe('Cardano token symbol (INDY, SNEK, MIN, NIGHT)'), }, async ({ symbol }) => { const upper = symbol.toUpperCase(); const token = SUPPORTED_TOKENS[upper]; if (!token) { throw new Error( `Unsupported token: ${symbol}. Supported: ${Object.keys(SUPPORTED_TOKENS).join(', ')}` ); } const allPools = await fetchIrisPools(); const tokenPools = allPools .filter((p: any) => matchesToken(p, token.policyId)) .sort((a: any, b: any) => (b.state?.tvl || 0) - (a.state?.tvl || 0)); return { content: [ { type: 'text' as const, text: JSON.stringify( { symbol: upper, totalPools: tokenPools.length, pools: tokenPools.map((p: any) => ({ identifier: p.identifier, dex: p.dex || 'unknown', tvl: p.state?.tvl || 0, reserveA: p.state?.reserveA || 0, reserveB: p.state?.reserveB || 0, price: p.state?.price || null, isActive: p.isActive !== false, })), timestamp: new Date().toISOString(), }, null, 2 ), }, ], }; } ); } - src/worker.ts:18-47 (registration)Worker endpoint that exposes the MCP server capabilities, listing discover_pools as one of the available tools in the server card JSON response.
if (url.pathname === '/.well-known/mcp/server-card.json' && request.method === 'GET') { const card = { name: 'openmm-mcp-agent', version: '1.0.4', description: 'MCP server for OpenMM — exposes market data, account, trading, and strategy tools to AI agents', url: 'https://openmm-mcp.qbtlabs.io/mcp', transport: { type: 'streamable-http' }, capabilities: { tools: [ { name: 'get_ticker' }, { name: 'get_orderbook' }, { name: 'get_trades' }, { name: 'get_balance' }, { name: 'list_orders' }, { name: 'create_order' }, { name: 'cancel_order' }, { name: 'cancel_all_orders' }, { name: 'start_grid_strategy' }, { name: 'stop_strategy' }, { name: 'get_strategy_status' }, { name: 'get_cardano_price' }, { name: 'discover_pools' }, ], }, }; return new Response(JSON.stringify(card), { headers: { 'Content-Type': 'application/json' }, }); }