---
title: Read your accounts
description: Ask an AI agent which ad accounts you have, what runs in them, and what they spend and return. The agent reads what AdCrunch stores, or it asks the provider now, and it changes nothing.
---

Ask an AI agent about your connected ad accounts: which accounts you have, what runs in them, and what they spend and return. Most answers come from the copy that AdCrunch stores. When you need the state of now, the agent asks the provider. Each tool only reads, so no question in this job changes a campaign or spends money.

## Before you start

- Connect a provider. Meta, TikTok and Google Ads give campaigns and metrics. [What each provider supports](/connect/providers) tells which provider gives what.
- The agent needs the scope `observe:read`. [Auth & scopes](/mcp/auth) tells how the agent gets it.

## 1. Find your ad accounts

> Which ad accounts do I have in AdCrunch?

The agent calls [`list_advertisers`](/mcp/tools/list-advertisers). You see each ad account that your organization connected: its name, its provider, its currency, and whether it is active. The agent keeps the id of each account, so that the next steps name the account by its id and not by its name.

To see the accounts of one provider only, name the provider: "Which Meta ad accounts do I have?"

## 2. See what runs in an account

> List the active campaigns in the EU account, with their daily budgets.

The agent calls [`list_campaigns`](/mcp/tools/list-campaigns) for that account. You see each campaign with its status, its objective, and its budget in the currency of the account. A campaign whose ad sets have the budget shows no budget of its own.

To go one level down, name a campaign: "Show the ad sets of the Q4 Acquisition campaign." The agent calls [`list_ad_groups`](/mcp/tools/list-ad-groups) with that campaign. Each provider has its own word for this level: an ad set on Meta, and an ad group on TikTok and on Google Ads. The tool has one name for all three, and each row keeps the word of its provider. [`list_ads`](/mcp/tools/list-ads), [`list_creatives`](/mcp/tools/list-creatives) and [`list_asset_groups`](/mcp/tools/list-asset-groups) read the other levels.

A long list comes one page at a time. The agent asks for the next page when it needs more rows.

## 3. Read all the settings of one campaign

> Show me all the settings of the Q4 Acquisition campaign.

The agent calls [`get_campaign`](/mcp/tools/get-campaign) with the campaign that it found in step 2. Each level has its own get: [`get_ad_group`](/mcp/tools/get-ad-group), [`get_ad`](/mcp/tools/get-ad), [`get_creative`](/mcp/tools/get-creative) and [`get_asset_group`](/mcp/tools/get-asset-group). You see each field that AdCrunch stored from the provider for that campaign, in the words of the provider, such as its start time. Use this step when the list of step 2 does not show the field that you need.

## 4. Measure performance

> How much did each campaign in the EU account spend last week, and what was the ROAS?

The agent calls [`query_insights`](/mcp/tools/query-insights). You see one row for each campaign, with its spend and its return on ad spend for that week. When the agent sends no dates, AdCrunch reads the last 15 days.

Ask a follow-up question to change the view:

- "Show it day by day." The agent adds one row for each day.
- "Now by ad set." The agent reads the ad sets in place of the campaigns. It asks for `ad-groups`, the same word for every provider, and each row keeps the word of its provider: `adset` on Meta, `adgroup` on TikTok and `ad_group` on Google Ads.
- "Show all of it in euros." The agent asks AdCrunch for euros. AdCrunch converts each day at the European Central Bank rate of that day, and then adds the days up. Each row then shows euros. With no currency, each row shows the currency of its ad account.

## 5. Ask the provider now

> Which Meta campaigns run on Northwind right now?

The agent calls [`meta_list_campaigns`](/mcp/tools/meta-list-campaigns). A tool whose name starts with a provider asks that provider now. It does not read the copy that AdCrunch stores. So you see a change that someone made in the interface of the provider a minute ago. Use it when the answer must be current, for example before a change.

| Provider | Tools |
| --- | --- |
| Meta | [`meta_list_campaigns`](/mcp/tools/meta-list-campaigns), [`meta_list_adsets`](/mcp/tools/meta-list-adsets), [`meta_list_ads`](/mcp/tools/meta-list-ads), [`meta_list_creatives`](/mcp/tools/meta-list-creatives) |
| TikTok | [`tiktok_list_campaigns`](/mcp/tools/tiktok-list-campaigns), [`tiktok_list_adgroups`](/mcp/tools/tiktok-list-adgroups), [`tiktok_list_ads`](/mcp/tools/tiktok-list-ads) |
| Google Ads | [`gads_list_campaigns`](/mcp/tools/gads-list-campaigns), [`gads_list_ad_groups`](/mcp/tools/gads-list-ad-groups), [`gads_list_ad_group_ads`](/mcp/tools/gads-list-ad-group-ads), [`gads_list_asset_groups`](/mcp/tools/gads-list-asset-groups) |

Each of these tools reads one ad account, and it names each level in the words of its provider. A row has the same fields as a stored row. The times when AdCrunch stored the row are empty, because AdCrunch stores nothing from this read.

A provider can filter by some statuses and not by others. Google Ads filters by each status. For a status that the provider cannot filter by, the call fails with `live_read_unsupported`, and the agent reads the copy that AdCrunch stores.

## Guardrails

- **Read-only.** No tool of this job changes your ad accounts.
- **Your organization only.** An ad account that your organization does not own gives an empty answer. For an entity of another organization, a get such as `get_campaign` answers `not_found`, the same answer as for an entity that does not exist. A tool that asks the provider answers `not_found` for an ad account of another organization, and for an ad account of another provider. So the agent cannot find out what another organization has.
- **Most data comes from AdCrunch, not from the provider.** A tool whose name does not start with a provider, such as `list_campaigns` or `query_insights`, reads the copy that AdCrunch stores. The ingestion of that copy starts each day at 00:00 UTC. So a change that you make in the provider's own interface shows after the next ingestion. Right after you connect a provider, the first ingestion is still in progress, and the answers can be empty or incomplete.
- **A read of the provider costs a call at the provider.** Each call of a tool that asks the provider counts against the rate limits of that provider. AdCrunch keeps no copy of the answer, and the next ingestion does not change.
- **A stored budget can be old.** Meta does not mark a campaign changed when only its budget changes, and AdCrunch does not follow a budget change on Google Ads yet. So a budget that someone edits in the provider's own interface can be old in the stored copy. A tool that asks the provider gives the budget of now.
- **Each provider reports different metrics.** A metric that a provider does not report reads `0`. Google Ads reports no reach, for example. Before you compare one metric across two providers, read [what each provider supports](/connect/providers#read-insights).
- **A failure has a code.** When a call fails, the agent gets a code and a message. [Errors](/mcp/errors) lists the codes.
- **Each tool follows the same rules.** [What to expect](/mcp/what-to-expect) states how fresh a stored answer is, and how AdCrunch states money.
