Skip to main content
Glama
mmarqueti

ActiveCampaign MCP Server

by mmarqueti

get_contact_tracking_logs

Retrieve event and tracking logs for a specific contact in ActiveCampaign. Filter by event type, date range, and paginate results for precise tracking data analysis.

Instructions

Busca os logs de eventos/tracking de um contato específico

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
contactIdYesID do contato para buscar os logs de eventos
dateRangeNoFiltrar por intervalo de datas
eventTypeNoFiltrar por tipo de evento específico (opcional)
limitNoLimite de resultados (padrão: 100, máximo: 100)
offsetNoOffset para paginação (padrão: 0)

Implementation Reference

  • The primary handler function that executes the tool logic: fetches tracking logs via API for a specific contact ID with optional filters, formats the data, and returns it in MCP content format.
    private async getContactTrackingLogs(
      contactId: string,
      options: TrackingOptions = {}
    ) {
      try {
        console.error(`[DEBUG] Buscando tracking logs para contato ID: ${contactId}`);
    
        const params: any = {
          limit: options.limit || 100,
          offset: options.offset || 0,
        };
    
        // Adicionar filtros opcionais
        if (options.eventType) {
          params.type = options.eventType;
        }
    
        if (options.dateRange?.start) {
          params.after = options.dateRange.start;
        }
    
        if (options.dateRange?.end) {
          params.before = options.dateRange.end;
        }
    
        const response = await this.apiClient.get(
          `/api/3/contacts/${contactId}/trackingLogs`,
          { params }
        );
    
        const trackingData = await this.formatTrackingLogs(response.data);
    
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(trackingData, null, 2),
            },
          ],
        };
      } catch (error) {
        console.error(`[ERROR] Erro ao buscar tracking logs:`, error);
        throw new Error(
          `Erro ao buscar logs de tracking: ${error instanceof Error ? error.message : 'Erro desconhecido'}`
        );
      }
    }
  • Tool definition object including name, description, and detailed input schema with properties for contactId (required), limit, offset, eventType (enum), and dateRange.
    {
      name: 'get_contact_tracking_logs',
      description: 'Busca os logs de eventos/tracking de um contato específico',
      inputSchema: {
        type: 'object',
        properties: {
          contactId: {
            type: 'string',
            description: 'ID do contato para buscar os logs de eventos',
          },
          limit: {
            type: 'number',
            description: 'Limite de resultados (padrão: 100, máximo: 100)',
            default: 100,
            maximum: 100,
          },
          offset: {
            type: 'number',
            description: 'Offset para paginação (padrão: 0)',
            default: 0,
          },
          eventType: {
            type: 'string',
            description: 'Filtrar por tipo de evento específico (opcional)',
            enum: [
              'open',
              'click',
              'sent',
              'bounce',
              'unsubscribe',
              'subscribe',
              'reply',
              'forward',
              'update',
              'deal_add',
              'deal_update',
              'deal_delete',
              'note_add',
              'task_add',
              'automation_start',
              'automation_complete'
            ]
          },
          dateRange: {
            type: 'object',
            description: 'Filtrar por intervalo de datas',
            properties: {
              start: {
                type: 'string',
                description: 'Data de início (formato: YYYY-MM-DD)',
              },
              end: {
                type: 'string',
                description: 'Data de fim (formato: YYYY-MM-DD)',
              },
            },
          },
        },
        required: ['contactId'],
      },
  • src/index.ts:68-71 (registration)
    Registration in the main MCP server CallTool handler: checks if the tool name matches and dispatches to TrackingTools.executeTool.
    const trackingToolNames = ['get_contact_tracking_logs', 'get_contact_tracking_logs_by_email'];
    if (trackingToolNames.includes(name)) {
      return await this.trackingTools.executeTool(name, args);
    }
  • src/index.ts:47-54 (registration)
    MCP ListTools handler registration that combines and returns tools from ContactTools and TrackingTools, including this tool's schema.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      const contactTools = this.contactTools.getTools();
      const trackingTools = this.trackingTools.getTools();
      
      return {
        tools: [...contactTools, ...trackingTools] as Tool[],
      };
    });
  • Helper function that processes raw API tracking logs: enriches with additional API calls for campaigns, formats timestamps, adds event descriptions, and creates summary.
    private async formatTrackingLogs(rawData: any): Promise<any> {
      const trackingLogs = rawData.trackingLogs || [];
      const meta = rawData.meta || {};
    
      // Buscar informações adicionais para enriquecer os dados
      const enrichedLogs = await Promise.all(
        trackingLogs.map(async (log: any) => {
          const enrichedLog: any = {
            id: log.id,
            type: log.type,
            timestamp: log.tstamp,
            date: this.formatTimestamp(log.tstamp),
            contact: log.contact,
            subscriberId: log.subscriberid,
            hash: log.hash,
            description: this.getEventDescription(log.type),
          };
    
          // Adicionar valor se existir
          if (log.value) {
            enrichedLog.value = log.value;
          }
    
          // Adicionar links se existirem
          if (log.links) {
            enrichedLog.links = log.links;
          }
    
          // Adicionar dados específicos baseados no tipo de evento (apenas se existirem)
          if (log.campaign) {
            try {
              const campaignResponse = await this.apiClient.get(`/api/3/campaigns/${log.campaign}`);
              enrichedLog.campaign = {
                id: log.campaign,
                name: campaignResponse.data.campaign?.name || 'N/A',
              };
            } catch (error) {
              enrichedLog.campaign = { id: log.campaign, name: 'N/A' };
            }
          }
    
          if (log.automation) {
            enrichedLog.automation = { id: log.automation };
          }
    
          if (log.email) {
            enrichedLog.email = { id: log.email };
          }
    
          if (log.link) {
            enrichedLog.link = { id: log.link };
          }
    
          if (log.eventdata) {
            enrichedLog.eventData = log.eventdata;
          }
    
          return enrichedLog;
        })
      );
    
      return {
        summary: {
          total: meta.total || trackingLogs.length,
          count: meta.count || trackingLogs.length,
          limit: meta.limit || 100,
          offset: meta.offset || 0,
          eventTypes: this.getEventTypeSummary(trackingLogs),
        },
        events: enrichedLogs,
      };
    }
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. While 'busca' (search) implies a read-only operation, the description doesn't clarify if this is safe (non-destructive), whether it requires specific permissions, or if there are rate limits. It also doesn't describe the return format (e.g., list of logs with fields) or pagination behavior beyond what the schema hints at with 'limit' and 'offset'. For a tool with no annotations, this leaves significant gaps in understanding its behavior.

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, clear sentence in Portuguese: 'Busca os logs de eventos/tracking de um contato específico.' It's front-loaded with the core purpose, has zero wasted words, and is appropriately sized for the tool's function. Every part of the sentence earns its place by specifying what is being searched and for what resource.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (5 parameters, no output schema, no annotations), the description is incomplete. It doesn't address behavioral aspects like safety or permissions, provide usage guidelines relative to siblings, or explain the output (since there's no output schema). For a tool that retrieves logs with filtering and pagination, more context is needed to help an agent use it effectively, especially with sibling tools like 'get_contact_tracking_logs_by_email' present.

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?

The schema description coverage is 100%, meaning all parameters are documented in the schema itself (e.g., 'contactId' for the contact ID, 'dateRange' for filtering by date, 'eventType' with enum values). The description doesn't add any additional meaning beyond this, such as explaining parameter interactions or usage examples. With high schema coverage, the baseline score is 3, as the description doesn't compensate but also doesn't detract.

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 tool's purpose: 'Busca os logs de eventos/tracking de um contato específico' (Search the event/tracking logs of a specific contact). It specifies the verb 'busca' (search) and the resource 'logs de eventos/tracking' (event/tracking logs), and distinguishes it from siblings like 'get_contact_by_email' or 'search_contacts' by focusing on logs rather than contact details. However, it doesn't explicitly differentiate from 'get_contact_tracking_logs_by_email', which appears to be a similar tool with a different parameter approach.

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. It doesn't mention siblings like 'get_contact_tracking_logs_by_email' or explain scenarios where this tool is preferred over others (e.g., when you have a contact ID vs. email). There's also no information about prerequisites, such as needing an existing contact, or exclusions for usage.

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/mmarqueti/activecampaign-mcp-server'

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