@ideepakrajput/taboola-backstage-full-mcp
v1.1.0
Published
Full-coverage MCP server for the Taboola Backstage API — every endpoint (campaigns, creatives, audiences, conversions, targeting, reporting, publishers, dictionaries) exposed as a typed tool.
Maintainers
Readme
Taboola Backstage MCP Server
A Model Context Protocol (MCP) server that exposes the full Taboola Backstage API as a set of well-documented tools — every endpoint Backstage publishes is available as a typed MCP tool, ready to be called from Claude Desktop, Claude Code, Cursor, or any other MCP-compatible chat client.
- Language: TypeScript / Node 18+
- Transport: stdio
- Auth: OAuth2
client_credentials(Backstage standard) - Tool surface: ~85 tools spanning campaigns, creatives, audiences,
conversions, targeting, reporting, publishers, dictionaries, plus a
generic escape-hatch (
taboola_call_backstage_endpoint) for the long tail.
Install
The simplest path — install from npm and run via npx:
npx -y @ideepakrajput/taboola-backstage-full-mcp
# -> "taboola-backstage-full-mcp ready. N tools registered." on stderrOr install globally and run the bundled binary:
npm install -g @ideepakrajput/taboola-backstage-full-mcp
taboola-backstage-full-mcpBuild from source
git clone https://github.com/ideepakrajput/taboola_backstage_mcp.git
cd taboola_backstage_mcp
# 1. Install deps & build
npm install
npm run build
# 2. Configure credentials
cp .env.example .env
$EDITOR .env # paste your TABOOLA_CLIENT_ID and TABOOLA_CLIENT_SECRET
# 3. Try it locally
node dist/index.js
# -> "taboola-backstage-full-mcp ready. N tools registered." on stderrThe server speaks MCP over stdio and waits silently for an MCP client to connect.
During development you can run the TypeScript source directly:
npm run dev # uses tsx; no build step neededGetting Taboola credentials
You need a Backstage client_id and client_secret.
- Ask your Taboola account manager, or
- Create an API client yourself in the Backstage UI under Integrations / API Access.
Backstage returns an access token via the standard
client_credentials flow. Tokens expire after 12 hours and are
auto-refreshed by the server — you only ever need to provide the
client_id/client_secret pair.
Configuration
Environment variables read at startup:
| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| TABOOLA_CLIENT_ID | yes | — | OAuth2 client_id |
| TABOOLA_CLIENT_SECRET | yes | — | OAuth2 client_secret |
| TABOOLA_API_BASE_URL | no | https://backstage.taboola.com/backstage/api/1.0 | Override for staging / alt endpoints |
| TABOOLA_TOKEN_URL | no | https://backstage.taboola.com/backstage/oauth/token | Override for staging |
| TABOOLA_DEFAULT_ACCOUNT_ID | no | — | If set, tools that need an account_id use it when the caller omits one |
| TABOOLA_HTTP_TIMEOUT_MS | no | 30000 | Per-request timeout in ms |
The server will also pick up a .env file next to the binary or in the
process cwd (best-effort — no dotenv dependency is required).
Wiring up clients
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json
(macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"taboola-backstage": {
"command": "npx",
"args": ["-y", "@ideepakrajput/taboola-backstage-full-mcp"],
"env": {
"TABOOLA_CLIENT_ID": "...",
"TABOOLA_CLIENT_SECRET": "...",
"TABOOLA_DEFAULT_ACCOUNT_ID": "acme-advertising"
}
}
}
}If you built from source instead, point at the local file:
{
"mcpServers": {
"taboola-backstage": {
"command": "node",
"args": ["/absolute/path/to/taboola_backstage_mcp/dist/index.js"],
"env": {
"TABOOLA_CLIENT_ID": "...",
"TABOOLA_CLIENT_SECRET": "..."
}
}
}
}Restart Claude Desktop and the taboola-backstage tools will appear.
Claude Code
claude mcp add --scope user taboola-backstage \
--command npx \
--args -y \
--args @ideepakrajput/taboola-backstage-full-mcp \
--env TABOOLA_CLIENT_ID=... \
--env TABOOLA_CLIENT_SECRET=...Cursor / other MCP clients
Use the same stdio command shape — anything that can spawn a child process and speak MCP over stdio will work.
Tool inventory
Naming convention: taboola_<verb>_<resource>. Every tool's
description starts with READ or WRITE so the model can quickly tell
what's safe and what mutates state.
Account & user (READ-only)
taboola_get_account_details— your account_id, currency, partner_typestaboola_get_allowed_accounts— accounts your credentials can accesstaboola_get_advertiser_accounts_in_network— advertisers under a network account
Dictionary / resources (READ-only)
taboola_get_dictionaries,taboola_get_campaign_enums,taboola_get_item_enumstaboola_get_item_cta_values,taboola_get_item_status_values,taboola_get_campaign_category_values,taboola_get_min_cpc_valuestaboola_get_countries,taboola_get_regions_in_country,taboola_get_us_dmas,taboola_get_cities_in_country,taboola_get_postal_codes_for_countrytaboola_get_platforms,taboola_get_operating_systems,taboola_get_ios_versions,taboola_get_android_versions,taboola_get_browserstaboola_get_languages,taboola_get_days_of_week,taboola_get_image_library_languagestaboola_get_marketplace_audiences,taboola_get_marketplace_audiences_by_countrytaboola_get_lookalike_audiences,taboola_get_lookalike_audiences_by_countrytaboola_get_contextual_segments
Campaigns
READ: taboola_get_all_campaigns, taboola_get_all_campaigns_across_network,
taboola_get_campaign, taboola_get_postal_code_targeting,
taboola_get_contextual_targeting.
WRITE: taboola_create_campaign, taboola_update_campaign,
taboola_pause_campaign, taboola_activate_campaign,
taboola_set_campaign_bid, taboola_set_campaign_budget,
taboola_set_campaign_dayparting, taboola_set_campaign_geo_targeting,
taboola_set_campaign_device_targeting, taboola_delete_campaign,
taboola_duplicate_campaign, taboola_bulk_update_campaigns,
taboola_patch_campaign_collection, taboola_campaign_reach_estimator,
taboola_update_postal_code_targeting, taboola_update_contextual_targeting.
Campaign items / creatives (static + motion ads)
READ: taboola_get_all_campaign_items, taboola_get_campaign_item,
taboola_get_child_items, taboola_get_child_item,
taboola_get_all_motion_ads, taboola_get_motion_ad,
taboola_get_image_library_taxonomies, taboola_search_image_library.
WRITE: taboola_create_campaign_item, taboola_update_campaign_item,
taboola_pause_campaign_item, taboola_activate_campaign_item,
taboola_delete_campaign_item, taboola_update_child_item,
taboola_mass_create_campaign_items,
taboola_bulk_create_items_across_campaigns,
taboola_bulk_update_items_across_campaigns,
taboola_bulk_delete_items_across_campaigns,
taboola_create_motion_ad, taboola_update_motion_ad,
taboola_delete_motion_ad,
taboola_upload_image_from_local_device,
taboola_upload_image_from_library.
Audiences
READ: taboola_get_all_custom_audiences, taboola_get_custom_audience,
taboola_get_my_audience, taboola_get_all_combined_audiences,
taboola_get_combined_audience, taboola_list_available_audiences_for_combine,
plus the per-campaign targeting getters:
taboola_get_marketplace_audience_targeting,
taboola_get_custom_audience_targeting,
taboola_get_lookalike_audience_targeting,
taboola_get_my_audience_targeting.
WRITE: taboola_create_custom_audience, taboola_update_custom_audience,
taboola_create_first_party_audience, taboola_add_or_remove_audience_users,
taboola_create_combined_audience, taboola_update_combined_audience,
plus the per-campaign targeting setters:
taboola_update_marketplace_audience_targeting,
taboola_update_custom_audience_targeting,
taboola_update_lookalike_audience_targeting,
taboola_update_my_audience_targeting.
Conversion rules
READ: taboola_get_all_conversion_rules,
taboola_get_all_conversion_rules_plus_data, taboola_get_conversion_rule.
WRITE: taboola_create_conversion_rule, taboola_update_conversion_rule,
taboola_archive_conversion_rule.
Reporting (READ-only)
taboola_get_campaign_summary_reporttaboola_get_top_campaign_content_reporttaboola_get_campaign_history_report(audit log of campaign changes)taboola_get_activity_codes(dictionary of activity codes for the history report)taboola_get_video_campaign_summary_report(brand-video accounts)taboola_get_bidder_revenue_report(Header Bidding accounts — separate credentials)taboola_get_realtime_campaign_summary_report(10 req/min)taboola_get_realtime_ads_report(10 req/min)
Brand Video Campaigns (requires brand-video-enabled account)
READ: taboola_get_all_video_campaigns, taboola_get_video_campaign,
taboola_get_all_video_campaign_creatives, taboola_get_video_campaign_creative,
taboola_get_video_creative_assets.
WRITE: taboola_create_video_campaign, taboola_update_video_campaign,
taboola_pause_video_campaign, taboola_activate_video_campaign,
taboola_duplicate_video_campaign, taboola_delete_video_campaign,
taboola_update_video_campaign_creative.
Publishers / site blocking
READ: taboola_get_all_publishers, taboola_get_blocked_publishers.
WRITE: taboola_replace_blocked_publishers, taboola_patch_blocked_publishers.
Escape hatch
taboola_call_backstage_endpoint — call any Backstage endpoint not yet
covered by a typed tool. Method + path + optional query + optional body.
Example chats
"What's my Taboola account_id?"
The model calls taboola_get_account_details and replies with the
account_id field of the response.
"Pause campaign 1234 until tomorrow morning."
taboola_pause_campaign({ campaign_id: "1234" })…and (separately, when the user is ready) taboola_activate_campaign.
"Run a campaign-summary report by day for last month, filtered to campaign 1234."
taboola_get_campaign_summary_report({
dimension: "day",
start_date: "2026-04-01",
end_date: "2026-04-30",
campaign: "1234"
})"Block sites X and Y at the account level (don't touch the rest of the list)."
taboola_patch_blocked_publishers({
sites: ["X", "Y"],
patch_operation: "ADD"
})Error handling
Errors from Backstage surface as MCP error responses with the Backstage
JSON body intact (e.g. {"http_status":400,"message":"..."}). The HTTP
client:
- Refreshes the access token automatically when it expires or 401s.
- Retries 429 / 5xx with capped exponential backoff (up to 4 attempts).
- Honors
Retry-Afterheaders in the error message so the model can wait. - Times out individual requests after
TABOOLA_HTTP_TIMEOUT_MS.
The realtime reports are rate-limited by Backstage to 10 req/min; the
server does not enforce this client-side — keep calls modest or you'll
see 429s.
Project layout
src/
index.ts # MCP server entrypoint (stdio)
config.ts # env -> TaboolaConfig
auth.ts # OAuth2 client_credentials + token cache
client.ts # Authenticated fetch wrapper + retries + errors
tools/
framework.ts # tool() helper + Zod -> JSON Schema converter
account.ts # Account & user tools
dictionary.ts # Resource / dictionary lookups
campaigns.ts # Campaign CRUD + targeting + lifecycle
items.ts # Campaign items (creatives) + motion ads + image lib
audiences.ts # Custom / first-party / combined / lookalike + targeting
conversions.ts # Conversion-rule CRUD
reports.ts # 4 report endpoints (incl. realtime)
publishers.ts # Account-level site blocking
generic.ts # Escape-hatch generic-endpoint toolSafety notes for agents
- WRITE tools mutate live Taboola state. The descriptions say
WRITEexplicitly so the agent can pick correctly. taboola_delete_campaignis irreversible.taboola_archive_conversion_ruleis the closest thing to "delete" for conversion rules and custom audiences.taboola_replace_blocked_publishersreplaces the whole list. Prefertaboola_patch_blocked_publishersfor additive changes.- The Backstage API treats POST and PUT as equivalent for "update" — we use POST consistently in the write tools, except where the Backstage docs explicitly require PUT (e.g. motion-ad updates).
License
MIT.
