Skip to main content
Glama
zarelli1

MCP DeFiLlama Airdrops

by zarelli1

get_airdrops

Fetch and filter cryptocurrency airdrop data from DeFiLlama. Retrieve active airdrops, filter by blockchain, and refresh cached data for updated results.

Instructions

Buscar todos os airdrops disponíveis no DeFiLlama

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chainNoFiltrar por blockchain específica
forceRefreshNoForçar atualização dos dados (ignorar cache)
onlyActiveNoRetornar apenas airdrops ativos

Implementation Reference

  • The main handler for the 'get_airdrops' tool. Manages caching with a 5-minute timeout, scrapes fresh data from DeFiLlama if needed using the scraper, applies optional filters for active airdrops and specific chains, and returns a JSON-formatted response with total count, last update time, and the list of airdrops.
    private async getAirdrops(args: { forceRefresh?: boolean; onlyActive?: boolean; chain?: string }) {
      const shouldRefresh = args.forceRefresh || 
                           !this.lastUpdate || 
                           (Date.now() - this.lastUpdate.getTime()) > this.cacheTimeout;
    
      if (shouldRefresh) {
        console.log('Atualizando cache de airdrops...');
        this.cachedAirdrops = await this.scraper.scrapeAirdrops();
        this.lastUpdate = new Date();
      }
    
      let airdrops = [...this.cachedAirdrops];
    
      // Aplicar filtros
      if (args.onlyActive) {
        airdrops = airdrops.filter(a => a.status?.toLowerCase().includes('active') || a.status?.toLowerCase().includes('ativo'));
      }
    
      if (args.chain) {
        airdrops = airdrops.filter(a => a.chain?.toLowerCase().includes(args.chain!.toLowerCase()));
      }
    
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify({
              total: airdrops.length,
              lastUpdate: this.lastUpdate?.toISOString(),
              airdrops: airdrops
            }, null, 2)
          }
        ]
      };
    }
  • src/index.ts:40-62 (registration)
    Registration of the 'get_airdrops' tool in the ListToolsRequestSchema handler, including name, description, and input schema definition.
    {
      name: 'get_airdrops',
      description: 'Buscar todos os airdrops disponíveis no DeFiLlama',
      inputSchema: {
        type: 'object',
        properties: {
          forceRefresh: {
            type: 'boolean',
            description: 'Forçar atualização dos dados (ignorar cache)',
            default: false
          },
          onlyActive: {
            type: 'boolean',
            description: 'Retornar apenas airdrops ativos',
            default: false
          },
          chain: {
            type: 'string',
            description: 'Filtrar por blockchain específica'
          }
        }
      }
    },
  • src/index.ts:125-126 (registration)
    Registration in the CallToolRequestSchema switch statement that routes calls to the getAirdrops handler.
    case 'get_airdrops':
      return await this.getAirdrops(args as any);
  • Zod schema defining the structure of Airdrop objects used throughout the codebase for type safety and validation.
    export const AirdropSchema = z.object({
      name: z.string(),
      description: z.string().optional(),
      value: z.string().optional(),
      status: z.string(),
      deadline: z.string().optional(),
      requirements: z.array(z.string()).optional(),
      url: z.string().optional(),
      category: z.string().optional(),
      chain: z.string().optional(),
      estimatedValue: z.string().optional(),
      difficulty: z.string().optional(),
      lastUpdated: z.string().optional(),
      // Novos campos DeFiLlama
      tvl: z.string().optional(),
      listedAt: z.string().optional(),
      change1d: z.string().optional(),
      change7d: z.string().optional(),
      change1m: z.string().optional(),
      logo: z.string().optional(),
      symbol: z.string().optional(),
      mcap: z.string().optional()
    });
  • Core helper function scrapeAirdrops() called by the handler to fetch airdrop data. Attempts direct page scraping with Cheerio, falls back to DeFiLlama protocols API conversion, and uses hardcoded fallback data if all else fails.
    async scrapeAirdrops(options: ScrapingOptions = {}): Promise<Airdrop[]> {
      try {
        console.log('🚀 Fazendo scraping da página de airdrops DeFiLlama...');
        
        // Tentar múltiplas abordagens para obter dados de airdrops
        let airdrops: Airdrop[] = [];
        
        try {
          // Primeira tentativa: scraping direto da página
          airdrops = await this.scrapeAirdropsPage();
          if (airdrops.length > 0) {
            console.log(`✅ Extraídos ${airdrops.length} airdrops via scraping direto`);
            return airdrops;
          }
        } catch (error) {
          console.log('⚠️ Scraping direto falhou, tentando API alternativa...');
        }
        
        try {
          // Segunda tentativa: usar API de protocolos e inferir airdrops
          const protocols = await this.scrapeProtocols();
          airdrops = await this.convertProtocolsToAirdrops(protocols);
          console.log(`✅ Gerados ${airdrops.length} airdrops potenciais via API`);
          return airdrops;
        } catch (error) {
          console.log('⚠️ API de protocolos falhou, usando dados de exemplo...');
        }
        
        // Fallback: dados conhecidos de airdrops reais
        return this.getFallbackAirdrops();
        
      } catch (error) {
        console.error('❌ Erro durante scraping:', error);
        return this.getFallbackAirdrops();
      }
    }
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It mentions searching airdrops on DeFiLlama but doesn't describe return format, pagination, rate limits, authentication needs, or what 'disponíveis' (available) entails operationally. This leaves significant behavioral gaps.

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 a single, efficient sentence in Portuguese that directly states the tool's purpose without any wasted words. It's appropriately sized and front-loaded with the core functionality.

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 no annotations and no output schema, the description is minimally adequate for a read operation but lacks details on return values, error handling, or behavioral constraints. It covers the basic purpose but doesn't fully compensate for the missing structured data.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all three parameters thoroughly. The description adds no additional parameter semantics beyond what's in the schema, meeting the baseline for high coverage but not providing extra value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Buscar' meaning 'Search') and resource ('todos os airdrops disponíveis no DeFiLlama'), providing specific verb+resource. However, it doesn't explicitly differentiate from sibling tools like 'filter_airdrops' or 'get_best_airdrops', which prevents a perfect score.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives like 'filter_airdrops' or 'get_best_airdrops'. There's no mention of prerequisites, context, or exclusions, leaving the agent without usage direction.

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

Related 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/zarelli1/mcp-defillama-airdrops'

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