Paid Media MCP
Provides integration with Amazon advertising campaign data, enabling analysis of campaign performance, budgets, and targeting.
Provides integration with Google Ads campaign data, allowing Claude to analyze campaign performance, budgets, and targeting.
Provides integration with Meta (Facebook/Instagram) advertising campaign data, enabling analysis of campaign performance, budgets, and targeting.
Provides integration with Pinterest advertising campaign data, enabling analysis of campaign performance, budgets, and targeting.
Provides integration with Snapchat advertising campaign data, enabling analysis of campaign performance, budgets, and targeting.
Provides integration with TikTok advertising campaign data, enabling analysis of campaign performance, budgets, and targeting.
Provides integration with YouTube advertising campaign data, enabling analysis of campaign performance, budgets, and targeting.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Paid Media MCPShow me last week's campaign performance"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Paid Media MCP
A Model Context Protocol (MCP) server template for paid media teams. Connect Claude to your campaign data, team structure, performance history, attribution models, reporting templates, asset library, test-and-learn history, audience library, and measurement setup — so it can answer questions, write reports, debug tracking issues, and assist with analysis directly in your workflow.
This is a template. The example data is for a fictional e-commerce company ("Acme Corp"). You replace it with your own.
Table of Contents
What this does
When connected to Claude, this MCP server gives Claude real knowledge of your paid media operation:
Your campaigns — platforms, budgets, objectives, targeting, funnel stage, status
Your team structure — who manages what, their KPIs, platforms, and responsibilities
Your performance data — historical metrics you've loaded, with automatic aggregation
Your attribution setup — how you measure conversions, window settings, model comparisons
Your reporting formats — templates for weekly team reports, executive decks, pacing dashboards
Without this, Claude can only give generic paid media advice. With it, Claude can say:
"Looking at your Q2 Meta prospecting campaign, it's running a 2.4x ROAS against your 4.0x target. The retargeting campaign is at 12.3x, which suggests the prospecting pool may be too cold — worth tightening the lookalike to 1% and suppressing recent purchasers."
Quick start
Prerequisites
Claude Desktop (for connecting Claude)
Git
Step 1 — Clone and install
git clone https://github.com/arcticgreyy/paidmedia-mcp.git
cd paidmedia-mcp
npm installStep 2 — Fill in your data
Edit the JSON files in the data/ folder. Each file has detailed examples. See the Filling in your data section for field-by-field guidance.
At minimum, fill in:
data/metadata.json— your company namedata/accounts.json— your ad accountsdata/teams.json— your team(s)
The server will start even if other files are missing or partially filled.
Step 3 — Build
npm run buildFor development without building (requires tsx):
npm run devStep 4 — Connect to Claude Desktop
Open your Claude Desktop config file:
Mac:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Add the following (replace the paths with your actual absolute paths):
{
"mcpServers": {
"paid-media": {
"command": "node",
"args": ["/absolute/path/to/paidmedia-mcp/dist/index.js"],
"env": {
"PAID_MEDIA_DATA_DIR": "/absolute/path/to/paidmedia-mcp/data"
}
}
}
}To find your absolute path, run this from the project folder:
pwdCopy the output and append /dist/index.js for the args value and /data for PAID_MEDIA_DATA_DIR.
Step 5 — Restart Claude Desktop
Fully quit and reopen Claude Desktop. You should see a hammer icon (🔨) in the chat input — click it to verify the paid-media tools are listed.
Updating data
After editing files in data/, restart Claude Desktop (or the MCP server process) for changes to take effect. The server loads data files at startup.
Filling in your data
metadata.json
Basic company info. Used in report headers and resource descriptions.
{
"metadata": {
"company_name": "Your Company Name",
"industry": "E-commerce",
"primary_currency": "USD",
"fiscal_year_start": "01-01",
"last_updated": "2026-05-31"
}
}Field | Required | Notes |
| Yes | Appears in Claude's context |
| No | Helps Claude give relevant benchmarks and advice |
| Yes | ISO 4217 code (USD, EUR, GBP, etc.) |
| Yes | MM-DD format |
| Yes | ISO date — update when you refresh data |
accounts.json
One entry per ad account. Each account belongs to exactly one team.
{
"accounts": [
{
"id": "acc_brand_gads",
"name": "Brand — Google Ads",
"platform": "google_ads",
"platform_account_id": "123-456-7890",
"team_id": "team_brand",
"status": "active",
"currency": "USD",
"timezone": "America/New_York",
"monthly_budget": 50000,
"notes": "Brand campaigns only"
}
]
}Field | Required | Notes |
| Yes | Your internal ID — used in campaigns.json and teams.json |
| Yes | Human-readable name for Claude to display |
| Yes | See platform values below |
| Yes | The actual ID shown in the platform UI (e.g. Google Ads customer ID) |
| Yes | Must match an |
| Yes |
|
| Yes | ISO 4217 |
| Yes | IANA timezone string |
| No | Used for pacing analysis |
| No | Free text — Claude reads this |
Platform values: google_ads · meta · dv360 · youtube · linkedin · tiktok · twitter_x · pinterest · snapchat · amazon · other
teams.json
One entry per media team. This is where you capture the strategic context Claude needs to give relevant advice.
{
"teams": [
{
"id": "team_brand",
"name": "Brand & Awareness",
"description": "Manages upper-funnel brand campaigns focused on reach and video.",
"objectives": ["awareness", "reach", "video_views"],
"primary_kpis": ["impressions", "reach", "cpm", "brand_lift"],
"account_ids": ["acc_brand_gads", "acc_brand_dv360"],
"member_ids": ["user_sarah", "user_james"],
"lead_id": "user_sarah",
"platforms": ["google_ads", "dv360", "youtube"],
"reporting_cadence": "weekly",
"budget_owner": "vp_marketing",
"notes": "Brand lift studies run quarterly. All campaigns follow brand safety guidelines."
}
]
}Field | Required | Notes |
| Yes | Referenced by accounts and campaigns |
| Yes | List from: |
| Yes | Free-text metric names — Claude uses these when reviewing performance |
| Yes | Must match IDs in |
| Yes | Must match IDs in |
| Yes | Team lead — must be in |
| Yes |
|
| No | Put key context here: targets, processes, constraints |
Tip: The notes and description fields are the most valuable for Claude. Include:
ROAS/CPA/CPL targets
Key rules or constraints (e.g. "brand safe only")
Important processes (e.g. "budget reviews every Monday")
Links or references to external docs
team-members.json
One entry per person. Members can belong to multiple teams.
{
"team_members": [
{
"id": "user_mike",
"name": "Mike Rodriguez",
"email": "mike@yourcompany.com",
"role": "director",
"team_ids": ["team_performance"],
"platform_specialties": ["google_ads", "meta"],
"responsibilities": [
"Performance team leadership",
"ROAS and CPA target setting",
"Budget allocation across channels"
],
"notes": "Primary stakeholder for attribution model decisions."
}
]
}Field | Required | Notes |
| Yes | Must match |
| Yes |
|
| Yes | Array — analysts or shared staff can be on multiple teams |
| Yes | Which platforms they work in day-to-day |
| Yes | Free-text list — Claude uses this to route questions to the right person |
| No | Useful for capturing context like certifications, agency relationships, or ownership areas |
campaigns.json
One entry per campaign. This is the largest and most important data file.
{
"campaigns": [
{
"id": "camp_perf_search_001",
"name": "Performance Search — Always On",
"platform": "google_ads",
"account_id": "acc_perf_gads",
"team_id": "team_performance",
"status": "active",
"objective": "conversions",
"budget": {
"type": "daily",
"amount": 2000,
"currency": "USD",
"pacing": "standard"
},
"start_date": "2026-01-01",
"end_date": null,
"targeting": {
"geo": ["US"],
"devices": ["desktop", "mobile"],
"keyword_themes": ["branded", "competitor", "category"]
},
"funnel_stage": "lower",
"tags": ["always-on", "search", "performance"],
"notes": "Target ROAS: 5.0x. Smart Bidding tROAS strategy."
}
]
}Budget types: daily · lifetime · monthly
Objective values: awareness · reach · traffic · engagement · video_views · lead_generation · app_installs · conversions · catalog_sales · store_visits
Funnel stages: upper · mid · lower
Status values: active · paused · ended · draft · archived
Targeting fields (all optional):
Field | Example |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Tags tip: Tags are searchable. Use them consistently for filtering — e.g. q2-2026, always-on, brand, retargeting, test.
historical-performance.json
Contains two sections: daily records and benchmarks.
Records
One entry per campaign per day. Include whatever metrics you have — rate metrics are re-calculated automatically when aggregating.
{
"records": [
{
"campaign_id": "camp_perf_search_001",
"date": "2026-05-01",
"metrics": {
"impressions": 125000,
"clicks": 4200,
"spend": 1850.00,
"conversions": 310,
"conversion_value": 12400.00
}
}
]
}Available metric fields:
Metric | Description |
| Total ad impressions |
| Total clicks |
| Total spend in account currency |
| Unique users reached |
| Average impressions per user |
| Click-through rate (%) |
| Cost per click |
| Cost per 1,000 impressions |
| Cost per acquisition/conversion |
| Return on ad spend |
| Total conversion events |
| Revenue value of conversions |
| Video view count |
| Percentage who watched |
| View-assisted conversions |
| Any additional metrics as key-value pairs |
Tip: You don't need to pre-calculate rate metrics (CTR, CPC, ROAS). The server calculates them when aggregating. Just include the raw counts.
How to export data: Most platforms let you download daily campaign performance as CSV. Use a tool like Google Sheets or Python to convert to this JSON format. See data/historical-performance.json for the full structure.
Benchmarks
Industry reference points for comparison. Optional but makes performance analysis much richer.
{
"benchmarks": [
{
"platform": "google_ads",
"objective": "conversions",
"industry": "e-commerce",
"avg_ctr": 2.69,
"avg_cpc": 1.33,
"avg_cpa": 33.52,
"avg_roas": 3.5
}
]
}Use published industry benchmarks from WordStream, Meta, Google, or your agency. Update annually.
attribution-models.json
Documents how you measure conversions — not connected to live platforms, purely descriptive. Claude uses this to explain your measurement setup and make recommendations.
{
"attribution_configurations": [
{
"id": "attr_last_click_30d",
"name": "Last Click — 30-Day",
"model": "last_click",
"window": {
"click": 30,
"view": 0,
"unit": "days"
},
"platforms_applied": ["google_ads", "meta"],
"conversion_events": ["purchase", "lead_form_submit"],
"cross_device": false,
"view_through_enabled": false,
"description": "100% credit to the last clicked ad within 30 days.",
"use_cases": [
"Bottom-funnel campaign optimization",
"Simple baseline for cross-channel comparison"
],
"notes": "Over-credits search/retargeting; undervalues prospecting."
}
]
}Model values: last_click · first_click · linear · time_decay · position_based · data_driven · custom
Tip: Add one entry per meaningful configuration you use — e.g. one for Google Ads, one for Meta, one for cross-channel analysis. The use_cases and notes fields are especially valuable for Claude's analysis.
reporting-templates.json
Defines the structure of your reports and dashboards. Claude uses these when generating reports to follow the right format for the right audience.
{
"reporting_templates": [
{
"id": "tmpl_weekly_team",
"name": "Weekly Performance Report",
"type": "performance_summary",
"audience": "media_team",
"cadence": "weekly",
"metrics_included": ["spend", "conversions", "roas", "cpa"],
"dimensions": ["campaign", "platform", "date"],
"visualizations": ["spend_by_campaign_bar", "roas_trend_line"],
"delivery_format": ["google_sheets", "slack"],
"sections": [
{
"title": "Week Summary",
"description": "Overall performance vs. prior week and vs. targets.",
"metrics": ["spend", "conversions", "roas"]
},
{
"title": "Campaign Scorecards",
"description": "One row per active campaign with pacing status.",
"metrics": ["spend", "conversions", "cpa", "roas"]
},
{
"title": "Action Items",
"description": "Specific actions to take next week.",
"metrics": []
}
]
}
]
}Audience values: executive · media_team · client · internal
Type values: performance_summary · pacing · budget_flight · audience_insights · creative_analysis · channel_mix · attribution_path · executive_summary · custom
Tip: The sections array is the most important part — it's the outline Claude follows when writing a report. Make section descriptions as specific as possible.
assets.json
Documents your creative asset library and per-platform specs. Claude uses this to answer asset questions, check spec compliance, and guide campaign trafficking.
{
"asset_library": {
"dam_system": "Bynder",
"dam_url": "https://yourcompany.bynder.com",
"access_instructions": "Request access via IT helpdesk. Login with SSO.",
"brand_guidelines_url": "https://yourcompany.bynder.com/brand-guidelines",
"copy_guidelines_url": "https://yourcompany.bynder.com/copy-guidelines",
"categories": [
{
"id": "cat_social_video",
"name": "Social Video",
"type": "video",
"location_url": "https://yourcompany.bynder.com/collections/social-video",
"naming_convention": "{brand}_{campaign}_{duration}s_{platform}_{version}",
"specs": [
{
"platform": "meta",
"format": "MP4 or MOV",
"dimensions": "1080x1080, 1080x1920, 1920x1080",
"max_file_size": "4GB",
"duration_max": "60s (Reels), 15s (Stories)",
"notes": "Include captions — 85% watch without sound"
}
]
}
]
}
}Asset type values: image · video · copy · audio · html5 · document · other
Tip: The specs array per category is especially valuable — Claude can answer "what do I need to traffic this campaign on TikTok?" directly from this data.
testing.json
Documents your entire test-and-learn program: methodology, tools, and every test (active, planned, completed). This gives Claude a searchable institutional memory of what your team has tested and learned.
{
"testing_program": {
"methodology": {
"confidence_threshold": 95,
"require_stat_sig": true,
"minimum_sample_size": 1000,
"minimum_test_duration_days": 14,
"minimum_detectable_effect_pct": 10,
"winner_criteria": "≥10% lift at 95% confidence, minimum 14 days runtime. If stat sig not achieved, test is inconclusive — retain prior best practice."
},
"tools": [
{
"id": "tool_meta_ab",
"name": "Meta A/B Testing (native)",
"type": "platform_native",
"platform": "meta",
"used_for": ["Creative A/B tests", "Audience split tests"]
}
],
"tests": [
{
"id": "test_001",
"name": "UGC vs Brand Creative",
"hypothesis": "UGC content will drive lower CPA on Meta prospecting due to higher thumb-stop rate.",
"status": "completed",
"type": "creative",
"platform": "meta",
"variants": [
{ "id": "v_control", "name": "Brand Creative", "description": "Polished brand video", "is_control": true },
{ "id": "v_ugc", "name": "UGC Video", "description": "Creator-style mobile video", "is_control": false }
],
"results": {
"winner_variant_id": "v_ugc",
"stat_sig_achieved": true,
"confidence_level": 97,
"primary_metric": "CPA",
"primary_metric_lift_pct": -23,
"conclusion": "UGC drove 23% lower CPA.",
"action_taken": "Scaled UGC — producing 2 new variants monthly."
}
}
]
}
}Field | Required | Notes |
| Yes | 90 or 95 are most common |
| Yes | Plain-English rule — Claude quotes this when analyzing tests |
| Yes | Claude uses this to evaluate whether the test was well-designed |
| No | Negative = improvement for cost metrics (CPA, CPC) |
Test type values: creative · audience · bidding · landing_page · copy · format · offer · other
Test status values: planned · active · completed · paused · abandoned
Tip: Historical tests are the most valuable part — the more completed tests you document, the better Claude can summarize learnings and recommend next experiments.
audiences.json
Documents your full audience infrastructure: first-party segments, contracted data providers, data onboarding platforms, lookalike strategy, and third-party overlay layers.
{
"audience_library": {
"business_unit": "Consumer",
"first_party_audiences": [
{
"id": "aud_purchasers_180d",
"name": "Past Purchasers — 180 Days",
"type": "pixel_based",
"description": "All purchasers in the last 180 days.",
"size_estimate": 45000,
"platforms_available": ["meta", "google_ads"],
"refresh_cadence": "daily",
"tags": ["purchasers", "lookalike-seed"]
}
],
"data_providers": [
{
"id": "dp_oracle",
"name": "Oracle Data Cloud",
"contract_status": "active",
"segments_available": ["In-Market: Home & Garden"],
"platforms_available": ["dv360", "google_ads"],
"contract_end_date": "2026-12-31"
}
],
"onboarding_platforms": [
{
"id": "ob_liveramp",
"name": "LiveRamp",
"type": "data_onboarding",
"platforms_connected": ["meta", "google_ads", "dv360"],
"use_cases": ["CRM list onboarding", "Identity resolution"]
}
],
"lookalike_strategy": {
"default_expansion_pct": 1,
"entries": [
{
"seed_audience_id": "aud_purchasers_180d",
"seed_audience_name": "Past Purchasers — 180 Days",
"platform": "meta",
"expansion_percentages": [1, 2, 5],
"best_performing_expansion": 1
}
]
},
"third_party_layers": [
{
"id": "3p_in_market",
"name": "In-Market: Your Category",
"provider": "Google",
"category": "in-market",
"platforms_available": ["google_ads", "dv360"],
"is_default": true,
"is_best_performer": true,
"cpm_premium_estimate": 0.50
}
]
}
}First-party audience types: crm_list · pixel_based · customer_match · email_list · app_users · lookalike_seed · suppression · other
Onboarding platform types: clean_room · data_onboarding · identity_resolution · cdp
Tip: Set is_default: true on audience layers you apply to every campaign, and is_best_performer: true on layers with proven efficiency gains — Claude uses both flags to make targeting recommendations.
measurement.json
Documents your full tracking and measurement infrastructure: tag management, pixels, Conversion APIs, CM360/Floodlight setup, website data layer, and measurement partners.
{
"measurement_setup": {
"tag_management": {
"system": "google_tag_manager",
"container_id": "GTM-XXXXXXX",
"implementation_type": "hybrid",
"server_side_endpoint": "https://sst.yourcompany.com"
},
"pixels_and_tags": [
{
"id": "pixel_meta",
"name": "Meta Pixel",
"platform": "meta",
"pixel_id": "XXXXXXXXXXXXXXXX",
"implementation": "both",
"events_tracked": ["PageView", "AddToCart", "Purchase"],
"custom_parameters": ["value", "currency", "order_id"]
}
],
"conversion_apis": [
{
"id": "capi_meta",
"platform": "meta",
"api_name": "Meta Conversions API (CAPI)",
"implementation": "both",
"events_sent": ["Purchase", "Lead"],
"match_rate_estimate_pct": 87,
"deduplication_method": "event_id matched client-side and server-side"
}
],
"cm360": {
"account_id": "XXXXXXX",
"floodlight_configuration_id": "FL-XXXXXXXX",
"u_variables": [
{ "variable": "u1", "name": "order_id", "type": "string", "description": "Unique order ID for deduplication" },
{ "variable": "u2", "name": "order_value", "type": "number", "description": "Order revenue in USD" }
]
},
"website_data_capture": {
"data_layer_implemented": true,
"data_layer_spec_url": "https://docs.yourcompany.com/datalayer",
"data_layer_variables": ["pageType", "transactionId", "transactionRevenue", "userId"],
"analytics_platform": "Google Analytics 4",
"analytics_property_id": "G-XXXXXXXXXX",
"first_party_cookies_implemented": true,
"cookie_domain": ".yourcompany.com",
"cookie_session_duration": "13 months",
"cookie_data_captured": ["_ga", "_gcl_aw (GCLID)", "_fbc (Meta click ID)"]
},
"measurement_partners": [
{
"id": "mp_mmm",
"name": "Your MMM Provider",
"type": "mmm",
"status": "active",
"platforms_covered": ["google_ads", "meta", "dv360"],
"cadence": "quarterly"
}
]
}
}Tag management system values: google_tag_manager · tealium · adobe_launch · segment · mparticle · manual · other
Implementation type values: client_side · server_side · hybrid
Measurement partner types: mmm · incrementality · brand_lift · attribution · analytics · identity · other
Tip: The cm360.u_variables section is especially useful — Claude can explain what each u-variable captures and help troubleshoot Floodlight discrepancies when you reference specific variable names.
What Claude can do
Tools
Tools are actions Claude takes to retrieve your data.
Campaign tools
Tool | What it does |
| Filter campaigns by team, platform, status, objective, funnel stage, or tag |
| Full details for one campaign by ID |
| All accounts, optionally filtered by team |
| Full account details by ID |
Team tools
Tool | What it does |
| All teams with objectives, KPIs, platforms |
| Team details + its members + its accounts |
| Which team owns a given account |
| Members, optionally filtered by team |
| Full member details |
Performance tools
Tool | What it does |
| Per-day records + aggregated totals for a campaign |
| Aggregated totals by team, broken down per campaign |
| Industry benchmarks by platform and objective |
Attribution tools
Tool | What it does |
| All configured attribution setups |
| Full details for one model |
| Side-by-side diff of two models |
Reporting tools
Tool | What it does |
| Templates filtered by audience |
| Full template with all sections |
| Assembles raw data + template for Claude to narrate |
Asset tools
Tool | What it does |
| DAM system info, access instructions, guidelines links, category summary |
| All asset categories, optionally filtered by type (image, video, copy, etc.) |
| Full details for one category: location, naming convention, specs |
| Platform-specific specs (dimensions, file size, format) for a given asset type and platform |
Testing tools
Tool | What it does |
| Confidence threshold, stat sig rules, winner criteria, and testing tools in use |
| All tests filtered by status, type, team, or platform |
| Full details for one test: hypothesis, all variants, results |
| Summarized learnings from all completed tests |
Audience tools
Tool | What it does |
| High-level summary: 1P count, data providers, onboarding platforms, LAL strategy |
| All 1P segments filtered by business unit or platform |
| Contracted data providers filtered by contract status |
| Full LAL strategy: seed audiences, expansion sizes, best performers |
| Overlay segments filtered by platform, default use, or best-performer flag |
| Data onboarding and clean room platforms in use |
Measurement tools
Tool | What it does |
| High-level tracking stack: TMS, pixel count, CAPI count, measurement partners |
| TMS details: platform, container ID, implementation type, server-side endpoint |
| All platform pixels filtered by platform: events tracked, implementation |
| All Conversion API implementations: events, match rate, deduplication method |
| CM360 account, Floodlight config ID, and all u-variables with descriptions |
| Data layer status/variables, analytics platform, first-party cookie setup |
| MMM, incrementality, brand lift, attribution partners filtered by type |
Resources
Resources are documents Claude can read as context (similar to attaching a file).
Resource URI | What it contains |
| Company metadata + all teams + all accounts |
| All campaigns |
| Teams enriched with their members |
| All attribution configurations |
| All reporting templates |
| Full asset library: DAM info, categories, and specs |
| Full testing program: methodology, tools, and all tests |
| Full audience library: 1P, providers, LAL strategy, 3P layers |
| Full tracking stack: TMS, pixels, APIs, CM360, data capture |
Prompts
Pre-built prompt templates that guide Claude through multi-step analysis tasks. Access them from Claude's prompt picker (the / command in supported clients).
Prompt | Arguments | What it does |
|
| Full performance review with pacing and benchmark comparison |
|
| Weekly scorecard using your team's reporting template |
|
| Explains model options and recommends the right one for the campaign objective |
|
| Flags over/under-pacing campaigns with specific actions |
|
| Channel efficiency ranking and reallocation recommendations |
|
| Summarizes test history, active tests, gaps, and recommends next experiments |
|
| Full audience strategy audit: 1P usage, LAL quality, 3P layer gaps, recommendations |
| (none) | End-to-end tracking audit: signal gaps, deduplication risks, attribution reliability |
|
| Checks whether required assets exist for a campaign's platform and generates a trafficking checklist |
Example conversations
Once connected, you can ask Claude things like:
Campaign lookup
"What active Meta campaigns does the performance team have running right now?"
"Show me all upper-funnel campaigns tagged q2-2026."
Performance analysis
"How did the search always-on campaign perform last week? Compare it to our benchmarks."
"Which of our campaigns had the best ROAS in May?"
Pacing
"Is our Q2 Meta prospecting campaign on pace to deliver its budget?"
"Check pacing across all active campaigns as of today."
Team and ownership
"Who manages the LinkedIn account and what are their KPIs?"
"I need to talk to someone about our Meta creative strategy — who should I contact?"
Attribution
"We're seeing a big discrepancy between Meta reported conversions and GA4. Can you explain why that might be based on our attribution setup?"
"Should we use last-click or data-driven attribution for our Google Shopping campaigns?"
Reporting
"Write a weekly performance report for the performance team for the week of May 26."
"Generate an executive summary of our Q2 paid media results."
Assets
"What video specs do I need for TikTok? What about YouTube?"
"Where do I find the Q2 brand campaign assets and what's the naming convention?"
"Are we ready to launch the Meta prospecting campaign? Do we have all the required creative sizes?"
Testing
"What have we learned from our Meta creative tests this year?"
"We want to test bid strategies on Google Ads — has anyone tested tROAS vs tCPA before? What happened?"
"What should we test next on LinkedIn? We haven't run any tests there in 6 months."
"Is the TikTok creator test statistically significant yet?"
Audiences
"What first-party audiences do we have available on Meta right now?"
"Explain our lookalike strategy — what seed audiences are we using and what expansion size performs best?"
"We have an Experian contract — are we using all the segments we're paying for?"
"What third-party audience layers should we apply to a new DV360 campaign targeting homeowners?"
Measurement
"Do we have server-side tracking on Meta? What's our Conversions API match rate?"
"What are our CM360 u-variables and what does u3 capture?"
"We're seeing a discrepancy between Meta CAPI and GA4 purchase counts — why might that happen based on our setup?"
"Is our data layer capturing order value correctly for all conversion events?"
"What measurement partners do we use and when is our next MMM run?"
Connecting to live APIs
The default FileAdapter reads from local JSON files. To connect to a live platform API:
Step 1 — Create a new adapter file, e.g. src/adapters/google-ads-adapter.ts
Step 2 — Implement the PaidMediaAdapter interface:
import type { PaidMediaAdapter } from "./base.js";
// ... import Google Ads API client
export class GoogleAdsAdapter implements PaidMediaAdapter {
constructor(private customerId: string) {}
async getCampaigns(filters = {}) {
// call Google Ads API
}
// implement all other methods...
}Step 3 — Swap it in src/index.ts:
// Before:
const adapter = new FileAdapter(DATA_DIR);
// After:
const adapter = new GoogleAdsAdapter({
customerId: process.env.GOOGLE_ADS_CUSTOMER_ID!,
developerToken: process.env.GOOGLE_ADS_DEVELOPER_TOKEN!,
});All tools, resources, and prompts work unchanged — they only call the adapter interface.
Hybrid approach: You can also create a HybridAdapter that pulls campaigns from the API but falls back to file data for teams, attribution, and reporting templates (which rarely change and aren't in platform APIs).
Troubleshooting
Claude Desktop doesn't show the paid-media tools
Check the config path:
~/Library/Application Support/Claude/claude_desktop_config.json(Mac) or%APPDATA%\Claude\claude_desktop_config.json(Windows)Make sure paths in the config are absolute, not relative
Check that
npm run buildran without errors (dist/index.jsmust exist)Fully quit and reopen Claude Desktop (Cmd+Q on Mac, not just closing the window)
Check Claude Desktop's MCP logs: Settings → Developer → Logs
Server starts but returns no data
The server logs warnings (to stderr) for each data file it can't load. Run the server directly to see them:
node dist/index.jsYou'll see lines like:
[FileAdapter] Warning: Data file not found: /path/to/data/campaigns.jsonData changes aren't reflected
The server loads data files at startup. After editing any file in data/, restart the MCP server:
In Claude Desktop: Settings → Developer → restart the paid-media server
Or fully restart Claude Desktop
JSON syntax errors
If a data file has a syntax error, the server silently skips it. Validate your JSON at jsonlint.com or run:
node -e "JSON.parse(require('fs').readFileSync('data/campaigns.json', 'utf8'))"Performance data not aggregating correctly
Rate metrics (CTR, CPC, ROAS) are re-computed from raw totals during aggregation. If you include both raw counts and pre-calculated rates in your records, the server will sum both, which will double-count rates. Best practice: include only raw count metrics in records (impressions, clicks, spend, conversions, conversion_value) and let the server compute rates.
Project structure
paidmedia-mcp/
├── src/
│ ├── index.ts # MCP server entry point
│ ├── types.ts # TypeScript interfaces for all data models
│ ├── adapters/
│ │ ├── base.ts # PaidMediaAdapter interface — implement to connect live APIs
│ │ └── file-adapter.ts # Default: reads from data/*.json at startup
│ ├── tools/
│ │ ├── campaigns.ts # list_campaigns, get_campaign, list_accounts, get_account
│ │ ├── teams.ts # list_teams, get_team, get_team_for_account, list_team_members, get_team_member
│ │ ├── performance.ts # get_campaign_performance, get_team_performance, get_benchmarks
│ │ ├── attribution.ts # list_attribution_models, get_attribution_model, compare_attribution_models
│ │ ├── reporting.ts # list_reporting_templates, get_reporting_template, build_performance_report
│ │ ├── assets.ts # get_asset_library, list_asset_categories, get_asset_category, get_asset_specs
│ │ ├── testing.ts # get_testing_methodology, list_tests, get_test, get_test_learnings
│ │ ├── audiences.ts # get_audience_library_overview, list_first_party_audiences, list_data_providers,
│ │ │ # get_lookalike_strategy, list_third_party_audience_layers, get_onboarding_platforms
│ │ └── measurement.ts # get_measurement_overview, get_tag_management, list_pixels_and_tags,
│ │ # list_conversion_apis, get_cm360_setup, get_website_data_capture, list_measurement_partners
│ ├── resources/
│ │ └── index.ts # 9 readable MCP resources
│ └── prompts/
│ └── index.ts # 9 pre-built prompt templates
├── data/
│ ├── metadata.json # Company info
│ ├── accounts.json # Ad accounts by platform
│ ├── teams.json # Media teams, objectives, KPIs
│ ├── team-members.json # Team members, roles, responsibilities
│ ├── campaigns.json # All campaigns
│ ├── historical-performance.json # Daily metrics + benchmarks
│ ├── attribution-models.json # Attribution configurations
│ ├── reporting-templates.json # Report structures by audience
│ ├── assets.json # DAM info, asset categories, per-platform specs
│ ├── testing.json # Testing methodology, tools, and test history
│ ├── audiences.json # 1P audiences, data providers, LAL strategy, 3P layers
│ └── measurement.json # TMS, pixels, Conversion APIs, CM360, data layer, partners
├── claude_desktop_config.example.json # Config snippet for Claude Desktop
├── package.json
├── tsconfig.json
└── README.mdContributing
Issues and pull requests welcome. If you build an adapter for a specific platform (Google Ads API, Meta Marketing API, etc.), consider contributing it back.
License
MIT
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/arcticgreyy/paidmedia-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server