Skip to main content
Glama

Metadata MCP Connector

Add & Edit Campaign Elements — Native / Channel-First (N×N×N)

add_and_edit_native_campaign_elements
Destructive

Add elements to, and edit campaign-level fields of, an existing Channel-First / Native (N×N×N) campaign — the one built with create_native_structure_campaign (channel.structureType=NATIVE, WizNativeAdContainer). This is the NATIVE counterpart of add_and_edit_campaign_elements: that tool edits Precision (1×1×1 / METADATA) campaigns; THIS tool edits Native (N×N×N) campaigns.

            CRITICAL: PICK THE TOOL BY THE CAMPAIGN'S STRUCTURE (not by user phrasing):
              • Native / Channel-First / Platform-First / N×N×N campaign → THIS tool (`add_and_edit_native_campaign_elements`).
              • Precision Optimization / 1×1×1 / METADATA campaign → `add_and_edit_campaign_elements`.
            Both tools guard: call THIS tool on a Precision/METADATA campaign and it returns an error telling you to use `add_and_edit_campaign_elements`, and vice-versa. So if you guess wrong, the error tells you the right one — no silent mis-write. If you don't know the structure, check the campaign first (its channels' structureType) or just try and follow the redirect.

            WHAT THIS TOOL DOES:
            - EDIT campaign-level fields: name, budgetGroup, startDate, endDate (same smart/partial semantics as the flat tool — only pushed when different / supplied).
            - ADD new containers: each channel's `containers[]` APPENDS new WizNativeAdContainers (one audience × an `ad_offers` list of {ad, offer} pairs each, same shape as `create_native_structure_campaign`). Existing containers are PRESERVED — the channel's current container list is re-POSTed with the new ones appended.
            - ADD bare target groups: each channel's optional `target_groups[]` (names, each matching one target group, ignoring case and surrounding spaces) attaches targeting groups to the native channel without a full container. Each one goes on the first container that has no audience and no target group, which is renamed after the target group; when there is none, it goes on a new container with no ads. It goes in a call of its own, never beside `modify_containers[]`; to put a target group on a SPECIFIC container, use `set_target_group` there instead.
            - ATTACH negative keyword lists (Google Ads / Microsoft Ads only): the search channel block's optional `negative_keyword_lists[]` (names of EXISTING lists) attaches them channel-wide — valid with or without new containers. Names inside `containers[].negative_keyword_lists` are unioned in and applied at the same channel level. A name that doesn't resolve on the channel is reported in `errors[]`, never silently skipped.
            - EDIT existing containers (PER CONTAINER): each channel's optional `modify_containers[]` targets an existing container by `name` and, within it, deletes specific Ad—Offer rows (`remove_ads`), clears an offer from one ad while keeping it on the OTHER ads (`clear_offers_on_ads`), removes this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience`), puts a Targeting Group on this container (`set_target_group`, replacing any it has), or deletes the whole container (`delete_container`). This is the surgical counterpart to the channel-wide remove_* tools — use it when an audience/offer/ad is shared across containers and you only want to touch one. Removing a group clears it on that one container; a group reused by other containers stays alive for them, and an audience, target group or exclusion that no container uses any more (removed from its last container, or its container deleted) is deleted from the channel; keyword groups stay. A container an entry leaves holding ads with nothing to target them is named in the result's `warnings[]`: before launch, put a target group on it (`set_target_group`), have the user give it an audience in the platform UI, or delete it.
            - REPLACE a container's audience with a target group: ONE `modify_containers[]` entry on that container with `remove_audience: true` and `set_target_group: "<name>"` (see the example below). The container keeps its name and ads, and the old audience is deleted from the channel when no other container uses it, so no follow-up remove_audiences_from_campaign call is needed. `target_groups[]` and `modify_containers[]` go in separate calls: a channel block with both is refused, because a bare target group goes on the first container with no audience and no target group and renames it.

            WHAT THIS TOOL DOES NOT DO:
            - It does not switch a campaign's structure (that's fixed at creation).
            - For a change that spans ALL ads (remove an offer/ad everywhere it appears on the channel), use the channel-wide removal tools (remove_offers_from_campaign / remove_ad_from_campaign / remove_audiences_from_campaign / remove_target_groups_from_campaign / remove_keywords_from_campaign); `modify_containers` is only for a specific container/row.

            CONTAINER RULES (same as create_native_structure_campaign):
            - Each container is one audience × a LIST of (ad, offer) pairs (`ad_offers`, 1+). Group several ads/offers under one audience by adding pairs — e.g. 3 ads on the same offer = 3 pairs that repeat the same `offer` id. Send two containers only to run the audience as two separate ad-sets.
            - `audience` / `exclude_audience` / `target_group` are NAMES (resolved server-side); the `ad` / `offer` inside each `ad_offers` pair are integer IDs.
            - Audience names are resolved BEFORE anything is created: a container whose `audience` cannot be resolved is dropped with an error in `errors[]` that states whether retrying can help ("may still be matching") or not ("not available on this channel"); no keyword group or other element is left behind for a dropped container.
            - `audience` is REQUIRED for LinkedIn/Facebook/Instagram/Reddit; OPTIONAL for Google/Microsoft search containers (keyword-only is valid — provide `keywords`/`keyword_ids` instead).
            - Offer–channel lock still applies: a Lead Gen offer must be locked to the container's channel (LinkedIn→LINKEDIN, etc.); Google takes Landing Page offers only; Landing Page offers are universal.

            RESPONSE: same top-level shape as `add_and_edit_campaign_elements` (success, campaign_id, changes {renamed, budget_group_reassigned, schedule_updated}, added_summary per channel {containers, target_groups, negative_keyword_lists, and — when modify_containers is used — ads_removed, offers_cleared, containers_deleted, audiences_removed, target_groups_removed, keywords_removed, excludes_removed, target_groups_set, groups_deleted (groups no container uses any more, deleted from the channel)}, optimization_group, campaign_url, full_response), plus `warnings[]` naming any container left with ads and nothing to target them. success=false only when NOTHING applied and something failed; every failure is in `errors[]`, so read it whenever it is present, success=true included. The rest of the edit still proceeds past a failed element.

            EXAMPLE (append a LinkedIn container + rename):
            add_and_edit_native_campaign_elements(campaign_data={
                "campaignId": 159490,
                "name": "Q3_ABM_Native_v2",
                "linkedin": {"containers": [
                    {"name": "VPs > Demo > Form", "audience": "VPs - NA", "ad_offers": [{"ad": 156502, "offer": 57538}]}
                ]}
            })

            EXAMPLE (append a Google keyword-only container + bare target group):
            add_and_edit_native_campaign_elements(campaign_data={
                "campaignId": 159490,
                "google": {
                    "containers": [
                        {"name": "Incident Response", "ad_offers": [{"ad": 210804, "offer": 67269}],
                         "keywords": ["incident response platform"], "negative_keyword_lists": ["Competitor Brands"]}
                    ],
                    "target_groups": ["Tech Decision Makers"]
                }
            })

            EXAMPLE (ROW-LEVEL: drop the offer from ONE ad in a container, keep it on the other ads):
            add_and_edit_native_campaign_elements(campaign_data={
                "campaignId": 159490,
                "facebook": {"modify_containers": [
                    {"container": "ICP > 3 creatives > TOF offer",
                     "clear_offers_on_ads": ["Ungated-AI-in-Finance-v2-vert_FB"]}
                ]}
            })

            EXAMPLE (PER-CONTAINER: delete one Ad—Offer row in one container; delete a whole other container):
            add_and_edit_native_campaign_elements(campaign_data={
                "campaignId": 159490,
                "linkedin": {"modify_containers": [
                    {"container": "VPs > Demo > Form", "remove_ads": ["Old Creative A"]},
                    {"container": "Retired ad-set", "delete_container": True}
                ]}
            })

            EXAMPLE (PER-CONTAINER: drop a reused audience from ONE container, keep it on the others):
            add_and_edit_native_campaign_elements(campaign_data={
                "campaignId": 159490,
                "facebook": {"modify_containers": [
                    {"container": "ICP - A2", "remove_audience": True}
                ]}
            })

            EXAMPLE (PER-CONTAINER: replace a container's audience with a target group, keeping its ads):
            add_and_edit_native_campaign_elements(campaign_data={
                "campaignId": 159490,
                "linkedin": {"modify_containers": [
                    {"container": "VPs > Demo > Form", "remove_audience": True,
                     "set_target_group": "VPs - In-House Only"}
                ]}
            })

CRITICAL: PARTIAL EDITS ONLY. Only campaignId is required. Supply other fields only for the user's requested changes, never by copying the whole campaign read result. A budget-group-only move uses campaign_data={"campaignId": 12345, "budgetGroup": "Destination"}. Omit name, startDate, endDate and channel blocks unless the user also requested those edits. Campaign-level startDate/endDate writes apply to every channel, including switched-off channels, so replaying a campaign's aggregate dates can overwrite distinct channel dates. For a budget-only move, read the campaign before and after and verify each channel's startDate/endDate and enabled state are unchanged, alongside the new budget group. The handler returns budget_move_verification for a completed move without date or channel edits. verified=true confirms every channel's identity, dates and switch state and the destination group. verified=false also populates errors: stop further moves and report the changed fields or incomplete readback, even when success=true because the budget group already changed. No schedule rollback is attempted. Do not report dates preserved without that readback; report any mismatch explicitly.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
campaign_dataYesNative (N×N×N) campaign edit payload: campaignId + optional campaign-level fields + per-channel `containers[]` (append) and optional `target_groups[]`.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / campaign_data / properties / endDate / description
      Previous value: -"Campaign end date (YYYY-MM-DD) — REPLACES the existing end date."New value: +"Optional new end date (YYYY-MM-DD). Omit unless the user requested a schedule change; supplied dates overwrite that date on every channel, including switched-off channels."
    • changedInput schema / properties / campaign_data / properties / startDate / description
      Previous value: -"Campaign start date (YYYY-MM-DD) — REPLACES the existing start date."New value: +"Optional new start date (YYYY-MM-DD). Omit unless the user requested a schedule change; supplied dates overwrite that date on every channel, including switched-off channels."
  2. Changed18 schema fields changed
    • changedInput schema / properties / campaign_data / properties / facebook / properties / modify_containers / description
      Previous value: -"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once."New value: +"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Put a Targeting Group on a container with `set_target_group`; with `remove_audience` on the same entry it replaces the audience. Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once. An audience, target group or exclusion that no container uses any more is deleted from the channel (keyword groups stay), and a container left holding ads with nothing to target them is named in the result's `warnings[]`. Not in the same call as `target_groups`."
    • addedInput schema / properties / campaign_data / properties / facebook / properties / modify_containers / items / properties / set_target_group
      Added value: +{
      +  "description": "Name of an existing Targeting Group to put on THIS container, replacing any target group it has; the container keeps its name and ads. Together with `remove_audience` it REPLACES the container's audience with this target group, in one step. Matched by name, ignoring case and surrounding spaces; a name that matches no target group, or several, is refused.",
      +  "type": "string"
      +}
    • changedInput schema / properties / campaign_data / properties / facebook / properties / target_groups / description
      Previous value: -"Targeting Group names to attach to the channel without a full container (bare target-group add)."New value: +"Targeting Group names to attach to the channel without a full container (bare target-group add). Each name must match one target group, ignoring case and surrounding spaces; one that matches none or several is reported and skipped. Each goes on the first container with no audience and no target group (renamed after it), else on a new container with no ads. Not in the same call as `modify_containers`; to put a target group on a specific container, use `set_target_group` there instead."
    • changedInput schema / properties / campaign_data / properties / google / properties / modify_containers / description
      Previous value: -"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once."New value: +"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Put a Targeting Group on a container with `set_target_group`; with `remove_audience` on the same entry it replaces the audience. Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once. An audience, target group or exclusion that no container uses any more is deleted from the channel (keyword groups stay), and a container left holding ads with nothing to target them is named in the result's `warnings[]`. Not in the same call as `target_groups`."
    • addedInput schema / properties / campaign_data / properties / google / properties / modify_containers / items / properties / set_target_group
      Added value: +{
      +  "description": "Name of an existing Targeting Group to put on THIS container, replacing any target group it has; the container keeps its name and ads. Together with `remove_audience` it REPLACES the container's audience with this target group, in one step. Matched by name, ignoring case and surrounding spaces; a name that matches no target group, or several, is refused.",
      +  "type": "string"
      +}
    • changedInput schema / properties / campaign_data / properties / google / properties / target_groups / description
      Previous value: -"Targeting Group names to attach to the channel without a full container (bare target-group add)."New value: +"Targeting Group names to attach to the channel without a full container (bare target-group add). Each name must match one target group, ignoring case and surrounding spaces; one that matches none or several is reported and skipped. Each goes on the first container with no audience and no target group (renamed after it), else on a new container with no ads. Not in the same call as `modify_containers`; to put a target group on a specific container, use `set_target_group` there instead."
    • changedInput schema / properties / campaign_data / properties / instagram / properties / modify_containers / description
      Previous value: -"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once."New value: +"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Put a Targeting Group on a container with `set_target_group`; with `remove_audience` on the same entry it replaces the audience. Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once. An audience, target group or exclusion that no container uses any more is deleted from the channel (keyword groups stay), and a container left holding ads with nothing to target them is named in the result's `warnings[]`. Not in the same call as `target_groups`."
    • addedInput schema / properties / campaign_data / properties / instagram / properties / modify_containers / items / properties / set_target_group
      Added value: +{
      +  "description": "Name of an existing Targeting Group to put on THIS container, replacing any target group it has; the container keeps its name and ads. Together with `remove_audience` it REPLACES the container's audience with this target group, in one step. Matched by name, ignoring case and surrounding spaces; a name that matches no target group, or several, is refused.",
      +  "type": "string"
      +}
    • changedInput schema / properties / campaign_data / properties / instagram / properties / target_groups / description
      Previous value: -"Targeting Group names to attach to the channel without a full container (bare target-group add)."New value: +"Targeting Group names to attach to the channel without a full container (bare target-group add). Each name must match one target group, ignoring case and surrounding spaces; one that matches none or several is reported and skipped. Each goes on the first container with no audience and no target group (renamed after it), else on a new container with no ads. Not in the same call as `modify_containers`; to put a target group on a specific container, use `set_target_group` there instead."
    • changedInput schema / properties / campaign_data / properties / linkedin / properties / modify_containers / description
      Previous value: -"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once."New value: +"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Put a Targeting Group on a container with `set_target_group`; with `remove_audience` on the same entry it replaces the audience. Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once. An audience, target group or exclusion that no container uses any more is deleted from the channel (keyword groups stay), and a container left holding ads with nothing to target them is named in the result's `warnings[]`. Not in the same call as `target_groups`."
    • addedInput schema / properties / campaign_data / properties / linkedin / properties / modify_containers / items / properties / set_target_group
      Added value: +{
      +  "description": "Name of an existing Targeting Group to put on THIS container, replacing any target group it has; the container keeps its name and ads. Together with `remove_audience` it REPLACES the container's audience with this target group, in one step. Matched by name, ignoring case and surrounding spaces; a name that matches no target group, or several, is refused.",
      +  "type": "string"
      +}
    • changedInput schema / properties / campaign_data / properties / linkedin / properties / target_groups / description
      Previous value: -"Targeting Group names to attach to the channel without a full container (bare target-group add)."New value: +"Targeting Group names to attach to the channel without a full container (bare target-group add). Each name must match one target group, ignoring case and surrounding spaces; one that matches none or several is reported and skipped. Each goes on the first container with no audience and no target group (renamed after it), else on a new container with no ads. Not in the same call as `modify_containers`; to put a target group on a specific container, use `set_target_group` there instead."
    • changedInput schema / properties / campaign_data / properties / microsoft / properties / modify_containers / description
      Previous value: -"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once."New value: +"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Put a Targeting Group on a container with `set_target_group`; with `remove_audience` on the same entry it replaces the audience. Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once. An audience, target group or exclusion that no container uses any more is deleted from the channel (keyword groups stay), and a container left holding ads with nothing to target them is named in the result's `warnings[]`. Not in the same call as `target_groups`."
    • addedInput schema / properties / campaign_data / properties / microsoft / properties / modify_containers / items / properties / set_target_group
      Added value: +{
      +  "description": "Name of an existing Targeting Group to put on THIS container, replacing any target group it has; the container keeps its name and ads. Together with `remove_audience` it REPLACES the container's audience with this target group, in one step. Matched by name, ignoring case and surrounding spaces; a name that matches no target group, or several, is refused.",
      +  "type": "string"
      +}
    • changedInput schema / properties / campaign_data / properties / microsoft / properties / target_groups / description
      Previous value: -"Targeting Group names to attach to the channel without a full container (bare target-group add)."New value: +"Targeting Group names to attach to the channel without a full container (bare target-group add). Each name must match one target group, ignoring case and surrounding spaces; one that matches none or several is reported and skipped. Each goes on the first container with no audience and no target group (renamed after it), else on a new container with no ads. Not in the same call as `modify_containers`; to put a target group on a specific container, use `set_target_group` there instead."
    • changedInput schema / properties / campaign_data / properties / reddit / properties / modify_containers / description
      Previous value: -"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once."New value: +"Edit EXISTING containers in place: delete specific Ad—Offer rows (`remove_ads`), clear an offer from one ad while keeping it on others (`clear_offers_on_ads`), remove this container's audience / targeting group / keywords / exclusion (`remove_audience` / `remove_target_group` / `remove_keywords` / `remove_exclude_audience` — clears it on THIS container only, leaving any container that reuses it untouched), or delete a whole container (`delete_container`). Put a Targeting Group on a container with `set_target_group`; with `remove_audience` on the same entry it replaces the audience. Target each by its `container` name. Use this for surgical per-container changes; use the channel-wide remove_* tools only to act on ALL containers at once. An audience, target group or exclusion that no container uses any more is deleted from the channel (keyword groups stay), and a container left holding ads with nothing to target them is named in the result's `warnings[]`. Not in the same call as `target_groups`."
    • addedInput schema / properties / campaign_data / properties / reddit / properties / modify_containers / items / properties / set_target_group
      Added value: +{
      +  "description": "Name of an existing Targeting Group to put on THIS container, replacing any target group it has; the container keeps its name and ads. Together with `remove_audience` it REPLACES the container's audience with this target group, in one step. Matched by name, ignoring case and surrounding spaces; a name that matches no target group, or several, is refused.",
      +  "type": "string"
      +}
    • changedInput schema / properties / campaign_data / properties / reddit / properties / target_groups / description
      Previous value: -"Targeting Group names to attach to the channel without a full container (bare target-group add)."New value: +"Targeting Group names to attach to the channel without a full container (bare target-group add). Each name must match one target group, ignoring case and surrounding spaces; one that matches none or several is reported and skipped. Each goes on the first container with no audience and no target group (renamed after it), else on a new container with no ads. Not in the same call as `modify_containers`; to put a target group on a specific container, use `set_target_group` there instead."
  3. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already flag destructiveHint=true and openWorldHint=true, but the description adds substantial behavioral context: existing containers are preserved and re-POSTed with new ones appended, an audience/target group/exclusion is deleted from the channel once its last container drops it (keyword groups stay), failed elements don't halt the rest of the edit, success=false only when nothing applied, and budget_move_verification must be read back. It also discloses the warnings[]/errors[] reporting contract.

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 highest-stakes decision (tool selection) and organized under clear headers (WHAT THIS TOOL DOES / DOES NOT DO / CONTAINER RULES / RESPONSE / EXAMPLE). It is very long, and a few points repeat (the channel-wide remove_* alternative and the target_groups-vs-modify_containers split each appear twice), but the length is largely justified by the tool's complexity.

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?

For a single-parameter but deeply nested edit tool with no output schema, the description covers behavior, append-vs-modify semantics, per-container removal side effects, the response shape, warnings/errors handling, and the verification requirement. An agent has everything needed to invoke it correctly and interpret the result.

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 100%, so the schema carries most parameter meaning and the baseline is 3. The description nonetheless adds value the schema cannot: 'PARTIAL EDITS ONLY — only campaignId is required', the instruction never to copy a whole campaign read result, and the budget-only-move example. These are call-shaping semantics rather than field 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?

The description names a specific verb pair (add elements to / edit campaign-level fields of) and an exact resource (an existing Channel-First/Native N×N×N campaign built with create_native_structure_campaign). It explicitly separates itself from the sibling add_and_edit_campaign_elements by structure type (NATIVE vs METADATA/1×1×1), so an agent can route correctly without opening either schema.

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?

It gives an explicit selection rule ('PICK THE TOOL BY THE CAMPAIGN'S STRUCTURE'), names the alternative and its trigger, and notes both tools redirect on mismatch. It further routes between modify_containers and the channel-wide remove_* tools, between target_groups and set_target_group, and between remove_ads and clear_offers_on_ads. When-to-use and when-not-to-use are both covered.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources