ads-mcp-server
ads-mcp-server
Google Ads + Meta Marketing 성과 데이터, 캠페인 설정, 변경 이력을 Claude(Cowork)에 노출하여 실시간 일일 대시보드 워크플로우를 지원하는 로컬 MCP 서버입니다.
기능
MCP에 등록된 세 가지 도구:
도구 | 목적 |
| 성과 + 진단 + 56일 시계열 + WoW + 8주 DoW 비교 + 캠페인 설정 + 변경 이력 |
| Google과 동일한 형태. 전환은 |
|
|
아키텍처: 플랫폼당 시간당 한 번씩 광고×일 단위 원시 데이터를 가져와 parquet으로 캐싱하고, pandas에서 모든 집계를 도출합니다. 분석 단위별로 API를 호출하지 않습니다.
Related MCP server: mcp-marketing-analytics
사전 요구 사항
macOS / Linux
Python 3.13 (pyenv 권장)
uv패키지 관리자:brew install uvGoogle Ads API 액세스 — Google Ads API 시작하기 참조
Meta Marketing API 액세스 — Marketing API 시작하기 참조
자격 증명 설정 링크
자격 증명 | 획득 방법 |
| Google Ads UI → 도구 → API 센터 |
| https://console.cloud.google.com → OAuth 2.0 클라이언트 (데스크톱 앱) |
|
|
| 쉼표로 구분, 대시(-) 제외. Google Ads UI 우측 상단에서 확인 |
| MCC 관리자 계정 ID, 대시(-) 제외 |
| https://developers.facebook.com → 내 앱 → 설정 → 기본 |
| https://business.facebook.com → 비즈니스 설정 → 시스템 사용자 → 새 토큰 생성 ( |
| Meta 광고 관리자 → 좌측 상단 계정 선택기. 형식: |
설치
cd ~/marketing-ds/ads-mcp-server
uv sync --extra devuv는 .venv/를 생성하고 pyproject.toml에 고정된 모든 종속성을 설치합니다.
자격 증명 구성
두 가지 옵션:
옵션 A — 기존 .env 지정 (~/marketing-ds/decision_science/.env에 이미 키가 있는 경우 권장):
export ADS_MCP_ENV_FILE=/Users/jmacaggi/marketing-ds/decision_science/.env옵션 B — 로컬 .env 사용:
cp .env.example .env
# fill in the blanks필수 키는 각 설명이 포함된 .env.example에 나열되어 있습니다.
실행
로컬 테스트:
uv run ads-mcp-server서버는 stdio를 통해 MCP와 통신하며, Cowork(또는 모든 MCP 클라이언트)가 필요할 때 실행합니다.
Claude(Cowork)에 연결
~/.claude/claude_desktop_config.json에 다음 블록을 추가합니다(파일이 없으면 생성):
{
"mcpServers": {
"ads": {
"command": "uv",
"args": [
"--directory",
"/Users/jmacaggi/marketing-ds/ads-mcp-server",
"run",
"ads-mcp-server"
],
"env": {
"ADS_MCP_ENV_FILE": "/Users/jmacaggi/marketing-ds/decision_science/.env"
}
}
}
}Claude/Cowork를 재시작합니다. get_google_ads_report, get_meta_ads_report, get_campaign_settings 도구가 나타나야 합니다.
백그라운드 데몬은 필요하지 않으며, Cowork가 세션마다 프로세스를 시작/종료합니다.
일일 사전 로드(라이브 대시보드 권장)
캐시 유효성 규칙: 어제 날짜가 포함되어 있으면 캐시가 최신 상태로 간주됩니다. 하루에 한 번 새로 고침됩니다. 당일 첫 번째 사용자 쿼리가 새로 고침을 트리거하며, 대규모 계정의 경우 56일치 데이터를 가져오는 데 1~3분이 소요될 수 있습니다.
대기 시간을 피하려면 macOS launchd를 통해 오전 6시에 사전 로드를 예약하세요:
# Install
cp /Users/jmacaggi/marketing-ds/ads-mcp-server/launchd/com.jmacaggi.adsmcp.prewarm.plist \
~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist
# Verify it's scheduled
launchctl list | grep adsmcp
# Trigger immediately (test)
launchctl start com.jmacaggi.adsmcp.prewarm
# Logs
tail -f ~/marketing-ds/ads-mcp-server/logs/prewarm.stdout.log
tail -f ~/marketing-ds/ads-mcp-server/logs/$(date +%Y-%m-%d).log매일 오전 6시에 수행되는 작업:
Google Ads 성과 56일치, 설정, 변경 이벤트 29일치 가져오기 → 캐시
(Meta는 현재 비활성화됨 — 아래 "Meta 상태" 참조)
새로 고침 타임스탬프
cache/google_lastrefresh.txt= 오늘 날짜로 작성
Cowork를 열 때 Google 데이터가 준비되어 있어 도구 호출이 1초 이내에 반환됩니다.
제거 방법:
launchctl unload ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist
rm ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plistMeta 상태 (2026-05-07 기준)
Meta 도구(get_meta_ads_report, get_campaign_settings(platform="meta"|"both"))는 구조적으로는 완성되었으나 엔드투엔드 검증은 완료되지 않았습니다.
작동하는 기능:
성과 가져오기는 7일 단위로 청크 처리됨 (
Service temporarily unavailable / subcode 1504044"결과가 너무 큼" 오류 방지)광고 수준 데이터 분리: 56일 시계열은
level=campaign, 어제 데이터만 필요한 경우level=ad사용 (5분 페이징 방지)광고 세트 가져오기는
effective_status IN [ACTIVE, PAUSED]로 필터링됨 (수천 개의 보관된 광고 세트 페이징 방지)
차단된 문제:
첫 번째 대규모 성과 청크 가져오기 후, 광고 세트 가져오기가 Meta의 시간당 속도 제한(
code 17, subcode 2446079: "사용자 요청 제한 도달")에 걸림. 쿨다운은 일반적으로 10~60분입니다.
내일 아침(할당량 초기화 후) 재테스트 방법:
# Remove --skip-meta from the launchd plist to enable Meta in pre-warm
sed -i '' '/<string>--skip-meta<\/string>/d' \
~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist
launchctl unload ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist
launchctl load ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist
# Or run manually
ADS_MCP_ENV_FILE=/Users/jmacaggi/marketing-ds/decision_science/.env \
uv run python scripts/prewarm.pyMeta 속도 제한이 계속될 경우의 대체 옵션(아직 구현되지 않음):
성과 가져오기를 위한 비동기 보고서 실행 (
async=True)더 엄격한
effective_status필터 (ACTIVE만 사용, 일시 중지된 항목 제외)
장기 실행 백그라운드 프로세스를 선호하는 경우(선택 사항, Cowork에는 필요 없음): nohup uv run ads-mcp-server > /tmp/ads-mcp.log 2>&1 & 또는 launchd plist를 사용하세요.
선택 사항: CSV 재정의 (API 건너뛰기)
Google Ads UI는 API 할당량 제한 없이 CSV 보고서를 내보냅니다. cache/external/에 CSV를 넣으면 API 가져오기를 재정의합니다:
cache/external/google_2026-05-07.csv
cache/external/meta_2026-05-07.csv일치하는 CSV가 존재하고 parquet 캐시보다 최신인 경우, 서버는 API를 호출하는 대신 CSV를 로드합니다. 응답은 metadata.data_source = "csv_override"로 설정되어 Cowork가 이를 인식합니다.
CSV 열 스키마는 parquet과 일치해야 합니다(src/ads_mcp_server/google_ads.py 및 meta_ads.py에서 열 이름 확인: date, campaign_id, campaign_name, ad_id, ad_name, spend, impressions, clicks, conversions, ...).
테스트
uv run pytest -v모든 테스트는 모의(mock) 기반이며 네트워크 호출이 없습니다. 다음을 포함합니다:
classify_campaign브랜드/비브랜드/기타 분류diagnose5단계 분류기8주 동일 요일 선택기가 올바른 8개 날짜를 선택하는지 확인
WoW 델타 + 0으로 나누기 처리
Meta용
actions[]필터null-old-value 및 가지치기를 포함한 스냅샷 차이
자격 증명 누락 시 깔끔한 오류 반환(예외 발생 없음)
로그
모든 API 호출 및 오류는 logs/YYYY-MM-DD.log에 기록됩니다(일별 파일).
문제 해결
google-ads설치 실패: Python 3.13(uv python pin 3.13)을 확인하고 시스템에서pip install grpcio가 작동하는지 확인하세요. Apple Silicon의 경우:arch -arm64 uv sync.Meta 토큰 만료: 비즈니스 설정에서 시스템 사용자 토큰을 다시 생성하세요. 장기 유지 토큰은 60일간 지속됩니다.
Cowork에 도구가 나타나지 않음:
~/Library/Logs/Claude/mcp*.log에서 생성 오류를 확인하세요. GUI 프로세스에uv가PATH에 있는지 확인하세요(전체 경로가 필요할 수 있음:which uv).캐시 오래됨:
cache/*.parquet를 삭제하여 강제로 새로 가져오기를 수행하세요.
파일 맵
src/ads_mcp_server/
server.py # MCP entry + tool handlers
config.py # env loading, validates creds
google_ads.py # 3 GAQL queries: perf, settings, change_event
meta_ads.py # Insights + AdSet pull
snapshots.py # Meta snapshot diff (Meta has no reliable change API)
cache.py # parquet + CSV override
aggregate.py # all pandas math
classify.py # Brand/NB/Other
diagnose.py # 5-state diagnosis
date_ranges.py # window resolution + 8wk DoW
retry.py # exponential backoff
logging_setup.py # daily file logs
schema.py # response shape constantsAvailable Tools
3 toolsget_campaign_settingsC
Current campaign settings + 56-day change history per platform.
| Name | Required | Description | Default |
|---|---|---|---|
| platform | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully convey behavioral traits. It discloses that the tool returns both settings and a 56-day history, but does not indicate whether it is read-only, any authentication needs, rate limits, or what triggers destructive actions. The behavior is partially described but lacks completeness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, making it very concise, but it omits important details such as parameter semantics and usage context. Conciseness is achieved at the expense of completeness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter, no output schema, no annotations), the description is insufficient. It does not explain the output structure, whether the data is aggregated per platform, or provide examples. The lack of detail makes it hard for an AI agent to fully understand the tool's capabilities.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has one parameter 'platform' with enum values, but the description does not explain the parameter's meaning beyond 'per platform'. It fails to clarify what 'both' implies or how the parameter affects the output. With 0% schema description coverage, the description adds no value over the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves 'current campaign settings + 56-day change history per platform', which is a specific verb+resource. However, it does not explicitly differentiate itself from sibling tools like get_google_ads_report or get_meta_ads_report, which are focused on ads reports rather than settings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives such as get_google_ads_report or get_meta_ads_report. It does not mention exclusion criteria or context for usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_google_ads_reportA
Pull Google Ads performance. Returns account totals, campaign-type breakdown, top-50 per-ad rows with diagnosis, 56-day daily series, and WoW + 8-week DoW comparisons. Set include_campaign_settings=True to also return per-campaign settings (target CPA, daily budget, diagnosis, utilization) for ENABLED campaigns only.
| Name | Required | Description | Default |
|---|---|---|---|
| date_range | Yes | ||
| breakdown | Yes | ||
| include_campaign_settings | No | If true, attach campaign_settings list to the response. Defaults to false to keep payload small. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but the description details return components and the conditional behavior of include_campaign_settings (only for ENABLED campaigns).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, no fluff, front-loaded with purpose and outputs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Description covers essential behavioral and parameter details despite lack of output schema; minor gaps in rate limits or authentication info.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is low (33%), but the description adds meaning to parameters by linking them to return elements (e.g., 'campaign-type breakdown' for breakdown enum).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Pull Google Ads performance' and lists specific outputs, distinguishing it from siblings like get_meta_ads_report and get_campaign_settings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies its use for Google Ads performance but does not explicitly guide when to use this tool over siblings or provide exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_meta_ads_reportB
Pull Meta Ads performance. Same shape as get_google_ads_report. Conversions filtered to META_CONVERSION_EVENT_NAME.
| Name | Required | Description | Default |
|---|---|---|---|
| date_range | Yes | ||
| breakdown | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It only mentions the output shape similarity and a conversion filter, but lacks details on side effects, rate limits, authentication needs, or other behavioral traits. This is minimal disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise with two short sentences, each providing distinct value. It front-loads the key information and avoids fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description should explain the report contents. It mentions a conversion filter but does not list other metrics or describe the full structure. Relying on the shape of get_google_ads_report is insufficient without that tool's description being present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description should add meaning to parameters. It does not explain the 'date_range' or 'breakdown' parameters beyond their enum values, which are self-explanatory but not enriched. This is a significant gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The name and description clearly indicate this tool retrieves Meta Ads performance data. The verb 'Pull' is specific, and the description explicitly states it is analogous to get_google_ads_report, which distinguishes it from sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by comparing to get_google_ads_report, but does not provide explicit guidance on when to use this tool versus alternatives or any prerequisites. No exclusions or when-not-to-use information is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
get_campaign_settings - First observed
get_google_ads_report - First observed
get_meta_ads_report
TDQS
Scored across 3 tools
Each tool targets a distinct area: campaign settings, Google Ads performance, and Meta Ads performance. No overlap; descriptions clearly differentiate them.
All tool names follow a consistent 'get_' prefix with the specific resource (campaign_settings, google_ads_report, meta_ads_report). Consistent snake_case pattern.
Three tools is minimal but appropriate for a focused ads reporting and settings retrieval server. Could be expanded but current count is reasonable for the stated purpose.
Only read operations are exposed; no create, update, or delete tools for campaigns or ads. Significant gaps for a full ads management workflow.
Maintenance
Related MCP Connectors
Live Google Ads, GA4, Search Console, Meta Ads and GBP data in Claude, ChatGPT and any MCP client
- mcp-serverOAuthco.flyweel
Access Google & Meta Ads data via AI. Analyse campaign performance in seconds.
GA4, Google Ads and Search Console in Claude. Read-only OAuth, multi-account for agencies.
Run Google Ads and Meta Ads from ChatGPT or Claude: audit wasted spend, create and manage campaigns.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides access to Google Ads API for comprehensive campaign analytics, enabling conversational ad performance analysis with Claude Code.25 npm2MIT
- FlicenseAqualityDmaintenanceEnables natural language querying of Google Analytics 4, Google Search Console, Meta Ads, and Google Ads data through Claude.23-

OQVA Marketing MCPofficial
AlicenseAqualityBmaintenanceConnect Claude to your marketing data from Google and Meta, enabling read and write operations on Search Console, Analytics, Tag Manager, Business Profile, and Meta platforms.35Apache 2.0- AlicenseNot gradedqualityDmaintenanceEnables Claude to fetch and analyze Meta ad accounts, campaigns, ad sets, ads, and performance insights via the Meta Marketing API.1,621 npmMIT