Skip to main content
Glama
ZLeventer

linkedin-campaign-manager-mcp

li_get_video_analytics

Retrieve video-specific performance metrics for LinkedIn campaigns, including video starts, views, and quartile completions. Compute video completion rates to evaluate ad quality. Scope to specific campaigns or report at account level.

Instructions

Fetch video-specific performance metrics for LinkedIn campaigns, broken down by creative. Returns videoStarts, videoViews, videoFirstQuartileCompletions, videoMidpointCompletions, videoThirdQuartileCompletions, videoCompletions, plus a computed videoCompletionRate (completions / starts × 100). Use to evaluate video ad quality — high completion rates indicate compelling content; low rates signal drop-off. Scope to specific campaigns via campaign_ids or report at account level.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
campaign_idsNoCampaign numeric IDs or URNs to scope the report. Omit to report at account level.
ad_account_idNo
start_dateNo28daysAgo
end_dateNoyesterday
time_granularityNoALL

Implementation Reference

  • The getVideoAnalytics async function that executes the tool logic: resolves dates, builds analytics URL with CREATIVE pivot and VIDEO_FIELDS, fetches raw data via liGetRaw, enriches each element with a computed videoCompletionRate, and returns the enriched response.
    export async function getVideoAnalytics(args: {
      campaign_ids?: string[];
      ad_account_id?: string;
      start_date?: string;
      end_date?: string;
      time_granularity?: (typeof TIME_GRANULARITIES)[number];
    }): Promise<AnalyticsResponse & { enriched?: unknown[] }> {
      const start = resolveDate(args.start_date ?? DEFAULT_START);
      const end = resolveDate(args.end_date ?? DEFAULT_END);
    
      const campaignUrns = args.campaign_ids?.map((id) => urn("sponsoredCampaign", id));
      const accountUrn =
        campaignUrns && campaignUrns.length > 0
          ? undefined
          : resolveAdAccount(args.ad_account_id);
    
      const url = buildAnalyticsUrl({
        pivot: "CREATIVE",
        timeGranularity: args.time_granularity ?? "ALL",
        start,
        end,
        fields: VIDEO_FIELDS,
        campaignUrns,
        accountUrn,
      });
    
      const raw = await liGetRaw<AnalyticsResponse>(url);
    
      // Compute completion rate per creative
      const enriched = (raw.elements ?? []).map((row) => {
        const starts = Number(row["videoStarts"] ?? row["videoViews"] ?? 0);
        const completions = Number(row["videoCompletions"] ?? 0);
        return {
          ...row,
          videoCompletionRate: starts > 0 ? Math.round((completions / starts) * 10000) / 100 : null,
        };
      });
    
      return { ...raw, enriched };
    }
  • The getVideoAnalyticsSchema Zod schema defining input parameters: optional campaign_ids, optional ad_account_id, start_date (defaults to DEFAULT_START), end_date (defaults to DEFAULT_END), and time_granularity (defaults to 'ALL').
    // ─── get-video-analytics ────────────────────────────────────────────────────
    
    export const getVideoAnalyticsSchema = {
      campaign_ids: z
        .array(z.string())
        .optional()
        .describe("Campaign numeric IDs or URNs to scope the report. Omit to report at account level."),
      ad_account_id: z.string().optional(),
      start_date: z.string().default(DEFAULT_START),
      end_date: z.string().default(DEFAULT_END),
      time_granularity: z.enum(TIME_GRANULARITIES).default("ALL"),
    };
  • VIDEO_FIELDS constant defining the video-specific metric fields requested from the LinkedIn API: impressions, clicks, costInUsd, videoViews, videoFirstQuartileCompletions, videoMidpointCompletions, videoThirdQuartileCompletions, videoCompletions, videoStarts.
    const VIDEO_FIELDS = [
      "impressions",
      "clicks",
      "costInUsd",
      "videoViews",
      "videoFirstQuartileCompletions",
      "videoMidpointCompletions",
      "videoThirdQuartileCompletions",
      "videoCompletions",
      "videoStarts",
    ].join(",");
  • The buildAnalyticsUrl helper function that constructs the LinkedIn adAnalytics API URL with query parameters for pivot, timeGranularity, dateRange, fields, and either campaigns or accounts scope.
    function buildAnalyticsUrl(opts: {
      pivot: string;
      timeGranularity: string;
      start: ReturnType<typeof resolveDate>;
      end: ReturnType<typeof resolveDate>;
      fields: string;
      campaignUrns?: string[];
      accountUrn?: string;
    }): string {
      const qs: string[] = [
        "q=statistics",
        `pivot=${opts.pivot}`,
        `timeGranularity=${opts.timeGranularity}`,
        `dateRange=${encodeURIComponent(dateRangeParam(opts.start, opts.end))}`,
        `fields=${opts.fields}`,
      ];
      if (opts.campaignUrns && opts.campaignUrns.length > 0) {
        qs.push(`campaigns=${encodeURIComponent(listParam(opts.campaignUrns))}`);
      } else if (opts.accountUrn) {
        qs.push(`accounts=${encodeURIComponent(listParam([opts.accountUrn]))}`);
      }
      return `${BASE_URL}/adAnalytics?${qs.join("&")}`;
    }
  • src/index.ts:132-137 (registration)
    Tool registration using server.tool() with name 'li_get_video_analytics', description, schema, and handler that calls getVideoAnalytics and wraps the result with ok/err.
    server.tool(
      "li_get_video_analytics",
      "Fetch video-specific performance metrics for LinkedIn campaigns, broken down by creative. Returns videoStarts, videoViews, videoFirstQuartileCompletions, videoMidpointCompletions, videoThirdQuartileCompletions, videoCompletions, plus a computed videoCompletionRate (completions / starts × 100). Use to evaluate video ad quality — high completion rates indicate compelling content; low rates signal drop-off. Scope to specific campaigns via campaign_ids or report at account level.",
      getVideoAnalyticsSchema,
      async (args) => { try { return ok(await getVideoAnalytics(args)); } catch (e) { return err(e); } }
    );
Behavior3/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. It describes what data is returned but does not mention side effects, rate limits, auth requirements, or whether it is read-only (though implied). Basic transparency is present but lacks depth.

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?

Three sentences with no fluff. The first sentence front-loads purpose and return fields, the second gives usage guidance, and the third explains scoping. Every sentence is essential and well-structured.

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

Completeness4/5

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

Given no output schema and moderate complexity, the description covers return metrics, interpretation, and scoping. Missing details like response format, pagination, or time zone handling. Still fairly complete for a read-only analytics tool.

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 coverage is only 20% (one parameter described). The description adds value by explaining campaign_ids: 'Scope to specific campaigns via campaign_ids or report at account level.' However, other parameters (ad_account_id, dates, time_granularity) receive no explanation. The description partially compensates for low schema coverage but not fully.

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

Purpose5/5

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

The description clearly states it fetches video-specific performance metrics for LinkedIn campaigns, broken down by creative. It lists specific metrics and distinguishes from sibling tools like li_get_campaign_performance by specifying 'video-specific' and 'broken down by creative'.

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

Usage Guidelines4/5

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

The description gives explicit use cases: 'Use to evaluate video ad quality — high completion rates indicate compelling content; low rates signal drop-off.' It also explains scoping options via campaign_ids or account level. However, it does not mention when not to use this tool or compare directly with siblings.

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

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/ZLeventer/linkedin-campaign-manager-mcp'

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