AdvisorPPC X Ads MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| X_ADS_ACCESS_TOKEN | Yes | X Ads API access token (OAuth2 Bearer token) with scopes ads.read, ads.write, and offline.access. Can also be supplied via an Authorization header for Streamable HTTP, but this environment variable is used by the server when no header is provided. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| resources | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| x_ads_create_audienceA | Create an empty CRM custom audience. Then load members with x_ads_audience_users (SHA-256 hashed). Name must come from the user. targetable stays false until it is large enough. |
| x_ads_update_audienceA | Rename or change description of a custom audience. Only fields the user named. |
| x_ads_delete_audienceA | Soft-delete a custom audience. Line items targeting it will stop matching. confirm=true after the user named the audience. |
| x_ads_audience_usersA | Add (Update) or remove (Delete) members of a custom audience. Pass raw emails/phones/handles — this server SHA-256 hashes after X normalization (lowercase email, strip @, digits-only phone). Set hashed=true only if values are already hex SHA-256. Max 2500 users per call. Never log the raw list. |
| x_ads_audience_targetedB | Campaigns and ad groups currently targeting a custom audience. |
| x_ads_estimate_audienceA | Estimate reachable unique users for a targeting set BEFORE spending. criteria same shape as x_ads_add_targeting. Does not create anything. |
| x_ads_list_dnrA | Account-level exclusion list (suppression). An account can have at most one DNR list. Excludes those users from ALL campaigns on the account; it does not strip them from custom audiences. |
| x_ads_create_dnrA | Create the account DNR (suppression) list. One per account; API names it 'Do Not Reach List'. Optional description only. Then load emails with x_ads_dnr_users. |
| x_ads_delete_dnrA | Delete the account DNR list. confirm=true after the user named it. Suppression stops. |
| x_ads_dnr_usersA | Add (Update) or remove (Delete) emails on the Do Not Reach list. Emails only. Raw emails are SHA-256 hashed here. hashed=true if already hex SHA-256. expires_at optional ISO 8601 (must be < 13 months). |
| x_ads_list_pixelsB | List Universal Website Tags / conversion pixels. id is the web_event_tag_id; website_tag_id is the pixel id used in embed code and Conversion API (tw-{website_tag_id}-…). embed_code is the snippet to put on the site. |
| x_ads_get_pixelB | Fetch one web event tag: type, windows, retargeting, embed_code, website_tag_id. |
| x_ads_create_pixelA | Create a conversion / site-visit web event tag. type default SITE_VISIT. click_window and view_through_window in days (0,1,7,14,30,60,90). retargeting_enabled default false. Returns embed_code + website_tag_id. Don't invent names. |
| x_ads_update_pixelA | Partial update of name, windows, or retargeting on a web event tag. Only fields the user named. |
| x_ads_delete_pixelA | Delete a web event tag. Conversion tracking for that event stops. confirm=true after the user named it. |
| x_ads_list_accountsA | List X ad accounts the connected token can manage. Returns id, name, approval status. Call this first. |
| x_ads_list_fundingA | How campaigns are paid. Trust able_to_fund=true and empty reasons_not_able_to_fund — NOT description, which for self-serve cards can read '(no payment method has been set up yet)' even when serving. The API exposes one representative instrument for self-serve accounts. |
| x_ads_list_campaignsB | List campaigns: status (ACTIVE/PAUSED/DRAFT) and any budgets. Requires account_id. |
| x_ads_list_line_itemsA | List line items (ad groups): status, objective, bid. Optionally filter by campaign_id. Budget lives HERE, not on the campaign. |
| x_ads_list_adsA | List promoted posts. Each row has status and tweet_id. Filter with line_item_id. Deleted ads are hidden unless with_deleted=true; the underlying post is not deleted. |
| x_ads_list_targetingA | List targeting criteria for an ad group. Always pass line_item_id to see why groups differ. |
| x_ads_list_audiencesA | List tailored audiences with size and targetable status. Use ids as CUSTOM_AUDIENCE targeting values. |
| x_ads_list_creativesA | Creative inventory: cards (cap 200) and media library (cap 50) in one call. Page with cards_cursor / media_cursor. |
| x_ads_get_tweetsA | Fetch posts behind ads (tweet_id from x_ads_list_ads) WITH card_uri and media. Use this, not a generic post fetch, to tell whether an ad has a card/image. Up to ~200 ids. tweet_type default PUBLISHED (includes promoted-only). |
| x_ads_get_cardsA | Expand card_uri values (card://…) into type, components, buttons, media_keys. Images inside a card are media_keys, not URLs — pass those to x_ads_get_media. |
| x_ads_get_mediaA | Resolve media_key values (e.g. 3_2069…) to media_url / poster_media_url from the Media Library. |
| x_ads_search_targetingA | Resolve human terms into targeting_value ids for x_ads_add_targeting. kind ∈ locations, interests, languages, platforms, devices, events, app_store_categories, conversations, network_operators, tv_markets, tv_shows. For locations pass query and optional location_type. Custom audiences: use x_ads_list_audiences. |
| x_ads_active_entitiesA | Which CAMPAIGN / LINE_ITEM / PROMOTED_TWEET ids had activity in a window. Call before analytics so you don't request empty ids. Times are whole-hour ISO 8601. |
| x_ads_get_analyticsA | Sync stats for up to 20 campaigns, ad groups, or ads. Range must be ≤ 7 days. Times whole-hour ISO 8601. granularity TOTAL (default) / DAY / HOUR. metric_groups default ENGAGEMENT,BILLING. Placement ALL_ON_TWITTER. Spend is billed_charge_local_micro / 1_000_000. |
| x_ads_reachA | Unique reach + average frequency for campaigns. Window ≤ 7 days, whole-hour ISO 8601. Impressions cannot tell you this. |
| x_ads_create_campaignA | Create a campaign PAUSED by default (no spend). Pass entity_status=ACTIVE only with confirm_spend=true after an explicit user ask. Needs funding_instrument_id. BUDGETS ARE SET PER AD GROUP — do not pass a campaign budget. Don't invent names. |
| x_ads_create_ad_groupA | Create a line item under a campaign. PAUSED by default. All groups in a campaign must share objective and product_type. Budget is set HERE (daily_budget_amount_local_micro / total_budget_amount_local_micro). Bid omitted = automatic. Amounts are local micro-units (1 unit = 1_000_000). If creating multiple groups from one stated budget, ASK split vs each. confirm_spend required for ACTIVE. |
| x_ads_update_campaignA | Partial update of name and/or budget micros. Only change fields the user named. Daily must be ≤ total. Money-affecting: pass confirm=true. |
| x_ads_update_ad_groupA | Partial update of name, bid, and/or budget micros. Only change what the user named. confirm=true for money fields. |
| x_ads_set_statusA | Set a campaign or ad group to ACTIVE or PAUSED. Pausing a campaign stops its groups and ads. Ads have no on/off switch — pause the group or delete the ad. confirm=true after an explicit named ask. Never inferred. |
| x_ads_deleteA | SOFT-delete CAMPAIGN, LINE_ITEM, or PROMOTED_TWEET. Children go with the parent. Cannot be undone here. Deleting an ad does not delete the post. confirm=true after the user named the exact entity. Never inferred. |
| x_ads_add_targetingA | Add targeting on an ad group. criteria: {targeting_type, targeting_value, operator_type?}. Types: LOCATION, CUSTOM_AUDIENCE, FOLLOWER_LOOK_ALIKE, INTEREST, LANGUAGE, PLATFORM, DEVICE, GENDER, AGE, EVENT, KEYWORD. GENDER=MALE/FEMALE, AGE like AGE_25_TO_34. operator EQ include (default) or NE exclude. replace=true removes existing criteria of the SAME types first. Only set targeting the user asked for. |
| x_ads_upload_mediaA | Upload an image or video via media_url or inline base64 (media.data). Images use simple upload; video and files >5MB use v2 chunked INIT/APPEND/FINALIZE and poll until processed. Ads videos use media_category amplify_video. Returns media_key for cards/tweets. Provide exactly one source. If the intended creative failed to upload or process, STOP. Do not promote a still, a source image, or a pre-existing library asset. |
| x_ads_create_cardA | Create an ad card from raw components. Returns card_uri. Website: [{"type":"MEDIA","media_key":"…"},{"type":"DETAILS","title":"…","destination":{"type":"WEBSITE","url":"https://…"}}]. App cards use BUTTON not DETAILS. Carousel uses SWIPEABLE_MEDIA. If the intended creative failed to upload or process, STOP. Do not promote a still, a source image, or a pre-existing library asset. |
| x_ads_create_tweetA | Create a promoted-only (nullcast) post. media_keys XOR card_uri. Returns tweet id; promote with x_ads_create_ad. nullcast default true. If the intended creative failed to upload or process, STOP. Do not promote a still, a source image, or a pre-existing library asset. |
| x_ads_create_adA | Promote an EXISTING post under an ad group. Ad serves only if group AND campaign are ACTIVE. For a brand-new image use x_ads_create_image_ad. If the intended creative failed to upload or process, STOP. Do not promote a still, a source image, or a pre-existing library asset. |
| x_ads_create_image_adA | Composite: upload creative → website card → nullcast post → promote onto an EXISTING ad group. Provide media_url or inline image. Requires text + destination_url. Serves only when campaign and ad group are ACTIVE. If the intended creative failed to upload or process, STOP. Do not promote a still, a source image, or a pre-existing library asset. |
| x_ads_create_video_adA | Composite: chunked video upload (amplify_video) → website card (or media_keys if no destination_url) → nullcast post → promote onto an EXISTING ad group. Provide media_url or inline video (base64). Requires text. If the intended creative failed to upload or process, STOP. Do not promote a still, a source image, or a pre-existing library asset. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| x-ads-dashboard | Inline table of campaigns / ad groups / ads from the last tool result. |
TDQS
Scored across 43 tools
Each tool maps cleanly to a distinct resource/action: audiences, campaigns, line items, ads, creatives, targeting, pixels, DNR, and analytics. Even nearby operations like create_ad vs create_image_ad vs create_video_ad are separated by existing-post promotion versus composite creation.
The x_ads_ prefix and snake_case verb_noun pattern are used almost everywhere, making the set very predictable. A few outliers like delete, active_entities, reach, audience_users, and dnr_users deviate slightly but remain readable and non-confusing.
43 tools is heavy and pushes well beyond the ideal range for agent usability, but the X Ads domain is broad and every tool appears purposeful with no obvious duplicates. The count is appropriate for the full API surface, yet it will still increase selection overhead for an agent.
The surface covers nearly the full lifecycle: accounts, funding, campaigns, ad groups, promoted posts, creatives, media, targeting, custom audiences, pixels, DNR, and analytics. Minor gaps include no dedicated single-criterion targeting removal and no way to list current DNR members, though these are workaroundable.