Skip to main content
Glama
andrealufino

aapl-ads-mcp

list_campaigns

List Apple Search Ads campaigns with metadata: id, name, status, budget, country, channel type. Filter by status and paginate using limit/offset. For campaign inventory management, not performance metrics.

Instructions

List all campaigns in the configured Apple Search Ads organization. Requires ASA authentication; read-only. Returns campaign metadata (id, name, status, budget, country, channel type) but not performance metrics — use get_campaign_report for metrics. Optionally filter by status. Supports pagination via limit/offset; default limit 20, max 1000.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
statusNoFilter results to campaigns with this status. Omit to return all statuses.
limitNoMax campaigns to return (1–1000). Defaults to 20.
offsetNoZero-based page offset for pagination. Defaults to 0.

Implementation Reference

  • The async handler function that executes the list_campaigns tool logic: parses args (status, limit, offset), builds the API path, calls client.getPaginated<Campaign[]> on '/campaigns', validates response data with CampaignOutputSchema, and returns the result as formatted JSON.
      async (args) => {
        const { status, limit, offset } = ListCampaignsInputSchema.parse(args);
    
        let path = "/campaigns";
        if (status !== undefined) {
          path += `?status=${status}`;
        }
    
        const response = await client.getPaginated<Campaign[]>(path, { limit, offset });
        const campaigns = Array.isArray(response.data) ? response.data : [];
    
        const result = {
          pagination: response.pagination,
          campaigns: campaigns.map((c) => CampaignOutputSchema.parse(c)),
        };
    
        return {
          content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
        };
      }
    );
  • The registerCampaignsTools function registers the list_campaigns tool on the MCP server with its name, description, input schema (status, limit, offset), and the async handler.
    /** Registers the list_campaigns tool. */
    export function registerCampaignsTools(server: McpServer, client: AsaClient): void {
      server.tool(
        "list_campaigns",
        "List all campaigns in the configured Apple Search Ads organization. Requires ASA authentication; read-only. Returns campaign metadata (id, name, status, budget, country, channel type) but not performance metrics — use get_campaign_report for metrics. Optionally filter by status. Supports pagination via limit/offset; default limit 20, max 1000.",
        {
          status: z
            .enum(["ENABLED", "PAUSED", "DELETED"])
            .optional()
            .describe("Filter results to campaigns with this status. Omit to return all statuses."),
          limit: z
            .number()
            .int()
            .min(1)
            .max(1000)
            .optional()
            .describe("Max campaigns to return (1–1000). Defaults to 20."),
          offset: z
            .number()
            .int()
            .min(0)
            .optional()
            .describe("Zero-based page offset for pagination. Defaults to 0."),
        },
        async (args) => {
          const { status, limit, offset } = ListCampaignsInputSchema.parse(args);
    
          let path = "/campaigns";
          if (status !== undefined) {
            path += `?status=${status}`;
          }
    
          const response = await client.getPaginated<Campaign[]>(path, { limit, offset });
          const campaigns = Array.isArray(response.data) ? response.data : [];
    
          const result = {
            pagination: response.pagination,
            campaigns: campaigns.map((c) => CampaignOutputSchema.parse(c)),
          };
    
          return {
            content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
          };
        }
      );
    }
  • CampaignOutputSchema defines the shape of each campaign returned by list_campaigns (id, orgId, name, status, budget, etc.), used to parse/validate API response data.
    export const CampaignOutputSchema = z.object({
      id: z.number(),
      orgId: z.number(),
      name: z.string(),
      status: z.enum(["ENABLED", "PAUSED", "DELETED"]),
      servingStatus: z.string().nullable(),
      adamId: z.number(),
      budgetAmount: MoneySchema,
      dailyBudgetAmount: MoneySchema.optional(),
      countriesOrRegions: z.array(z.string()),
      supplySources: z.array(z.string()),
      adChannelType: z.string(),
      billingEvent: z.string(),
      startTime: z.string(),
      endTime: z.string().nullable().optional(),
      creationTime: z.string(),
      modificationTime: z.string(),
    });
  • ListCampaignsInputSchema defines and validates the input parameters for list_campaigns: optional status filter (ENABLED/PAUSED/DELETED), limit (1-1000, default 20), and offset (min 0, default 0).
    export const ListCampaignsInputSchema = z.object({
      status: z.enum(["ENABLED", "PAUSED", "DELETED"]).optional().describe("Filter by campaign status"),
      limit: z
        .number()
        .int()
        .min(1)
        .max(1000)
        .optional()
        .default(20)
        .describe("Max results to return (1–1000)"),
      offset: z
        .number()
        .int()
        .min(0)
        .optional()
        .default(0)
        .describe("Zero-based offset for pagination"),
    });
  • The getPaginated helper method used by list_campaigns to make a GET request with offset-based pagination query parameters (limit/offset) appended to the API path.
    async getPaginated<T>(
      path: string,
      pagination: PaginationParams = {}
    ): Promise<AsaApiResponse<T>> {
      const limit = pagination.limit ?? 20;
      const offset = pagination.offset ?? 0;
      const separator = path.includes("?") ? "&" : "?";
      return this.request<T>("GET", `${path}${separator}limit=${limit}&offset=${offset}`);
    }
Behavior5/5

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

Discloses read-only nature, authentication requirement, returned fields, pagination behavior with default and max limit, and explicitly states what is not returned (performance metrics).

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?

Two sentences with all critical information front-loaded; no unnecessary words, efficient use of space.

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

Completeness5/5

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

Fully describes return value (fields listed), excludes performance metrics, notes authentication, and covers pagination details. No missing information for a list tool without output schema.

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?

Input schema has 100% coverage with descriptions; the description reiterates filter and pagination options but does not add new semantic meaning beyond the schema.

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 explicitly states the tool lists campaigns in the Apple Search Ads organization, specifies the resource and scope, and distinguishes from sibling tool get_campaign_report by noting it returns metadata not performance metrics.

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

Usage Guidelines5/5

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

Provides clear guidance on when to use this tool (for campaign metadata) and when to use an alternative (get_campaign_report for metrics), along with optional filtering and pagination details.

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/andrealufino/aapl-ads-mcp'

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