meta-ads-mcp 1.0.13__py3-none-any.whl → 1.0.16__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.
Potentially problematic release.
This version of meta-ads-mcp might be problematic. Click here for more details.
- meta_ads_mcp/__init__.py +1 -1
- meta_ads_mcp/core/ads.py +69 -75
- meta_ads_mcp/core/api.py +3 -2
- meta_ads_mcp/core/authentication.py +2 -1
- meta_ads_mcp/core/campaigns.py +35 -1
- meta_ads_mcp/core/duplication.py +2 -2
- {meta_ads_mcp-1.0.13.dist-info → meta_ads_mcp-1.0.16.dist-info}/METADATA +40 -2
- {meta_ads_mcp-1.0.13.dist-info → meta_ads_mcp-1.0.16.dist-info}/RECORD +11 -11
- {meta_ads_mcp-1.0.13.dist-info → meta_ads_mcp-1.0.16.dist-info}/WHEEL +0 -0
- {meta_ads_mcp-1.0.13.dist-info → meta_ads_mcp-1.0.16.dist-info}/entry_points.txt +0 -0
- {meta_ads_mcp-1.0.13.dist-info → meta_ads_mcp-1.0.16.dist-info}/licenses/LICENSE +0 -0
meta_ads_mcp/__init__.py
CHANGED
meta_ads_mcp/core/ads.py
CHANGED
|
@@ -831,32 +831,18 @@ async def create_ad_creative(
|
|
|
831
831
|
if description and descriptions:
|
|
832
832
|
return json.dumps({"error": "Cannot specify both 'description' and 'descriptions'. Use 'description' for single description or 'descriptions' for multiple."}, indent=2)
|
|
833
833
|
|
|
834
|
-
#
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
if headline:
|
|
839
|
-
final_headlines = [headline]
|
|
840
|
-
elif headlines:
|
|
841
|
-
final_headlines = headlines
|
|
842
|
-
|
|
843
|
-
if description:
|
|
844
|
-
final_descriptions = [description]
|
|
845
|
-
elif descriptions:
|
|
846
|
-
final_descriptions = descriptions
|
|
847
|
-
|
|
848
|
-
# Validate dynamic creative parameters
|
|
849
|
-
if final_headlines:
|
|
850
|
-
if len(final_headlines) > 5:
|
|
834
|
+
# Validate dynamic creative parameters (plural forms only)
|
|
835
|
+
if headlines:
|
|
836
|
+
if len(headlines) > 5:
|
|
851
837
|
return json.dumps({"error": "Maximum 5 headlines allowed for dynamic creatives"}, indent=2)
|
|
852
|
-
for i, h in enumerate(
|
|
838
|
+
for i, h in enumerate(headlines):
|
|
853
839
|
if len(h) > 40:
|
|
854
840
|
return json.dumps({"error": f"Headline {i+1} exceeds 40 character limit"}, indent=2)
|
|
855
841
|
|
|
856
|
-
if
|
|
857
|
-
if len(
|
|
842
|
+
if descriptions:
|
|
843
|
+
if len(descriptions) > 5:
|
|
858
844
|
return json.dumps({"error": "Maximum 5 descriptions allowed for dynamic creatives"}, indent=2)
|
|
859
|
-
for i, d in enumerate(
|
|
845
|
+
for i, d in enumerate(descriptions):
|
|
860
846
|
if len(d) > 125:
|
|
861
847
|
return json.dumps({"error": f"Description {i+1} exceeds 125 character limit"}, indent=2)
|
|
862
848
|
|
|
@@ -866,8 +852,9 @@ async def create_ad_creative(
|
|
|
866
852
|
}
|
|
867
853
|
|
|
868
854
|
# Choose between asset_feed_spec (dynamic creative) or object_story_spec (traditional)
|
|
869
|
-
|
|
870
|
-
|
|
855
|
+
# ONLY use asset_feed_spec when user explicitly provides plural parameters (headlines/descriptions)
|
|
856
|
+
if headlines or descriptions:
|
|
857
|
+
# Use asset_feed_spec for dynamic creatives with multiple variants
|
|
871
858
|
asset_feed_spec = {
|
|
872
859
|
"ad_formats": ["SINGLE_IMAGE"],
|
|
873
860
|
"images": [{"hash": image_hash}],
|
|
@@ -875,12 +862,12 @@ async def create_ad_creative(
|
|
|
875
862
|
}
|
|
876
863
|
|
|
877
864
|
# Handle headlines
|
|
878
|
-
if
|
|
879
|
-
asset_feed_spec["headlines"] = [{"text": headline_text} for headline_text in
|
|
865
|
+
if headlines:
|
|
866
|
+
asset_feed_spec["headlines"] = [{"text": headline_text} for headline_text in headlines]
|
|
880
867
|
|
|
881
868
|
# Handle descriptions
|
|
882
|
-
if
|
|
883
|
-
asset_feed_spec["descriptions"] = [{"text": description_text} for description_text in
|
|
869
|
+
if descriptions:
|
|
870
|
+
asset_feed_spec["descriptions"] = [{"text": description_text} for description_text in descriptions]
|
|
884
871
|
|
|
885
872
|
# Add message as primary_texts if provided
|
|
886
873
|
if message:
|
|
@@ -897,7 +884,7 @@ async def create_ad_creative(
|
|
|
897
884
|
"page_id": page_id
|
|
898
885
|
}
|
|
899
886
|
else:
|
|
900
|
-
# Use traditional object_story_spec for
|
|
887
|
+
# Use traditional object_story_spec with link_data for simple creatives
|
|
901
888
|
creative_data["object_story_spec"] = {
|
|
902
889
|
"page_id": page_id,
|
|
903
890
|
"link_data": {
|
|
@@ -909,17 +896,25 @@ async def create_ad_creative(
|
|
|
909
896
|
# Add optional parameters if provided
|
|
910
897
|
if message:
|
|
911
898
|
creative_data["object_story_spec"]["link_data"]["message"] = message
|
|
899
|
+
|
|
900
|
+
# Add headline (singular) to link_data
|
|
901
|
+
if headline:
|
|
902
|
+
creative_data["object_story_spec"]["link_data"]["name"] = headline
|
|
903
|
+
|
|
904
|
+
# Add description (singular) to link_data
|
|
905
|
+
if description:
|
|
906
|
+
creative_data["object_story_spec"]["link_data"]["description"] = description
|
|
907
|
+
|
|
908
|
+
# Add call_to_action to link_data for simple creatives
|
|
909
|
+
if call_to_action_type:
|
|
910
|
+
creative_data["object_story_spec"]["link_data"]["call_to_action"] = {
|
|
911
|
+
"type": call_to_action_type
|
|
912
|
+
}
|
|
912
913
|
|
|
913
914
|
# Add dynamic creative spec if provided
|
|
914
915
|
if dynamic_creative_spec:
|
|
915
916
|
creative_data["dynamic_creative_spec"] = dynamic_creative_spec
|
|
916
917
|
|
|
917
|
-
# Only add call_to_action to object_story_spec if we're not using asset_feed_spec
|
|
918
|
-
if call_to_action_type and "asset_feed_spec" not in creative_data:
|
|
919
|
-
creative_data["object_story_spec"]["link_data"]["call_to_action"] = {
|
|
920
|
-
"type": call_to_action_type
|
|
921
|
-
}
|
|
922
|
-
|
|
923
918
|
if instagram_actor_id:
|
|
924
919
|
creative_data["instagram_actor_id"] = instagram_actor_id
|
|
925
920
|
|
|
@@ -998,32 +993,18 @@ async def update_ad_creative(
|
|
|
998
993
|
if description and descriptions:
|
|
999
994
|
return json.dumps({"error": "Cannot specify both 'description' and 'descriptions'. Use 'description' for single description or 'descriptions' for multiple."}, indent=2)
|
|
1000
995
|
|
|
1001
|
-
#
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
if headline:
|
|
1006
|
-
final_headlines = [headline]
|
|
1007
|
-
elif headlines:
|
|
1008
|
-
final_headlines = headlines
|
|
1009
|
-
|
|
1010
|
-
if description:
|
|
1011
|
-
final_descriptions = [description]
|
|
1012
|
-
elif descriptions:
|
|
1013
|
-
final_descriptions = descriptions
|
|
1014
|
-
|
|
1015
|
-
# Validate dynamic creative parameters
|
|
1016
|
-
if final_headlines:
|
|
1017
|
-
if len(final_headlines) > 5:
|
|
996
|
+
# Validate dynamic creative parameters (plural forms only)
|
|
997
|
+
if headlines:
|
|
998
|
+
if len(headlines) > 5:
|
|
1018
999
|
return json.dumps({"error": "Maximum 5 headlines allowed for dynamic creatives"}, indent=2)
|
|
1019
|
-
for i, h in enumerate(
|
|
1000
|
+
for i, h in enumerate(headlines):
|
|
1020
1001
|
if len(h) > 40:
|
|
1021
1002
|
return json.dumps({"error": f"Headline {i+1} exceeds 40 character limit"}, indent=2)
|
|
1022
1003
|
|
|
1023
|
-
if
|
|
1024
|
-
if len(
|
|
1004
|
+
if descriptions:
|
|
1005
|
+
if len(descriptions) > 5:
|
|
1025
1006
|
return json.dumps({"error": "Maximum 5 descriptions allowed for dynamic creatives"}, indent=2)
|
|
1026
|
-
for i, d in enumerate(
|
|
1007
|
+
for i, d in enumerate(descriptions):
|
|
1027
1008
|
if len(d) > 125:
|
|
1028
1009
|
return json.dumps({"error": f"Description {i+1} exceeds 125 character limit"}, indent=2)
|
|
1029
1010
|
|
|
@@ -1033,45 +1014,58 @@ async def update_ad_creative(
|
|
|
1033
1014
|
if name:
|
|
1034
1015
|
update_data["name"] = name
|
|
1035
1016
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
if final_headlines or final_descriptions or dynamic_creative_spec:
|
|
1017
|
+
# Choose between asset_feed_spec (dynamic creative) or object_story_spec (traditional)
|
|
1018
|
+
# ONLY use asset_feed_spec when user explicitly provides plural parameters (headlines/descriptions)
|
|
1019
|
+
if headlines or descriptions or dynamic_creative_spec:
|
|
1020
|
+
# Handle dynamic creative assets via asset_feed_spec
|
|
1041
1021
|
asset_feed_spec = {}
|
|
1042
1022
|
|
|
1043
1023
|
# Add required ad_formats field for dynamic creatives
|
|
1044
1024
|
asset_feed_spec["ad_formats"] = ["SINGLE_IMAGE"]
|
|
1045
1025
|
|
|
1046
1026
|
# Handle headlines
|
|
1047
|
-
if
|
|
1048
|
-
asset_feed_spec["headlines"] = [{"text": headline_text} for headline_text in
|
|
1027
|
+
if headlines:
|
|
1028
|
+
asset_feed_spec["headlines"] = [{"text": headline_text} for headline_text in headlines]
|
|
1049
1029
|
|
|
1050
1030
|
# Handle descriptions
|
|
1051
|
-
if
|
|
1052
|
-
asset_feed_spec["descriptions"] = [{"text": description_text} for description_text in
|
|
1031
|
+
if descriptions:
|
|
1032
|
+
asset_feed_spec["descriptions"] = [{"text": description_text} for description_text in descriptions]
|
|
1053
1033
|
|
|
1054
1034
|
# Add message as primary_texts if provided
|
|
1055
1035
|
if message:
|
|
1056
1036
|
asset_feed_spec["primary_texts"] = [{"text": message}]
|
|
1057
1037
|
|
|
1038
|
+
# Add call_to_action_types if provided
|
|
1039
|
+
if call_to_action_type:
|
|
1040
|
+
asset_feed_spec["call_to_action_types"] = [call_to_action_type]
|
|
1041
|
+
|
|
1058
1042
|
update_data["asset_feed_spec"] = asset_feed_spec
|
|
1043
|
+
else:
|
|
1044
|
+
# Use traditional object_story_spec with link_data for simple creatives
|
|
1045
|
+
if message or headline or description or call_to_action_type:
|
|
1046
|
+
update_data["object_story_spec"] = {"link_data": {}}
|
|
1047
|
+
|
|
1048
|
+
if message:
|
|
1049
|
+
update_data["object_story_spec"]["link_data"]["message"] = message
|
|
1050
|
+
|
|
1051
|
+
# Add headline (singular) to link_data
|
|
1052
|
+
if headline:
|
|
1053
|
+
update_data["object_story_spec"]["link_data"]["name"] = headline
|
|
1054
|
+
|
|
1055
|
+
# Add description (singular) to link_data
|
|
1056
|
+
if description:
|
|
1057
|
+
update_data["object_story_spec"]["link_data"]["description"] = description
|
|
1058
|
+
|
|
1059
|
+
# Add call_to_action to link_data for simple creatives
|
|
1060
|
+
if call_to_action_type:
|
|
1061
|
+
update_data["object_story_spec"]["link_data"]["call_to_action"] = {
|
|
1062
|
+
"type": call_to_action_type
|
|
1063
|
+
}
|
|
1059
1064
|
|
|
1060
1065
|
# Add dynamic creative spec if provided
|
|
1061
1066
|
if dynamic_creative_spec:
|
|
1062
1067
|
update_data["dynamic_creative_spec"] = dynamic_creative_spec
|
|
1063
1068
|
|
|
1064
|
-
# Handle call_to_action - add to asset_feed_spec if using dynamic creative, otherwise to object_story_spec
|
|
1065
|
-
if call_to_action_type:
|
|
1066
|
-
if "asset_feed_spec" in update_data:
|
|
1067
|
-
update_data["asset_feed_spec"]["call_to_action_types"] = [call_to_action_type]
|
|
1068
|
-
else:
|
|
1069
|
-
if "object_story_spec" not in update_data:
|
|
1070
|
-
update_data["object_story_spec"] = {"link_data": {}}
|
|
1071
|
-
update_data["object_story_spec"]["link_data"]["call_to_action"] = {
|
|
1072
|
-
"type": call_to_action_type
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
1069
|
# Prepare the API endpoint for updating the creative
|
|
1076
1070
|
endpoint = f"{creative_id}"
|
|
1077
1071
|
|
meta_ads_mcp/core/api.py
CHANGED
|
@@ -6,7 +6,8 @@ import httpx
|
|
|
6
6
|
import asyncio
|
|
7
7
|
import functools
|
|
8
8
|
import os
|
|
9
|
-
from .
|
|
9
|
+
from . import auth
|
|
10
|
+
from .auth import needs_authentication, auth_manager, start_callback_server, shutdown_callback_server
|
|
10
11
|
from .utils import logger
|
|
11
12
|
|
|
12
13
|
# Constants
|
|
@@ -203,7 +204,7 @@ def meta_api_tool(func):
|
|
|
203
204
|
# If access_token is not in kwargs or not kwargs['access_token'], try to get it from auth_manager
|
|
204
205
|
if 'access_token' not in kwargs or not kwargs['access_token']:
|
|
205
206
|
try:
|
|
206
|
-
access_token = await get_current_access_token()
|
|
207
|
+
access_token = await auth.get_current_access_token()
|
|
207
208
|
if access_token:
|
|
208
209
|
kwargs['access_token'] = access_token
|
|
209
210
|
logger.debug("Using access token from auth_manager")
|
|
@@ -29,7 +29,8 @@ from typing import Optional
|
|
|
29
29
|
import asyncio
|
|
30
30
|
import os
|
|
31
31
|
from .api import meta_api_tool
|
|
32
|
-
from .
|
|
32
|
+
from . import auth
|
|
33
|
+
from .auth import start_callback_server, shutdown_callback_server, auth_manager
|
|
33
34
|
from .server import mcp_server
|
|
34
35
|
from .utils import logger, META_APP_SECRET
|
|
35
36
|
from .pipeboard_auth import pipeboard_auth_manager
|
meta_ads_mcp/core/campaigns.py
CHANGED
|
@@ -9,7 +9,14 @@ from .server import mcp_server
|
|
|
9
9
|
|
|
10
10
|
@mcp_server.tool()
|
|
11
11
|
@meta_api_tool
|
|
12
|
-
async def get_campaigns(
|
|
12
|
+
async def get_campaigns(
|
|
13
|
+
account_id: str,
|
|
14
|
+
access_token: Optional[str] = None,
|
|
15
|
+
limit: int = 10,
|
|
16
|
+
status_filter: str = "",
|
|
17
|
+
objective_filter: Union[str, List[str]] = "",
|
|
18
|
+
after: str = ""
|
|
19
|
+
) -> str:
|
|
13
20
|
"""
|
|
14
21
|
Get campaigns for a Meta Ads account with optional filtering.
|
|
15
22
|
|
|
@@ -26,6 +33,11 @@ async def get_campaigns(account_id: str, access_token: Optional[str] = None, lim
|
|
|
26
33
|
status_filter: Filter by effective status (e.g., 'ACTIVE', 'PAUSED', 'ARCHIVED').
|
|
27
34
|
Maps to the 'effective_status' API parameter, which expects an array
|
|
28
35
|
(this function handles the required JSON formatting). Leave empty for all statuses.
|
|
36
|
+
objective_filter: Filter by campaign objective(s). Can be a single objective string or a list of objectives.
|
|
37
|
+
Valid objectives: 'OUTCOME_AWARENESS', 'OUTCOME_TRAFFIC', 'OUTCOME_ENGAGEMENT',
|
|
38
|
+
'OUTCOME_LEADS', 'OUTCOME_SALES', 'OUTCOME_APP_PROMOTION'.
|
|
39
|
+
Examples: 'OUTCOME_LEADS' or ['OUTCOME_LEADS', 'OUTCOME_SALES'].
|
|
40
|
+
Leave empty for all objectives.
|
|
29
41
|
after: Pagination cursor to get the next set of results
|
|
30
42
|
"""
|
|
31
43
|
# Require explicit account_id
|
|
@@ -38,10 +50,32 @@ async def get_campaigns(account_id: str, access_token: Optional[str] = None, lim
|
|
|
38
50
|
"limit": limit
|
|
39
51
|
}
|
|
40
52
|
|
|
53
|
+
# Build filtering array for complex filtering
|
|
54
|
+
filters = []
|
|
55
|
+
|
|
41
56
|
if status_filter:
|
|
42
57
|
# API expects an array, encode it as a JSON string
|
|
43
58
|
params["effective_status"] = json.dumps([status_filter])
|
|
44
59
|
|
|
60
|
+
# Handle objective filtering - supports both single string and list of objectives
|
|
61
|
+
if objective_filter:
|
|
62
|
+
# Convert single string to list for consistent handling
|
|
63
|
+
objectives = [objective_filter] if isinstance(objective_filter, str) else objective_filter
|
|
64
|
+
|
|
65
|
+
# Filter out empty strings
|
|
66
|
+
objectives = [obj for obj in objectives if obj]
|
|
67
|
+
|
|
68
|
+
if objectives:
|
|
69
|
+
filters.append({
|
|
70
|
+
"field": "objective",
|
|
71
|
+
"operator": "IN",
|
|
72
|
+
"value": objectives
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
# Add filtering parameter if we have filters
|
|
76
|
+
if filters:
|
|
77
|
+
params["filtering"] = json.dumps(filters)
|
|
78
|
+
|
|
45
79
|
if after:
|
|
46
80
|
params["after"] = after
|
|
47
81
|
|
meta_ads_mcp/core/duplication.py
CHANGED
|
@@ -6,7 +6,7 @@ import httpx
|
|
|
6
6
|
from typing import Optional, Dict, Any, List, Union
|
|
7
7
|
from .server import mcp_server
|
|
8
8
|
from .api import meta_api_tool
|
|
9
|
-
from .
|
|
9
|
+
from . import auth
|
|
10
10
|
from .http_auth_integration import FastMCPAuthIntegration
|
|
11
11
|
|
|
12
12
|
|
|
@@ -204,7 +204,7 @@ async def _forward_duplication_request(resource_type: str, resource_id: str, acc
|
|
|
204
204
|
|
|
205
205
|
# Use provided access_token parameter if no Facebook token found in context
|
|
206
206
|
if not facebook_token:
|
|
207
|
-
facebook_token = access_token if access_token else await get_current_access_token()
|
|
207
|
+
facebook_token = access_token if access_token else await auth.get_current_access_token()
|
|
208
208
|
|
|
209
209
|
# Validate we have both required tokens
|
|
210
210
|
if not pipeboard_token:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meta-ads-mcp
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.16
|
|
4
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
|
|
@@ -25,12 +25,14 @@ Description-Content-Type: text/markdown
|
|
|
25
25
|
|
|
26
26
|
# Meta Ads MCP
|
|
27
27
|
|
|
28
|
-
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for interacting with Meta Ads
|
|
28
|
+
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for interacting with Meta Ads. Analyze, manage and optimize Meta advertising campaigns through an AI interface. Use an LLM to retrieve performance data, visualize ad creatives, and provide strategic insights for your ads on Facebook, Instagram, and other Meta platforms.
|
|
29
29
|
|
|
30
30
|
> **DISCLAIMER:** This is an unofficial third-party tool and is not associated with, endorsed by, or affiliated with Meta in any way. This project is maintained independently and uses Meta's public APIs according to their terms of service. Meta, Facebook, Instagram, and other Meta brand names are trademarks of their respective owners.
|
|
31
31
|
|
|
32
32
|
[](https://github.com/user-attachments/assets/3e605cee-d289-414b-814c-6299e7f3383e)
|
|
33
33
|
|
|
34
|
+
[](https://lobehub.com/mcp/nictuku-meta-ads-mcp)
|
|
35
|
+
|
|
34
36
|
mcp-name: co.pipeboard/meta-ads-mcp
|
|
35
37
|
|
|
36
38
|
## Community & Support
|
|
@@ -66,6 +68,16 @@ The fastest and most reliable way to get started is to **[🚀 Get started with
|
|
|
66
68
|
|
|
67
69
|
That's it! You can now ask Claude to analyze your Meta ad campaigns, get performance insights, and manage your advertising.
|
|
68
70
|
|
|
71
|
+
#### Advanced: Direct Token Authentication (Claude)
|
|
72
|
+
|
|
73
|
+
For direct token-based authentication without the interactive flow, use this URL format when adding the integration:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
https://mcp.pipeboard.co/meta-ads-mcp?token=YOUR_PIPEBOARD_TOKEN
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Get your token at [pipeboard.co/api-tokens](https://pipeboard.co/api-tokens).
|
|
80
|
+
|
|
69
81
|
### For Cursor Users
|
|
70
82
|
|
|
71
83
|
Add the following to your `~/.cursor/mcp.json`. Once you enable the remote MCP, click on "Needs login" to finish the login process.
|
|
@@ -81,12 +93,38 @@ Add the following to your `~/.cursor/mcp.json`. Once you enable the remote MCP,
|
|
|
81
93
|
}
|
|
82
94
|
```
|
|
83
95
|
|
|
96
|
+
#### Advanced: Direct Token Authentication (Cursor)
|
|
97
|
+
|
|
98
|
+
If you prefer to authenticate without the interactive login flow, you can include your Pipeboard API token directly in the URL:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"mcpServers": {
|
|
103
|
+
"meta-ads-remote": {
|
|
104
|
+
"url": "https://mcp.pipeboard.co/meta-ads-mcp?token=YOUR_PIPEBOARD_TOKEN"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Get your token at [pipeboard.co/api-tokens](https://pipeboard.co/api-tokens).
|
|
111
|
+
|
|
84
112
|
### For Other MCP Clients
|
|
85
113
|
|
|
86
114
|
Use the Remote MCP URL: `https://mcp.pipeboard.co/meta-ads-mcp`
|
|
87
115
|
|
|
88
116
|
**[📖 Get detailed setup instructions for your AI client here](https://pipeboard.co)**
|
|
89
117
|
|
|
118
|
+
#### Advanced: Direct Token Authentication (Other Clients)
|
|
119
|
+
|
|
120
|
+
For MCP clients that support token-based authentication, you can append your Pipeboard API token to the URL:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
https://mcp.pipeboard.co/meta-ads-mcp?token=YOUR_PIPEBOARD_TOKEN
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This bypasses the interactive login flow and authenticates immediately. Get your token at [pipeboard.co/api-tokens](https://pipeboard.co/api-tokens).
|
|
127
|
+
|
|
90
128
|
## Local Installation (Technical Users Only)
|
|
91
129
|
|
|
92
130
|
If you're a developer or need to customize the installation, you can run Meta Ads MCP locally. **Most marketers should use the Remote MCP above instead!** For complete technical setup instructions, see our **[Local Installation Guide](LOCAL_INSTALLATION.md)**.
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
meta_ads_mcp/__init__.py,sha256=
|
|
1
|
+
meta_ads_mcp/__init__.py,sha256=1vRTFKaJdcF1Ly2KZBp1Hp2QY-62dPdo5uEF1F4lsYo,1477
|
|
2
2
|
meta_ads_mcp/__main__.py,sha256=XaQt3iXftG_7f0Zu7Wop9SeFgrD2WBn0EQOaPMc27d8,207
|
|
3
3
|
meta_ads_mcp/core/__init__.py,sha256=IEJtqpyUo0CZSUWeQPljQ-D2vKorTFwXnpBQWSi1hIM,1819
|
|
4
4
|
meta_ads_mcp/core/accounts.py,sha256=7Zoqq0zMIJi_Xsxe9-_b3EYx-UTeieJJvO7HxVRuUS0,4327
|
|
5
|
-
meta_ads_mcp/core/ads.py,sha256=
|
|
5
|
+
meta_ads_mcp/core/ads.py,sha256=s-E_ZzgbsMbnv2xblaDFgazcKDJIPyYKY8VC2dkeMBQ,61595
|
|
6
6
|
meta_ads_mcp/core/ads_library.py,sha256=smGz9FhM6RIUjlQT4Jv1BaZmXahGdK21eRCB7QMhK-4,3228
|
|
7
7
|
meta_ads_mcp/core/adsets.py,sha256=3Ok3EwPTReKshtsVs4gRMlws6LMTUJTb4ZeGPPM8JR8,16570
|
|
8
|
-
meta_ads_mcp/core/api.py,sha256=
|
|
8
|
+
meta_ads_mcp/core/api.py,sha256=RvEbXpVO_SxKJeuqsiQhpGYLZuhQlYKCd9hNv7AIZac,16856
|
|
9
9
|
meta_ads_mcp/core/auth.py,sha256=l_IvejK2KYXg8yhBiP0ifE6mGwJ6ZujqYQbVw1KOUME,23649
|
|
10
|
-
meta_ads_mcp/core/authentication.py,sha256=
|
|
10
|
+
meta_ads_mcp/core/authentication.py,sha256=bAdmlSxQpqFN1vup9Wijl-iCfPLPMyFfMhIPdoNOPYg,10540
|
|
11
11
|
meta_ads_mcp/core/budget_schedules.py,sha256=FVyJuKbjUE4cmtlPJEbIwpN6JmU-1WQjc7io1y5JaHE,2911
|
|
12
12
|
meta_ads_mcp/core/callback_server.py,sha256=LIAJv9DW--83kdZ7VWWZal8xEprYjRZ8iug4rMczYbQ,9372
|
|
13
|
-
meta_ads_mcp/core/campaigns.py,sha256=
|
|
14
|
-
meta_ads_mcp/core/duplication.py,sha256=
|
|
13
|
+
meta_ads_mcp/core/campaigns.py,sha256=LKo5B8hNUUmfVQ1iu88o8HoU9ixOlGS9lwmPu6x9keA,15604
|
|
14
|
+
meta_ads_mcp/core/duplication.py,sha256=pJ41pI9bIxNf21TSy6KkpcUsc3aSr4KIiO__sunNoq0,18909
|
|
15
15
|
meta_ads_mcp/core/http_auth_integration.py,sha256=lGpKhfzJcyWugBcYEvypY-qnlt-3UDBLqh7xAUH0DGw,12473
|
|
16
16
|
meta_ads_mcp/core/insights.py,sha256=ogSGlC0ddh8RFzWydilfDc7GYnjtInFiEQS7cSoyTmw,5061
|
|
17
17
|
meta_ads_mcp/core/openai_deep_research.py,sha256=68ayGopnBSPEYhN9R1sFvTXtyWtM0lji9aWS3uSXnLY,18649
|
|
@@ -21,8 +21,8 @@ meta_ads_mcp/core/resources.py,sha256=-zIIfZulpo76vcKv6jhAlQq91cR2SZ3cjYZt3ek3x0
|
|
|
21
21
|
meta_ads_mcp/core/server.py,sha256=9SlgM_qvdlxo24ctnZzLgW1e1nfAspCSx3YyJQkKP64,17856
|
|
22
22
|
meta_ads_mcp/core/targeting.py,sha256=d2uLWbIEtucRuTgwZEdtVKLDZJgaxQ1lDtZ0ZgkBJC4,25150
|
|
23
23
|
meta_ads_mcp/core/utils.py,sha256=ytj41yC5SqduLrAiZYBSd6OUwlJRaIClTwnnYKpNFds,9387
|
|
24
|
-
meta_ads_mcp-1.0.
|
|
25
|
-
meta_ads_mcp-1.0.
|
|
26
|
-
meta_ads_mcp-1.0.
|
|
27
|
-
meta_ads_mcp-1.0.
|
|
28
|
-
meta_ads_mcp-1.0.
|
|
24
|
+
meta_ads_mcp-1.0.16.dist-info/METADATA,sha256=N0dMtlXVrGmyFLgv3-IKS14giZL6JVXD_n9hjTZW3Os,25499
|
|
25
|
+
meta_ads_mcp-1.0.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
26
|
+
meta_ads_mcp-1.0.16.dist-info/entry_points.txt,sha256=Dv2RkoBjRJBqj6CyhwqGIiwPCD-SCL1-7B9-zmVRuv0,57
|
|
27
|
+
meta_ads_mcp-1.0.16.dist-info/licenses/LICENSE,sha256=E2d762fbhwKRYn8o7J6Szr6vyBPrHVDlK3jbHPx-d84,3851
|
|
28
|
+
meta_ads_mcp-1.0.16.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|