Skip to main content
Glama

analyzeToken

Analyze Ethereum token performance by examining on-chain data for a specified address over a defined period to assess market behavior and trends.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
addressYes
networkIdNoNetwork ID (1 for Ethereum, 101 for Solana)
daysNoNumber of days to analyze

Implementation Reference

  • Registers the 'analyzeToken' MCP tool with input schema and inline handler function on the server.
    server.tool("analyzeToken", { address: z.string().min(1, "Token address is required"), networkId: z.number().int().positive().default(1).describe("Network ID (1 for Ethereum, 101 for Solana)"), days: z.number().int().positive().default(30).describe("Number of days to analyze") }, async ({ address, networkId, days }) => { try { // Get token info const tokenInfo = await fetchTokenInfo(address, networkId); if (!tokenInfo) { return { content: [{ type: "text", text: `No token information found for ${address} on network ${networkId}` }] }; } // Calculate time range const to = Math.floor(Date.now() / 1000); const from = to - (60 * 60 * 24 * days); // Fetch daily data const dailyData = await fetchChartData(address, networkId, "1D", from, to); // Fetch hourly data (last 7 days only to limit data size) const recentFrom = to - (60 * 60 * 24 * Math.min(days, 7)); const hourlyData = await fetchChartData(address, networkId, "60", recentFrom, to); // Perform analysis const analysis = performTokenAnalysis(tokenInfo, dailyData, hourlyData, days); return { content: [{ type: "text", text: analysis }] }; } catch (error) { return { content: [{ type: "text", text: `Error performing token analysis: ${error.message}` }] }; } } ); }
  • Handler function that orchestrates token analysis: fetches token info and chart data, calls performTokenAnalysis helper, formats and returns the analysis as text content.
    async ({ address, networkId, days }) => { try { // Get token info const tokenInfo = await fetchTokenInfo(address, networkId); if (!tokenInfo) { return { content: [{ type: "text", text: `No token information found for ${address} on network ${networkId}` }] }; } // Calculate time range const to = Math.floor(Date.now() / 1000); const from = to - (60 * 60 * 24 * days); // Fetch daily data const dailyData = await fetchChartData(address, networkId, "1D", from, to); // Fetch hourly data (last 7 days only to limit data size) const recentFrom = to - (60 * 60 * 24 * Math.min(days, 7)); const hourlyData = await fetchChartData(address, networkId, "60", recentFrom, to); // Perform analysis const analysis = performTokenAnalysis(tokenInfo, dailyData, hourlyData, days); return { content: [{ type: "text", text: analysis }] }; } catch (error) { return { content: [{ type: "text", text: `Error performing token analysis: ${error.message}` }] }; } }
  • Zod schema defining input parameters for the analyzeToken tool.
    { address: z.string().min(1, "Token address is required"), networkId: z.number().int().positive().default(1).describe("Network ID (1 for Ethereum, 101 for Solana)"), days: z.number().int().positive().default(30).describe("Number of days to analyze") },
  • Key helper function that performs the comprehensive token analysis including formatting info, volatility metrics, trading patterns from hourly data, and volume analysis.
    function performTokenAnalysis(tokenInfo, dailyData, hourlyData, days) { let analysis = formatTokenInfoResponse(tokenInfo); analysis += `\n=== ANALYZING LAST ${days} DAYS OF DATA ===\n`; // Add daily chart data with extended stats analysis += "\n=== DAILY CHART DATA ===\n"; analysis += formatChartDataResponse(dailyData); // Price volatility analysis if (dailyData.length > 0) { analysis += "\n=== VOLATILITY ANALYSIS ===\n"; // Calculate daily price changes const dailyChanges = []; for (let i = 1; i < dailyData.length; i++) { const prevClose = dailyData[i-1].c; const currClose = dailyData[i].c; const percentChange = ((currClose - prevClose) / prevClose) * 100; dailyChanges.push(percentChange); } // Calculate volatility metrics if (dailyChanges.length > 0) { const avgChange = dailyChanges.reduce((sum, change) => sum + Math.abs(change), 0) / dailyChanges.length; const maxUp = Math.max(...dailyChanges); const maxDown = Math.min(...dailyChanges); analysis += `Average Daily Price Movement: ${avgChange.toFixed(2)}%\n`; analysis += `Largest Single-Day Increase: ${maxUp.toFixed(2)}%\n`; analysis += `Largest Single-Day Decrease: ${maxDown.toFixed(2)}%\n`; } // Trading pattern analysis using hourly data if (hourlyData.length > 0) { analysis += "\n=== TRADING PATTERN ANALYSIS ===\n"; // Group trading activity by hour of day to identify patterns const hourlyActivity = Array(24).fill(0); const hourlyVolume = Array(24).fill(0); hourlyData.forEach(bar => { const date = new Date(bar.t * 1000); const hour = date.getUTCHours(); hourlyActivity[hour] += bar.transactions || 0; hourlyVolume[hour] += parseFloat(bar.volume || bar.v || 0); }); // Find peak trading hours let peakHour = 0; let peakVolume = 0; for (let i = 0; i < 24; i++) { if (hourlyVolume[i] > peakVolume) { peakVolume = hourlyVolume[i]; peakHour = i; } } analysis += `Peak Trading Hour (UTC): ${peakHour}:00 - ${peakHour+1}:00\n`; analysis += `Top 3 Active Hours (UTC):\n`; // Get top 3 active hours const hourIndices = Array.from({length: 24}, (_, i) => i); hourIndices.sort((a, b) => hourlyVolume[b] - hourlyVolume[a]); for (let i = 0; i < 3; i++) { const hour = hourIndices[i]; if (hourlyVolume[hour] > 0) { analysis += ` ${hour}:00 - ${hour+1}:00: $${formatNumber(hourlyVolume[hour])} volume, ${hourlyActivity[hour]} transactions\n`; } } } // Volume analysis analysis += '\n=== VOLUME ANALYSIS ===\n'; const totalBuyVolume = dailyData.reduce((sum, bar) => { const vol = typeof bar.buyVolume === 'string' ? parseFloat(bar.buyVolume) : (bar.buyVolume || 0); return sum + vol; }, 0); const totalSellVolume = dailyData.reduce((sum, bar) => { const vol = typeof bar.sellVolume === 'string' ? parseFloat(bar.sellVolume) : (bar.sellVolume || 0); return sum + vol; }, 0); analysis += `Buy Volume: $${formatNumber(totalBuyVolume)}\n`; analysis += `Sell Volume: $${formatNumber(totalSellVolume)}\n`; // Calculate volume ratio if (totalSellVolume > 0) { const volumeRatio = totalBuyVolume / totalSellVolume; analysis += `Buy/Sell Volume Ratio: ${volumeRatio.toFixed(2)}\n`; } } return analysis; }

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/0xGval/evm-mcp-tools'

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