← back to blog
    Berner SetterwallSeptember 9, 20266 min read

    Bing Ads Is Live in Cogny: Audit and Run Microsoft Advertising From an Agent

    Microsoft Advertising is the paid-search account almost everyone has and almost nobody opens. It was created with Import from Google Ads, it spends a few thousand a month, and its search-term report has not been read since the import. That neglect is exactly what an agent is good at fixing, and until today the agent could not reach it. Now it can: Bing Ads is a live MCP integration in Cogny, built directly on the Bing Ads API v13.

    A naming note, because Microsoft has renamed this product twice: the platform is called Microsoft Advertising, the API is still the Bing Ads API, and the searches come in on Bing Ads. Same account, same campaigns. We use the name people search for.

    It is a Microsoft sign-in, not an API key: you authorize once with the Microsoft account that has a role on your ad accounts, pick which accounts the workspace may use, and every tool works — from the Cogny chat, from the Cogny CLI, or from any MCP client pointed at app.cogny.com/mcp.


    TL;DR

    • Bing Ads is live now. Connect it under your warehouse Settings → Cogny Managed MCPs with your Microsoft sign-in, then choose the ad accounts. Cogny supplies the API developer token, so there is nothing to apply for.
    • 18 tools across five areas: accounts, campaigns and ad groups, ads, keywords and negative keywords, and one reporting tool that covers campaign, ad group, keyword, search-term, ad and geographic reports.
    • Reports return impressions, clicks, CTR, average CPC, spend, conversions, conversion rate, cost per conversion, revenue, ROAS, impression share and impression share lost to rank and to budget, plus Quality Score and its three components at keyword and ad-group level — as Summary rows or Daily / Weekly / Monthly buckets, with optional device, network, top-vs-other and delivered-match-type segments.
    • One scheduled template, Bing Ads (Microsoft Advertising) Optimization Audit, turns the data into biweekly tickets: negatives to add, imports that drifted from Google, bids losing on rank, budgets capping winners, Audience Network leakage, and conversion goals that cannot be trusted.
    • Read tools are auto-approved; writes (create, pause, re-bid, add or remove negatives) ask first, like every other ads MCP in Cogny.

    What is different about this channel

    Three things shape the audit.

    Most accounts are imports. The campaign names are Google's, the keywords are Google's, and the negatives are whatever existed on the day of the import. The template therefore diffs the Microsoft account against the Google Ads account when both are connected: negatives that never made it across, keywords paused in Google that still spend here, and campaigns Microsoft is underfunding despite a lower cost per conversion. It also refuses to mirror blindly — Bing's audience is older and more desktop-heavy, and keywords that failed on Google regularly convert here.

    Broad is broader. Microsoft's close-variant expansion delivers more phrase and exact keywords on broad-like queries than Google does, so the search-term report is where the money leaks. tool_get_report with report_type: "search_query" returns each query with the keyword and both the bid and delivered match types, and tool_add_negative_keywords closes the loop with Exact or Phrase negatives (Microsoft has no Broad negatives).

    Reports are asynchronous on Microsoft's side. Every report is a submit → poll → download of a ZIP with a CSV inside. The tool does all of that and hands back JSON rows, typically in five to thirty seconds. Percent columns come back as percentages already (a CTR of 5.93 means 5.93 %), and money is in the account currency in plain units — no micros.


    The tools

    Accountstool_list_accounts returns every ad account the signed-in Microsoft user can reach: numeric id, name, account number, manager (customer) id, currency, time zone and status. Call it first; it is the connection test, and the numeric id is what every other tool takes as account_id. The manager id is resolved and cached by the proxy, so you never pass it.

    Campaigns and ad groupstool_get_campaigns (Search by default; ask for Shopping, Audience, Performance Max or Dynamic Search Ads explicitly), tool_create_campaign, tool_update_campaign (status, daily budget, name), tool_get_ad_groups, tool_create_ad_group, tool_update_ad_group (status, default CPC bid, name). New objects are created Paused.

    Adstool_get_ads returns responsive search ads with their headline and description assets, editorial status and final URLs. tool_create_responsive_search_ad takes 3–15 headlines and 2–4 descriptions and checks the 30 / 90 character limits before sending; tool_update_ad_status pauses or activates.

    Keywordstool_get_keywords, tool_add_keywords (text, Exact | Phrase | Broad, optional bid), tool_update_keywords (status and bid per keyword, in one batch), tool_get_negative_keywords, tool_add_negative_keywords, tool_remove_negative_keywords.

    Reportingtool_get_report with report_type campaign | ad_group | keyword | search_query | ad | geographic, a date range in the account time zone, aggregation Summary | Daily | Weekly | Monthly | DayOfWeek | HourOfDay | Hourly, optional segments and campaign_ids / ad_group_ids scoping, and an optional columns override for any column name the report type supports.

    Batch mutations on Microsoft can half-succeed, so every write returns ids and partial_errors side by side — an ad group can be created while its sibling fails on a duplicate name, and the agent sees both.

    The tool names are the same on every surface. In the CLI:

    cogny tools call mcp__Bing_Ads__tool_get_report --input '{
      "account_id": "150123456",
      "report_type": "search_query",
      "start_date": "2026-08-01",
      "end_date": "2026-08-31",
      "campaign_ids": ["512345678"]
    }'
    

    The audit template

    Enable Bing Ads (Microsoft Advertising) Optimization Audit on the Reports page and Cogny runs it every other week. It grades the account on:

    1. Search-term waste and negative hygiene — zero-conversion queries with five or more clicks, cross-campaign cannibalization, phrase and exact keywords delivering on broad variants, and campaigns with no negatives at all.
    2. Google-import drift (when Google Ads is connected) — missing negatives, drifted keyword statuses, and matched campaigns Microsoft is underfunding despite a better cost per conversion.
    3. Keyword economics — Quality Score clusters by failing component, bids below the mainline estimate on converting keywords, impression share lost to rank and to budget, automated bidding without enough conversions to learn from.
    4. Ads and networks — single-ad ad groups, leftover Expanded Text Ads, Ad Strength, and spend leaking to syndicated partners or the Microsoft Audience Network at a worse cost per conversion.
    5. Conversion tracking — UET goals that count the wrong event, a cross-check against GA4's bing / cpc sessions when GA4 is connected, and UTM or auto-tagging gaps.

    Each finding names the campaign, ad group, keyword or search term and the id, so the ticket it becomes can be executed through the same MCP after you approve it.


    How it is built

    The server lives in the Cogny MCP proxy (services/mcp-proxy/src/servers/bing_ads/) next to the other ads connectors and talks to the JSON variant of the v13 API, so there is no SOAP envelope anywhere. Three details we did not paper over:

    • The connection is a Microsoft identity platform OAuth token with the msads.manage scope. It lives about an hour, so the proxy refreshes it on every call after that — and the connect flow refuses to store a connection Microsoft did not grant offline access to, rather than let it die silently.
    • The developer token is Cogny's, a single universal token that authenticates any Microsoft Advertising user. You do not apply for one, and it never leaves the proxy.
    • Account access is allow-listed. The accounts you pick at connect time are the only ones the agent can read or change; the proxy enforces the list on every tool, not only on the listing.

    Connect it from Settings, or run npx @cogny/cli init and let the agent do the rest.