meta-ads-mcp 0.7.2__tar.gz → 0.7.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/PKG-INFO +1 -1
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/__init__.py +1 -1
- meta_ads_mcp-0.7.3/meta_ads_mcp/core/ads_library.py +74 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/pyproject.toml +1 -1
- meta_ads_mcp-0.7.2/meta_ads_mcp/core/ads_library.py +0 -69
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/.github/workflows/publish.yml +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/.github/workflows/test.yml +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/.gitignore +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/CUSTOM_META_APP.md +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/Dockerfile +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/LICENSE +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/LOCAL_INSTALLATION.md +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/META_API_NOTES.md +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/README.md +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/RELEASE.md +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/STREAMABLE_HTTP_SETUP.md +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/examples/README.md +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/examples/example_http_client.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/future_improvements.md +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/images/meta-ads-example.png +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_auth.sh +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/__main__.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/__init__.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/accounts.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/ads.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/adsets.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/api.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/auth.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/authentication.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/budget_schedules.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/callback_server.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/campaigns.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/duplication.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/http_auth_integration.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/insights.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/openai_deep_research.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/pipeboard_auth.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/reports.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/resources.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/server.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/targeting.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/meta_ads_mcp/core/utils.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/requirements.txt +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/setup.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/smithery.yaml +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/README.md +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/README_REGRESSION_TESTS.md +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/__init__.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/conftest.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_account_search.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_duplication.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_duplication_regression.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_get_ad_creatives_fix.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_get_ad_image_regression.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_http_transport.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_integration_openai_mcp.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_openai.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_openai_mcp_deep_research.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_targeting.py +0 -0
- {meta_ads_mcp-0.7.2 → meta_ads_mcp-0.7.3}/tests/test_targeting_search_e2e.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meta-ads-mcp
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
4
4
|
Summary: Model Context Protocol (MCP) plugin for interacting with Meta Ads API
|
|
5
5
|
Project-URL: Homepage, https://github.com/pipeboard-co/meta-ads-mcp
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/pipeboard-co/meta-ads-mcp/issues
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Adds Library-related functionality for Meta Ads API."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from typing import Optional, List, Dict, Any
|
|
6
|
+
from .api import meta_api_tool, make_api_request
|
|
7
|
+
from .server import mcp_server
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Only register the search_ads_archive function if the environment variable is NOT set
|
|
11
|
+
DISABLE_ADS_LIBRARY = bool(os.environ.get("META_ADS_DISABLE_ADS_LIBRARY", ""))
|
|
12
|
+
|
|
13
|
+
if not DISABLE_ADS_LIBRARY:
|
|
14
|
+
@mcp_server.tool()
|
|
15
|
+
@meta_api_tool
|
|
16
|
+
async def search_ads_archive(
|
|
17
|
+
access_token: str = None,
|
|
18
|
+
search_terms: str = None,
|
|
19
|
+
ad_type: str = "ALL",
|
|
20
|
+
ad_reached_countries: List[str] = None,
|
|
21
|
+
limit: int = 25, # Default limit, adjust as needed
|
|
22
|
+
fields: str = "ad_creation_time,ad_creative_body,ad_creative_link_caption,ad_creative_link_description,ad_creative_link_title,ad_delivery_start_time,ad_delivery_stop_time,ad_snapshot_url,currency,demographic_distribution,funding_entity,impressions,page_id,page_name,publisher_platform,region_distribution,spend"
|
|
23
|
+
) -> str:
|
|
24
|
+
"""
|
|
25
|
+
Search the Facebook Ads Library archive.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
access_token: Meta API access token (optional - will use cached token if not provided).
|
|
29
|
+
search_terms: The search query for ads.
|
|
30
|
+
ad_type: Type of ads to search for (e.g., POLITICAL_AND_ISSUE_ADS, HOUSING_ADS, ALL).
|
|
31
|
+
ad_reached_countries: List of country codes (e.g., ["US", "GB"]).
|
|
32
|
+
limit: Maximum number of ads to return.
|
|
33
|
+
fields: Comma-separated string of fields to retrieve for each ad.
|
|
34
|
+
|
|
35
|
+
Example Usage via curl equivalent:
|
|
36
|
+
curl -G \\
|
|
37
|
+
-d "search_terms='california'" \\
|
|
38
|
+
-d "ad_type=POLITICAL_AND_ISSUE_ADS" \\
|
|
39
|
+
-d "ad_reached_countries=['US']" \\
|
|
40
|
+
-d "fields=ad_snapshot_url,spend" \\
|
|
41
|
+
-d "access_token=<ACCESS_TOKEN>" \\
|
|
42
|
+
"https://graph.facebook.com/<API_VERSION>/ads_archive"
|
|
43
|
+
"""
|
|
44
|
+
if not access_token:
|
|
45
|
+
# Attempt to get token implicitly if not provided - meta_api_tool handles this
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
if not search_terms:
|
|
49
|
+
return json.dumps({"error": "search_terms parameter is required"}, indent=2)
|
|
50
|
+
|
|
51
|
+
if not ad_reached_countries:
|
|
52
|
+
return json.dumps({"error": "ad_reached_countries parameter is required"}, indent=2)
|
|
53
|
+
|
|
54
|
+
endpoint = "ads_archive"
|
|
55
|
+
params = {
|
|
56
|
+
"search_terms": search_terms,
|
|
57
|
+
"ad_type": ad_type,
|
|
58
|
+
"ad_reached_countries": json.dumps(ad_reached_countries), # API expects a JSON array string
|
|
59
|
+
"limit": limit,
|
|
60
|
+
"fields": fields,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
data = await make_api_request(endpoint, access_token, params, method="GET")
|
|
65
|
+
return json.dumps(data, indent=2)
|
|
66
|
+
except Exception as e:
|
|
67
|
+
error_msg = str(e)
|
|
68
|
+
# Consider logging the full error for debugging
|
|
69
|
+
# print(f"Error calling Ads Library API: {error_msg}")
|
|
70
|
+
return json.dumps({
|
|
71
|
+
"error": "Failed to search ads archive",
|
|
72
|
+
"details": error_msg,
|
|
73
|
+
"params_sent": {k: v for k, v in params.items() if k != 'access_token'} # Avoid logging token
|
|
74
|
+
}, indent=2)
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
"""Adds Library-related functionality for Meta Ads API."""
|
|
2
|
-
|
|
3
|
-
import json
|
|
4
|
-
from typing import Optional, List, Dict, Any
|
|
5
|
-
from .api import meta_api_tool, make_api_request
|
|
6
|
-
from .server import mcp_server
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@mcp_server.tool()
|
|
10
|
-
@meta_api_tool
|
|
11
|
-
async def search_ads_archive(
|
|
12
|
-
access_token: str = None,
|
|
13
|
-
search_terms: str = None,
|
|
14
|
-
ad_type: str = "ALL",
|
|
15
|
-
ad_reached_countries: List[str] = None,
|
|
16
|
-
limit: int = 25, # Default limit, adjust as needed
|
|
17
|
-
fields: str = "ad_creation_time,ad_creative_body,ad_creative_link_caption,ad_creative_link_description,ad_creative_link_title,ad_delivery_start_time,ad_delivery_stop_time,ad_snapshot_url,currency,demographic_distribution,funding_entity,impressions,page_id,page_name,publisher_platform,region_distribution,spend"
|
|
18
|
-
) -> str:
|
|
19
|
-
"""
|
|
20
|
-
Search the Facebook Ads Library archive.
|
|
21
|
-
|
|
22
|
-
Args:
|
|
23
|
-
access_token: Meta API access token (optional - will use cached token if not provided).
|
|
24
|
-
search_terms: The search query for ads.
|
|
25
|
-
ad_type: Type of ads to search for (e.g., POLITICAL_AND_ISSUE_ADS, HOUSING_ADS, ALL).
|
|
26
|
-
ad_reached_countries: List of country codes (e.g., ["US", "GB"]).
|
|
27
|
-
limit: Maximum number of ads to return.
|
|
28
|
-
fields: Comma-separated string of fields to retrieve for each ad.
|
|
29
|
-
|
|
30
|
-
Example Usage via curl equivalent:
|
|
31
|
-
curl -G \\
|
|
32
|
-
-d "search_terms='california'" \\
|
|
33
|
-
-d "ad_type=POLITICAL_AND_ISSUE_ADS" \\
|
|
34
|
-
-d "ad_reached_countries=['US']" \\
|
|
35
|
-
-d "fields=ad_snapshot_url,spend" \\
|
|
36
|
-
-d "access_token=<ACCESS_TOKEN>" \\
|
|
37
|
-
"https://graph.facebook.com/<API_VERSION>/ads_archive"
|
|
38
|
-
"""
|
|
39
|
-
if not access_token:
|
|
40
|
-
# Attempt to get token implicitly if not provided - meta_api_tool handles this
|
|
41
|
-
pass
|
|
42
|
-
|
|
43
|
-
if not search_terms:
|
|
44
|
-
return json.dumps({"error": "search_terms parameter is required"}, indent=2)
|
|
45
|
-
|
|
46
|
-
if not ad_reached_countries:
|
|
47
|
-
return json.dumps({"error": "ad_reached_countries parameter is required"}, indent=2)
|
|
48
|
-
|
|
49
|
-
endpoint = "ads_archive"
|
|
50
|
-
params = {
|
|
51
|
-
"search_terms": search_terms,
|
|
52
|
-
"ad_type": ad_type,
|
|
53
|
-
"ad_reached_countries": json.dumps(ad_reached_countries), # API expects a JSON array string
|
|
54
|
-
"limit": limit,
|
|
55
|
-
"fields": fields,
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
try:
|
|
59
|
-
data = await make_api_request(endpoint, access_token, params, method="GET")
|
|
60
|
-
return json.dumps(data, indent=2)
|
|
61
|
-
except Exception as e:
|
|
62
|
-
error_msg = str(e)
|
|
63
|
-
# Consider logging the full error for debugging
|
|
64
|
-
# print(f"Error calling Ads Library API: {error_msg}")
|
|
65
|
-
return json.dumps({
|
|
66
|
-
"error": "Failed to search ads archive",
|
|
67
|
-
"details": error_msg,
|
|
68
|
-
"params_sent": {k: v for k, v in params.items() if k != 'access_token'} # Avoid logging token
|
|
69
|
-
}, indent=2)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|