Skip to main content
Glama
johnoconnor0

Google Ads MCP Server

by johnoconnor0

google_ads_update_ad_group_bid

Update the maximum cost-per-click (CPC) bid for a specific ad group in Google Ads to adjust ad spend.

Instructions

Update ad group CPC bid.

Args: customer_id: Customer ID (without hyphens) ad_group_id: Ad group ID cpc_bid: New CPC bid in currency units (e.g., 1.50 for $1.50)

Returns: Success message with bid details

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
customer_idYes
ad_group_idYes
cpc_bidYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • MCP tool handler for google_ads_update_ad_group_bid. Accepts customer_id, ad_group_id, and cpc_bid (float), converts to micros, calls AdGroupManager.update_ad_group_cpc_bid(), logs to audit, invalidates cache, and returns a success message with the new bid.
    def google_ads_update_ad_group_bid(
        customer_id: str,
        ad_group_id: str,
        cpc_bid: float
    ) -> str:
        """
        Update ad group CPC bid.
    
        Args:
            customer_id: Customer ID (without hyphens)
            ad_group_id: Ad group ID
            cpc_bid: New CPC bid in currency units (e.g., 1.50 for $1.50)
    
        Returns:
            Success message with bid details
        """
        with performance_logger.track_operation('update_ad_group_bid', customer_id=customer_id):
            try:
                client = get_auth_manager().get_client()
                ad_group_manager = AdGroupManager(client)
    
                cpc_bid_micros = int(cpc_bid * 1_000_000)
    
                result = ad_group_manager.update_ad_group_cpc_bid(
                    customer_id,
                    ad_group_id,
                    cpc_bid_micros
                )
    
                # Audit log
                audit_logger.log_api_call(
                    customer_id=customer_id,
                    operation="update_ad_group_bid",
                    resource_type="ad_group",
                    resource_id=ad_group_id,
                    action="update",
                    result="success",
                    details={'new_cpc_bid': cpc_bid}
                )
    
                # Invalidate cache
                get_cache_manager().invalidate(customer_id, ResourceType.AD_GROUP)
    
                return (
                    f"✅ Ad group {ad_group_id} bid updated successfully!\n\n"
                    f"**New CPC Bid**: ${result['new_cpc_bid']:.2f}\n\n"
                    f"The new bid will take effect immediately. "
                    f"Monitor performance closely to see the impact on impressions and clicks."
                )
    
            except Exception as e:
                error_msg = ErrorHandler.handle_error(e, context="update_ad_group_bid")
                return f"❌ Failed to update ad group bid: {error_msg}"
  • AdGroupManager.update_ad_group_cpc_bid() - the actual manager method that delegates to update_ad_group() with cpc_bid_micros, then converts micros back to currency units for the result.
    def update_ad_group_cpc_bid(
        self,
        customer_id: str,
        ad_group_id: str,
        cpc_bid_micros: int
    ) -> Dict[str, Any]:
        """
        Update ad group CPC bid.
    
        Args:
            customer_id: Customer ID
            ad_group_id: Ad group ID
            cpc_bid_micros: New CPC bid in micros
    
        Returns:
            Operation result with bid amount
        """
        result = self.update_ad_group(
            customer_id,
            ad_group_id,
            {"cpc_bid_micros": cpc_bid_micros}
        )
    
        result["new_cpc_bid"] = cpc_bid_micros / 1_000_000
    
        return result
  • Registration: The @mcp.tool() decorator on line 252 registers google_ads_update_ad_group_bid as an MCP tool. The parent function register_ad_group_tools(mcp) is the registration entry point.
    def register_ad_group_tools(mcp: FastMCP):
        """Register ad group management tools with MCP server."""
  • AdGroupManager.update_ad_group() - the generic update method that builds the AdGroupOperation with a field mask, supporting cpc_bid_micros updates among other fields.
    def update_ad_group(
        self,
        customer_id: str,
        ad_group_id: str,
        updates: Dict[str, Any]
    ) -> Dict[str, Any]:
        """
        Update ad group settings.
    
        Args:
            customer_id: Customer ID
            ad_group_id: Ad group ID
            updates: Dictionary of fields to update (name, status, cpc_bid_micros, etc.)
    
        Returns:
            Operation result
        """
        ad_group_service = self.client.get_service("AdGroupService")
    
        ad_group_operation = self.client.get_type("AdGroupOperation")
        ad_group = ad_group_operation.update
    
        ad_group.resource_name = ad_group_service.ad_group_path(customer_id, ad_group_id)
    
        # Track updated fields for field mask
        update_mask_paths = []
    
        # Update name
        if "name" in updates:
            ad_group.name = updates["name"]
            update_mask_paths.append("name")
    
        # Update status
        if "status" in updates:
            ad_group.status = self.client.enums.AdGroupStatusEnum[updates["status"]]
            update_mask_paths.append("status")
    
        # Update CPC bid
        if "cpc_bid_micros" in updates:
            ad_group.cpc_bid_micros = updates["cpc_bid_micros"]
            update_mask_paths.append("cpc_bid_micros")
    
        # Update CPM bid
        if "cpm_bid_micros" in updates:
            ad_group.cpm_bid_micros = updates["cpm_bid_micros"]
            update_mask_paths.append("cpm_bid_micros")
    
        # Update CPV bid
        if "cpv_bid_micros" in updates:
            ad_group.cpv_bid_micros = updates["cpv_bid_micros"]
            update_mask_paths.append("cpv_bid_micros")
    
        # Update Final URL suffix
        if "final_url_suffix" in updates:
            ad_group.final_url_suffix = updates["final_url_suffix"]
            update_mask_paths.append("final_url_suffix")
    
        # Set field mask
        self.client.copy_from(
            ad_group_operation.update_mask,
            field_mask_pb2.FieldMask(paths=update_mask_paths)
        )
    
        # Update ad group
        response = ad_group_service.mutate_ad_groups(
            customer_id=customer_id,
            operations=[ad_group_operation]
        )
    
        logger.info(f"Updated ad group {ad_group_id}: {', '.join(update_mask_paths)}")
    
        return {
            "ad_group_id": ad_group_id,
            "updated_fields": update_mask_paths,
            "message": f"Ad group updated successfully"
        }
Behavior2/5

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

No annotations provided, so description carries full burden. It only states 'Update' without mentioning side effects, permissions, or that it overwrites existing bids. Minimal disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Concise with clear Args/Returns sections. Slightly verbose but no superfluous sentences. Effective front-loading.

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?

Does not explain interaction with bidding strategies or that it only works for manual CPC. Missing behavioral context beyond basic action. Output schema exists but not detailed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but description adds meaning: customer_id format (no hyphens), ad_group_id, and cpc_bid with currency units and example. Compensates well for lack of schema descriptions.

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?

Description clearly states 'Update ad group CPC bid' – a specific verb and resource. It distinguishes from sibling tools like google_ads_update_ad_group (general update) and google_ads_update_keyword_bid (keyword bid).

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?

No guidance on when to use this tool over alternatives (e.g., batch updates or other bid types). No prerequisites or context about campaign type compatibility.

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/johnoconnor0/google-ads-mcp'

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