Skip to main content
Glama
650,521 tools. Updated 2026-10-14 00:42

"A server for finding scientific articles, creating ad ideas, and deploying Facebook ads" matching MCP tools:

  • Ad Radar — AI Ad & Creative Intelligence — Turn Facebook Ad Library scraper results into AI creative intel: hooks…. Turn Facebook Ad Library scraper results into AI creative intel: hooks, winners, fatigue & briefs. Paste a dataset ID. Works with any Meta ads scraper.
    ConnectorNo auth
  • Account-level statistics and channel breakdown for a timeframe. USE FOR: General account stats by period, channel breakdown, high-level metrics (ROI, spending, leads, opportunities), custom date ranges. NOT FOR: Campaign-level info (use experiment_performance_stats), specific experiments (use get_experiments). CHANNELS: FACEBOOK, LINKEDIN, GOOGLE ADS, ALL TIMEFRAME LOGIC: - 'quarter'/'Q1-Q4' → timeframe='QUARTER' - 'week'/'weekly' → timeframe='WEEK' - ≤3 months → timeframe='MONTH' - >3 months → timeframe='QUARTER' - Default: timeframe='MONTH' CUSTOM DATE RANGE: Provide ONLY startDate + endDate (NO timeframe). Format: ISO 8601 (YYYY-MM-DDTHH:mm:ss.sssZ) NO DELIVERY: a period with no delivery comes back with empty totals and an empty channelBreakDown (the platform sends null for both); read that as zeros for every channel, not as missing data. METRICS: impressions, clicks, spent, leads, mqls | opens, sends, actionClicks (CONVO/MESSAGE ads) | triggeredOpps, triggeredOppsAmount, influencedOpps, influencedOppsAmount | triggeredClosedWonOpps, triggeredClosedWonOppsAmount | roiInfluencedOpp, roiTriggeredOpp | cpc, cpl, cpm, ctr, conversionRate | costPerOpen, costPerSend (CONVO/MESSAGE ads) | customFields array CONVO/MESSAGE AD CAVEAT: opens, sends, actionClicks (and their per-cost derivatives) are the success metrics for CONVO and MESSAGE (LinkedIn message) ad types. clicks/ctr/cpc are typically 0 for these ads — do not treat that as "no performance". If account-level data shows high spend with 0 clicks, drill into experiment_performance_stats or get_ad_details to confirm ad type before drawing conclusions.
    ConnectorAPI key
  • Granular performance metrics for ads, audiences, creatives, offers, target groups, keywords. IMPORTANT: Always specify endpoint parameter. Always use ISO 8601 for dates. USE FOR: Best performing ads/audiences/creatives/offers/target groups, ingredient comparisons, ad type analysis (IMAGE, VIDEO, CAROUSEL), lead gen forms vs landing pages, pipeline by ingredient, creative previews, keyword performance. NOT FOR: Account-level stats, experiment-level analysis without ingredient focus. ENDPOINT LOGIC: - 'target group' → customAudience/group - 'audience' → customAudience - 'offer'/'lead gen'/'landing page' → offer - 'creative' → creative - 'keyword' → keywords - 'ad'/'ads' or default → ads AD TYPES: IMAGE, VIDEO, CAROUSEL, DOCUMENT, CONVO, SPOTLIGHT, SEARCH, MESSAGE - The `adFormat` field on each response row identifies the ad type. METRICS: spend, impressions, clicks, leads, mqls | opens, sends, actionClicks, costPerOpen, costPerSend (CONVO/MESSAGE ads) | cpl, cpc, cpm, ctr, conversionRate, formConversionRate, mqlRate | totalOpps, totalTriggered, oppsAmount, triggeredAmount | cpMql, cpOppInfluenced, cpOppTriggered | channel, goal, adFormat, audienceSize, statusLabel | previewUrl CONVO/MESSAGE AD CAVEAT: when adFormat is CONVO or MESSAGE (LinkedIn message ads), success is measured by opens, sends, and actionClicks (and costPerOpen / costPerSend), NOT clicks/ctr/cpc. Do not rank these ads by CTR or dismiss them when clicks=0. Use sort='actionClicks,desc' or sort='opens,desc' for conversational performance ranking. RULES: Field 'id' corresponds to endpoint queried. Exclude $0 CPL experiments from calculations.
    ConnectorAPI key
  • Archive (soft-delete) one or more ads on the Metadata platform. ARCHIVE IS HOW YOU DELETE AN AD. The platform has NO hard-delete endpoint for ads — archive is the soft-delete and the only way to remove an ad from the active library. When the user says "delete this ad", "remove this ad", "discard this ad", "trash this ad", or "get rid of this ad" → call archive_ad. Do NOT hallucinate a delete_ad or remove_ad tool; it does not exist. The archived ad is preserved on the platform (it still has its id, creative_json, and history) and can be restored with unarchive_ad. USE THIS TOOL WHEN: - User asks to delete, remove, discard, trash, drop, retire, or archive one or more ads. - User wants to clean up draft ads they no longer need. - User asks "make this ad go away" or similar. HOW TO GET THE id(s): - search_ads_by_names(ad_names=[...]) → returns active ad ids. - get_ad_details(ids=...) → confirms an ad exists if the id is already known (works for active ads). ALSO KNOWN AS: archive ad, delete ad, remove ad, discard ad, trash ad, drop ad, retire ad, soft-delete ad, get rid of ad. KEYWORDS: archive, delete, remove, discard, trash, drop, retire, soft-delete, hide, get rid of, clean up, ad cleanup. PARAMETERS: - ids: Array of integer ad ids (at least one). Bulk-friendly — pass several ids to archive multiple ads in a single call. RETURNS: { "success": true, "archived_ids": [123, 456], "count": 2 } To bring an archived ad back, call unarchive_ad with the same id(s).
    Connector
    Destructive
    API key
  • Set the channel-level Meta placement default of an existing DRAFT wizard campaign's Facebook or Instagram channel: automatic placements (Meta decides where ads serve) or a manual list of surfaces (Feed, Stories, Reels, ...). Placements are where the ads serve inside Meta's networks. This is the same "Placements" control the platform UI shows in the Facebook/Instagram section of the campaign draft page. The campaign MUST already have the channel enabled (via create_campaign / add_and_edit_campaign_elements). WARNING: DRAFT-ONLY: the platform rejects the edit once the campaign is Launching/Launched. KEYWORDS: meta, facebook, instagram, threads, placements, placement, feed, stories, reels, explore, search results, profile feed, automatic placements, manual placements, advantage+ placements, where ads serve, surfaces, channel settings, campaign settings WHEN TO USE: - Serve ads only on specific surfaces (e.g. Instagram Reels and Stories) - Switch a channel back to automatic placements (Meta optimizes delivery) - The user asks where their Facebook/Instagram ads will appear PARAMETERS: - campaign_id: the wizard campaign ID (required) - channel: FACEBOOK | INSTAGRAM (required — the campaign channel to edit) - mode: AUTO | MANUAL (required). AUTO = automatic placements, clears any manual set. MANUAL = serve only on the placements listed. - placements: array of placement codes, required when mode=MANUAL, ignored for AUTO. Facebook surfaces: FB_FEED, FB_STORIES, FB_REELS, FB_SEARCH_RESULTS. Instagram surfaces: IG_FEED, IG_PROFILE_FEED, IG_EXPLORE, IG_EXPLORE_HOME, IG_STORIES, IG_REELS, IG_SEARCH_RESULTS. Threads: TH_THREADS_STREAM. PLACEMENT RULES (enforced; violations return a descriptive error): - Companion rules: FB_STORIES and FB_SEARCH_RESULTS require FB_FEED; IG_PROFILE_FEED, IG_SEARCH_RESULTS and IG_EXPLORE require IG_FEED; IG_EXPLORE_HOME requires IG_EXPLORE; TH_THREADS_STREAM requires IG_FEED. - An INSTAGRAM channel accepts IG_* placements only. - A FACEBOOK channel always accepts FB_* placements. IG_* / TH_* placements on a FACEBOOK channel additionally need the account's unified-placement rollout (feature flag CORE_META_IG_PLACEMENT_ON_FB) — the platform rejects them on accounts without it. - IG_PROFILE_FEED is not available on Lead Gen (CPL) campaigns. - AUTO is rejected while the channel has ad groups (per-ad-group setups keep manual placements). This tool sets the campaign-wide default for the channel. Per-ad-group placement overrides exist in the platform UI but are not editable through chat yet — send users to the campaign page for per-ad-group customization. EXAMPLES: Instagram channel, Reels + Stories + Feed only: update_meta_placements({"campaign_id": 12345, "channel": "INSTAGRAM", "mode": "MANUAL", "placements": ["IG_FEED", "IG_STORIES", "IG_REELS"]}) Facebook channel back to automatic placements: update_meta_placements({"campaign_id": 12345, "channel": "FACEBOOK", "mode": "AUTO"}) RESPONSE: {success, campaign_id, channel_id, channel, campaign_status, applied:{mode, placements}, previous?, errors?} `previous` echoes the channel's placement state before the edit. INTEGRATION WITH OTHER TOOLS: - Use search_campaigns_by_names / get_campaign_by_wizard_id to find the campaign - The channel is enabled by create_campaign or add_and_edit_campaign_elements - Reddit placements (feed/conversations) are a different system: use update_reddit_channel_settings for those
    Connector
    Destructive
    API key
  • Attaches Google Business Profile LOCATION assets (store address, map pin, "Get directions", call-from-map) to the account's ads. In Google Ads, location assets are created AUTOMATICALLY once the Business Profile is LINKED to the Google Ads account, then serve account-wide. This tool: (1) detects whether a linked location asset set (LOCATION_SYNC / Business-Profile location group) exists in the account; (2) if it exists AND a campaign_id is given, pins that asset set to the campaign (otherwise Google already serves it account-wide — nothing to do); (3) if none exists, returns the exact steps to link the Business Profile. confirm=false → dry-run. AD GROUP LEVEL: pass ad_group_id to pin the location asset set to ONE ad group (AdGroupAssetSet) instead of the whole campaign, e.g. a branch ad group that should show only that branch's address. asset_set_id picks a specific location asset set (a location group such as "Bağcılar", from the location_asset_sets list this tool returns); without it the Business Profile sync set is used. NOTE: creating the Business-Profile↔Ads link itself needs Business Profile API access (pending Google approval); until then the customer links it once in the Google Ads UI (~2 minutes).
    ConnectorOAuth

Matching MCP Servers

  • F
    license
    C
    quality
    D
    maintenance
    Enables managing Facebook ads campaigns, ad sets, ads, creatives, insights, and audience targeting via Meta's Marketing API.
    39
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables searching and scraping the public Facebook Ad Library to extract structured ad data such as advertiser, copy, landing URLs, and CTAs for competitive research, all without an account or API token.
    MIT

Matching MCP Connectors

  • Turns a single Google Ads AD on or off, or DELETES it: status 'ENABLED' to enable / publish / resume / unpause an ad, 'PAUSED' to pause / stop it, 'REMOVED' to delete it for good. This is how you launch ads (e.g. an RSA) that were created PAUSED for safety. REMOVED matters during an iteration cycle: Google allows only 3 enabled RSAs per ad group, so revising copy repeatedly leaves dead paused ads behind that keep occupying the group — removing them is the only way to clean up. Removal cannot be undone, the ad and its history are gone, so pause first if you are unsure. For the whole ad group use update_ad_group_status, for the campaign use update_campaign_status. confirm=false → dry-run.
    Connector
    Destructive
    OAuth
  • Create a new or update an existing Google Ads text ad on the Metadata platform. IMPORTANT: This tool is ONLY for Google Ads (GOOGLE_ADS channel) text ads. Do NOT use this tool for Facebook, LinkedIn, or Instagram ads. For other channels or ad types use the dedicated tools: create_update_image_ad (IMAGE/GIF) or create_update_video_ad (VIDEO). CAROUSEL is not yet covered by the new tools — flag it if you hit that case. BEHAVIOR: - If "id" is NOT provided → creates a new Google Ads text ad. - If "id" IS provided → updates the existing Google Ads text ad with that ID. CRITICAL — GOOGLE ADS CHARACTER LIMITS (HARD LIMITS — API WILL REJECT IF EXCEEDED) - Headlines: MAXIMUM 30 characters each (minimum 3, maximum 15 headlines) - Descriptions: MAXIMUM 90 characters each (2 to 4 descriptions). Each description string MUST be 90 characters or fewer. Count every letter, space, and punctuation mark. 90 is the absolute maximum. - Ad name: MAXIMUM 50 characters WARNING: DESCRIPTIONS — 90 CHARACTER HARD LIMIT — READ THIS CAREFULLY THIS IS THE #1 MOST COMMON FAILURE MODE. DO NOT SKIP THIS SECTION. - 90 characters is an ABSOLUTE, NON-NEGOTIABLE HARD CEILING. - 91 characters = REJECTION. 100 characters = REJECTION. 89 characters = OK. - "Characters" means EVERY character: letters, digits, spaces, punctuation, apostrophes, hyphens, slashes, line breaks, and emoji code points. ALL count. - There is NO grace, NO rounding, NO partial credit. The boundary is exact. - The MCP schema enforces maxLength=90 — an over-length string is rejected before your tool call even runs. The server ALSO truncates as a backstop, meaning your over-length copy will be SILENTLY CUT MID-SENTENCE if it somehow slips through. Either way, you will not get the description you wrote. - This rule applies to EACH description independently. 4 descriptions of 80 chars each is fine. 1 description of 91 chars is NOT fine. - Do NOT pad descriptions to "use the space." Shorter is always safer. - Do NOT rely on the user noticing — you are responsible for compliance. COMMON WAYS LLMs BLOW THE 90-CHAR LIMIT (avoid these): - Writing a "complete sentence" without counting first. - Adding a CTA at the end ("Sign up today!") that pushes past 90. - Including the company name AND a tagline AND a benefit in one description. - Using em dashes (—), ellipses (…), or smart quotes (" ") which still count as characters and often appear longer than expected when counted. - Trusting your "feel" for length — LLMs systematically underestimate by 5-15 characters. ALWAYS COUNT. RECOMMENDED SAFETY MARGIN: - Target 70-85 characters per description. This leaves headroom for sanitization (smart-quote conversion, whitespace normalization) and avoids edge-case rejections. 90 is the cliff — do not write to the cliff. MANDATORY PRE-CALL VALIDATION — YOU MUST DO THIS BEFORE EVERY CALL: 1. Write out each headline and count its characters — each MUST be ≤ 30 characters 2. Write out each description and count its characters — each MUST be ≤ 90 characters (this is the most common error — descriptions MUST NOT exceed 90 characters) 3. For EACH description, do an explicit character count: len(description). If the number is 91 or higher, REWRITE before calling. Do not "estimate" — count. 4. If any text exceeds the limit, rewrite and shorten it BEFORE calling the tool 5. Do NOT rely on the API to catch these errors — validate client-side first 6. When in doubt, make descriptions shorter. A 70-character description is better than a rejected 91-character one 7. If a user provides copy that is too long, shorten it yourself and proceed — do NOT submit known-bad copy and hope for the best. EXAMPLES — DESCRIPTIONS AT THE 90-CHAR BOUNDARY: - "Shop the best deals online." (27 chars) SAFE - "Free shipping on every order over fifty dollars. Sign up today!" (63 chars) SAFE - "Discover our award-winning marketing platform built for B2B teams of every size today" (89 chars) SAFE — at the edge - "Discover our award-winning marketing platform built for modern B2B teams of every size today" (94 chars) REJECTED — 4 over - "Transform your B2B marketing strategy with AI-powered automation that drives real revenue today!" (98 chars) REJECTED — REWRITE USAGE INSTRUCTIONS FOR LLM: Use this tool when users want to: - Create a new Google Ads text ad - Update an existing Google Ads text ad (headlines, descriptions, or name) - Set up a Google Ads responsive search ad with headlines and descriptions WHEN TO USE: - User asks "create a Google Ads ad" - User wants to create a text ad for Google Ads - User says "make a new Google ad with these headlines and descriptions" - User wants to update the headlines or descriptions of an existing Google Ads ad - User says "update Google ad 23149 with new headlines" WHEN NOT TO USE: - User wants to create a Facebook, LinkedIn, Instagram, or Reddit IMAGE ad → use create_update_image_ad - User wants to create a Facebook, LinkedIn, Instagram, or Reddit VIDEO ad → use create_update_video_ad - User wants to update a non-Google Ads ad → use create_update_image_ad or create_update_video_ad (whichever matches the ad's adType) INPUT PARAMETERS: - id: The ad ID (optional). If provided, the ad with this ID will be updated. If omitted, a new ad is created. This is the adLibraryId inside the creatives of the google channel in campaign response. - name: The name/label for the ad (required, max 50 characters) - headlines: Array of headline text strings (required, minimum 3, maximum 15 headlines, each STRICT MAX 30 CHARACTERS) - descriptions: Array of description text strings (required, 2 to 4 descriptions, each STRICT MAX 90 CHARACTERS — count characters carefully, this is the most common validation failure) EXAMPLE USAGE (Create): create_update_google_ads_ad( name="My Google Ad Q1 2025", headlines=["Buy Now", "Best Deals", "Free Shipping"], descriptions=["Shop the best deals online.", "Free shipping on all orders."] ) EXAMPLE USAGE (Update): create_update_google_ads_ad( id=23149, name="My Google Ad Q1 2025 Updated", headlines=["Updated Headline 1", "Updated Headline 2", "Updated Headline 3"], descriptions=["Updated description 1.", "Updated description 2."] )
    Connector
    Destructive
    API key
  • Create a multi-channel campaign using the platform's "Channel First Structure" (N×N×N) — the UI also labels it "Native Structure" / "Platform-First Structure". Your audiences, ads, and offers are organized into the ad platform's NATIVE structure (the WizNativeAdContainer entity) and optimized TOGETHER by the platform's own algorithm — ~1 experiment per channel (LinkedIn is the only exception: one experiment per container), with unified reporting and pacing. You specify the structure as explicit per-container groupings (each container is one audience + its `ad_offers` rows); the "N×N×N" label refers to the native structure holding your full set of audiences, ads, and offers together (it is NOT one isolated experiment per combination — that's Precision Optimization, `create_campaign`). Platform product copy: "Traditional hierarchical setup that leverages native platform algorithms while maintaining Metadata's pacing control, unified user experience and reporting." Sets channel.structureType=NATIVE. KEYWORDS (for tool discovery — many users ask by the math, not the product name): NxNxN, N×N×N, "NxNxN campaign", Channel First Structure, Native Structure, Platform-First Structure, channel-first, platform-first, native platform structure, WizNativeAdContainer, container-based campaign, traditional / hierarchical structure, unified reporting. NAMING CONVENTION (from the platform UI's "Campaign Structure" selector — match these exact labels): • "Channel First Structure (NxNxN)" = THIS tool (`create_native_structure_campaign`); the UI also shows "Native Structure" / "Platform-First Structure". Audiences/ads/offers grouped in the platform's native structure and optimized together (~1 experiment per channel). "native" / "platform" here = the native ad platform (LinkedIn / Facebook / Google) whose algorithms this leans on — and structureType=NATIVE matches. • "Precision Optimization (1x1x1)" = the OTHER tool, `create_campaign` — each audience×ad×offer combination tested as its own isolated experiment. Metadata's signature approach; the DEFAULT. Routing anchor: "native" / "channel first" / "platform first" / "NxNxN" → this tool; "precision" / "1x1x1" → create_campaign. ════════════════════════════════════════════════════════════════════════════════ WARNING: TWO CAMPAIGN-CREATION TOOLS EXIST — READ BEFORE PICKING ONE ════════════════════════════════════════════════════════════════════════════════ CRITICAL: REMEMBER — HOW TO CHOOSE THE STRUCTURE (the user's decision always wins): 1. If the user explicitly names one, RESPECT IT — "native" / "Native Structure" / "Channel First" / "Platform-First" / "NxNxN" → create_native_structure_campaign (this tool); "precision" / "Precision Optimization" / "1x1x1" → create_campaign. 2. ELSE, if the request involves MANY ads AND audiences (Precision Optimization makes one experiment per combination — a large experiment count), ASK the user which structure they want before creating — do not guess. 3. OTHERWISE, DEFAULT to Precision Optimization (1×1×1) → create_campaign (NOT this tool). The two build structurally different, non-swappable campaigns — so once the user decides, respect that decision for the rest of the campaign. USE THIS TOOL (`create_native_structure_campaign`) — "Channel First" / "Native Structure" (N×N×N) — WHEN: • The user says "native", "Native Structure", "Channel First Structure", "channel-first", "Platform-First Structure", "platform-first", "NxNxN", "N×N×N", "WizNativeAdContainer", or asks for the traditional / hierarchical / native-platform structure. • The user wants the ad platform's native structure to group and optimize audiences/ads/offers together (~1 experiment per channel, unified reporting) rather than an isolated experiment per combination. • The user provides explicit per-container groupings of one audience + its (ad, offer) pairs. USE `create_campaign` ("Precision Optimization", 1×1×1) INSTEAD — DO NOT USE THIS TOOL — WHEN: • The user says "Precision Optimization", "precision", "1x1x1", "1×1×1", or wants every audience×ad×offer combination tested separately in its own experiment. • The user wants maximum budget control / fastest per-combination learning. • No structure was specified — Precision Optimization (`create_campaign`) is the DEFAULT. If you're unsure whether the user wants isolated per-combination experiments (→ `create_campaign`, Precision Optimization) or the native-platform grouped structure (→ this tool, Channel First), ASK which structure they want — switching modes after creation requires rebuilding the campaign from scratch. The two tools produce structurally different campaigns on the backend (channel.structureType = METADATA for create_campaign, = NATIVE for this tool) and are NOT swappable mid-campaign. Pick correctly the first time. ════════════════════════════════════════════════════════════════════════════════ WHEN TO USE THIS TOOL: - The user explicitly asks for "Channel First Structure" / "Native Structure" / "Platform-First Structure" / N×N×N / WizNativeAdContainer / the native-platform structure. - You want the ad platform's algorithm to optimize audiences/ads/offers together under a unified structure (~1 experiment per channel) instead of isolating every combination. - You want a compact, platform-managed experiment footprint with unified reporting. WHEN NOT TO USE THIS TOOL: - The user wants "Precision Optimization" (1×1×1) — every combination tested as its own isolated experiment — use `create_campaign`. - No structure was specified (default is Precision Optimization) — use `create_campaign`. CAMPAIGN TYPES (same as create_campaign): 1. "Lead Gen" — only Lead Gen (LG) offers allowed in any container. 2. "Brand Awareness" — both LG and LP offers allowed. WARNING: OFFER-CHANNEL CHANNEL-LOCK STILL APPLIES Lead Gen offers are channel-locked at the offer's creation time. A container under `linkedin.containers` MUST reference an offer whose data.channel='LINKEDIN' (or any Landing Page offer). Cross-channel reuse silently produces a non-serving campaign. The server does NOT validate the pairing. Same rules as create_campaign: - linkedin.containers[i].ad_offers[].offer → LINKEDIN-locked LG OR any LP - facebook.containers[i].ad_offers[].offer → FACEBOOK-locked LG OR any LP - instagram.containers[i].ad_offers[].offer → FACEBOOK/INSTAGRAM-locked LG OR any LP - google.containers[i].ad_offers[].offer → Landing Page offers ONLY (Google Ads has no native LG form support) - reddit.containers[i].ad_offers[].offer → Landing Page offers ONLY (Reddit has no native LG form support) - microsoft.containers[i].ad_offers[].offer → MICROSOFT_ADS-locked LG OR any LP Each container is one audience × a LIST of (ad, offer) pairs (`ad_offers`, 1+). Put several pairs in one container to group multiple ads/offers under the same audience — the platform's native ad-set with multiple Ad/Offer rows. "1 audience → 3 ads → 1 offer" is ONE container whose `ad_offers` holds 3 pairs that repeat the same `offer` id. (Each pair is exactly one ad with one offer; to run the same audience as two separate ad-sets, send two containers instead.) WARNING: SEARCH CHANNELS ARE KEYWORD-FIRST — `audience` IS OPTIONAL FOR GOOGLE ADS & MICROSOFT ADS Google/Microsoft search ad groups are keyword-targeted, so a search container may OMIT `audience` and run keyword-only (just keywords + ad_offers). The platform allows audience-less native search containers, so this tool no longer forces an audience there. `audience` STAYS REQUIRED for the audience-targeted social channels (LinkedIn / Facebook / Instagram / Reddit). A search container with neither an audience nor keywords has nothing to target and is rejected. REQUIRED FIELDS: - campaignType: "Lead Gen" | "Brand Awareness" - name: unique campaign name - startDate / endDate: YYYY-MM-DD - budgetGroup: budget group name - At least one channel block with a non-empty containers list PER-CHANNEL SHAPE: Every channel block (linkedin / facebook / instagram / google / reddit / microsoft) takes: containers: [ { name: "string (<=255 chars) — visible in the platform UI", audience: "audience name (resolved server-side via the same matched-poll create_campaign uses). REQUIRED for LinkedIn/Facebook/Instagram/Reddit; OPTIONAL for Google/Microsoft search (omit it for keyword-only ad groups)", ad_offers: [ {ad: <int WizCreative ID>, offer: <int offer ID>}, ... ] // 1+ Ad/Offer pairs sharing this container's audience; repeat the same offer id to run several ads on it, target_group: "optional Targeting Group name (singular — one per container)", exclude_audience: "optional audience name to use as the exclude group for this container" } ] SEARCH-CHANNEL EXTRAS (Google Ads + Microsoft Ads, per container): keywords: ["string", ...] // free-text phrases — created in the keyword library and grouped into this container's keyword group keyword_ids: [<int>, ...] // optional; existing keyword-library IDs (from list_keywords) to put in this container's group — unioned with `keywords` match_type: "PHRASE"|"BROAD"|"EXACT" // optional; match type for this container's keyword group (default PHRASE) negative_keyword_lists: ["name", ...] // optional; applied at the channel level On a search channel `audience` is OPTIONAL: a keyword-only container (keywords + ad_offers, no audience) is valid and is how non-brand / pure-keyword search is normally structured. You can still pass an audience to layer one on. The keyword group is created and linked to the container automatically. A search container with neither an audience nor keywords (`keywords`/`keyword_ids`) is rejected (nothing to target). AUDIENCE NAME RESOLUTION: - `audience` and `exclude_audience` are NAMES, not IDs. Same lookup path as create_campaign — the tool waits up to ~20s per channel for a freshly-created audience to become attachable (firmographics + FB/IG can take 8-15s). - Audience names are resolved BEFORE any container elements are created: a container whose `audience` cannot be resolved is dropped up front (no keyword group or other element is left behind for it) and the failure is reported in the response `errors[]`. The error states whether retrying can help ("may still be matching") or not ("not available on this channel") — do NOT blind-retry the latter. The rest of the campaign still gets built. - On Google/Microsoft search containers `audience` may be omitted entirely (keyword-only) — only names that are actually provided are resolved, so leaving it out costs no polling and raises no error. AD AND OFFER ARE IDS (one `ad_offers` pair = one ad + one offer): - `ad` is the ID returned by `create_update_image_ad` or `create_update_video_ad`. - `offer` is the ID returned by `create_update_offer`. The tool looks up each unique offer to discover whether it's a Landing Page or Lead Gen Form and routes it into the right `nativeAds[].landingPageId` vs `nativeAds[].leadGenFormId` slot. Every pair becomes one `nativeAds[]` entry under the container. BID STRATEGY (automatic): Same defaults as create_campaign: - LinkedIn / Facebook / Instagram → AUTO_BID - Google Ads / Microsoft Ads → TARGET_SPEND (device modifiers reset) - Reddit → objective-driven, mirroring the platform UI: Lead Gen forces CLICKS (Traffic) + AUTO_BID; Brand Awareness keeps IMPRESSIONS + MANUAL_BID. Adjust later with update_reddit_channel_settings. WHAT THE TOOL DOES FOR YOU (single call, no follow-up needed): Creates the campaign shell and its budget group, enables each requested channel and sets it to the NATIVE structure, builds the per-container keyword group on Google / Microsoft Ads search channels, creates one native ad container per grouping with its ad/offer pairs, applies the bid strategy, and sets the schedule. The response reflects the final campaign state — you do not need to sequence or repeat any of this. RESPONSE: Same top-level shape as create_campaign (`success`, `campaign_id`, `campaign_url`, `status`, `optimization_group`, `summary`, `full_response`), including the `refusal="name_taken"` refusal when the account already holds a campaign under the requested name (only the name is the problem: call again with a different name, never with the same one). The per-channel breakdown returns a `containers` array — `[{id, name, experiment_id, audience_group_id, targeting_group_id, group_exclude_id, keyword_group_id, native_ads: [{id, ad_id, landing_page_id, lead_gen_form_id}]}]` — instead of the legacy `audiences`/`ad_groups`/`lead_gen_forms` arrays. On partial failures, returns success=false plus `errors[]` with per-container detail. EXAMPLE (Lead Gen, LinkedIn-only, two containers): create_native_structure_campaign(campaign_data={ "campaignType": "Lead Gen", "name": "Q3_ABM_Native_2026", "startDate": "2026-06-01", "endDate": "2026-08-31", "budgetGroup": "BoFu", "linkedin": { "containers": [ {"name": "IT Mgrs > Demo > Form", "audience": "IT Managers - NA", "ad_offers": [{"ad": 156502, "offer": 57538}]}, {"name": "CTOs > Demo > Form", "audience": "CTOs - Tech", "ad_offers": [{"ad": 156485, "offer": 57504}]} ] } }) EXAMPLE (one audience → 3 ads on the SAME offer, ONE container — the multi-ad ad-set): create_native_structure_campaign(campaign_data={ "campaignType": "Brand Awareness", "name": "Q3_3Ads_1Offer_2026", "startDate": "2026-06-01", "endDate": "2026-07-31", "budgetGroup": "Brand", "facebook": { "containers": [ {"name": "ICP > 3 creatives > TOF offer", "audience": "26-Q2-ICP-AllPersonas-NA", "ad_offers": [ {"ad": 210801, "offer": 67269}, {"ad": 210802, "offer": 67269}, {"ad": 210803, "offer": 67269} ]} ] } }) EXAMPLE (Brand Awareness, Google + LinkedIn, with keywords): create_native_structure_campaign(campaign_data={ "campaignType": "Brand Awareness", "name": "Q3_Brand_Native_2026", "startDate": "2026-06-01", "endDate": "2026-07-31", "budgetGroup": "Brand", "linkedin": { "containers": [ {"name": "Professionals A", "audience": "Professional Audience", "ad_offers": [{"ad": 173669, "offer": 57538}]} ] }, "google": { "containers": [ {"name": "CRM Search", "audience": "Tech Decision Makers", "ad_offers": [{"ad": 175260, "offer": 57600}], "keywords": ["crm software", "lead gen tools"], "negative_keyword_lists": ["Competitor Brands"]} ] } }) EXAMPLE (Brand Awareness, Google keyword-only — NO audience, pure non-brand search): create_native_structure_campaign(campaign_data={ "campaignType": "Brand Awareness", "name": "Q3_NonBrand_Search_2026", "startDate": "2026-06-01", "endDate": "2026-07-31", "budgetGroup": "Search", "google": { "containers": [ {"name": "Incident Response", "ad_offers": [{"ad": 210804, "offer": 67269}], "keywords": ["incident response platform", "on-call alerting"], "negative_keyword_lists": ["Competitor Brands"]} # note: no "audience" key — keyword-targeted ad group ] } }) BEST PRACTICES: 1. Decide each container's audience and its `ad_offers` pairs up front — this tool will not invent pairings for you. Group several ads under one audience by adding pairs to `ad_offers`. On Google/Microsoft search, audience-less (keyword + ad_offers) containers are valid; pure non-brand search normally has no audience. On Reddit, targeting is the `target_group` (create_reddit_target_group) and `audience` is optional — an audience only exists on a channel the account has CONNECTED, so naming one on a disconnected Reddit loses the container. 2. Use descriptive container names — they show up in the platform UI as the ad-set/ad-group label. 3. For Google Ads, put related keywords in the same container (each container becomes one keyword group). Don't pile dozens of unrelated keywords into a single container. 4. Use Brand Awareness for any container that needs Landing Page offers — Lead Gen campaigns reject LP offers. 5. The campaign URL is returned in the response: https://platform.metadata.io/hub/advertise/campaigns/{campaign_id}
    ConnectorAPI key
  • Create OR update an IMAGE (or GIF) ad on Facebook, Instagram, LinkedIn, and/or Reddit. TO UPDATE: include `id`; to CREATE: omit it. CREATIVE WORKFLOW: 1. Upload the image/GIF via `upload_image_creative` → response gives `id` (the imageLibraryId). 2. Pass that integer as `creativeID` here. - Need a new image? `generate_brand_creative` → `upload_image_creative` → `create_update_image_ad`. ALSO KNOWN AS: create image ad, update image ad, edit image ad, modify image ad, image creative, post image, image post, photo ad. KEYWORDS: image, gif, create, update, edit, modify, ad, ads, image ad, image ads, image creative, photo, picture, banner, image campaign, image upload, LinkedIn image, Facebook image, Instagram image, Reddit image, IG post. CLIENT-SIDE VALIDATION (refuses what the platform UI would also reject): - adName: required, max 50 chars, pattern `[a-zA-Z0-9 _.?,:'/+\-=&;%$#\[\]|()]`. - creativeID: required integer (imageLibraryId from `upload_image_creative`). - Landing-page URL is per channel (`facebookDisplayURL`, `instagramDisplayURL`, `linkedinDisplayURL`, `redditDisplayURL`). Required for FB/IG/LinkedIn, optional for Reddit. Per-channel caps: LinkedIn max 2000, Reddit max 100, FB/IG no length rule. URL format accepts both `metadata.io` and `https://metadata.io` for IMAGE ads. If only one channel's URL is set the server fans it across the other targeted channels; each channel's cap is then enforced per channel. - LinkedIn: linkedinText (required, max 3000), linkedinHeadline (required, max 200), linkedinDescription (optional, max 300 — IMAGE only), linkedinCTA (required, must be a valid LinkedIn CTA enum). - Facebook: metaCTA (required), facebookText (required, no length rule on Facebook), facebookHeadline (required, max 250), facebookDescription (optional, max 300). - Instagram: metaCTA (required), instagramText (required, max 125), instagramHeadline (required, max 40), instagramDescription (optional, max 30). - FB+IG ad with one body text: set just one of facebookText / instagramText and the server copies it across (capped at the receiving channel's limit). Set both explicitly only when you want per-channel copy. - Reddit: redditHeadline (required, max 300), redditCTA (required, must be a valid Reddit CTA enum). redditThumbnailLibraryId is optional and defaults to creativeID. COMMON CTA VALUES: - LinkedIn: LEARN_MORE, REGISTER, APPLY_NOW, DOWNLOAD, JOIN, SIGN_UP, GET_QUOTE, ATTEND, REQUEST_DEMO, SUBSCRIBE. (UNLOCK_FULL_DOCUMENT is DOCUMENT-only — use create_update_document_ad, not this tool.) - Facebook/Instagram: APPLY_NOW, DOWNLOAD, GET_QUOTE, LEARN_MORE, SIGN_UP, SUBSCRIBE. (SCREAMING_SNAKE form only; the platform supports a strict subset of Meta's native catalog. Out-of-set values like BOOK_NOW / GET_STARTED are rejected.) - Reddit: Apply Now, Contact Us, Download, Get a Quote, Learn More, Play Now, Sign Up, View More, Watch Now, Book Now, Listen Now, Read More, Subscribe. See `create_update_video_ad` for video-creative ads (different libraryId source + stricter URL format).
    Connector
    Destructive
    API key
  • Create OR update a VIDEO ad on Facebook, Instagram, LinkedIn, and/or Reddit. TO UPDATE: include `id`; to CREATE: omit it. CREATIVE WORKFLOW: 1. Upload the video via `upload_video_creative` → response gives `id` (the videoLibraryId). 2. Pass that integer as `creativeID` here. - For Reddit, ALSO upload a still thumbnail via `upload_image_creative` and pass its imageLibraryId as `redditThumbnailLibraryId` (required; the video cannot be its own thumbnail). ALSO KNOWN AS: create video ad, update video ad, edit video ad, modify video ad, video creative, post video, video post, motion ad. KEYWORDS: video, create, update, edit, modify, ad, ads, video ad, video ads, mp4, motion, video creative, video campaign, video upload, video post, video promo, LinkedIn video, Facebook video, Instagram video, Reddit video, IG reel. CLIENT-SIDE VALIDATION (refuses what the platform UI would also reject): - adName: required, max 50 chars, pattern `[a-zA-Z0-9 _.?,:'/+\-=&;%$#\[\]|()]`. - creativeID: required integer (videoLibraryId from `upload_video_creative`). - Landing-page URL is per channel (`facebookDisplayURL`, `instagramDisplayURL`, `linkedinDisplayURL`, `redditDisplayURL`). Required for FB/IG/LinkedIn, optional for Reddit. Per-channel caps: LinkedIn max 2000, Reddit max 100, FB/IG no length rule. For VIDEO the URL MUST be ABSOLUTE (http:// or https:// is required); inputs like `metadata.io` or `www.foo.com` are rejected the same way the UI rejects them. If only one channel's URL is set the server fans it across the other targeted channels. - LinkedIn: linkedinText (max 3000, OPTIONAL for VIDEO unlike IMAGE), linkedinHeadline (required, max 200), linkedinCTA (required, valid enum). linkedinDescription is NOT accepted on VIDEO ads (the platform DTO does not declare it). - Facebook: metaCTA (required), facebookText (required, no length rule on Facebook), facebookHeadline (required, max 250), facebookDescription (optional, max 300). - Instagram: metaCTA (required), instagramText (required, max 125), instagramHeadline (required, max 40), instagramDescription (optional, max 30). - FB+IG ad with one body text: set just one of facebookText / instagramText and the server copies it across (capped at the receiving channel's limit). Set both explicitly only when you want per-channel copy. - Reddit: redditHeadline (required, max 300), redditCTA (required, valid enum), redditThumbnailLibraryId (REQUIRED — separate IMAGE library id). COMMON CTA VALUES: same as `create_update_image_ad` (see that tool for the lists). META UPLOAD READINESS: a video library id means ingestion, not completion of Facebook/Instagram's asynchronous upload. The entire ad batch is refused before writes unless every requested Meta video channel reports READY. Read fetch_creative_details later; do not build campaigns from a refused call, busy-poll or claim an unfinished ad is ready. Existing ads saved without a Meta video id must be rebuilt or updated after upload completion and refreshed in the campaign. See `create_update_image_ad` for image/GIF ads (the URL rule is looser there). For LinkedIn CTV (Connected TV) ads use `create_update_ctv_ad`; the video must be uploaded with `upload_video_creative(usage_type="CTV")`.
    Connector
    Destructive
    API key
  • Create OR update a LinkedIn CTV (Connected TV) video ad. LinkedIn only. TO UPDATE: include `id`; to CREATE: omit it. CTV ads play on streaming TV inventory through the LinkedIn Audience Network. On the platform they are LinkedIn VIDEO ads with adType=CTV, and they carry rules the campaign must meet: - Campaign type Brand Awareness only (never Lead Gen); the LinkedIn channel launches as objective BRAND_AWARENESS optimized for REACH. - The LinkedIn channel MUST use AUTO_BID (a manual bid fails pre-launch validation); `update_linkedin_channel_settings` sets it. - Audiences and target groups may target the United States and Canada ONLY; any other location fails pre-launch validation. - Video spec, enforced when the creative is uploaded: 6 to 60 seconds, 1920x1080 or 1280x720, at most 500 MB. LinkedIn recommends exactly 15, 30, 45 or 60 seconds for delivery. CREATIVE WORKFLOW: 1. Upload the video via `upload_video_creative` with `usage_type: "CTV"` -> response gives `id` (the videoLibraryId). The platform runs the CTV checks at that step and rejects a non-compliant file. 2. Pass that integer as `creativeID` here. A video uploaded without the CTV usage type is not eligible for a CTV ad. 3. Ann attaches the returned ad id to a Brand Awareness campaign's LinkedIn channel like any other ad. ALSO KNOWN AS: connected tv ad, ctv ad, streaming tv ad, linkedin tv ad, ott ad, tv commercial on linkedin. KEYWORDS: ctv, connected tv, streaming, tv, ott, linkedin ctv, video, brand awareness, reach, audience network, commercial. CLIENT-SIDE VALIDATION (refuses what the platform UI would also reject): - adName: required, max 50 chars, same pattern as the other ad tools. - creativeID: required integer (videoLibraryId). - linkedinDisplayURL: required, ABSOLUTE (http:// or https://), max 2000. - linkedinHeadline: required, max 200. linkedinCTA: required enum. - linkedinText: optional, max 3000. No description field (same DTO as LinkedIn VIDEO ads). COMMON CTA VALUES: same as `create_update_video_ad` on LinkedIn. RESPONSE: same envelope as `create_update_video_ad` (`created_ads[]` with adType "CTV", channelType "LINKEDIN"). See `create_update_video_ad` for in-feed video ads and `create_update_image_ad` for image / GIF ads.
    Connector
    Destructive
    API key
  • Add an extra clickable shortcut (sitelink) that appears beneath a Google Ads ad — helpful deep-links like "See Pricing", "Book a Demo", or "Contact Sales" with two short description lines. Sitelinks lift click-through rate by giving searchers alternate landing paths to the same advertiser. ALSO KNOWN AS: sitelink, site link, extra link, ad link, secondary link, deep link, additional link, jump link KEYWORDS: sitelink, site link, link, deep link, shortcut, google ads, extension, pricing link, demo link, contact link, landing page, CTR, click through WHEN TO USE: - "Add a sitelink to our Google Ads library" - "Create a 'See Pricing' / 'Book a Demo' / 'Contact Sales' link extension" - "Register a new sitelink for the homepage redesign" - "I need a shortcut under our search ads that points to the new pricing page" WHEN NOT TO USE: - Want a non-clickable selling-point snippet ("Free Shipping", "24/7 Support") → use create_google_callout_extension - Want a labeled list of offerings (e.g. "Brands: Nest, Nexus") → use create_google_structured_snippet_extension - Same sitelink for Microsoft Ads / Bing → use create_microsoft_sitelink_extension (library entries are per-channel) - Anything for Facebook / LinkedIn / Reddit — ad extensions are a search-channel-only concept INPUTS (all required): - url: destination the sitelink opens. - link_text: visible link text (1-25 chars). - description1: first description line under the link (1-35 chars). - description2: second description line (1-35 chars). EXAMPLE: create_google_sitelink_extension( url="https://example.com/pricing", link_text="See Pricing", description1="Plans for every team size", description2="Start free, upgrade anytime", ) Returns the persisted extension (id, externalId, type=SITELINK, channel=GOOGLE_ADS). A 400 usually means a character-limit was exceeded.
    ConnectorAPI key
  • SHOW what Ad Library ads ACTUALLY LOOK LIKE (creative, copy, page name), in a SELF-CONTAINED card. Pass up to 8 ad ids in ad_ids and ONE call renders them all as a gallery the user can click through; pass one id for a single full-size ad. Video ads PLAY in the card and carousel ads show their slides. Use this right after adsap_search_ad_library whenever the user asks to SEE or SHOW ads: a table of links shows nothing, so render the top results (up to 8) in the SAME turn instead of offering to. One call takes about 8 seconds whatever the number of ads, so always batch: never call once per ad. This is public ad-transparency data, not your own ads (for those use adsap_get_ad_preview). It renders ads exactly as the Ad Library shows them, so it works only for ads that search returned in the first place.
    ConnectorAPI key
  • Search Meta's public Ad Library for ads (competitor research / ad transparency). Find the ads a competitor page is currently running, or ads matching a keyword, in given countries. Returns each ad's page, creative text, platforms, languages, delivery dates, days_running, eu_total_reach (people reached in the EU: with days_running, the public signal of which ads an advertiser is scaling), a public Ad Library permalink, and a pagination cursor. Filters: media_type (STATIC for image ads only, VIDEO for video only), exact-phrase matching, platform, language, delivery dates. A keyword search also returns data.pages, the distinct advertisers found, so you can re-run on one page_id. Read-only public data (not your own account's ads — use adsap_list_campaigns/adsap_get_insights for that). COVERAGE CEILING (Meta's rule, not ADSAP's): the public Ad Library API returns ordinary commercial ads ONLY where they reached the EU or UK. Ads that never reached the EU/UK are returned only when they are political or social-issue ads. So a US-only (or any non-EU/UK) commercial search returns zero results however it is phrased, and that empty result is NOT evidence the advertiser is inactive. Never promise non-EU/UK competitor research from this tool; point the user at the public Ad Library website for those markets.
    ConnectorAPI key
  • Create a complete Google Ads Search campaign in ONE atomic request: budget, campaign (ALWAYS created PAUSED — activate later with adsap_google_set_entity_status), location/language targeting, ad group, keywords, and a responsive search ad. Use dry_run: true first — Google validates the whole operation chain without creating anything; show the plan, get confirmation, then execute. Location ids come from adsap_google_search_geo_targets. bidding_strategy 'auto' (default) resolves via a conversion-tracking preflight — maximize_conversions when the account has conversion actions, otherwise target_spend (Maximize Clicks) with an explanatory warning — and can always be overridden explicitly. ad_account_id is the bare 10-digit customer ID. For Meta campaigns use adsap_create_campaign instead.
    ConnectorAPI key
  • Duplicate an existing Meta ad set into 1-10 copies, keeping ALL its ads (including ads with no delivery yet). Every copy and every recreated ad is PAUSED. Each recreated ad reuses the source ad's creative, so the original post and its likes/comments are preserved. Per copy you can override the name, the geo targeting (geo-split flow: one copy per region/country) and daily spend limits — as absolute amounts or as a % of the campaign daily budget (Advantage campaign budget campaigns only; the % auto-computes the absolute like Ads Manager). ALWAYS call with dry_run: true first: it returns the plan (source ad set, the exact ads that will be recreated, per-copy overrides, warnings) — show it to the user and only execute after they confirm. Partial failures are reported per copy and per ad in data.copies[].errors with Meta's own error text.
    ConnectorAPI key
  • Reads the actual AD COPY of specific LinkedIn ads — built for "which messaging performs best" analysis. Give it a shortlist (comma-separated, max 60): `creative_ids` (urn:li:sponsoredCreative:N or bare N — e.g. the top pivotValues from linkedin_campaign_analytics pivot=CREATIVE) and/or `post_urns` (urn:li:share:N / urn:li:ugcPost:N). Per creative you get: `ad_copy` (the ACTUAL ad text of post-based ads), `author_type` / `is_thought_leader_ad`, format, name, headline, description, landing_page, post_urn, `post_permalink`, `ad_library_url` and — where LinkedIn supports it — official `preview_url` / `preview_url_mobile`. HOW THE COPY IS OBTAINED (so you can be precise with the user): LinkedIn's Posts API is NOT open to this connector (needs `r_organization_social` / Community Management API), so the copy is read from two PUBLIC sources, in order — LinkedIn's Ad Library (`ad_copy_source: "linkedin_public_ad_library"`) and, when that is rate-limited or has no text, the post's own public page (`ad_copy_source: "linkedin_public_post_page"`). Both are verified live for Document Ads and Sponsored Content. RATE LIMIT — READ THIS BEFORE BATCHING: the Ad Library throttles hard. Measured live: 10 lookups fine, 60 in one go → most return HTTP 429 and the penalty window lasts minutes. So ask for the TOP rows (10–20 creative_ids), not the whole account. A throttled row comes back with `ad_copy_status: "ad_library_rate_limited"` — that means TEMPORARY, retry smaller in a few minutes; it does NOT mean the ad has no copy. `is_thought_leader_ad` / `author_name` describe the POST'S AUTHOR (a person = Thought Leader Ad, vs the company page); `advertiser_name` is the paying advertiser and is almost always the company. When the author cannot be read the field is null (never false) and `thought_leader_ad_status` explains why — do not report "not a Thought Leader Ad" on a null. When a row has no `ad_copy`, say so plainly and give `post_permalink` / `ad_library_url`. NEVER fabricate ad copy and never pass the internal creative `name` off as the ad text. Text-based formats (textAd, spotlight, follow/jobs ads) carry their copy inline, so for those the headline/description here IS the real ad copy.
    ConnectorOAuth
  • Lists the Instagram accounts usable from a Meta ad account. Use this when list_meta_pages shows no Page, or the Instagram account is not linked to a Page. FOUR sources are merged, so an account the Ads Manager 'connected Instagram accounts' list omits is still found: (1) act_{id}/connected_instagram_accounts, (2) the legacy instagram_accounts edge, (3) the ad account's own AD HISTORY (adcreatives → instagram_user_id) — an Instagram account this ad account has already advertised from is usable even when both link edges are empty, (4) the FACEBOOK PAGE BRIDGE — in practice an Instagram business account is linked to a Page, not to the ad account, so the Pages assigned to this ad account (and, when nothing else was found, the user's other Pages) are read for instagram_business_account. Each entry: ig_user_id (pass it to list_meta_instagram_posts or create_meta_instagram_post_ad), username, and `source` (ad_account_link | previously_advertised | page_linked). For page_linked entries check `usable_from_this_ad_account`: false means the Instagram account exists and is linked to a Page, but that Page is not assigned to this ad account — the blocker is the Page assignment, not Instagram. If the list is EMPTY, no Instagram account is reachable from this ad account: the user must add it in Meta Business Suite → Settings → Accounts → Instagram accounts, then 'Assign to people and assets' → this ad account. A missing account here usually indicates a sharing/permission gap rather than a non-existent account; check every returned `source` first, and check list_meta_pages(account_id=...) for the Page-assignment cause. account_id comes from list_meta_ad_accounts.
    ConnectorOAuth
  • Permanently remove an ad group from a live Google Ads campaign. All keywords and ads in it stop serving. **Irreversible** — Google Ads sets status=REMOVED rather than truly deleting, but the only way back is to recreate the ad group + keywords + ads from scratch. Prefer pause_campaign (whole campaign) or remove_keywords (specific keywords) for less drastic interventions. Use this only when a whole thematic block of the campaign needs to go (e.g. 'commercial leads' ad group when the user pivots to residential-only).
    Connector
    Destructive
    OAuth
  • Create a new or update an existing Microsoft Ads (Bing) text ad on the Metadata platform. IMPORTANT: This tool is ONLY for Microsoft Ads (MICROSOFT_ADS channel) text ads. Ad library entries are PER-CHANNEL: a Google RSA can NOT be attached to a Microsoft Ads channel, and vice versa. Building the "same" ad for both channels means two calls, one per tool. For Google Ads text ads use create_update_google_ads_ad. Do NOT use this tool for Facebook, LinkedIn, Instagram or Reddit ads: use create_update_image_ad (IMAGE/GIF) or create_update_video_ad (VIDEO). ALSO KNOWN AS: Microsoft Ads text ad, Bing text ad, Bing search ad, MS Ads ad, Microsoft responsive search ad BEHAVIOR: - If "id" is NOT provided -> creates a new Microsoft Ads text ad. - If "id" IS provided -> updates the existing Microsoft Ads text ad with that ID. CHARACTER LIMITS (HARD LIMITS — THE API REJECTS ANYTHING OVER) Microsoft Ads and Google Ads share one text-ad shape on the platform, so the limits are identical: - Headlines: MAXIMUM 30 characters each (minimum 3, maximum 15 headlines) - Descriptions: MAXIMUM 90 characters each (minimum 2, maximum 4 descriptions) - Ad name: MAXIMUM 50 characters DESCRIPTIONS — 90 CHARACTER HARD LIMIT — READ THIS CAREFULLY THIS IS THE #1 MOST COMMON FAILURE MODE. - 90 characters is an ABSOLUTE ceiling. 91 = REJECTION. 89 = OK. - EVERY character counts: letters, digits, spaces, punctuation, apostrophes, hyphens, line breaks, emoji. - The MCP schema enforces maxLength=90, and the server truncates as a backstop, so over-length copy is either rejected outright or SILENTLY CUT MID-SENTENCE. - Target 70-85 characters per description. Do not write to the cliff. - LLMs systematically underestimate length by 5-15 characters. ALWAYS COUNT, never estimate. EVERY HEADLINE AND EVERY DESCRIPTION MUST BE UNIQUE The platform rejects the WHOLE ad when two headlines carry identical text ("Enter a headline that is different from: '<text>'"), and applies the same rule to descriptions. Writing 12 real headlines plus 3 near-copies of them is the second most common rejection. Make every line genuinely different. NO EXCLAMATION MARK IN A HEADLINE "!" is rejected in headline text ("! is not supported"). Descriptions accept it. DYNAMIC KEYWORD INSERTION A headline may use the "{KeyWord:fallback text}" form; the platform measures the 30-character limit against the fallback text inside the braces. MANDATORY PRE-CALL VALIDATION — DO THIS BEFORE EVERY CALL: 1. Count each headline: every one MUST be 30 characters or fewer, and free of "!". 2. Count each description: every one MUST be 90 characters or fewer. 3. Check for repeats across headlines, and across descriptions. Rewrite any duplicate. 4. Rewrite anything over the limit BEFORE calling. Do not submit known-bad copy and hope. USAGE INSTRUCTIONS FOR LLM: Use this tool when users want to: - Create a new Microsoft Ads / Bing text ad - Update an existing Microsoft Ads text ad (headlines, descriptions, or name) - Give a Microsoft Ads campaign the ad it needs to become launch-ready WHEN TO USE: - User asks "create a Microsoft Ads ad" / "Bing ad" / "MS Ads search ad" - A campaign has Microsoft Ads enabled and the channel has no ad yet - User says "update Microsoft ad 23149 with new headlines" WHEN NOT TO USE: - User wants the Google Ads version of the ad -> use create_update_google_ads_ad - User wants a Facebook, LinkedIn, Instagram or Reddit IMAGE ad -> use create_update_image_ad - User wants a Facebook, LinkedIn, Instagram or Reddit VIDEO ad -> use create_update_video_ad - User wants a sitelink, callout or other extension -> use the create_microsoft_*_extension tools INPUT PARAMETERS: - id: The ad ID (optional). If provided, that ad is updated. If omitted, a new ad is created. This is the adLibraryId inside the creatives of the microsoft channel in a campaign response. - name: The name/label for the ad (required, max 50 characters) - headlines: Array of headline text strings (required, minimum 3, maximum 15, each STRICT MAX 30 CHARACTERS, all distinct, no "!") - descriptions: Array of description text strings (required, minimum 2, maximum 4, each STRICT MAX 90 CHARACTERS, all distinct) EXAMPLE USAGE (Create): create_update_microsoft_ads_ad( name="Bing Hosting Q1 2026", headlines=["EU Data Centers", "Local Expert Support", "Hosting Built For Founders"], descriptions=["Keep your business data in Europe.", "2000+ local experts, one platform."] ) EXAMPLE USAGE (Update): create_update_microsoft_ads_ad( id=23149, name="Bing Hosting Q1 2026 v2", headlines=["Updated Headline 1", "Updated Headline 2", "Updated Headline 3"], descriptions=["Updated description one.", "Updated description two."] )
    Connector
    Destructive
    API key