Skip to main content
Glama
EfrainTorres

ArmaVita Meta Ads MCP

clone_ad_set

Duplicate Meta ad sets to replicate targeting, budget, and creative configurations for testing or scaling campaigns.

Instructions

Duplicate an ad set using Meta's local Graph copy edge.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ad_set_idYes
meta_access_tokenNo
target_campaign_idNo
name_suffixNo - Copy
include_adsNo
include_creativesNo
new_daily_budgetNo
new_targetingNo
new_statusNoPAUSED

Implementation Reference

  • The tool handler function `clone_ad_set` which implements the logic for duplicating an ad set by calling `_forward_duplication_request`.
    async def clone_ad_set(
        ad_set_id: str,
        meta_access_token: Optional[str] = None,
        target_campaign_id: Optional[str] = None,
        name_suffix: Optional[str] = " - Copy",
        include_ads: bool = True,
        include_creatives: bool = True,
        new_daily_budget: Optional[float] = None,
        new_targeting: Optional[Dict[str, Any]] = None,
        new_status: Optional[str] = "PAUSED",
    ) -> str:
        """Duplicate an ad set using Meta's local Graph copy edge."""
        return await _forward_duplication_request(
            "adset",
            ad_set_id,
            meta_access_token,
            {
                "target_campaign_id": target_campaign_id,
                "name_suffix": name_suffix,
                "include_ads": include_ads,
                "include_creatives": include_creatives,
                "new_daily_budget": new_daily_budget,
                "new_targeting": new_targeting,
                "new_status": new_status,
            },
        )
  • Registration of `clone_ad_set` as an MCP tool using `@mcp_server.tool()` and `@meta_api_tool`.
    @mcp_server.tool()
    @meta_api_tool
    async def clone_ad_set(
        ad_set_id: str,
        meta_access_token: Optional[str] = None,
        target_campaign_id: Optional[str] = None,
        name_suffix: Optional[str] = " - Copy",
        include_ads: bool = True,
        include_creatives: bool = True,
        new_daily_budget: Optional[float] = None,
        new_targeting: Optional[Dict[str, Any]] = None,
        new_status: Optional[str] = "PAUSED",
    ) -> str:
        """Duplicate an ad set using Meta's local Graph copy edge."""
        return await _forward_duplication_request(
            "adset",
            ad_set_id,
            meta_access_token,
            {
                "target_campaign_id": target_campaign_id,
                "name_suffix": name_suffix,
                "include_ads": include_ads,
                "include_creatives": include_creatives,
                "new_daily_budget": new_daily_budget,
                "new_targeting": new_targeting,
                "new_status": new_status,
            },
        )
    
    
    @mcp_server.tool()
  • Helper function that performs the actual API request to the Meta Graph API copy edge for all duplication tools.
    async def _forward_duplication_request(
        resource_type: str,
        resource_id: str,
        meta_access_token: Optional[str],
        options: Dict[str, Any],
    ) -> str:
        """Execute OSS-local duplication against Graph API copy edges."""
        try:
            facebook_token = meta_access_token if meta_access_token else await auth.get_current_access_token()
            if not facebook_token:
                raise DuplicationError(
                    json.dumps(
                        {
                            "success": False,
                            "error": "authentication_required",
                            "message": "Meta Ads access token not found",
                            "details": {
                                "required": "Valid Meta access token",
                                "check": "Authenticate and retry duplication request.",
                            },
                        },
                        indent=2,
                    )
                )
    
            preflight_block = await _run_v25_duplication_preflight(resource_type, resource_id, facebook_token)
            if preflight_block:
                raise DuplicationError(
                    json.dumps(
                        {
                            "success": False,
                            "error": "v25_blocked_operation",
                            "message": "Duplication is blocked for deprecated Advantage+ Shopping/App campaign flows in v25.",
                            "details": {
                                "resource_type": resource_type,
                                "resource_id": resource_id,
                                "campaign_id": preflight_block.get("campaign_id"),
                                "campaign_name": preflight_block.get("campaign_name"),
                                "campaign_objective": preflight_block.get("campaign_objective"),
                                "smart_promotion_type": preflight_block.get("smart_promotion_type"),
                                "reason": preflight_block.get("reason"),
                            },
                            "suggestion": (
                                "Use supported Advantage+ migration or rebuild the campaign with v25-compatible "
                                "flows before attempting duplication."
                            ),
                        },
                        indent=2,
                    )
                )
    
            copy_params, warnings = _build_copy_params(resource_type, options)
            endpoint = f"{resource_id}/copies"
    
            data = await make_api_request(endpoint, facebook_token, copy_params, method="POST")
            if not isinstance(data, dict):
                raise DuplicationError(
                    json.dumps(
                        {
                            "success": False,
                            "error": "duplication_failed",
                            "message": "Unexpected response from Graph API copy edge",
                            "details": {
                                "resource_type": resource_type,
                                "resource_id": resource_id,
                                "response_type": type(data).__name__,
                            },
                        },
                        indent=2,
                    )
                )
    
            graph_error = data.get("error") if isinstance(data.get("error"), dict) else None
            if graph_error:
                code = graph_error.get("code")
                if code == 4:
                    raise RateLimitError(
                        json.dumps(
                            {
                                "error": "rate_limit_exceeded",
                                "message": graph_error.get("message") or graph_error.get("primary_text", "Meta API rate limit exceeded"),
                                "details": {
                                    "code": code,
                                    "error_subcode": graph_error.get("error_subcode"),
                                    "retry_hint": "Retry with backoff.",
                                },
                            },
                            indent=2,
                        )
                    )
    
                raise DuplicationError(
                    json.dumps(
                        _build_graph_error_payload(resource_type, resource_id, graph_error),
                        indent=2,
                    )
                )
    
            new_id = _extract_new_id(resource_type, data)
            success = bool(new_id) or bool(data.get("success") is True)
    
            return json.dumps(
                {
                    "success": success,
                    "source_id": resource_id,
                    "resource_type": resource_type,
                    "new_id": new_id,
                    "warnings": warnings,
                    "meta_response": data,
                },
                indent=2,
            )

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/EfrainTorres/armavita-meta-ads-mcp'

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