google_ads_create_ad_group
Create a new ad group in a Google Ads campaign by specifying campaign ID, ad group name, and optional cost-per-click bid. Ad group is created paused for safety.
Instructions
Create a new ad group within a campaign.
Args: customer_id: Customer ID (without hyphens) campaign_id: Campaign ID to create ad group in ad_group_name: Name for the ad group cpc_bid: Cost-per-click bid in currency units (e.g., 1.50 for $1.50) status: Initial status (ENABLED or PAUSED, default: PAUSED) ad_group_type: Optional ad group type (SEARCH_STANDARD, DISPLAY_STANDARD, etc.)
Returns: Success message with ad group details
Note: Ad groups are created PAUSED by default for safety.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| customer_id | Yes | ||
| campaign_id | Yes | ||
| ad_group_name | Yes | ||
| cpc_bid | No | ||
| status | No | PAUSED | |
| ad_group_type | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- The MCP tool handler that creates an ad group. Validates inputs, builds an AdGroupConfig, delegates to AdGroupManager.create_ad_group(), logs the operation, invalidates cache, and returns a formatted success/error message.
@mcp.tool() def google_ads_create_ad_group( customer_id: str, campaign_id: str, ad_group_name: str, cpc_bid: Optional[float] = None, status: str = "PAUSED", ad_group_type: Optional[str] = None ) -> str: """ Create a new ad group within a campaign. Args: customer_id: Customer ID (without hyphens) campaign_id: Campaign ID to create ad group in ad_group_name: Name for the ad group cpc_bid: Cost-per-click bid in currency units (e.g., 1.50 for $1.50) status: Initial status (ENABLED or PAUSED, default: PAUSED) ad_group_type: Optional ad group type (SEARCH_STANDARD, DISPLAY_STANDARD, etc.) Returns: Success message with ad group details Note: Ad groups are created PAUSED by default for safety. """ with performance_logger.track_operation('create_ad_group', customer_id=customer_id): try: client = get_auth_manager().get_client() ad_group_manager = AdGroupManager(client) # Convert bid to micros cpc_bid_micros = int(cpc_bid * 1_000_000) if cpc_bid else None # Create config config = AdGroupConfig( name=ad_group_name, campaign_id=campaign_id, status=AdGroupStatus[status.upper()], cpc_bid_micros=cpc_bid_micros, ad_group_type=AdGroupType[ad_group_type.upper()] if ad_group_type else None ) # Create ad group result = ad_group_manager.create_ad_group(customer_id, config) # Audit log audit_logger.log_api_call( customer_id=customer_id, operation="create_ad_group", resource_type="ad_group", resource_id=result['ad_group_id'], action="create", result="success", details={ 'name': ad_group_name, 'campaign_id': campaign_id, 'cpc_bid': cpc_bid } ) # Invalidate cache get_cache_manager().invalidate(customer_id, ResourceType.AD_GROUP) output = f"✅ Ad group created successfully!\n\n" output += f"**Ad Group ID**: {result['ad_group_id']}\n" output += f"**Name**: {ad_group_name}\n" output += f"**Campaign ID**: {campaign_id}\n" output += f"**Status**: {status}\n" if cpc_bid: output += f"**CPC Bid**: ${cpc_bid:.2f}\n" output += f"\n" output += f"Ad group is now {status.lower()}. " output += f"Next steps:\n" output += f"1. Add keywords to the ad group\n" output += f"2. Create ads\n" output += f"3. Enable the ad group when ready" return output except Exception as e: error_msg = ErrorHandler.handle_error(e, context="create_ad_group") return f"❌ Failed to create ad group: {error_msg}" - tools/ad_groups/mcp_tools_ad_groups.py:24-26 (registration)The @mcp.tool() decorator on line 31 registers google_ads_create_ad_group as an MCP tool. This registration is triggered by register_ad_group_tools() which is called from google_ads_mcp.py via _register_all_modular_tools().
def register_ad_group_tools(mcp: FastMCP): """Register ad group management tools with MCP server.""" - managers/ad_group_manager.py:44-56 (schema)Data class schema for ad group configuration, including name, campaign_id, status, CPC bid (in micros), ad_group_type, and other bid types.
@dataclass class AdGroupConfig: """Configuration for creating an ad group.""" name: str campaign_id: str status: AdGroupStatus = AdGroupStatus.PAUSED cpc_bid_micros: Optional[int] = None # Manual CPC bid cpm_bid_micros: Optional[int] = None # CPM bid (display) cpv_bid_micros: Optional[int] = None # CPV bid (video) target_cpa_micros: Optional[int] = None # Target CPA percent_cpc_bid_micros: Optional[int] = None # Enhanced CPC ad_group_type: Optional[AdGroupType] = None - managers/ad_group_manager.py:78-140 (helper)The AdGroupManager.create_ad_group() helper that executes the Google Ads API call to mutate/create an ad group, including setting campaign path, status, type, and bid fields.
def create_ad_group( self, customer_id: str, config: AdGroupConfig ) -> Dict[str, Any]: """ Create a new ad group. Args: customer_id: Customer ID config: Ad group configuration Returns: Created ad group details """ ad_group_service = self.client.get_service("AdGroupService") campaign_service = self.client.get_service("CampaignService") # Create operation ad_group_operation = self.client.get_type("AdGroupOperation") ad_group = ad_group_operation.create # Set basic fields ad_group.name = config.name ad_group.campaign = campaign_service.campaign_path( customer_id, config.campaign_id ) ad_group.status = self.client.enums.AdGroupStatusEnum[config.status.value] # Set ad group type if specified if config.ad_group_type: ad_group.type_ = self.client.enums.AdGroupTypeEnum[config.ad_group_type.value] # Set bidding (only set the relevant bid type) if config.cpc_bid_micros is not None: ad_group.cpc_bid_micros = config.cpc_bid_micros elif config.cpm_bid_micros is not None: ad_group.cpm_bid_micros = config.cpm_bid_micros elif config.cpv_bid_micros is not None: ad_group.cpv_bid_micros = config.cpv_bid_micros elif config.target_cpa_micros is not None: ad_group.target_cpa_micros = config.target_cpa_micros elif config.percent_cpc_bid_micros is not None: ad_group.percent_cpc_bid_micros = config.percent_cpc_bid_micros # Create ad group response = ad_group_service.mutate_ad_groups( customer_id=customer_id, operations=[ad_group_operation] ) ad_group_resource_name = response.results[0].resource_name ad_group_id = ad_group_resource_name.split("/")[-1] logger.info(f"Created ad group: {ad_group_id} in campaign {config.campaign_id}") return { "ad_group_id": ad_group_id, "resource_name": ad_group_resource_name, "name": config.name, "campaign_id": config.campaign_id, "status": config.status.value } - google_ads_mcp.py:480-495 (registration)Top-level registration entry: google_ads_mcp.py lists ad_groups module with register_ad_group_tools, which is imported and called by _register_all_modular_tools() to register all tools including google_ads_create_ad_group.
_TOOL_MODULES = [ ("campaigns", "tools.campaigns.mcp_tools_campaigns", "register_campaign_tools"), ("ad_groups", "tools.ad_groups.mcp_tools_ad_groups", "register_ad_group_tools"), ("keywords", "tools.keywords.mcp_tools_keywords", "register_keyword_tools"), ("ads", "tools.ads.mcp_tools_ads", "register_ad_tools"), ("bidding", "tools.bidding.mcp_tools_bidding", "register_bidding_tools"), ("automation", "tools.automation.mcp_tools_automation", "register_automation_tools"), ("audiences", "tools.audiences.mcp_tools_audiences", "register_audience_tools"), ("conversions", "tools.conversions.mcp_tools_conversions", "register_conversion_tools"), ("reporting", "tools.reporting.mcp_tools_reporting", "register_reporting_tools"), ("insights", "tools.insights.mcp_tools_insights", "register_insights_tools"), ("batch", "tools.batch.mcp_tools_batch", "register_batch_tools"), ("shopping_pmax", "tools.shopping_pmax.mcp_tools_shopping_pmax", "register_shopping_pmax_tools"), ("extensions", "tools.extensions.mcp_tools_extensions", "register_extension_tools"), ("local_app", "tools.local_app.mcp_tools_local_app", "register_local_app_tools"), ]