meta-ads-mcp 0.10.0__py3-none-any.whl → 0.10.2__py3-none-any.whl
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/__init__.py +1 -1
- meta_ads_mcp/core/adsets.py +4 -3
- meta_ads_mcp/core/targeting.py +65 -21
- {meta_ads_mcp-0.10.0.dist-info → meta_ads_mcp-0.10.2.dist-info}/METADATA +14 -2
- {meta_ads_mcp-0.10.0.dist-info → meta_ads_mcp-0.10.2.dist-info}/RECORD +8 -8
- {meta_ads_mcp-0.10.0.dist-info → meta_ads_mcp-0.10.2.dist-info}/WHEEL +0 -0
- {meta_ads_mcp-0.10.0.dist-info → meta_ads_mcp-0.10.2.dist-info}/entry_points.txt +0 -0
- {meta_ads_mcp-0.10.0.dist-info → meta_ads_mcp-0.10.2.dist-info}/licenses/LICENSE +0 -0
meta_ads_mcp/__init__.py
CHANGED
meta_ads_mcp/core/adsets.py
CHANGED
|
@@ -130,8 +130,9 @@ async def create_adset(
|
|
|
130
130
|
promoted_object: Mobile app configuration for APP_INSTALLS campaigns. Required fields: application_id, object_store_url.
|
|
131
131
|
Optional fields: custom_event_type, pixel_id, page_id.
|
|
132
132
|
Example: {"application_id": "123456789012345", "object_store_url": "https://apps.apple.com/app/id123456789"}
|
|
133
|
-
destination_type: Where users are directed after clicking the ad (e.g., 'APP_STORE', 'DEEPLINK', 'APP_INSTALL').
|
|
134
|
-
Required for mobile app campaigns.
|
|
133
|
+
destination_type: Where users are directed after clicking the ad (e.g., 'APP_STORE', 'DEEPLINK', 'APP_INSTALL', 'ON_AD').
|
|
134
|
+
Required for mobile app campaigns and lead generation campaigns.
|
|
135
|
+
Use 'ON_AD' for lead generation campaigns where user interaction happens within the ad.
|
|
135
136
|
access_token: Meta API access token (optional - will use cached token if not provided)
|
|
136
137
|
"""
|
|
137
138
|
# Check required parameters
|
|
@@ -196,7 +197,7 @@ async def create_adset(
|
|
|
196
197
|
|
|
197
198
|
# Validate destination_type if provided
|
|
198
199
|
if destination_type:
|
|
199
|
-
valid_destination_types = ["APP_STORE", "DEEPLINK", "APP_INSTALL"]
|
|
200
|
+
valid_destination_types = ["APP_STORE", "DEEPLINK", "APP_INSTALL", "ON_AD"]
|
|
200
201
|
if destination_type not in valid_destination_types:
|
|
201
202
|
return json.dumps({
|
|
202
203
|
"error": f"Invalid destination_type: {destination_type}",
|
meta_ads_mcp/core/targeting.py
CHANGED
|
@@ -147,27 +147,16 @@ async def estimate_audience_size(
|
|
|
147
147
|
}
|
|
148
148
|
}, indent=2)
|
|
149
149
|
|
|
150
|
-
# Build
|
|
151
|
-
endpoint = f"{account_id}/
|
|
150
|
+
# Build reach estimate request (using correct Meta API endpoint)
|
|
151
|
+
endpoint = f"{account_id}/reachestimate"
|
|
152
152
|
params = {
|
|
153
|
-
"
|
|
154
|
-
"optimization_goal": optimization_goal
|
|
153
|
+
"targeting_spec": targeting
|
|
155
154
|
}
|
|
156
155
|
|
|
157
|
-
#
|
|
158
|
-
if optimization_goal == "REACH":
|
|
159
|
-
params["objective"] = "REACH"
|
|
160
|
-
elif optimization_goal in ["LINK_CLICKS", "LANDING_PAGE_VIEWS"]:
|
|
161
|
-
params["objective"] = "TRAFFIC"
|
|
162
|
-
elif optimization_goal == "CONVERSIONS":
|
|
163
|
-
params["objective"] = "CONVERSIONS"
|
|
164
|
-
elif optimization_goal == "APP_INSTALLS":
|
|
165
|
-
params["objective"] = "APP_INSTALLS"
|
|
166
|
-
else:
|
|
167
|
-
params["objective"] = "REACH" # Default fallback
|
|
156
|
+
# Note: reachestimate endpoint doesn't support optimization_goal or objective parameters
|
|
168
157
|
|
|
169
158
|
try:
|
|
170
|
-
data = await make_api_request(endpoint, access_token, params, method="
|
|
159
|
+
data = await make_api_request(endpoint, access_token, params, method="GET")
|
|
171
160
|
|
|
172
161
|
# Format the response for easier consumption
|
|
173
162
|
if "data" in data and len(data["data"]) > 0:
|
|
@@ -191,14 +180,69 @@ async def estimate_audience_size(
|
|
|
191
180
|
else:
|
|
192
181
|
return json.dumps({
|
|
193
182
|
"error": "No estimation data returned from Meta API",
|
|
194
|
-
"raw_response": data
|
|
183
|
+
"raw_response": data,
|
|
184
|
+
"debug_info": {
|
|
185
|
+
"response_keys": list(data.keys()) if isinstance(data, dict) else "not_a_dict",
|
|
186
|
+
"response_type": str(type(data)),
|
|
187
|
+
"endpoint_used": f"{account_id}/reachestimate"
|
|
188
|
+
}
|
|
195
189
|
}, indent=2)
|
|
196
190
|
|
|
197
191
|
except Exception as e:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
192
|
+
# Check if this is the specific Business Manager system user permission error
|
|
193
|
+
error_str = str(e)
|
|
194
|
+
if "100" in error_str and "33" in error_str:
|
|
195
|
+
# Try to provide fallback estimation using individual interests if available
|
|
196
|
+
interests_found = []
|
|
197
|
+
if targeting and "interests" in targeting:
|
|
198
|
+
interests_found.extend([interest.get("id") for interest in targeting["interests"] if interest.get("id")])
|
|
199
|
+
elif targeting and "flexible_spec" in targeting:
|
|
200
|
+
for spec in targeting["flexible_spec"]:
|
|
201
|
+
if "interests" in spec:
|
|
202
|
+
interests_found.extend([interest.get("id") for interest in spec["interests"] if interest.get("id")])
|
|
203
|
+
|
|
204
|
+
if interests_found:
|
|
205
|
+
# Attempt to get individual interest data as fallback
|
|
206
|
+
try:
|
|
207
|
+
fallback_result = await estimate_audience_size(
|
|
208
|
+
access_token=access_token,
|
|
209
|
+
interest_fbid_list=interests_found
|
|
210
|
+
)
|
|
211
|
+
fallback_data = json.loads(fallback_result)
|
|
212
|
+
|
|
213
|
+
return json.dumps({
|
|
214
|
+
"comprehensive_targeting_failed": True,
|
|
215
|
+
"error_code": "100-33",
|
|
216
|
+
"fallback_used": True,
|
|
217
|
+
"details": {
|
|
218
|
+
"issue": "reachestimate endpoint returned error - possibly due to targeting parameters or account limitations",
|
|
219
|
+
"solution": "Individual interest validation used as fallback - comprehensive targeting may have specific requirements",
|
|
220
|
+
"endpoint_used": f"{account_id}/reachestimate"
|
|
221
|
+
},
|
|
222
|
+
"individual_interest_data": fallback_data,
|
|
223
|
+
"note": "Individual interest audience sizes provided as fallback. Comprehensive targeting via reachestimate endpoint failed."
|
|
224
|
+
}, indent=2)
|
|
225
|
+
except:
|
|
226
|
+
pass
|
|
227
|
+
|
|
228
|
+
return json.dumps({
|
|
229
|
+
"error": "reachestimate endpoint returned error (previously was incorrectly using delivery_estimate)",
|
|
230
|
+
"error_code": "100-33",
|
|
231
|
+
"details": {
|
|
232
|
+
"issue": "The endpoint returned an error, possibly due to targeting parameters or account limitations",
|
|
233
|
+
"endpoint_used": f"{account_id}/reachestimate",
|
|
234
|
+
"previous_issue": "Code was previously using non-existent delivery_estimate endpoint - now fixed",
|
|
235
|
+
"available_alternative": "Use interest_list or interest_fbid_list parameters for individual interest validation"
|
|
236
|
+
},
|
|
237
|
+
"raw_error": error_str
|
|
238
|
+
}, indent=2)
|
|
239
|
+
else:
|
|
240
|
+
return json.dumps({
|
|
241
|
+
"error": f"Failed to get audience estimation from reachestimate endpoint: {str(e)}",
|
|
242
|
+
"details": "Check targeting parameters and account permissions",
|
|
243
|
+
"error_type": "general_api_error",
|
|
244
|
+
"endpoint_used": f"{account_id}/reachestimate"
|
|
245
|
+
}, indent=2)
|
|
202
246
|
|
|
203
247
|
|
|
204
248
|
@mcp_server.tool()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meta-ads-mcp
|
|
3
|
-
Version: 0.10.
|
|
4
|
-
Summary: Model Context Protocol (MCP)
|
|
3
|
+
Version: 0.10.2
|
|
4
|
+
Summary: Model Context Protocol (MCP) server 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
|
|
7
7
|
Author-email: Yves Junqueira <yves.junqueira@gmail.com>
|
|
@@ -43,6 +43,7 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for in
|
|
|
43
43
|
- [Features](#features)
|
|
44
44
|
- [Configuration](#configuration)
|
|
45
45
|
- [Available MCP Tools](#available-mcp-tools)
|
|
46
|
+
- [Licensing](#licensing)
|
|
46
47
|
- [Privacy and Security](#privacy-and-security)
|
|
47
48
|
- [Testing](#testing)
|
|
48
49
|
- [Troubleshooting](#troubleshooting)
|
|
@@ -407,6 +408,17 @@ For local installation configuration, authentication options, and advanced techn
|
|
|
407
408
|
- `query`: Search query string (e.g., "Injury Payouts pages", "active campaigns")
|
|
408
409
|
- Returns: List of matching record IDs in ChatGPT-compatible format
|
|
409
410
|
|
|
411
|
+
## Licensing
|
|
412
|
+
|
|
413
|
+
Meta Ads MCP is licensed under the [Business Source License 1.1](LICENSE), which means:
|
|
414
|
+
|
|
415
|
+
- ✅ **Free to use** for individual and business purposes
|
|
416
|
+
- ✅ **Modify and customize** as needed
|
|
417
|
+
- ✅ **Redistribute** to others
|
|
418
|
+
- ✅ **Becomes fully open source** (Apache 2.0) on January 1, 2029
|
|
419
|
+
|
|
420
|
+
The only restriction is that you cannot offer this as a competing hosted service. For questions about commercial licensing, please contact us.
|
|
421
|
+
|
|
410
422
|
## Privacy and Security
|
|
411
423
|
|
|
412
424
|
Meta Ads MCP follows security best practices with secure token management and automatic authentication handling.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
meta_ads_mcp/__init__.py,sha256=
|
|
1
|
+
meta_ads_mcp/__init__.py,sha256=EYdsc6GoKV3a2tDxk_X9rDEokwvdfMK-jAA60i0jgPQ,1501
|
|
2
2
|
meta_ads_mcp/__main__.py,sha256=XaQt3iXftG_7f0Zu7Wop9SeFgrD2WBn0EQOaPMc27d8,207
|
|
3
3
|
meta_ads_mcp/core/__init__.py,sha256=v1k95keVnIx_-npUsb7ppSJ0DvdLQgySpf6xBwob_Lc,1717
|
|
4
4
|
meta_ads_mcp/core/accounts.py,sha256=0lfyvRbhBigFKgNq5Mk3fk4Qh6MtIkKScdOnoc_rQkg,4314
|
|
5
5
|
meta_ads_mcp/core/ads.py,sha256=3UpoktML-5hJ_k2u5KOk3-VcFe_goz531jLi6-qJhqU,54929
|
|
6
6
|
meta_ads_mcp/core/ads_library.py,sha256=BBGVbtjO5eFV42iiY3XPU-wIV8HupzUKpHgPBrydSvU,3232
|
|
7
|
-
meta_ads_mcp/core/adsets.py,sha256=
|
|
7
|
+
meta_ads_mcp/core/adsets.py,sha256=kfggH1F2KD19iPDErE0QdKw2aVX7F409EPLDTM7MKnQ,16024
|
|
8
8
|
meta_ads_mcp/core/api.py,sha256=kWpIafvSsxnesfb5TqndA7ozKoIspby5e_6Jl23L7hY,16447
|
|
9
9
|
meta_ads_mcp/core/auth.py,sha256=2CjFbxpJM3OR3OzCipB8l_-l2xQ1nioGfdI3ZDMnjHM,23629
|
|
10
10
|
meta_ads_mcp/core/authentication.py,sha256=-AJxa3a5ZshRCvmJThBaNwCAJ1D2_qOgUkvu539c_MY,10159
|
|
@@ -19,10 +19,10 @@ meta_ads_mcp/core/pipeboard_auth.py,sha256=ZwEQy8r0TwobFRQ5gmlSjhIfvlUmMtfWNlpQj
|
|
|
19
19
|
meta_ads_mcp/core/reports.py,sha256=Dv3hfsPOR7IZ9WrYrKd_6SNgZl-USIphg7knva3UYAw,5747
|
|
20
20
|
meta_ads_mcp/core/resources.py,sha256=-zIIfZulpo76vcKv6jhAlQq91cR2SZ3cjYZt3ek3x0w,1236
|
|
21
21
|
meta_ads_mcp/core/server.py,sha256=9SlgM_qvdlxo24ctnZzLgW1e1nfAspCSx3YyJQkKP64,17856
|
|
22
|
-
meta_ads_mcp/core/targeting.py,sha256=
|
|
22
|
+
meta_ads_mcp/core/targeting.py,sha256=nl_JVXNhCu85ho5ssklZiQYC3iL_oosdlpEuyCOVXcM,13824
|
|
23
23
|
meta_ads_mcp/core/utils.py,sha256=ytj41yC5SqduLrAiZYBSd6OUwlJRaIClTwnnYKpNFds,9387
|
|
24
|
-
meta_ads_mcp-0.10.
|
|
25
|
-
meta_ads_mcp-0.10.
|
|
26
|
-
meta_ads_mcp-0.10.
|
|
27
|
-
meta_ads_mcp-0.10.
|
|
28
|
-
meta_ads_mcp-0.10.
|
|
24
|
+
meta_ads_mcp-0.10.2.dist-info/METADATA,sha256=xeSFuAjk99sc6cYIS7KVUCGwUZiLxc5lNWKc8vBsCok,22904
|
|
25
|
+
meta_ads_mcp-0.10.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
26
|
+
meta_ads_mcp-0.10.2.dist-info/entry_points.txt,sha256=Dv2RkoBjRJBqj6CyhwqGIiwPCD-SCL1-7B9-zmVRuv0,57
|
|
27
|
+
meta_ads_mcp-0.10.2.dist-info/licenses/LICENSE,sha256=E2d762fbhwKRYn8o7J6Szr6vyBPrHVDlK3jbHPx-d84,3851
|
|
28
|
+
meta_ads_mcp-0.10.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|