Skip to main content
Glama

getTokenPriceHistory

Retrieve historical price data for Ethereum tokens to analyze market trends and track performance over time.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
addressYes
networkIdNoNetwork ID (1 for Ethereum, 101 for Solana)
daysNoNumber of days of history
resolutionNoTime resolution (e.g. 1D, 1H, 60)1D

Implementation Reference

  • The core handler function that executes the tool: calculates unix timestamps for the requested period, fetches OHLCV chart data via fetchChartData helper from Codex GraphQL API, formats it using formatChartDataResponse, and returns formatted text response or error.
    async ({ address, networkId, days, resolution }) => { try { // Calculate time range const to = Math.floor(Date.now() / 1000); const from = to - (60 * 60 * 24 * days); // Get chart data from Codex API const chartData = await fetchChartData(address, networkId, resolution, from, to); if (!chartData || chartData.length === 0) { return { content: [{ type: "text", text: `No price history found for ${address} on network ${networkId}` }] }; } // Format the chart data for display const response = formatChartDataResponse(chartData); return { content: [{ type: "text", text: response }] }; } catch (error) { return { content: [{ type: "text", text: `Error fetching token price history: ${error.message}` }] }; } }
  • Zod input validation schema defining required token address, optional networkId (default 1), days (default 7), and resolution (default '1D').
    { 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(7).describe("Number of days of history"), resolution: z.string().default("1D").describe("Time resolution (e.g. 1D, 1H, 60)") },
  • MCP tool registration via server.tool() call within registerTokenAnalysisTools function, specifying name, input schema, and inline handler implementation.
    server.tool("getTokenPriceHistory", { 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(7).describe("Number of days of history"), resolution: z.string().default("1D").describe("Time resolution (e.g. 1D, 1H, 60)") }, async ({ address, networkId, days, resolution }) => { try { // Calculate time range const to = Math.floor(Date.now() / 1000); const from = to - (60 * 60 * 24 * days); // Get chart data from Codex API const chartData = await fetchChartData(address, networkId, resolution, from, to); if (!chartData || chartData.length === 0) { return { content: [{ type: "text", text: `No price history found for ${address} on network ${networkId}` }] }; } // Format the chart data for display const response = formatChartDataResponse(chartData); return { content: [{ type: "text", text: response }] }; } catch (error) { return { content: [{ type: "text", text: `Error fetching token price history: ${error.message}` }] }; } } );
  • Key helper that performs GraphQL query to Codex API (graph.codex.io) for historical price bars (OHLCV + volume, transactions, etc.), processes multi-field response into structured bar array.
    async function fetchChartData(address, networkId, resolution = '1D', from, to) { try { // Use API key from environment variable const apiKey = process.env.CODEX_API_KEY; if (!apiKey) { throw new Error("CODEX_API_KEY environment variable is not set"); } const response = await axios({ url: API_URL, method: 'post', headers: { 'Content-Type': 'application/json', 'Authorization': apiKey }, data: { query: `{ getBars( symbol: "${address}:${networkId}" from: ${from} to: ${to} resolution: "${resolution}" removeEmptyBars: true ) { t o h l c v volume transactions buyers sellers traders liquidity buyVolume sellVolume buys sells volumeNativeToken } }` } }); if (response.data && response.data.data && response.data.data.getBars) { const bars = response.data.data.getBars; // Process bars data if (Array.isArray(bars.t)) { // Multiple bars - restructure into an array of bar objects const result = []; for (let i = 0; i < bars.t.length; i++) { result.push({ t: bars.t[i], o: bars.o[i], h: bars.h[i], l: bars.l[i], c: bars.c[i], v: bars.v ? bars.v[i] : null, volume: bars.volume ? bars.volume[i] : null, transactions: bars.transactions ? bars.transactions[i] : null, buyers: bars.buyers ? bars.buyers[i] : null, sellers: bars.sellers ? bars.sellers[i] : null, traders: bars.traders ? bars.traders[i] : null, liquidity: bars.liquidity ? bars.liquidity[i] : null, buyVolume: bars.buyVolume ? bars.buyVolume[i] : null, sellVolume: bars.sellVolume ? bars.sellVolume[i] : null, buys: bars.buys ? bars.buys[i] : null, sells: bars.sells ? bars.sells[i] : null, volumeNativeToken: bars.volumeNativeToken ? bars.volumeNativeToken[i] : null }); } return result; } else if (typeof bars.t === 'number') { // Single bar return [{ t: bars.t, o: bars.o, h: bars.h, l: bars.l, c: bars.c, v: bars.v, volume: bars.volume, transactions: bars.transactions, buyers: bars.buyers, sellers: bars.sellers, traders: bars.traders, liquidity: bars.liquidity, buyVolume: bars.buyVolume, sellVolume: bars.sellVolume, buys: bars.buys, sells: bars.sells, volumeNativeToken: bars.volumeNativeToken }]; } } return []; } catch (error) { console.error('Error fetching chart data:', error.response?.data || error.message); throw new Error(`API error: ${error.response?.data?.errors?.[0]?.message || error.message}`); } }
  • Helper to format raw chart data into human-readable markdown table with OHLCV prices, volume, overall price change percentage, and aggregate trading stats.
    function formatChartDataResponse(data) { let response = `=== Price History ===\n`; response += `Date | Open | High | Low | Close | Volume\n`; response += `-----------|----------|----------|----------|----------|------------\n`; data.forEach(bar => { // Make sure all fields are present to avoid errors if (bar.t && bar.o !== undefined && bar.h !== undefined && bar.l !== undefined && bar.c !== undefined) { response += `${formatDate(bar.t)} | $${bar.o.toFixed(4).padEnd(8)} | $${bar.h.toFixed(4).padEnd(8)} | $${bar.l.toFixed(4).padEnd(8)} | $${bar.c.toFixed(4).padEnd(8)} | $${formatNumber(bar.volume || bar.v)}\n`; } }); // Display price change if (data.length > 1) { const firstPrice = data[0].o; const lastPrice = data[data.length - 1].c; const priceChange = ((lastPrice - firstPrice) / firstPrice) * 100; response += `\nPrice change over period: ${priceChange.toFixed(2)}%\n`; // Show basic trading activity response += '\n=== Recent Trading Activity ===\n'; const totalTransactions = data.reduce((sum, bar) => sum + (bar.transactions || 0), 0); const totalTraders = data.reduce((sum, bar) => sum + (bar.traders || 0), 0); response += `Total Transactions: ${totalTransactions}\n`; response += `Total Unique Traders: ${totalTraders}\n`; } return response; }

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