Skip to main content
Glama

Propose Google Analytics changes (applies nothing)

propose_analytics_changes
Idempotent

Checks proposed Google Analytics setup changes against the live property, stores them with a plain-English summary, and applies nothing until you approve.

Instructions

Checks Google Analytics setup changes against the live property and stores them as a proposal with a plain-English summary; nothing is changed. Show the summary to the user and apply only after they approve, with apply_changes (undo_changes reverses it). Supported: create_ga4_property (a property plus a web stream; the applied result gives the measurement ID and the tag the site needs), mark_key_event / unmark_key_event (GA4's conversions), set_key_event_counting (also recounts a Google Ads import of it), link_google_ads / unlink_google_ads. Point out any ⚠ line before they approve.

Input Schema

NameRequiredDescriptionDefault
changesYesChanges to propose; several can go in one proposal

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.20.0
    • changedInput schema / properties / changes / items / oneOf
      Previous value: -[
      -  {
      -    "description": "Create a GA4 property with a web data stream for the site; the result gives the measurement ID and the tag to add to every page",
      -    "properties": {
      -      "account_id": {
      -        "description": "Google Analytics account id (from analytics_properties' accounts)",
      -        "pattern": "^\\d+$",
      -        "type": "string"
      -      },
      -      "currency": {
      -        "default": "USD",
      -        "description": "Currency for revenue, ISO 4217",
      -        "pattern": "^[A-Z]{3}$",
      -        "type": "string"
      -      },
      -      "name": {
      -        "description": "Property name, usually the business or site",
      -        "maxLength": 100,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "time_zone": {
      -        "description": "IANA time zone reports use, e.g. America/New_York",
      -        "maxLength": 64,
      -        "minLength": 3,
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "create_ga4_property",
      -        "type": "string"
      -      },
      -      "website_url": {
      -        "description": "The site's address, e.g. https://www.example.com",
      -        "format": "uri",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "account_id",
      -      "name",
      -      "website_url",
      -      "time_zone"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "description": "Mark an event as a key event (GA4's conversion), so it is counted and can be imported into Google Ads",
      -    "properties": {
      -      "counting": {
      -        "default": "ONCE_PER_EVENT",
      -        "description": "ONCE_PER_EVENT counts every time; ONCE_PER_SESSION counts one per visit (leads)",
      -        "enum": [
      -          "ONCE_PER_EVENT",
      -          "ONCE_PER_SESSION"
      -        ],
      -        "type": "string"
      -      },
      -      "event_name": {
      -        "description": "GA4 event name, e.g. generate_lead, purchase, sign_up, or a custom event the site sends",
      -        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$",
      -        "type": "string"
      -      },
      -      "property_id": {
      -        "description": "GA4 property id (from analytics_properties)",
      -        "pattern": "^\\d+$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "mark_key_event",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "property_id",
      -      "event_name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "description": "Stop counting an event as a key event",
      -    "properties": {
      -      "event_name": {
      -        "description": "GA4 event name, e.g. generate_lead, purchase, sign_up, or a custom event the site sends",
      -        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$",
      -        "type": "string"
      -      },
      -      "property_id": {
      -        "description": "GA4 property id (from analytics_properties)",
      -        "pattern": "^\\d+$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "unmark_key_event",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "property_id",
      -      "event_name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "description": "Link a GA4 property to a Google Ads account, so Ads can import its key events and GA4 shows ad clicks and cost (the user must be an admin of both)",
      -    "properties": {
      -      "customer_id": {
      -        "description": "Google Ads customer ID, with or without dashes",
      -        "pattern": "^\\d{3}-?\\d{3}-?\\d{4}$",
      -        "type": "string"
      -      },
      -      "property_id": {
      -        "description": "GA4 property id (from analytics_properties)",
      -        "pattern": "^\\d+$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "link_google_ads",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "property_id",
      -      "customer_id"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "description": "Remove the link between a GA4 property and a Google Ads account",
      -    "properties": {
      -      "customer_id": {
      -        "description": "Google Ads customer ID, with or without dashes",
      -        "pattern": "^\\d{3}-?\\d{3}-?\\d{4}$",
      -        "type": "string"
      -      },
      -      "property_id": {
      -        "description": "GA4 property id (from analytics_properties)",
      -        "pattern": "^\\d+$",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "unlink_google_ads",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "property_id",
      -      "customer_id"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "description": "Create a GA4 property with a web data stream for the site; the result gives the measurement ID and the tag to add to every page",
      +    "properties": {
      +      "account_id": {
      +        "description": "Google Analytics account id (from analytics_properties' accounts)",
      +        "pattern": "^\\d+$",
      +        "type": "string"
      +      },
      +      "currency": {
      +        "default": "USD",
      +        "description": "Currency for revenue, ISO 4217",
      +        "pattern": "^[A-Z]{3}$",
      +        "type": "string"
      +      },
      +      "name": {
      +        "description": "Property name, usually the business or site",
      +        "maxLength": 100,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "time_zone": {
      +        "description": "IANA time zone reports use, e.g. America/New_York",
      +        "maxLength": 64,
      +        "minLength": 3,
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "create_ga4_property",
      +        "type": "string"
      +      },
      +      "website_url": {
      +        "description": "The site's address, e.g. https://www.example.com",
      +        "format": "uri",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "account_id",
      +      "name",
      +      "website_url",
      +      "time_zone"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "description": "Mark an event as a key event (GA4's conversion), so it is counted and can be imported into Google Ads",
      +    "properties": {
      +      "counting": {
      +        "default": "ONCE_PER_EVENT",
      +        "description": "ONCE_PER_EVENT counts every time; ONCE_PER_SESSION counts one per visit (leads)",
      +        "enum": [
      +          "ONCE_PER_EVENT",
      +          "ONCE_PER_SESSION"
      +        ],
      +        "type": "string"
      +      },
      +      "event_name": {
      +        "description": "GA4 event name, e.g. generate_lead, purchase, sign_up, or a custom event the site sends",
      +        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$",
      +        "type": "string"
      +      },
      +      "property_id": {
      +        "description": "GA4 property id (from analytics_properties)",
      +        "pattern": "^\\d+$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "mark_key_event",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "property_id",
      +      "event_name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "description": "Stop counting an event as a key event",
      +    "properties": {
      +      "event_name": {
      +        "description": "GA4 event name, e.g. generate_lead, purchase, sign_up, or a custom event the site sends",
      +        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$",
      +        "type": "string"
      +      },
      +      "property_id": {
      +        "description": "GA4 property id (from analytics_properties)",
      +        "pattern": "^\\d+$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "unmark_key_event",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "property_id",
      +      "event_name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "description": "Recount an existing key event; a Google Ads action imported from it follows (ONCE_PER_SESSION is Ads' one per click)",
      +    "properties": {
      +      "counting": {
      +        "description": "ONCE_PER_EVENT: every time; ONCE_PER_SESSION: one per visit",
      +        "enum": [
      +          "ONCE_PER_EVENT",
      +          "ONCE_PER_SESSION"
      +        ],
      +        "type": "string"
      +      },
      +      "event_name": {
      +        "description": "GA4 event name, e.g. generate_lead, purchase, sign_up, or a custom event the site sends",
      +        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,39}$",
      +        "type": "string"
      +      },
      +      "property_id": {
      +        "description": "GA4 property id (from analytics_properties)",
      +        "pattern": "^\\d+$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "set_key_event_counting",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "property_id",
      +      "event_name",
      +      "counting"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "description": "Link a GA4 property to a Google Ads account, so Ads can import its key events and GA4 shows ad clicks and cost (the user must be an admin of both)",
      +    "properties": {
      +      "customer_id": {
      +        "description": "Google Ads customer ID, with or without dashes",
      +        "pattern": "^\\d{3}-?\\d{3}-?\\d{4}$",
      +        "type": "string"
      +      },
      +      "property_id": {
      +        "description": "GA4 property id (from analytics_properties)",
      +        "pattern": "^\\d+$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "link_google_ads",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "property_id",
      +      "customer_id"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "description": "Remove the link between a GA4 property and a Google Ads account",
      +    "properties": {
      +      "customer_id": {
      +        "description": "Google Ads customer ID, with or without dashes",
      +        "pattern": "^\\d{3}-?\\d{3}-?\\d{4}$",
      +        "type": "string"
      +      },
      +      "property_id": {
      +        "description": "GA4 property id (from analytics_properties)",
      +        "pattern": "^\\d+$",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "unlink_google_ads",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "property_id",
      +      "customer_id"
      +    ],
      +    "type": "object"
      +  }
      +]
  2. Addedv0.15.0

TDQS

A4.5/5.0
Behavior5/5

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

Annotations only declare the generic profile (readOnlyHint=false, destructiveHint=false, idempotentHint=true, openWorldHint=true); the description adds the crucial non-generic fact that despite writing a proposal nothing is applied, plus per-change side effects (an Ads import follows a recount; linking requires admin on both sides). That is well beyond what the annotations convey and is internally consistent with them.

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?

Front-loaded with the purpose and the safety guarantee, then the approval workflow, then the supported type catalogue. Dense semicolon-chained clauses make the middle sentence heavy, but every clause carries operational meaning and none is filler.

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?

With no output schema and a single parameter, the description covers the approval loop, reversibility and change catalogue thoroughly. The one gap is what a proposal returns (an id or handle to pass to apply_changes/discard_proposal), which the agent must infer.

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 description coverage is 100% and the sole parameter's oneOf variants are already fully documented in the schema, including const types, required fields and even the Ads-import caveat. The description enumerates the same change types and their outcomes, so it largely restates structured data rather than adding format or constraint detail (e.g., the 20-item cap and batching are schema-only).

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?

States a specific verb and resource — checks Google Analytics setup changes against the live property and stores a proposal — and explicitly says nothing is applied. It also names its counterpart apply_changes, so an agent can distinguish this from the sibling propose_changes (non-GA) and from apply_changes at a glance.

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?

Gives an explicit workflow: show the summary to the user, apply only after approval with apply_changes, and undo_changes reverses it. It even instructs the agent to point out ⚠ lines before approval, so the conditions for use and follow-up are fully spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.