{"title":"Supermetrics MCP Changelog","format":"markdown","content":"# Changelog\n\nAll notable changes to the Supermetrics MCP server will be documented in this file.\n\n<!-- next-release -->\n\n## [1.16.7] - 2026-09-22\n\n### Changed\n\n- **Field descriptions with load-bearing usage constraints are no longer truncated.**\n  The field list now honors a `preserve_full_description` flag from the backend, so\n  warnings like \"cannot be split by a date dimension\" always reach you whole instead\n  of being cut short in large result sets. These per-connector notes now come from the\n  Supermetrics backend rather than being hardcoded here.\n\n## [1.16.6] - 2026-09-22\n\n### Fixed\n\n- **Authentication now rejects requests with a missing or malformed `Authorization` header instead of falling back to a server-configured key.** Previously, when `SUPERMETRICS_API_KEY` was set in the server environment, a request with no bearer token or a non-`Bearer` header was served using that key rather than being rejected; such requests now receive a 401.\n- **The direct tool path (`POST /mcp/{tool}`) now enforces the same request-body size cap as the `/mcp` JSON-RPC path.** An oversized request is rejected with 413 — whether it declares an over-cap `Content-Length` (previously the connection hung) or streams an over-cap body with no `Content-Length` at all (previously read into memory unbounded). Both paths now share the same protection.\n\n### Removed\n\n- The optional `request` argument on `field_discovery`, `accounts_discovery`, `data_query` and\n  `instagram_insights` has been removed. It was recorded for quality diagnostics only and never\n  affected execution, results or caching.\n\n## [1.16.4] - 2026-09-21\n\n### Added\n\n- Meta ad sets: the EU transparency fields are now documented on `manage_campaign`. Pass `dsa_beneficiary` and `dsa_payor` in an ad set's `platform_settings` to name the legal entity being promoted and the one paying — without them, Meta can reject an EU-targeted ad set.\n\n## [1.16.3] - 2026-09-18\n\n### Added\n\n- Optional `request` argument on `field_discovery`, `accounts_discovery`, `data_query` and\n  `instagram_insights`: a short statement of the user's task, recorded for quality diagnostics.\n  It does not affect execution, permissions, results or caching, and is never sent upstream.\n\n### Changed\n\n- **`manage_dashboards`: board-authoring guidance now forbids displaying data the query didn't return.**\n  The values a board shows must come from the fetched results, never from a hardcoded table/lookup/join baked into the code (static UI text like a KPI title is fine); the AI should say so when the data can't provide what was asked, and any deliberate example data must be visibly labelled as example.\n\n## [1.16.2] - 2026-09-18\n\n### Added\n\n- **`data_source_discovery` now tells you which connectors can receive activated audiences.** Each listed source carries a `data_out` flag (`true` for data-out-capable connectors such as Google Ads and Meta), sourced from the Supermetrics API so there is one source of truth for every client.\n\n## [1.16.0] - 2026-09-17\n\n### Added\n\n- **New `/migrate-data-studio-to-sm-studio` prompt.** Paste a link-shared Google Data Studio report URL and get back step-by-step instructions for rebuilding it as a Supermetrics Studio dashboard — pages, charts, data sources and field bindings. Run it from your client's slash-command menu; it reads the report's structure only, never its data. Available in clients that support MCP prompts, such as Claude Code and Claude Desktop.\n\n### Changed\n\n- **AI-built boards now scope to the accounts they use instead of all accounts.** The `manage_dashboards` `allowed_accounts` guidance no longer presents `{\"*\": [\"*\"]}` (all of the owner's accounts) as the default for new boards — it tells the assistant to list only the accounts the board actually queries. In owner-auth mode every viewer queries on the board owner's credentials, so this stops new boards from unintentionally exposing the owner's other accounts. The all-accounts wildcard remains available for genuinely interactive boards where viewers pick their own accounts.\n\n## [1.15.13] - 2026-09-15\n\n### Changed\n\n- Discovery tools now flag when a team has no saved business context yet and suggest capturing durable guidelines, preferences, or naming conventions — so they persist across sessions instead of being re-explained each time.\n\n### Fixed\n\n- **Data queries now tell you when SuperAPI adjusted your date range.** When requested dates fall outside what a metric supports — e.g. Instagram's \"New followers\" only covers the last 30 days excluding today — SuperAPI clamps the range to the supported window and returns the data instead of failing. That adjustment note was being dropped; the assistant now surfaces it, so a query that quietly returned a narrower window no longer looks like it ignored the dates you asked for.\n\n## [1.15.12] - 2026-09-14\n\n### Added\n\n- The server now answers at per–data-source paths such as `/google-ads` and `/meta-ads`, each offering the same tools and sign-in as the main `/mcp` endpoint, so you can connect a data-source-specific Supermetrics app in ChatGPT.\n\n## [1.15.11] - 2026-09-14\n\n### Changed\n\n- **Documented the AW `manage_campaign` ad_schedule shape.** The `platform_settings` help now spells out that `ad_schedule` is a list of `{day_of_week: MONDAY..SUNDAY, bid_modifier}` where `bid_modifier` is a Google Ads multiplier in 0.1–10 (0.7 = −30%, 1.3 = +30%, the same convention as `bid_adjustments`) that sets a day-of-week bid modifier without restricting which days serve, and that adding `start_hour`/`end_hour` restricts serving to those hours (dayparting) — so day-of-week bid modifiers are sent in a form Google Ads accepts.\n- Campaign details now show a keyword's status only when it is not enabled. Enabled keywords omit the status field, paused keywords keep it, and a note explains that a keyword shown without a status is enabled.\n\n## [1.15.10] - 2026-09-14\n\n### Added\n\n- **Added inline (base64) creative uploads to `creative_picker`.** The `upload_creative` action now accepts `file_data` (base64 image bytes, or a `data:` URI) with optional `filename`/`content_type`, writes the bytes to temporary storage server-side, and returns a reusable `upload_ref` for `manage_campaign`. This lets a creative that exists only as a conversation attachment be ingested without the browser upload widget — previously such files produced an `upload_ref` pointing at an empty object, which failed downstream with \"Image download failed\". Inline transport is image/small-file only (capped at 10 MB); video must still use the picker widget, a public `asset_url`, or a pre-uploaded `asset_id`.\n\n## [1.15.9] - 2026-09-14\n\n### Added\n\n- **Data queries now apply a connector's default-on checkbox settings automatically.** When a connector defaults an options checkbox on (for example, Instagram Public Data now skips invalid or restricted handles instead of failing the whole query), queries honour that default without the assistant having to pass the setting. Any value you set explicitly is always respected.\n- **`supermetrics_guide` troubleshooting now covers X / Twitter connectors (X Ads and X Organic) and Google Ads Keyword Planner (GAKEY), and gives clearer help when a just-purchased plan still shows a trial-expired error.** X Organic \"no accounts found\" now explains you must sign in with the X account that owns/administers the handle; GAKEY calls out that it needs Standard (not read-only) Google Ads access; and the license/trial guide now covers the case where a new subscription or trial is in place but `TRIAL_EXPIRED` persists (reconnect so the connector picks up the new license, check it's on the connected team).\n\n## [1.15.8] - 2026-09-14\n\n### Added\n\n- Successful data queries for Microsoft Ads, TikTok Ads, LinkedIn Ads, ChatGPT Ads, and Snapchat Ads now note that campaigns on that platform can also be created, paused, and updated with the manage_campaign tool. The note is skipped when you have managed campaigns on that platform in the last week, and appears at most once per platform per session.\n\n### Changed\n\n- Discovery tools now point the agent at a scope's saved business context when a tag is relevant to what it's doing, and no longer repeat context the agent already fetched earlier in the same session — at team, data-source, and account level. Context too large to show inline is flagged so it isn't silently missed.\n\n## [1.15.4] - 2026-09-11\n\n### Changed\n\n- The deprecated `campaign_create` and `campaign_update` tools are no longer shown in the tool list — use `manage_campaign`, which both creates (omit `campaign_id`) and updates (pass `campaign_id`) campaigns. Existing calls that still use the old tool names continue to work.\n- When `manage_business_context` save text is too long, the error now states the actual length and the per-entry limit and suggests splitting into separate tagged entries, instead of a bare \"maximum length\" message.\n\n### Fixed\n\n- **Corrected the advertised data source count and tool list.** The server instructions and the `llms.txt` / `llms-full.txt` references now state 174 data sources (was \"150+\"/\"170+\") and list the current tools — adding `supermetrics_guide`, `manage_business_context`, `manage_dashboards`, `manage_user_and_team` and `creative_picker`, and surfacing `manage_campaign` — instead of the hidden `user_info` alias.\n- **`data_query`: filters and other parameters placed inside `settings` no longer fail the query.** When a filter expression, date range, `max_rows` or similar query parameter is nested in the `settings` object — a common mistake — it is now moved to where the API expects it instead of being rejected with `SETTING_KEY_INVALID`. Parameters duplicated in both places, and the internal `compress` flag, are dropped rather than passed through.\n\n## [1.15.2] - 2026-09-10\n\n### Changed\n\n- Renamed the creative picker tool from `resources_manage` to `creative_picker`, and made its description clearer that it works with both image and video creatives. The previous name keeps working for existing integrations.\n\n## [1.15.0] - 2026-09-10\n\n### Added\n\n- **Snapchat Ads (SCM) campaign management.** `manage_campaign`, `campaign_and_resource_get` and `data_source_discovery` now support Snapchat Ads. Targeting and optimization are set on each ad squad (ad group) rather than on the campaign, and a `profile_id` on the campaign is required before ads can be created. Budgets are entered as regular amounts (25 for $25), with a $20/day campaign minimum and a $5/day ad squad minimum. Collection, Story, Ad-to-Lens, Reminder and Lead Generation ads each need one extra creative field referencing an id created in Snapchat — see the `manage_campaign` schema for the field names.\n\n## [1.14.19] - 2026-09-10\n\n### Added\n\n- **`campaign_and_resource_get` can now list Google Ads campaign experiments (A/B tests).** Pass `resource_type: \"experiments\"` (or the alias `\"experiment\"`) with a Google Ads `ds_id` and `account_id` to get each experiment's name, status, type, and date range. Previously experiments were only visible in the Google Ads UI.\n\n## [1.14.18] - 2026-09-10\n\n### Changed\n\n- Links to the Supermetrics Hub returned by the tools — for connecting or reconnecting a data source, managing connections, viewing a subscription, tagging accounts, inviting members, or changing campaign settings — now open in the team your session is working in, so the page and any change you make there land in the right team.\n\n## [1.14.17] - 2026-09-09\n\n### Changed\n\n- `manage_business_context` get now matches on any of the tags you pass (OR): `tags: [\"acme,globex\"]` (or `[\"acme\",\"globex\"]`) returns context tagged with either. Useful for fetching context for several clients in one call.\n\n### Fixed\n\n- Team-level business context now appears in `field_discovery` and `accounts_discovery` (and data source config views), not only when listing data sources. Previously a data-source-scoped lookup returned no team rows, so team-wide guidelines could be missed unless you happened to list data sources first.\n\n## [1.14.15] - 2026-09-08\n\n### Added\n\n- **Business context scopes are now advertised in the OAuth protected resource metadata.** The `.well-known/oauth-protected-resource` document now lists `business_context_read` and `business_context_write` in `scopes_supported`, matching the authorization server metadata. OAuth clients discovering the resource server can now request these scopes.\n\n## [1.14.14] - 2026-09-08\n\n### Added\n\n- **A failed campaign approval now shows a support ID.** When applying an approved change does not work, the approval page displays the ID for that request; error responses also carry it as `span_id`, and the `X-Span-Id` response header always has it. Quoting it to Supermetrics support identifies the exact request in our logs; previously a failure gave you nothing to refer to.\n- **Query results now say whether they were answered from the platform's cache, and as of when.** Results carry `cache_used`, plus `cache_time` when a cache answered, and a note naming that time. Ad platforms serve repeat queries from their own result cache — Meta's holds for around 50 minutes — so a read taken shortly after a change can disagree with a live read while both are correct. Previously the response gave no way to tell the two apart. This applies to results returned inline by `data_query` and to those collected with `get_async_query_results`. Where a repeat of an identical `data_query` is served from a stored copy of the earlier run, the response now says so rather than reporting the earlier run's freshness. Both fields are omitted, rather than reported as a live read, when the platform does not tell us.\n\n### Changed\n\n- **Documented `pixel_id` and `promoted_object` on a Meta ad group's `platform_settings`.** Both were already accepted and neither appeared in the schema. `pixel_id` selects which pixel the ad set optimizes for, and `promoted_object` sets what the ad set optimizes towards, as `{pixel_id, custom_event_type}`, `{custom_conversion_id}` or `{page_id}`, which some campaign objectives require. No behaviour changed; these were working before and simply could not be discovered.\n- **The `conversion_types` resource now says that it returns pixels as well as conversion actions.** Pixel details were already in the response on platforms that have them, but nothing in the tool schema mentioned it, so there was no way to find them short of reading a response you had no reason to request. Only the description changed; the data is the same.\n- **`field_discovery` no longer strips a field's description from the cache for later callers.** A wide browse shortens descriptions for its own response; previously it shortened them in the shared catalog, so a later narrow query for the same data source got the shortened copy instead of the full one. Per-data-source description overrides are unaffected either way, and now cannot be shortened at all. The `filter` parameter's description also now mentions that aliases and report types are searched, which they always were.\n\n### Fixed\n\n- **Corrected the documented default for an ad's `status`.** The `status` field said a new ad defaults to PAUSED when omitted. That is not true on every platform — on Meta an ad created without an explicit status can start serving immediately. The description now says the default is the platform's own and may be live, and to set `status: PAUSED` explicitly when an ad must not serve. Nothing about how the field behaves has changed; if you relied on the documented default rather than setting the status, check whether those ads are live.\n- **`campaign_and_resource_get` with `resource_type: videos` now returns videos, not images.** `videos` and `video` resolve to the account's asset library, which holds both and chooses between them by `asset_type` — and the choice fell through to the image default, so a request for videos came back as the image library with nothing in the response saying so. A response whose asset type we inferred — a `videos` request, or a plain `assets` request, which silently meant images — now states which type it served. An explicit `params.asset_type` still wins, so if you have been passing it to work around this, that keeps working unchanged.\n- **`health_check` now states what its click and conversion figures actually count.** On Meta the generic `clicks` field is Clicks (all) — every click on the ad, not only clicks through to your site, which is a separate \"Link clicks\" field — and `conversions` is Actions, a count of every action type rather than one conversion action. The CTR and CPA in a health check are derived from those, so its CTR is CTR (all) and reads higher than link CTR, and its CPA is cost per action. Both figures were correct for what they measured and neither said what that was. Meta health checks now carry a note naming the grain and pointing at `data_query` for link clicks or a specific conversion action. The numbers themselves are unchanged — if you have compared a health-check CTR against link CTR elsewhere and found a gap, this is why.\n- **`resources_manage` now documents the `create_upload_url` action.** The `action` parameter was described as \"Always 'browse_assets'\", so the one action a script needs — create a signed upload URL, PUT your file to it, then pass the returned `upload_ref` to `manage_campaign` as a creative source — could not be found without reading the source. The schema now names it along with the default, and documents the `filename`, `content_type` and `size` inputs it takes. The tool's other actions are unchanged and still accepted; they are driven by the media picker rather than called directly, so they are deliberately left out of the schema.\n\n## [1.14.13] - 2026-09-08\n\n### Added\n\n- **`supermetrics_guide` now offers step-by-step troubleshooting for common problems, so many issues can be solved on the spot instead of waiting on support.** Covered topics: connecting a data source and \"no accounts found\"; connector-specific access for Google (GA4, Search Console, YouTube and more), Meta (Facebook Ads/Insights, Instagram Insights/Public Data), Microsoft (Ads, Bing Webmaster), LinkedIn (Ads vs Company Pages), TikTok (Ads vs Organic), Amazon (Ads/DSP/Seller/Vendor) and data warehouses (BigQuery, Snowflake); reconnecting an expired connection; license and trial errors; adding a data source or destination (e.g. the AI Chats destination) to your plan; adding users or accounts to a subscription (and prioritizing a new account so it's usable); empty query results; numbers that don't match the platform (including GA4 sampling/thresholding); common query errors; quota-exceeded limits; and enabling campaign write access. Just describe the problem (e.g. \"my Google Ads shows no accounts\" or \"why don't my GA4 numbers match?\") and you'll get the relevant steps. The `contact_supermetrics` tool now points to these guides first, so common problems are resolved before a support ticket is created.\n\n### Changed\n\n- `accounts_discovery` now includes an account's saved business context inline (as `context`) when the result is narrowed to a few accounts, so the guidance appears directly instead of requiring a separate lookup. Larger account lists continue to show only `context_tags`.\n\n## [1.14.11] - 2026-09-07\n\n### Added\n\n- New `manage_business_context` tool for storing and retrieving campaign guidelines, policies, and preferences that persist across conversations and are shared with all team members. Context can be saved at team, data source, or account scope, tagged by purpose, and retrieved as a cascade (team + data source + account) so applicable guidelines are applied automatically when creating campaigns, analyzing performance, or building reports.\n\n### Changed\n\n- Discovery tools now surface your team's saved business context in a structured `business_context` property, grouped by scope (`team` and `data_source`) as tags/context entries — or, when a scope holds a lot of context, as a list of tags to load on demand with `manage_business_context`. It's included by `data_source_discovery` (a data source's config, plus team-level context when listing sources), `accounts_discovery`, and `field_discovery`, and the same context isn't repeated once you've already seen it in a session.\n- `accounts_discovery` now lists `context_tags` on an account when your team has saved business context for it, so you can see which accounts have guidelines and load them with `manage_business_context`.\n\n## [1.14.10] - 2026-09-06\n\n### Changed\n\n- **Query results carry fewer, more relevant capability suggestions.** The \"Related capability\" notes attached to a completed query result no longer include the campaign health-check and spend-forecast prompts on every Google, Facebook, LinkedIn or TikTok Ads result. Only the cross-platform comparison suggestion remains — it is still shown only when the paired platform is connected, and it now appears at most once per session instead of on every result.\n\n## [1.14.9] - 2026-09-06\n\n### Fixed\n\n- **`data_query` now accepts a report type given as the index number shown in `field_discovery`'s report type legend.** The index is translated back to the report type name before the query runs, so passing an index (e.g. `report_type: 1`) instead of the name no longer fails.\n\n## [1.14.8] - 2026-09-03\n\n### Changed\n\n- **More data source ID shorthands and typos resolve automatically.** Common guesses are now corrected to the right data source: `SHF` (Shopify), `TT` and `TTA` (TikTok Ads), `SNAPCHAT` (Snapchat Marketing), and `GWT` (Google Search Console).\n\n### Fixed\n\n- **`accounts_discovery` now flags an unknown data source ID instead of offering a dead connection link.** When the data source ID does not exist, the tool points you to `data_source_discovery` to find the correct one, rather than suggesting you connect a source that cannot be connected.\n\n## [1.14.6] - 2026-09-03\n\n### Fixed\n\n- **Meta: an ad set end time sent with a time but no timezone offset no longer lands a day late.** A value like `2026-11-20T23:59:00` was passed to Meta unanchored, which resolved it in its own timezone — an end-of-day time then crossed midnight and moved the date to the 21st. Such values are now anchored to the ad account's timezone, matching the behaviour already applied to campaign dates. A value that carries an explicit offset is still used exactly as sent. If you have been compensating by sending a date one day early, that adjustment is no longer needed.\n- **Meta: an ad set's start and end date can now be changed after it is created.** Set `start_date` / `end_date` in an ad group's `platform_settings` — Meta holds the flight on the ad set, so a campaign-level date never reached one that already existed. Previously each route failed differently: a campaign-level date reported the write as applied and changed nothing, and a date on the ad group was either reported as an unrecognized field or passed to Meta and silently dropped. A campaign-level date on an update now also says that ad sets keep their own flight, instead of reporting success over an unchanged value.\n\n## [1.14.5] - 2026-09-03\n\n### Fixed\n\n- **Approvals blocked by a data source connection now say so, and link you straight to reconnecting it.**\n  A change that could not be applied because the connection was missing permissions or had expired used to\n  report a server error and suggest trying again, which never worked. The approval page now explains that\n  the connection needs reauthorising and shows the reconnect address as a link you can click.\n\n## [1.14.3] - 2026-09-03\n\n### Changed\n\n- **The `campaign_and_resource_get` conversions resource is now called `conversion_types`, making clear it lists the account's configured conversion actions (definitions), not per-campaign conversion counts.** The previous `conversions` name continues to work unchanged.\n\n### Fixed\n\n- **`campaign_and_resource_get` now gives targeted guidance when `campaign_id` is passed to a resource that cannot filter by it, instead of always saying \"fetch a single campaign\".** Asking `conversion_types` for a campaign's conversion numbers now points to the `data_query` tool, and asking `assets` for a campaign's creatives now points to fetching that campaign with full detail.\n\n## [1.14.2] - 2026-09-02\n\n### Fixed\n\n- **`data_query` no longer fails with \"Missing value for query start date\" when the date range is placed inside `settings`.** A date range provided as `date_range_type`, `start_date`/`end_date`, or `date_range` inside the `settings` object — rather than as a top-level parameter — is now applied to the query instead of being ignored.\n- Published pages and other clients that invoke `campaign_create` or `campaign_update` by name from a declared tool manifest work again. The two legacy names are listed as deprecated aliases of `manage_campaign` (they had briefly stopped appearing in the tool list after the tools were merged). Prefer `manage_campaign` — the aliases forward to it with identical parameters.\n\n## [1.14.0] - 2026-09-02\n\n### Changed\n\n- Campaign creation and updates are now performed through a single `manage_campaign` tool: provide `campaign_id` to update an existing campaign, or omit it to create a new one. The previous `campaign_create` and `campaign_update` names continue to work unchanged.\n\n### Fixed\n\n- `campaign_create` and `campaign_update` now say plainly that a platform has no campaign management, instead of returning a write-access error that pointed to a settings page where the platform could never be enabled.\n\n## [1.13.3] - 2026-09-01\n\n### Changed\n\n- The `max_rows` parameter for `data_query` no longer documents a fixed 10,000-row maximum. There is no such hard ceiling; the default remains 1000 and any upper limit depends on your license.\n- `accounts_discovery` now names the team you are currently working in and explains that the accounts it lists belong to that team — a connection added while signed in to a different team will not appear here — and its link for adding more connections opens that same team, so a new connection lands where your queries can find it.\n\n## [1.13.2] - 2026-08-31\n\n### Fixed\n\n- **Asset picker: creatives you generate or upload during a session no longer disappear when the picker is reopened or the page is reloaded.** The picker now refreshes \"Your assets\" from the server on load, so a freshly generated AI image or uploaded file stays visible instead of dropping off on the next render.\n\n## [1.13.1] - 2026-08-31\n\n### Fixed\n\n- **Asset picker: AI-generated creative thumbnails now keep loading, and deletions stick.** Previously, AI-generated images in the media picker's \"Your assets\" showed a blank thumbnail and could vanish when the picker was reopened, and deleting your last asset(s) could make them reappear on reload. Both are resolved — AI creatives now preview reliably alongside your uploads, and a deleted asset stays gone.\n\n## [1.12.13] - 2026-08-31\n\n### Added\n\n- `data_source_discovery` now tells you, when you fetch a specific ad platform's configuration, which read operations that platform exposes through the `campaign_and_resource_get` tool — such as keyword ideas, keyword volumes, forecasts, targeting search, and audiences — so you can reach for the right tool instead of attempting a `data_query` that cannot return them.\n\n## [1.12.11] - 2026-08-28\n\n### Added\n\n- **Connect suggestions on query results** — a completed query against Google Ads, Facebook Ads, Google Analytics or Google Search Console may now note one related data source you have not connected and what it would add that the source you queried cannot answer on its own. Only sources you genuinely do not have are named, at most one per query, and each is mentioned once and not raised again.\n\n### Changed\n\n- `data_query` now returns your rows directly when the query finishes quickly, instead of always handing back an ID to fetch them with. Combined with the change below, a short report can arrive in a single call rather than three. Rolling out gradually.\n- `get_async_query_results` now waits for your query to finish instead of reporting it as still running after a couple of seconds. Most queries return their data on the first call, so retrieving a report no longer costs several rounds of asking and waiting. Rolling out gradually.\n\n### Fixed\n\n- A query could be reported as still queued, with out-of-date progress, after it had already started running.\n- A query that failed could return a generic message instead of the error explaining what actually went wrong.\n- A campaign health check whose query ran long took about twice as long as it needed to before reporting the problem.\n\n## [1.12.7] - 2026-08-27\n\n### Fixed\n\n- Campaign management: Google Ads Shopping ad groups now honour a `product_filter` set in their own `ad_groups[]` entry. It was accepted and never applied, and because a bid sent alongside it did apply, the response reported the write as successful — leaving the ad group serving no products. Previously only Performance Max asset groups supported a per-group filter.\n- Campaign management: a `product_filter` that cannot be applied — an unsupported campaign type, an ad group that cannot be identified, or one belonging to a different campaign — is now reported in `failures` with `dropped: [\"product_filter\"]` rather than only mentioned in `notes`, so it is no longer reported as an applied write.\n\n### Changed\n\n- Campaign management: the `campaign_update` `platform_settings.product_filter` description now points at the per-ad-group alternative, since the campaign-level filter rebuilds every group in the campaign.\n\n## [1.12.6] - 2026-08-26\n\n### Changed\n\n- `data_source_discovery` now recognizes common alternative names when filtering, so searches like \"GA4\", \"Google Business Profile\", \"DV360\", \"AdWords\", \"Microsoft Ads\", \"Magento\", or \"Facebook Page\" resolve to the right data source instead of returning nothing.\n\n## [1.12.5] - 2026-08-25\n\n### Added\n\n- `campaign_update` ads now accept a top-level `status` field (ENABLED, PAUSED, or REMOVED) instead of requiring it inside `platform_settings`.\n\n### Fixed\n\n- Google Ads: updating an ad's creative no longer silently pauses the ad. Google Ads has no in-place creative update, so the ad is removed and recreated under a new ID — its status is now carried over from the ad being replaced. If the prior status can't be confirmed, the update now stops with an explanation rather than risking an unintended pause; pass `status` explicitly to proceed anyway.\n\n## [1.12.3] - 2026-08-24\n\n### Fixed\n\n- `get_async_query_results` now returns an empty `data: []` for a completed query that produced no rows, instead of a single sentinel row `[[\"No data found\"]]`. Empty results are now a consistent shape regardless of which data source or report type produced them.\n\n## [1.12.0] - 2026-08-20\n\n### Added\n\n- Clients speaking MCP `2026-07-28` are now served directly instead of being turned away and having to fall back to an older protocol version. Change notifications are not part of that support: the server does not push tool, prompt, or resource updates and does not accept a subscription stream, so re-read the tool list whenever you need it to be current.\n\n### Fixed\n\n- A conversation that moves between servers mid-session now keeps the capabilities your client declared when it connected, instead of being treated as though it had declared none.\n- A request whose body is not valid JSON now answers `400 Bad Request` with a parse error naming where it failed, instead of reporting a `500` server error.\n- Calling a method the server does not have now answers \"Method not found\" and names the method, instead of the misleading \"Invalid request parameters\".\n\n### Changed\n\n- `serverInfo.version` in the initialize response now reports the Supermetrics MCP server's own version rather than the version of the MCP library it is built on.\n\n## [1.11.9] - 2026-08-20\n\n### Added\n\n- Campaign create and update responses now say whether the platform actually applied the change. `write_status` is `applied`, `partial_failure` or `failed`, and `failures` lists each change the platform refused, with its error code where the platform gives one. Previously a partly-refused write looked like a success and the reason appeared only as a note, so there was no reliable way to tell how much of a request had gone through. `notes` still carries advisories, and any refusal a connector cannot report in `failures`.\n\n## [1.11.8] - 2026-08-19\n\n### Changed\n\n- Tool responses no longer include `trace_id` in their metadata. Responses continue to carry a `span_id`; on a failed request, this is the ID to quote when contacting Supermetrics support.\n\n### Fixed\n\n- A data query that fails because the connection behind the account is no longer usable now says what to do about it. Previously it returned only the bare message `Query authentication \"<id>\" is no longer available.` — an id that appears nowhere in the product, with no reconnect link. It now comes with a link to reconnect the data source, and, for the case where you have already reconnected and nothing changed, a pointer to `accounts_discovery`: reconnecting under a different login creates a new connection rather than restoring the one the account was being queried through.\n\n- Query errors no longer repeat the same guidance twice. A missing date range, or a missing/mismatched per-query setting, now returns a single `SOLUTION` hint. For missing settings, that hint names the exact `setting_id` values by their identifier (not just the human-readable label), and lists only the settings required for the report type being queried.\n\n## [1.11.6] - 2026-08-18\n\n### Fixed\n\n- Ending a session that has already expired now answers `404 Not Found` with a readable JSON error, instead of reporting success for a session that was no longer there. Ending a live session is unchanged.\n- Ending a session with a malformed session id now answers with a JSON error too. It previously returned unlabelled plain text, which some clients could only report as invalid content from the server.\n\n## [1.11.4] - 2026-08-18\n\n### Changed\n\n- `contact_supermetrics` now checks your existing open tickets before creating a new support ticket, and adds to a matching open ticket instead of opening a duplicate.\n\n## [1.11.2] - 2026-08-17\n\n### Added\n\n- `contact_supermetrics` can now check on your existing support tickets: list your tickets (each with a link to view it), read the replies on one, and post a follow-up — all limited to tickets you opened. Use `type: \"ticket_status\"` (optionally with a `ticket_id`) to view, and `type: \"ticket_reply\"` with a `ticket_id` and `message` to respond.\n\n## [1.11.1] - 2026-08-17\n\n### Fixed\n\n- Uploading a creative from a web page URL now works: when the URL points at a page rather than a direct image file, the asset picker automatically uses the page's preview image (`og:image`) instead of failing with \"URL returned a web page, not an image.\"\n\n### Changed\n\n- When AI image generation isn't available on your plan, the asset picker now returns a clear message explaining an active license is required and suggesting you browse or upload an existing image, instead of surfacing a generic error.\n\n## [1.11.0] - 2026-08-16\n\n### Fixed\n\n- A conversation whose session had expired could keep failing against it — often surfacing as a tool call that suddenly errored after working for hours, with only disconnecting and reconnecting the connector fixing it. The server now tells the client to start a fresh session, so it reconnects on its own.\n\n## [1.10.16] - 2026-08-15\n\n### Fixed\n\n- Media picker asset thumbnails and previews now load in Claude across all production environments. The 1.10.15 fix restored the image request URL but did not yet allow that origin, so images stayed blocked in some deployments.\n\n## [1.10.15] - 2026-08-15\n\n### Fixed\n\n- The media picker (opened by `resources_manage`) again shows asset thumbnails and image previews, and file uploads work again. Both had silently stopped loading in Claude.\n\n## [1.10.14] - 2026-08-14\n\n### Fixed\n\n- The asset picker (`resources_manage`) no longer intermittently fails to open. Opening calls that carried an explicit `null` or empty `action` are now treated as the default `browse_assets` instead of being rejected.\n- `field_discovery` no longer fails for a whole data source when its field catalog contains an unusual field definition (seen with some Klaviyo custom-event metrics). Fields are now returned even if an individual field can't be read, instead of the entire source becoming unusable.\n\n## [1.10.11] - 2026-08-14\n\n### Added\n\n- Every response now includes a \"span ID\" identifier for that individual request. Quoting it when reporting a problem lets support pinpoint the exact request that went wrong, rather than narrowing it down from everything else that happened in the same conversation.\n\n## [1.10.9] - 2026-08-14\n\n### Added\n\n- Feature requests can now be submitted and voted on at the public wishlist (https://wishlist.supermetrics.com). The `contact_supermetrics` tool points users there for feature ideas, offering it as an alternative when they share feedback.\n\n## [1.10.3] - 2026-08-12\n\n### Removed\n\n- `accounts_discovery` no longer accepts `include_connection_details`, introduced in 1.10.1. Accounts are returned as a single list again, without the connection grouping.\n\n## [1.10.2] - 2026-08-12\n\n### Changed\n\n- Requests larger than 45 MB are now rejected.\n\n## [1.10.1] - 2026-08-11\n\n### Added\n\n- `accounts_discovery` can now return accounts grouped by the connection they come through, with each account carrying its data source username. Enable it with `include_connection_details`; it is off by default, and the normal account list is unchanged.\n- Completed query results for Facebook Ads, Google Ads, LinkedIn Ads and TikTok Ads now carry short notes about related capabilities that apply to that platform — the campaign health check, spend forecasting, and comparing against a second ad platform — each with a phrase you can say to try it. A cross-platform note only appears when the other platform is already connected, so it never points at a source you cannot query.\n\n### Changed\n\n- `supermetrics_guide` is now surfaced at the moments it actually helps: an opening question like \"what can you do?\", a request the connector cannot fulfil (where the guide can point to an alternative), or a natural pause after several queries against one source. It stays out of the way while a specific question is being answered or a query is being drilled into, and related capabilities mentioned in query result notes are offered as one follow-up option among others rather than pushed.\n\n## [1.10.0] - 2026-08-10\n\n### Fixed\n\n- MCP clients can now close a session when they disconnect. The server previously refused the request, so the session stayed open until it timed out.\n\n## [1.9.42] - 2026-08-10\n\n### Fixed\n\n- `accounts_discovery` no longer fails with \"Could not resolve team ID from user identity\" when the Supermetrics sign-in has expired. The tool now reports the expired sign-in so the client can refresh it and retry, instead of reporting a team problem that has nothing to do with the actual cause. It also recovers on its own in cases where it previously gave up without trying.\n\n## [1.9.41] - 2026-08-07\n\n### Added\n\n- New `supermetrics_guide` tool answers \"what can I do with Supermetrics?\" and \"what's new?\" with a short, numbered list of capabilities, each with the exact phrase to try on its own line so it is easy to spot and copy. Previously there was no way to find out what the connector supports from inside a conversation, so features went unnoticed unless a user happened to ask for them by name.\n\n### Changed\n\n- Reverted the 1.9.38 change that returned an error for a query reported as stalled after it had completed. It also affected queries that re-run on a schedule, reporting a failure for them while they were simply running normally. These queries now behave as they did before 1.9.38.\n\n## [1.9.38] - 2026-08-06\n\n### Fixed\n\n- Queries that stall after completing no longer leave results loading indefinitely. `get_async_query_results` now returns a clear error for such a query so it can be re-run, instead of reporting it as still running forever.\n\n## [1.9.35] - 2026-08-05\n\n### Fixed\n\n- `contact_supermetrics`: support tickets are now created reliably and return a working ticket link. Previously a ticket could report success with an invalid link ending in `/None` while not actually reaching Supermetrics support; the tool now confirms the ticket was created and returns a clear error if it was not.\n- `contact_supermetrics`: support tickets submitted without a category are no longer rejected. A general category is now applied automatically when none is provided, so the ticket is accepted instead of failing.\n\n## [1.9.33] - 2026-08-03\n\n### Added\n\n- Campaign management: Google Ads Performance Max asset groups accept their own `product_filter` in an `ad_groups[]` entry's `platform_settings`, applied to that asset group alone. Previously the only option was the campaign-level filter, which rebuilds the listing groups of every asset group in the campaign — unusable for changing one group in a campaign that has many.\n- Campaign management: the accepted Performance Max image aspect ratios (1.91:1, 1:1, 4:5) are now stated in the `assets` description, so an image can be corrected before it is submitted rather than after Google rejects it.\n\n### Fixed\n\n- Campaign management: `status` on an ad group / asset group entry is now honoured when creating Google Ads Performance Max asset groups. Previously the requested status was discarded and the asset group was always created ENABLED, so an asset group added to a live campaign began serving immediately despite an explicit `PAUSED` request.\n- Campaign management: new Performance Max asset groups in a Merchant Center-linked campaign now get an all-products listing group when no `product_filter` is given. Previously they were created with no listing group at all, so they served no products while reporting success.\n- Campaign management: warnings returned by the campaign API now appear in the response's top-level `notes`. Previously they were nested one level deeper and easy to miss.\n\n### Changed\n\n- Campaign management: `status` is now a documented field on ad group / asset group entries. New Performance Max asset groups default to PAUSED unless a status is given, and the guidance now requires explicit user approval before an ad group or asset group is enabled — previously the approval step covered campaigns only.\n- Campaign management: the campaign-level `product_filter` description now states that it rebuilds the listing groups of every ad group in the campaign, and the guidance on omitting it for all products now matches actual behaviour.\n\n## [1.9.32] - 2026-07-29\n\n### Fixed\n\n- `field_discovery` no longer returns an empty field list when `filter` terms are separated by spaces instead of commas (e.g. `impressions clicks spend`). Previously such a filter matched nothing, which could leave an assistant unable to name any fields for a query. Multi-word terms that match a field name (e.g. `impression share`) still match as a phrase.\n\n### Changed\n\n- The `field_discovery` `filter` parameter description now states that terms are comma-separated.\n\n## [1.9.31] - 2026-07-28\n\n### Added\n\n- Campaign management: Google Ads (AW) now supports radius/proximity targeting. Use `location_details` with `type=custom_location`, `latitude`, `longitude`, `radius`, and `distance_unit` (mile or kilometer) to target people within a radius of a point. Works for local service campaigns.\n- Campaign management: Google Business Profile locations can now be linked to Google Ads campaigns via `extensions.locations` with a `place_id`. Requires the GBP to be linked to the Google Ads account first.\n\n## [1.9.29] - 2026-07-27\n\n### Added\n\n- Campaign management: Google Ads (AW) now supports city-level geo targeting. Pass numeric geo target constant IDs in `locations` (e.g. `[\"DE\", \"1001062\"]`) or use `location_details` with city/region entries. Use targeting search with `type=city` or `type=location` to discover geo IDs by name.\n- Campaign management: Google Ads `geo_target_type` setting — set `PRESENCE` in platform_settings to target people physically present in the location (default: `PRESENCE_OR_INTEREST`).\n\n## [1.9.25] - 2026-07-21\n\n### Added\n\n- `field_discovery` now marks non-aggregatable metrics (e.g. Reach, Frequency, Users, and rate/ratio metrics like CTR, CPC, ROAS) with `is_non_aggregatable: true`, and adds a note clarifying that these metrics can still be broken down by dimensions or dates within a single query, but their returned values must not be summed or averaged across rows afterward. Previously these metrics were returned with no such indication, so summing them (for example, adding daily Reach into a weekly total) silently produced inflated, double-counted figures.\n\n## [1.9.23] - 2026-07-21\n\n### Fixed\n\n- Publishing a dashboard to Supermetrics Studio now warns when the uploaded board contains no live `smQuery` calls. Previously a static, data-baked-in board could be published silently and would never refresh — leaving viewers to reconnect every source by hand. The upload response now flags this so the board can be rebuilt with live queries and re-uploaded.\n- Campaign management: end dates no longer shift +1 day for ad accounts in timezones east of UTC. Previously, setting `end_date=2026-09-30` could display as October 1st in Meta Ads Manager.\n\n### Added\n\n- Campaign management: `start_date` and `end_date` now accept an optional time-of-day in ISO 8601 format (e.g. `2026-09-30T18:00:00`), in addition to the existing date-only format (`YYYY-MM-DD`). This lets you schedule campaigns to start or stop at a specific hour.\n\n## [1.9.22] - 2026-07-21\n\n### Added\n\n- Campaign management: saved audiences are now included when listing audiences (`type=saved`). Previously only custom/remarketing/lookalike audiences were returned.\n- Campaign management: geo-location search is now available via targeting search. Use `type=city`, `type=region`, `type=country`, `type=zip`, `type=geo_market`, or `type=location` (all types) to find Meta geo keys for sub-country targeting in `location_details`.\n\n## [1.9.21] - 2026-07-20\n\n### Changed\n\n- Campaign management: `destination_type` documentation now covers all objectives (WEBSITE, ON_AD, APP, etc.), not just messaging ads. Helps avoid trial-and-error when setting conversion location for non-messaging campaigns.\n- Campaign management: `platforms` field now lists valid Meta publisher platforms (facebook, instagram, audience_network, messenger). `placements` field documents cross-platform shortcuts (feed, reels).\n- Campaign management: creative asset documentation reordered to highlight `asset_url` (public URL) as the recommended path for uploading new media. Both `campaign_create` and `campaign_update` tool descriptions now mention available creative options.\n\n## [1.9.20] - 2026-07-17\n\n### Changed\n\n- Dashboards built for Supermetrics Studio now come with more flexible dates and period comparison. Date pickers offer a wider set of ranges — including last 90 days and other multi-day/week/month/year windows — plus fully custom start/end dates and derived ranges like this/last quarter and year to date. When you want to compare performance, dashboards can now apply a single comparison — previous period or the same period last year — consistently across every widget, including time-series charts, not just individual scorecards.\n\n## [1.9.19] - 2026-07-17\n\n### Removed\n\n- Reverted the \"Query stalled\" detection for async queries (introduced in 1.9.16 and refined in 1.9.18). `get_async_query_results` no longer marks a query as stalled based on it running without scheduled work — that signal proved unreliable for some data sources (for example Adobe Analytics), which can run in that state for several minutes and still complete, so healthy queries were being failed. Such queries now continue polling until they finish, as they did before 1.9.16.\n\n## [1.9.18] - 2026-07-16\n\n### Fixed\n\n- `get_async_query_results` no longer fails a query with a \"Query stalled\" error just because it is briefly reported as running without any work scheduled yet — a normal state in the first seconds after a query is submitted. A query is now only reported as stalled if it stays in that state for a sustained period across polls, so newly submitted queries that simply need a moment to start are allowed to finish. This removes spurious stall errors (and empty dashboard tiles) that could appear for queries that would otherwise complete normally.\n\n## [1.9.17] - 2026-07-16\n\n### Added\n\n- After a dashboard is published to Supermetrics Studio, the assistant now invites you to share feedback on your overall Studio experience (once per session, non-blocking, and skippable). If you share feedback, it is delivered to the Supermetrics team.\n\n## [1.9.16] - 2026-07-14\n\n### Fixed\n\n- `get_async_query_results` no longer polls forever on a query that has stalled. When a query is reported as running but has no work actually scheduled or running — a state it can never recover from on its own — it is now returned as a failed query instead of an endless \"keep polling\" response. The stalled query's cached schedule is cleared, so re-running it (or reloading the page) submits a fresh query that completes normally. Previously such a query could stall indefinitely and repeated attempts kept reusing the same stuck query for up to ~53 minutes.\n\n## [1.9.15] - 2026-07-09\n\n### Fixed\n\n- Query results are no longer automatically compressed. Compression now only applies when you explicitly pass `compress=true`. Previously, results were sometimes returned in a compact text format even when raw data was requested, which broke integrations that expected standard JSON arrays.\n\n## [1.9.13] - 2026-07-09\n\n### Fixed\n\n- `manage_dashboards` `upload`/`edit`: when Supermetrics Studio rejects a dashboard for invalid code (for example, the same top-level function declared twice, or truncated/unparseable code), the error now shows Studio's full, actionable message — which problem it is, where it is, and how to fix it — instead of a generic, truncated \"HTTP 422\" response. This lets the dashboard be corrected and re-uploaded without guesswork.\n\n## [1.9.11] - 2026-07-09\n\n### Fixed\n\n- Large query results (over 10,000 rows) no longer crash the server. Results above 10K rows are automatically compressed and skip the result cache to stay within memory limits. Previously, very large results (e.g. a full product catalog) could cause a server crash with no actionable error message.\n\n## [1.9.10] - 2026-07-09\n\n### Fixed\n\n- `manage_dashboards` `upload`: uploading no longer fails when the `title` is missing or blank. A title is now derived from the dashboard code — its `<title>`, otherwise the first heading, otherwise \"Untitled dashboard\" — so the board is created instead of the whole upload being rejected. Set `title` explicitly to control the display name.\n\n## [1.9.9] - 2026-07-08\n\n### Fixed\n\n- `manage_dashboards` `upload`: uploading now rejects a `code` value that is a file path (e.g. `/home/claude/board.html`) or other non-dashboard text before the board is created, with an actionable error telling you to pass the file's contents instead. Previously such a value was stored verbatim, so the shared Studio link showed the literal path text instead of a rendered dashboard.\n\n## [1.9.7] - 2026-07-07\n\n### Added\n\n- `manage_dashboards` `upload`: you can now set an optional `description` (a short subtitle/summary of the dashboard, up to 2000 chars) when uploading. It is stored on the board and shown in the board list, and is returned by `get`. Previously only the title, code, and access settings could be set.\n\n### Fixed\n\n- Campaign approval errors now show the actual rejection reason from the ad platform instead of a generic \"HTTP 502\" error\n\n## [1.9.6] - 2026-07-07\n\n### Fixed\n\n- `manage_dashboards`: after building a dashboard, the assistant now always offers to publish it to Supermetrics Studio for a shareable, always-fresh link, instead of just showing the in-chat preview and stopping. The upload still happens only after you confirm — this just makes sure you're always told the option exists.\n\n## [1.9.5] - 2026-07-07\n\n### Added\n\n- `manage_dashboards` `upload`: the response now includes a `code_warnings` list when an uploaded board looks likely to render empty — specifically when it queries Supermetrics data but never maps columns via `result.data.requested_field_ids`. The warning names the fix so the board can be corrected and re-uploaded before sharing, instead of the data-wiring problem only surfacing when someone opens the board. Advisory and non-blocking: the upload still succeeds.\n\n### Fixed\n\n- `manage_dashboards`: the in-chat preview shown before uploading is now a static page with your real data baked in, so it actually renders here instead of coming up empty. Previously the preview reused the live Studio version (which fetches data through a Studio-only helper), so it showed no data and came with a confusing \"won't pull data outside Studio\" note. The version uploaded to Supermetrics Studio is still the live, always-fresh one.\n\n## [1.9.4] - 2026-07-07\n\n### Fixed\n\n- `manage_dashboards` `upload`: a dashboard is now shown to you in the chat first and you're asked before it's published to Supermetrics Studio as a shareable link, instead of being uploaded and shared unprompted. If you explicitly ask to publish or share it to Studio (e.g. \"put this in Studio and give me a share link\"), it still uploads right away.\n\n## [1.9.3] - 2026-07-06\n\n### Fixed\n\n- `manage_dashboards` `upload`: dashboards you generate now render their data on the first view instead of frequently coming up empty until fixed in the Studio editor. The `code` guidance now documents the exact shape `smQuery` returns (data is a 2D array at `result.data.data` — row 0 headers, rows 1+ data — with columns mapped by `result.data.requested_field_ids`, not the display labels), so the generated board code parses query results correctly out of the box.\n\n## [1.9.2] - 2026-07-06\n\n### Changed\n\n- `manage_dashboards` `edit`: region-replace patches (`from`/`to`) now replace the whole region **including** the anchor marker lines, matching the Supermetrics Studio edit AI. Write the complete new block in `replace` and reproduce the `from`/`to` marker lines inside it (the server forces this behavior, so a restated anchor no longer duplicates a declaration). Requires the paired dazl-backend change that adds `include_anchors` support.\n\n## [1.8.4] - 2026-07-03\n\n### Changed\n\n- `manage_dashboards` `upload` and `get` responses now omit the board review-status fields unless the board has been blocked by content review — in which case the status and reason are included so you can surface a remediation notice. Previously these fields were always returned, even for the benign default state.\n\n## [1.8.3] - 2026-07-03\n\n### Changed\n\n- `manage_dashboards` `upload` no longer echoes back the dashboard code you just submitted — the response now returns only the dashboard metadata (id, title, view URL). Use the `get` action to retrieve the stored code when you need it.\n\n## [1.8.1] - 2026-07-03\n\n### Added\n\n- TikTok Ads (TIK) REACH campaigns now support frequency cap settings. Set `frequency` (max impressions per user) and `frequency_schedule` (period in days) in ad group `platform_settings`. Previously these fields were silently dropped, blocking all REACH campaign creation.\n- TikTok Ads (TIK) ad groups now support additional `optimization_goal` values (`ENGAGED_VIEW`, `CONVERSION`, `INSTALL`) and the `CPV` `billing_event`.\n- TikTok Ads (TIK) campaigns now support Campaign Budget Optimization (CBO). Set `budget_optimize_switch: \"ON\"` in campaign `platform_settings` to manage budget at the campaign level — ad groups no longer require their own budget when CBO is enabled.\n- TikTok Ads (TIK) placement type is now auto-detected: when `placements` are specified (in targeting or platform_settings), `placement_type` is automatically set to `PLACEMENT_TYPE_NORMAL`. This fixes VIDEO_VIEWS campaigns that previously failed with \"This ad objective only supports manual placement.\"\n\n### Fixed\n\n- TikTok Ads (TIK) campaign read-back now includes `budget_type` (DAILY/LIFETIME) on ad groups when the data is available from TikTok's API.\n\n## [1.8.0] - 2026-07-02\n\n### Fixed\n\n- Meta Ads (FA) ad set creation no longer fails with \"you need to enable or disable the Advantage audience feature.\" Advantage+ Audience now defaults to disabled when not specified — your targeting is applied as-is. Set `advantage_audience` to `true` in targeting to let Meta expand beyond your specified audience. Both the flat key and Meta's nested `targeting_automation.advantage_audience` format are accepted.\n\n## [1.7.0] - 2026-07-02\n\n### Added\n\n- New `manage_dashboards` tool: upload dashboards to Supermetrics Studio. Studio dashboards have live data and refresh without spending tokens (unlike dashboards in Claude) and can be shared with anyone.\n\n## [1.6.2] - 2026-07-02\n\n### Added\n\n- PMax asset group UPDATE: you can now update an existing Performance Max asset group by providing its ID. Headlines, descriptions, images, and other assets are replaced in-place instead of requiring a new asset group. Set `ad_groups[].id` to the existing asset group ID.\n- Warnings for silent transformations: the `notes` array now reports when portrait images (4:5 ratio) may not appear on all PMax surfaces, and confirms when search themes are applied as optimization signals.\n\n### Changed\n\n- The `campaign_update` tool description now documents the extensions payload schema (callouts, sitelinks, structured snippets) including field names and required formats.\n- Sitelinks now accept both `text` and `link_text` as the display text field name, for compatibility with Google Ads API conventions.\n- Structured snippet `header` field description now lists all valid English enum values.\n\n## [1.6.1] - 2026-06-30\n\n### Changed\n\n- The campaign change-approval page now shows the full proposed change — campaign fields, plus a card per ad group and ad with each changed field (headline, primary text, CTA, final URL, page, image) shown as old → new on edits — instead of collapsed lines like \"Ad groups updated\".\n\n## [1.6.0] - 2026-06-29\n\n### Added\n\n- Campaign changes that go live — enabling a campaign, or editing a campaign that is already live — can now require your explicit approval. When approval is required, the response includes a secure approval link; opening it shows a summary of the change and applies it only after you click Approve. Validation errors are surfaced first, so you only ever approve a change that is ready to apply. If applying the approved change fails, the page shows the specific reason; if it applies with caveats (for example, an ad pending platform review), those notes are shown too. The link works in any client.\n\n## [1.5.18] - 2026-06-28\n\n### Fixed\n\n- **Connecting an unconnected data source now gives clear next steps** — when `accounts_discovery` finds no connected account for a data source, the response already includes a connection link. Previously the appended guidance also told the assistant to call `accounts_discovery` again (the tool that just reported the problem), which could cause it to loop instead of helping the user connect. The guidance now tells the assistant to share the connection link with the user so they can connect the data source, then retry.\n\n## [1.5.17] - 2026-06-28\n\n### Fixed\n\n- **`accounts_discovery` no longer shows a connection link for connectors that don't use an account list** — some data sources (e.g. free-text connectors) have no account list to browse, and some require no connection at all. Calling `accounts_discovery` for those used to return a misleading \"connect this data source\" login link. It now returns clear guidance computed from the connector: whether an account is supplied as a free-text identifier in `ds_accounts`, and a connection link only when the data source actually needs to be connected. For no-auth data sources, the connection is set up automatically so accounts can be listed without a login step.\n\n## [1.5.16] - 2026-06-26\n\n### Fixed\n\n- **Runtime connector errors are no longer mislabelled as an invalid data source** — when a query against a valid connector failed at runtime with a message like \"Data Source Error: Not Found\" (seen with Google BigQuery), `get_async_query_results` would wrongly append \"Did you mean …?\" suggestions and tell you to pick a different data source. The original connector error is now returned unchanged, without the misleading data-source suggestion.\n\n## [1.5.15] - 2026-06-25\n\n### Fixed\n\n- **Meta Ads (FA) campaign tools now accept ad-account IDs with or without the `act_` prefix** — campaign tools (list, create, update, status, assets, forecast, audiences, conversions, …) no longer fail with \"Connection expired\" when an `account_id` is supplied without the `act_` prefix. Both `1234567890` and `act_1234567890` now work.\n\n## [1.5.14] - 2026-06-25\n\n### Added\n\n- **Add or remove keywords on an ad group (Google Ads & Microsoft Advertising)** — `campaign_create` and `campaign_update` now accept `add_keywords` and `remove_keywords` on an ad group. `add_keywords` appends positive keywords (skipping duplicates) without touching the ad group's other targeting; `remove_keywords` deletes matching keywords. Use these for incremental keyword edits — `targeting.keywords` still replaces the whole set.\n\n### Fixed\n\n- **`campaign_update` no longer silently does nothing when keywords are passed at the top level** — previously, calling `campaign_update` with keywords (e.g. under an invented `action` argument) instead of nesting them under an ad group returned success while changing nothing. Such keywords are now routed to the intended ad group when it's unambiguous (an `ad_group_id` or a single ad group is given), and otherwise return a clear error explaining the correct shape.\n\n## [1.5.13] - 2026-06-25\n\n### Added\n\n- **Sub-country location targeting for Meta Ads campaigns** — `campaign_create`, `campaign_update`, and forecast/reach-estimate tools now accept `location_details` in `targeting` for city, region, ZIP, geo-market, and custom-location targeting. Use `targeting_search` to look up Meta geo keys.\n- **Facebook Ads carousel, video, and boosted-post creatives** — `campaign_create` and `campaign_update` now expose `carousel_cards`, `object_story_id`, and `asset_type` on ad creatives, making it possible to create carousel ads (2–10 cards), boost existing Page/Instagram posts by ID, and explicitly mark uploaded media as video.\n\n## [1.5.11] - 2026-06-24\n\n### Fixed\n\n- **`campaign_update` tool guidance** — tool and parameter descriptions now explain that `campaign_update` is also used to create new ad groups/ads inside an existing campaign, and that operations are inferred from the presence/absence of `id` fields (there is no `update_type` parameter).\n\n## [1.5.10] - 2026-06-18\n\n### Added\n\n- `user_info` now reports license warnings (such as an expired credit card) in the license details on every call.\n- When your account has a license warning like an expired credit card, the warning — including a link to update your card — is now surfaced as a note once per session, on the first tool you use.\n\n## [1.5.9] - 2026-06-16\n\n### Added\n\n- **AI-generated logos in campaign creatives** — `campaign_create` and `campaign_update` now accept `logo_prompt` on ad creatives, generating the logo from a text prompt. Combined with `asset_prompt`, visuals can be supplied end-to-end without opening the media picker.\n\n### Changed\n\n- **Clearer error when uploading local files** — passing a local file path or unsupported URL scheme to image upload or the image proxy now returns a specific message explaining the issue, instead of the generic \"Only HTTPS URLs are supported\".\n\n## [1.5.8] - 2026-06-15\n\n### Changed\n\n- **Leaner tool responses** — presentation fields (`title`, `subtitle`, `source_url`) are now included only for clients that render them as cards (Microsoft Copilot). All other clients receive smaller responses without these fields, reducing token usage.\n- **Null `error` omitted** — tool responses no longer include the `error` field when it is null; it appears only on actual failures.\n- **`get_async_query_results`** — the redundant `message` field is dropped from polling responses (`polling_instruction` already explains how to poll), and the tool description now clarifies that result rows are in `data.data` (the inner `data` field), not directly in the top-level `data`.\n- **Currency recommendation** — when a query returns monetary values without a currency dimension, the recommendation is now more concise and names the specific currency field IDs available for that data source so you know exactly what to add.\n\n### Added\n\n- **Query result field IDs** — `get_async_query_results` now includes a `requested_field_ids` list in completed responses: the field IDs you requested, in the same order as the data columns (`requested_field_ids[i]` labels the i-th value in each row). This makes it easier to map result columns back to the fields that were requested.\n- **Field remapping visibility** — when a requested field ID resolves to a different canonical ID (e.g. an alias, different casing, or underscores), `get_async_query_results` also returns a parallel `canonical_field_ids` list (same order) so clients can reconcile any stored field IDs (for example in a saved dashboard) against the canonical values. A note additionally highlights substantive remaps (aliases/synonyms); cosmetic differences that only involve casing or underscores are left out of the note since they resolve automatically. When nothing was remapped, `canonical_field_ids` is omitted.\n\n## [1.5.7] - 2026-06-14\n\n### Changed\n\n- **AI image generation branding** — image generation in the media picker is now clearly branded as SuperAI, by Supermetrics. The generate tab, prompt placeholder, generated-image badges, tooltips, and the ready toast all carry SuperAI/Supermetrics attribution, and a note reminds users to review generated images before publishing.\n- **Campaign tool descriptions** — trimmed verbose prose from campaign tool descriptions and parameter docstrings to reduce token usage while preserving all enum values, format hints, and critical constraints. Added `ad_groups`/`ad_group`/`adgroups` aliases to `resource_type` normalization so LLMs that hallucinate these values are silently redirected to `campaigns` instead of erroring.\n\n## [1.5.6] - 2026-06-11\n\n### Changed\n\n- **Contact Supermetrics** — the `contact_supermetrics` tool now directs users to buy standard plans online at https://supermetrics.com/pricing and reserves sales enquiries for special needs (many data sources, accounts, users, or other custom requirements). Reduces unnecessary sales tickets for purchases that can be self-served.\n\n## [1.5.5] - 2026-06-10\n\n### Changed\n\n- **Campaign and resource listing** — the `campaign_and_resource_get` tool now documents that list results (campaigns, assets, pages, posts) default to 50 and explains how to use `max_rows` to retrieve more. Previously the 50-result default was undocumented, so large accounts could appear capped at 50 entities.\n\n## [1.5.0] - 2026-06-08\n\n### Added\n\n- **Google Drive integration** — import images and videos from Google Drive directly into the media picker. Select individual files, multiple files, or entire folders. Supports multiple Google accounts with automatic session caching.\n\n## [1.4.14] - 2026-06-02\n\n### Added\n\n- **Assign users to subscription** — new `add_user_to_subscription` action in the `manage_user_and_team` tool lets you assign team members to a license. Requires `license_id` and `user_ids` parameters.\n\n## [1.4.13] - 2026-06-02\n\n### Added\n\n- **Product feed filtering for Google Ads Shopping and PMax campaigns** — use `product_filter` in `platform_settings` to target specific products from your Merchant Center feed by custom labels, product IDs, brand, condition, or product type. Supports both include and exclude modes.\n\n## [1.4.7] - 2026-05-30\n\n### Fixed\n\n- **Data query date handling** — queries no longer fail with \"Missing value for query start date\" when the AI places date parameters (`start_date`, `end_date`, `date_range_type`) inside the `settings` object or uses alternate key names (`date_from`, `date_to`).\n\n## [1.4.5] - 2026-05-27\n\n### Removed\n\n- **Logout action** — removed the `logout` action from the `manage_user_and_team` tool.\n\n## [1.4.4] - 2026-05-27\n\n### Added\n\n- **AI image generation in asset picker** — the AI Generate tab is now available for all clients, including Claude.\n\n## [1.4.3] - 2026-05-24\n\n### Added\n\n- **Structured output for all tools**\n\n## [1.4.2] - 2026-05-24\n\n### Added\n\n- **Structured output for query tools** — `data_query` and `get_async_query_results` now declare their response shape via MCP `outputSchema`, so clients know the expected fields (schedule_id, status, data rows, error) at discovery time. Responses include typed `structuredContent` alongside the text content for backwards compatibility.\n\n## [1.4.0] - 2026-05-22\n\n### Added\n\n- **Team management tool** — new `manage_user_and_team` tool replaces `user_info` with expanded capabilities. Use `action` parameter to:\n  - `get_info` — get your profile, license, team members, pending invitations, and other teams you belong to\n  - `invite_member` — invite someone to your team by email and role\n  - `login_data_source` — get a login link for a data source\n- The previous `user_info` tool continues to work for existing sessions.\n\n## [1.3.4] - 2026-05-20\n\n### Changed\n\n- **Data source configuration** — large option lists for countries, timezones, currencies, and languages are now replaced with concise descriptions of accepted values, significantly reducing response size. When the same option list appears across multiple report types, it is included once and referenced by pointer.\n\n## [1.2.21] - 2026-05-19\n\n### Added\n\n- **Campaign forecast tool** — estimate ad performance at different spend levels before creating a campaign. Supports Google Ads (keyword forecasts) and Facebook Ads (audience reach estimates).\n\n## [1.2.20] - 2026-05-18\n\n### Added\n\n- ChatGPT Ads integration: you can now create and update ChatGPT Ads campaigns, and fetch data about them.\n\n## [1.2.18] - 2026-05-18\n\n### Added\n\n- Data source discovery now supports a `filter` parameter for narrowing results. If exactly one data source matches, its full configuration is returned automatically.\n\n## [1.2.11] - 2026-05-09\n\n### Added\n\n- Support for Meta's Advantage+ Audience with expand_audience parameter.\n\n## [1.2.10] - 2026-05-08\n\n### Added\n\n- Query results now include a note when dimensions were requested after metrics, since the API always returns dimensions first regardless of request order.\n\n## [1.2.1] - 2026-05-07\n\n### Added\n\n- Asset picker UI for creating ad creatives.\n\n## [1.1.23] - 2026-05-05\n\n### Changed\n- Account discovery no longer returns ds_user or ds_user_display_name.\n\n## [1.1.21] - 2026-05-05\n\n### Added\n- Account discovery now returns `tags` when present, and the `filter` parameter matches against tag values.\n\n### Changed\n- Account discovery only returns group name and currency if they are not empty.\n\n## [1.1.11] - 2026-04-28\n\n### Added\n- **Posts resource type** — list Facebook Page posts that can be promoted as ads via `resource_type='posts'`. Optionally pass `page_id` to pick a specific page, or let it auto-select the first available one.\n\n## [1.1.8] - 2026-04-26\n\n### Added\n\n- New \"Create Campaign\" prompt to guide you through setting up an ad campaign step by step. Optionally specify the ad platform upfront, or let it ask you.\n\n### Fixed\n\n- Pre-defined starter prompts were returning garbled JSON instead of plain text due to a serialization bug. They now work as intended.\n\n## [1.0.6] - 2026-04-17\n\n### Added\n\n- Targeting search now supports LinkedIn Ads — search for interests, industries, job titles, employers, schools, fields of study, skills, degrees, seniorities, and job functions. Six targeting types (interest, industry, school, field_of_study, employer, job_title) now work across both Meta Ads and LinkedIn Ads.\n\n## [1.0.1] - 2026-04-16\n\n### Fixed\n\n- Health check for Facebook Ads was returning ad set IDs instead of campaign IDs due to a legacy field naming mismatch (`campaign_id` = ad set in FA). This caused subsequent campaign detail requests to fail with \"nonexisting field (objective)\".\n- Campaign tools now show a login link when a data source account is not connected, instead of returning a raw \"NO_TOKEN_FOR_ACCOUNT\" error. This matches the behavior already present in data query and account discovery tools.\n\n## [1.0.0] - 2026-04-15\n\n### Changed\n\n- Supermetrics MCP server is out of beta. Starting from this release, the project follows semantic versioning: major versions for breaking changes, minor versions for new features, and patch versions for bug fixes.\n\n## [0.18.5] - 2026-04-14\n\n### Added\n\n- Campaign management now supports LinkedIn Ads (LIA) — create, update, and manage LinkedIn campaigns alongside Google Ads, Meta Ads, Microsoft Ads, and TikTok Ads.\n\n## [0.18.3] - 2026-04-14\n\n### Changed\n\n- Bearer tokens must now use a recognised prefix (`api_` or `otok_`). Tokens with other formats are rejected with 401 instead of being passed to the downstream API.\n\n## [0.18.2] - 2026-04-14\n\n### Fixed\n\n- In some cases, we were caching data query errors, which caused them to be returned repeatedly, even if the underlying issue was fixed. We no longer cache errors.\n\n## [0.18.1] - 2026-04-14\n\n### Added\n\n- `campaign_create` and `campaign_update` tools now accept an optional `url_tags` parameter for campaign-level URL tracking parameters.\n\n### Changed\n\n- Campaign management tools beta is now opened to everyone: `campaign_create`, `campaign_update`, and `campaign_and_resource_get`.\n- Queries without date parameters no longer default to `last_30_days`; the API handles defaults server-side\n\n### Fixed\n\n- Date range types not in the hardcoded whitelist (e.g. `last_31_days`) are now passed through to the API correctly instead of being silently replaced with `last_30_days`\n\n## [0.17.5] - 2026-04-13\n\n### Fixed\n\n- Field discovery filter now matches against report type names (e.g., filtering by 'Posts' returns fields belonging to that report type)\n\n### Fixed\n\n- `get_async_query_results` now correctly signals expired OAuth tokens so clients can refresh automatically, instead of returning a generic error.\n\n## [0.17.4] - 2026-04-11\n\n### Added\n\n- Amazon Ads data source\n\n## [0.15.13] - 2026-04-02\n\n### Added\n\n- New campaign management tools in beta: `campaign_create`, `campaign_update`, and `campaign_and_resource_get`. Create, update, and manage advertising campaigns on Google Ads, Meta Ads, Microsoft Ads, and TikTok Ads directly from conversations. Includes ad group/ad set and ad creation, targeting, extensions, image and video creatives (including AI-generated images), and a full change history with undo support. This functionality will be available for everyone soon; to get access to the beta, please contact Supermetrics support or your customer success contact.\n\n## [0.15.8] - 2026-03-31\n\n### Added\n\n- Data Blending and Semrush Analytics are now available as data sources.\n\n### Changed\n\n- The list of available data sources now reflects your team's actual access, including invite-only and early access sources you've been granted. The list also includes any private connectors your team owns, distinguished by the `is_private` property. Previously, some sources your team had access to may not have appeared.\n- Data source list responses are now leaner: the `status` field is only included for non-released sources (e.g. \"Early access\", \"Invite only\"). The values are now in proper case instead of all caps. The same for categories: `Paid media` instead of `PAID_MEDIA`.\n\n## [0.15.7] - 2026-03-31\n\n### Added\n\n- New `sales` contact type in `contact_supermetrics` tool for submitting sales enquiries and demo requests via HubSpot.\n\n## [0.15.6] - 2026-03-30\n\n### Changed\n\n- The `filter` parameter in `field_discovery` and `accounts_discovery` now supports multiple comma-separated values (e.g. `\"click,impression\"`), returning items matching any of them.\n\n## [0.15.1] - 2026-03-23\n\n### Added\n\n- New `contact_supermetrics` tool: send product feedback or create support tickets directly from conversations.\n\n## [0.14.6] - 2026-03-18\n\n### Added\n\n- New optional `max_rows` parameter for data queries. Defaults to 1000 if not specified. Increase to retrieve larger datasets (up to 10,000 recommended).\n\n## [0.14.5] - 2026-03-18\n\n### Added\n\n- New `filter` parameter for field discovery: case-insensitive text search across field ID, name, description, group, and type. Replaces the `field_type` parameter, which still works for backward compatibility.\n\n### Changed\n\n- Field discovery now returns report types as compact integer indices with a `report_type_legend` array, reducing response size for data sources with many report types.\n\n## [0.14.3] - 2026-03-16\n\n### Added\n\n- Public `/datasources` endpoint listing available connectors.\n\n## [0.14.2] - 2026-03-16\n\n### Changed\n\n- All responses now include `trace_id` in metadata for easier request correlation in support scenarios.\n\n### Fixed\n\n- Tool responses now include the correct server version in metadata.\n- Supermetrics OAuth errors are now always raised as 401 to ensure MCP clients trigger token refresh.\n\n## [0.13.8] - 2026-03-11\n\n### Fixed\n\n- Data queries no longer fail when `report_type` is included for data sources that don't support report type selection.\n- Error messages for unknown fields, incompatible field combinations, and invalid report types now include actionable guidance (e.g. \"call field_discovery\") instead of returning raw API errors.\n\n## [0.13.3] - 2026-03-06\n\n### Added\n\n- Data queries now return a login link when authentication is missing, so users can connect directly from the error message.\n\n### Changed\n\n- Auto-connection creation for no-auth data sources is now dynamic — any connector with `authentication_status: NOT_REQUIRED` is supported, not just a hardcoded list.\n\n## [0.13.1] - 2026-03-06\n\n### Added\n\n- Support for 118 new data sources.\n\n\n## [0.13.0] - 2026-03-05\n\n### Changed\n\n- Tool response notes are now returned as a `notes` array instead of a single `note` string.\n\n## [0.12.9] - 2026-03-05\n\n### Fixed\n\n- Direct tool endpoint (`POST /mcp/{tool_name}`) now correctly handles the settings parameter.\n- Data queries now rescue misplaced settings (e.g. `country`, `list_type`) from root-level parameters into the `settings` object automatically.\n\n## [0.12.4] - 2026-03-04\n\n### Added\n\n- Trace ID in error responses — when a tool call fails, the response now includes a trace ID that users can provide to Supermetrics support for faster troubleshooting.\n\n## [0.12.0] - 2026-03-03\n\n### Added\n\n- Config mode for data source discovery — passing a `ds_id` now returns full data source configuration (capabilities, report types, settings).\n- Authentication status checks with login link generation for unconnected data sources.\n- 10 new data sources: Facebook Pages, Apple Search Ads, Adobe Analytics, Callrail, Google Trends, Instagram Public Data, Snapchat, Taboola, YouTube.\n- Report types included in field discovery output for multi-report-type data sources.\n- Contextual account hints in data query error responses.\n- For some data sources, report type property to field discovery to indicate which fields are compatible.\n\n### Changed\n\n- `ds_accounts` and `fields` are now optional in data queries, supporting data sources that don't require them.\n- Updated tool descriptions to guide agents through a config-driven workflow.\n\n## [0.11.3] - 2026-03-02\n\n### Added\n\n- Filter parameter for account discovery to narrow results by keyword.\n\n## [0.11.2] - 2026-03-02\n\n### Changed\n\n- Improved subtitle for data query tool responses.\n\n## [0.11.1] - 2026-02-26\n\n### Added\n\n- Purchase note on license error responses to guide users toward resolving access issues.\n\n### Changed\n\n- Improved tool titles across all tools for clearer agent integration.\n\n## [0.11.0] - 2026-02-25\n\n### Added\n\n- authentication_status property to data source discovery, with values AUTHENTICATED, NOT_AUTHENTICATED and NOT_REQUIRED.\n\n## [0.10.0] - 2026-02-18\n\n### Added\n\n- Prompts.\n- Title, subtitle and source_url properties to all tool responses.\n"}