meta-ads-mcp 0.3.7__py3-none-any.whl → 0.3.9__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/__init__.py +1 -0
- meta_ads_mcp/core/http_auth_integration.py +248 -0
- meta_ads_mcp/core/reports.py +133 -0
- meta_ads_mcp/core/server.py +260 -8
- {meta_ads_mcp-0.3.7.dist-info → meta_ads_mcp-0.3.9.dist-info}/METADATA +106 -102
- {meta_ads_mcp-0.3.7.dist-info → meta_ads_mcp-0.3.9.dist-info}/RECORD +10 -9
- meta_ads_mcp/api.py +0 -2091
- {meta_ads_mcp-0.3.7.dist-info → meta_ads_mcp-0.3.9.dist-info}/WHEEL +0 -0
- {meta_ads_mcp-0.3.7.dist-info → meta_ads_mcp-0.3.9.dist-info}/entry_points.txt +0 -0
- {meta_ads_mcp-0.3.7.dist-info → meta_ads_mcp-0.3.9.dist-info}/licenses/LICENSE +0 -0
meta_ads_mcp/core/server.py
CHANGED
|
@@ -5,6 +5,8 @@ import argparse
|
|
|
5
5
|
import os
|
|
6
6
|
import sys
|
|
7
7
|
import webbrowser
|
|
8
|
+
import json
|
|
9
|
+
from typing import Dict, Any, Optional
|
|
8
10
|
from .auth import login as login_auth
|
|
9
11
|
from .resources import list_resources, get_resource
|
|
10
12
|
from .utils import logger
|
|
@@ -19,6 +21,173 @@ mcp_server.resource(uri="meta-ads://resources")(list_resources)
|
|
|
19
21
|
mcp_server.resource(uri="meta-ads://images/{resource_id}")(get_resource)
|
|
20
22
|
|
|
21
23
|
|
|
24
|
+
class StreamableHTTPHandler:
|
|
25
|
+
"""Handles stateless Streamable HTTP requests for Meta Ads MCP"""
|
|
26
|
+
|
|
27
|
+
def __init__(self):
|
|
28
|
+
"""Initialize handler with no session storage - all auth per request"""
|
|
29
|
+
logger.debug("StreamableHTTPHandler initialized for stateless operation")
|
|
30
|
+
|
|
31
|
+
def handle_request(self, request_headers: Dict[str, str], request_body: Dict[str, Any]) -> Dict[str, Any]:
|
|
32
|
+
"""Handle individual request with authentication
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
request_headers: HTTP request headers
|
|
36
|
+
request_body: JSON-RPC request body
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
JSON response with auth status and any tool results
|
|
40
|
+
"""
|
|
41
|
+
try:
|
|
42
|
+
# Extract authentication configuration from headers
|
|
43
|
+
auth_config = self.get_auth_config_from_headers(request_headers)
|
|
44
|
+
logger.debug(f"Auth method detected: {auth_config['auth_method']}")
|
|
45
|
+
|
|
46
|
+
# Handle based on auth method
|
|
47
|
+
if auth_config['auth_method'] == 'bearer':
|
|
48
|
+
return self.handle_bearer_request(auth_config, request_body)
|
|
49
|
+
elif auth_config['auth_method'] == 'custom_meta_app':
|
|
50
|
+
return self.handle_custom_app_request(auth_config, request_body)
|
|
51
|
+
else:
|
|
52
|
+
return self.handle_unauthenticated_request(request_body)
|
|
53
|
+
|
|
54
|
+
except Exception as e:
|
|
55
|
+
logger.error(f"Error handling request: {e}")
|
|
56
|
+
return {
|
|
57
|
+
'jsonrpc': '2.0',
|
|
58
|
+
'error': {
|
|
59
|
+
'code': -32603,
|
|
60
|
+
'message': 'Internal error',
|
|
61
|
+
'data': str(e)
|
|
62
|
+
},
|
|
63
|
+
'id': request_body.get('id')
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
def get_auth_config_from_headers(self, request_headers: Dict[str, str]) -> Dict[str, Any]:
|
|
67
|
+
"""Extract authentication configuration from HTTP headers
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
request_headers: HTTP request headers
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Dictionary with auth method and relevant credentials
|
|
74
|
+
"""
|
|
75
|
+
# Security validation - only allow safe headers
|
|
76
|
+
ALLOWED_VIA_HEADERS = {
|
|
77
|
+
'pipeboard_api_token': True, # ✅ Primary method - simple and secure
|
|
78
|
+
'meta_app_id': True, # ✅ Fallback only - triggers OAuth complexity
|
|
79
|
+
'meta_app_secret': False, # ❌ Server environment only
|
|
80
|
+
'meta_access_token': False, # ❌ Use proper auth flows instead
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# PRIMARY: Check for Bearer token in Authorization header (handles 90%+ of cases)
|
|
84
|
+
auth_header = request_headers.get('Authorization') or request_headers.get('authorization')
|
|
85
|
+
if auth_header and auth_header.lower().startswith('bearer '):
|
|
86
|
+
token = auth_header[7:].strip()
|
|
87
|
+
logger.info("Bearer authentication detected (primary path)")
|
|
88
|
+
return {
|
|
89
|
+
'auth_method': 'bearer',
|
|
90
|
+
'bearer_token': token,
|
|
91
|
+
'requires_oauth': False # Simple token-based auth
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# FALLBACK: Custom Meta app (minority of users)
|
|
95
|
+
meta_app_id = request_headers.get('X-META-APP-ID') or request_headers.get('x-meta-app-id')
|
|
96
|
+
if meta_app_id:
|
|
97
|
+
logger.debug("Custom Meta app authentication detected (fallback path)")
|
|
98
|
+
return {
|
|
99
|
+
'auth_method': 'custom_meta_app',
|
|
100
|
+
'meta_app_id': meta_app_id,
|
|
101
|
+
'requires_oauth': True # Complex OAuth flow required
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# No authentication provided
|
|
105
|
+
logger.warning("No authentication method detected in headers")
|
|
106
|
+
return {
|
|
107
|
+
'auth_method': 'none',
|
|
108
|
+
'requires_oauth': False
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
def handle_bearer_request(self, auth_config: Dict[str, Any], request_body: Dict[str, Any]) -> Dict[str, Any]:
|
|
112
|
+
"""Handle request with Bearer token (primary path)
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
auth_config: Authentication configuration from headers
|
|
116
|
+
request_body: JSON-RPC request body
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
JSON response ready for tool execution
|
|
120
|
+
"""
|
|
121
|
+
logger.debug("Processing Bearer authenticated request")
|
|
122
|
+
token = auth_config['bearer_token']
|
|
123
|
+
|
|
124
|
+
# Token is ready to use immediately for API calls
|
|
125
|
+
# TODO: In next phases, this will execute the actual tool call
|
|
126
|
+
return {
|
|
127
|
+
'jsonrpc': '2.0',
|
|
128
|
+
'result': {
|
|
129
|
+
'status': 'ready',
|
|
130
|
+
'auth_method': 'bearer',
|
|
131
|
+
'message': 'Authentication successful with Bearer token',
|
|
132
|
+
'token_source': 'bearer_header'
|
|
133
|
+
},
|
|
134
|
+
'id': request_body.get('id')
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
def handle_custom_app_request(self, auth_config: Dict[str, Any], request_body: Dict[str, Any]) -> Dict[str, Any]:
|
|
138
|
+
"""Handle request with custom Meta app (fallback path)
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
auth_config: Authentication configuration from headers
|
|
142
|
+
request_body: JSON-RPC request body
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
JSON response indicating OAuth flow is required
|
|
146
|
+
"""
|
|
147
|
+
logger.debug("Processing custom Meta app request (OAuth required)")
|
|
148
|
+
|
|
149
|
+
# This may require OAuth flow initiation
|
|
150
|
+
# Each request is independent - no session state
|
|
151
|
+
return {
|
|
152
|
+
'jsonrpc': '2.0',
|
|
153
|
+
'result': {
|
|
154
|
+
'status': 'oauth_required',
|
|
155
|
+
'auth_method': 'custom_meta_app',
|
|
156
|
+
'meta_app_id': auth_config['meta_app_id'],
|
|
157
|
+
'message': 'OAuth flow required for custom Meta app authentication',
|
|
158
|
+
'next_steps': 'Use get_login_link tool to initiate OAuth flow'
|
|
159
|
+
},
|
|
160
|
+
'id': request_body.get('id')
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
def handle_unauthenticated_request(self, request_body: Dict[str, Any]) -> Dict[str, Any]:
|
|
164
|
+
"""Handle request with no authentication
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
request_body: JSON-RPC request body
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
JSON error response requesting authentication
|
|
171
|
+
"""
|
|
172
|
+
logger.warning("Unauthenticated request received")
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
'jsonrpc': '2.0',
|
|
176
|
+
'error': {
|
|
177
|
+
'code': -32600,
|
|
178
|
+
'message': 'Authentication required',
|
|
179
|
+
'data': {
|
|
180
|
+
'supported_methods': [
|
|
181
|
+
'Authorization: Bearer <token> (recommended)',
|
|
182
|
+
'X-META-APP-ID: Custom Meta app OAuth (advanced users)'
|
|
183
|
+
],
|
|
184
|
+
'documentation': 'https://github.com/pipeboard-co/meta-ads-mcp'
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
'id': request_body.get('id')
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
22
191
|
def login_cli():
|
|
23
192
|
"""
|
|
24
193
|
Command-line function to authenticate with Meta
|
|
@@ -34,17 +203,37 @@ def main():
|
|
|
34
203
|
"""Main entry point for the package"""
|
|
35
204
|
# Log startup information
|
|
36
205
|
logger.info("Meta Ads MCP server starting")
|
|
37
|
-
logger.
|
|
38
|
-
logger.
|
|
206
|
+
logger.debug(f"Python version: {sys.version}")
|
|
207
|
+
logger.debug(f"Args: {sys.argv}")
|
|
39
208
|
|
|
40
209
|
# Initialize argument parser
|
|
41
|
-
parser = argparse.ArgumentParser(
|
|
210
|
+
parser = argparse.ArgumentParser(
|
|
211
|
+
description="Meta Ads MCP Server - Model Context Protocol server for Meta Ads API",
|
|
212
|
+
epilog="For more information, see https://github.com/pipeboard-co/meta-ads-mcp"
|
|
213
|
+
)
|
|
42
214
|
parser.add_argument("--login", action="store_true", help="Authenticate with Meta and store the token")
|
|
43
215
|
parser.add_argument("--app-id", type=str, help="Meta App ID (Client ID) for authentication")
|
|
44
216
|
parser.add_argument("--version", action="store_true", help="Show the version of the package")
|
|
45
217
|
|
|
218
|
+
# Transport configuration arguments
|
|
219
|
+
parser.add_argument("--transport", type=str, choices=["stdio", "streamable-http"],
|
|
220
|
+
default="stdio",
|
|
221
|
+
help="Transport method: 'stdio' for MCP clients (default), 'streamable-http' for HTTP API access")
|
|
222
|
+
parser.add_argument("--port", type=int, default=8080,
|
|
223
|
+
help="Port for Streamable HTTP transport (default: 8080, only used with --transport streamable-http)")
|
|
224
|
+
parser.add_argument("--host", type=str, default="localhost",
|
|
225
|
+
help="Host for Streamable HTTP transport (default: localhost, only used with --transport streamable-http)")
|
|
226
|
+
parser.add_argument("--sse-response", action="store_true",
|
|
227
|
+
help="Use SSE response format instead of JSON (default: JSON, only used with --transport streamable-http)")
|
|
228
|
+
|
|
46
229
|
args = parser.parse_args()
|
|
47
|
-
logger.
|
|
230
|
+
logger.debug(f"Parsed args: login={args.login}, app_id={args.app_id}, version={args.version}")
|
|
231
|
+
logger.debug(f"Transport args: transport={args.transport}, port={args.port}, host={args.host}, sse_response={args.sse_response}")
|
|
232
|
+
|
|
233
|
+
# Validate CLI argument combinations
|
|
234
|
+
if args.transport == "stdio" and (args.port != 8080 or args.host != "localhost" or args.sse_response):
|
|
235
|
+
logger.warning("HTTP transport arguments (--port, --host, --sse-response) are ignored when using stdio transport")
|
|
236
|
+
print("Warning: HTTP transport arguments are ignored when using stdio transport")
|
|
48
237
|
|
|
49
238
|
# Update app ID if provided as environment variable or command line arg
|
|
50
239
|
from .auth import auth_manager, meta_config
|
|
@@ -52,7 +241,7 @@ def main():
|
|
|
52
241
|
# Check environment variable first (early init)
|
|
53
242
|
env_app_id = os.environ.get("META_APP_ID")
|
|
54
243
|
if env_app_id:
|
|
55
|
-
logger.
|
|
244
|
+
logger.debug(f"Found META_APP_ID in environment: {env_app_id}")
|
|
56
245
|
else:
|
|
57
246
|
logger.warning("META_APP_ID not found in environment variables")
|
|
58
247
|
|
|
@@ -124,6 +313,69 @@ def main():
|
|
|
124
313
|
logger.error(f"Error initiating browser-based authentication: {e}")
|
|
125
314
|
print(f"Error: Could not start authentication: {e}")
|
|
126
315
|
|
|
127
|
-
#
|
|
128
|
-
|
|
129
|
-
|
|
316
|
+
# Transport-specific server initialization and startup
|
|
317
|
+
if args.transport == "streamable-http":
|
|
318
|
+
logger.info(f"Starting MCP server with Streamable HTTP transport on {args.host}:{args.port}")
|
|
319
|
+
logger.info("Mode: Stateless (no session persistence)")
|
|
320
|
+
logger.info(f"Response format: {'SSE' if args.sse_response else 'JSON'}")
|
|
321
|
+
logger.info("Primary auth method: Bearer Token (recommended)")
|
|
322
|
+
logger.info("Fallback auth method: Custom Meta App OAuth (complex setup)")
|
|
323
|
+
|
|
324
|
+
print(f"Starting Meta Ads MCP server with Streamable HTTP transport")
|
|
325
|
+
print(f"Server will listen on {args.host}:{args.port}")
|
|
326
|
+
print(f"Response format: {'SSE' if args.sse_response else 'JSON'}")
|
|
327
|
+
print("Primary authentication: Bearer Token (via Authorization: Bearer <token> header)")
|
|
328
|
+
print("Fallback authentication: Custom Meta App OAuth (via X-META-APP-ID header)")
|
|
329
|
+
|
|
330
|
+
# Configure the existing server with streamable HTTP settings
|
|
331
|
+
mcp_server.settings.host = args.host
|
|
332
|
+
mcp_server.settings.port = args.port
|
|
333
|
+
mcp_server.settings.stateless_http = True
|
|
334
|
+
mcp_server.settings.json_response = not args.sse_response
|
|
335
|
+
|
|
336
|
+
# Import all tool modules to ensure they are registered
|
|
337
|
+
logger.info("Ensuring all tools are registered for HTTP transport")
|
|
338
|
+
from . import accounts, campaigns, adsets, ads, insights, authentication
|
|
339
|
+
from . import ads_library, budget_schedules, reports
|
|
340
|
+
|
|
341
|
+
# ✅ NEW: Setup HTTP authentication middleware
|
|
342
|
+
logger.info("Setting up HTTP authentication middleware")
|
|
343
|
+
try:
|
|
344
|
+
from .http_auth_integration import setup_fastmcp_http_auth
|
|
345
|
+
|
|
346
|
+
# Setup the FastMCP HTTP auth integration
|
|
347
|
+
setup_fastmcp_http_auth(mcp_server)
|
|
348
|
+
logger.info("FastMCP HTTP authentication integration setup successful")
|
|
349
|
+
print("✅ FastMCP HTTP authentication integration enabled")
|
|
350
|
+
print(" - Bearer tokens via Authorization: Bearer <token> header")
|
|
351
|
+
print(" - Direct Meta tokens via X-META-ACCESS-TOKEN header")
|
|
352
|
+
|
|
353
|
+
except Exception as e:
|
|
354
|
+
logger.error(f"Failed to setup FastMCP HTTP authentication integration: {e}")
|
|
355
|
+
print(f"⚠️ FastMCP HTTP authentication integration setup failed: {e}")
|
|
356
|
+
print(" Server will still start but may not support header-based auth")
|
|
357
|
+
|
|
358
|
+
# Log final server configuration
|
|
359
|
+
logger.info(f"FastMCP server configured with:")
|
|
360
|
+
logger.info(f" - Host: {mcp_server.settings.host}")
|
|
361
|
+
logger.info(f" - Port: {mcp_server.settings.port}")
|
|
362
|
+
logger.info(f" - Stateless HTTP: {mcp_server.settings.stateless_http}")
|
|
363
|
+
logger.info(f" - JSON Response: {mcp_server.settings.json_response}")
|
|
364
|
+
logger.info(f" - Streamable HTTP Path: {mcp_server.settings.streamable_http_path}")
|
|
365
|
+
|
|
366
|
+
# Start the FastMCP server with Streamable HTTP transport
|
|
367
|
+
try:
|
|
368
|
+
logger.info("Starting FastMCP server with Streamable HTTP transport")
|
|
369
|
+
print(f"✅ Server configured successfully")
|
|
370
|
+
print(f" URL: http://{args.host}:{args.port}{mcp_server.settings.streamable_http_path}/")
|
|
371
|
+
print(f" Mode: {'Stateless' if mcp_server.settings.stateless_http else 'Stateful'}")
|
|
372
|
+
print(f" Format: {'JSON' if mcp_server.settings.json_response else 'SSE'}")
|
|
373
|
+
mcp_server.run(transport="streamable-http")
|
|
374
|
+
except Exception as e:
|
|
375
|
+
logger.error(f"Error starting Streamable HTTP server: {e}")
|
|
376
|
+
print(f"Error: Failed to start Streamable HTTP server: {e}")
|
|
377
|
+
return 1
|
|
378
|
+
else:
|
|
379
|
+
# Default stdio transport
|
|
380
|
+
logger.info("Starting MCP server with stdio transport")
|
|
381
|
+
mcp_server.run(transport='stdio')
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meta-ads-mcp
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.9
|
|
4
4
|
Summary: Model Calling Protocol (MCP) plugin for interacting with Meta Ads API
|
|
5
|
-
Project-URL: Homepage, https://github.com/
|
|
6
|
-
Project-URL: Bug Tracker, https://github.com/
|
|
5
|
+
Project-URL: Homepage, https://github.com/pipeboard-co/meta-ads-mcp
|
|
6
|
+
Project-URL: Bug Tracker, https://github.com/pipeboard-co/meta-ads-mcp/issues
|
|
7
7
|
Author-email: Yves Junqueira <yves.junqueira@gmail.com>
|
|
8
8
|
License: MIT
|
|
9
9
|
License-File: LICENSE
|
|
@@ -13,7 +13,7 @@ Classifier: Operating System :: OS Independent
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
14
|
Requires-Python: >=3.10
|
|
15
15
|
Requires-Dist: httpx>=0.26.0
|
|
16
|
-
Requires-Dist: mcp[cli]>=1.
|
|
16
|
+
Requires-Dist: mcp[cli]>=1.9.0
|
|
17
17
|
Requires-Dist: pathlib>=1.0.1
|
|
18
18
|
Requires-Dist: pillow>=10.0.0
|
|
19
19
|
Requires-Dist: python-dateutil>=2.8.2
|
|
@@ -27,135 +27,104 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for in
|
|
|
27
27
|
|
|
28
28
|
> **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.
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
[](https://github.com/user-attachments/assets/3e605cee-d289-414b-814c-6299e7f3383e)
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
## Community & Support
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
- [Discord](https://discord.gg/hNxpJcqM52). Join the community.
|
|
35
|
+
- [Email Support](info@pipeboard.co). Email us for support.
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
2. Get your Pipeboard token at [pipeboard.co/api-tokens](https://pipeboard.co/api-tokens)
|
|
38
|
-
3. Add this configuration to your MCP client:
|
|
37
|
+
## Table of Contents
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
```
|
|
39
|
+
- [🚀 Getting started with Remote MCP (Recommended for Marketers)](#getting-started-with-remote-mcp-recommended)
|
|
40
|
+
- [Local Installation (Technical Users Only)](#local-installation-technical-users-only)
|
|
41
|
+
- [Features](#features)
|
|
42
|
+
- [Configuration](#configuration)
|
|
43
|
+
- [Available MCP Tools](#available-mcp-tools)
|
|
44
|
+
- [Privacy and Security](#privacy-and-security)
|
|
45
|
+
- [Testing](#testing)
|
|
46
|
+
- [Troubleshooting](#troubleshooting)
|
|
51
47
|
|
|
52
|
-
|
|
48
|
+
## Getting started with Remote MCP (Recommended)
|
|
53
49
|
|
|
54
|
-
|
|
50
|
+
The fastest and most reliable way to get started is to **[🚀 Get started with our Meta Ads Remote MCP](https://pipeboard.co)**. No technical setup required - just connect and start analyzing your ad campaigns with AI!
|
|
55
51
|
|
|
56
|
-
|
|
52
|
+
### For Claude Pro/Max Users
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
- **
|
|
61
|
-
- **
|
|
62
|
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
- **Universal LLM Support**: Compatible with any MCP client including Claude Desktop, Cursor, Cherry Studio, and more
|
|
66
|
-
- **Simple Authentication**: Easy setup with secure OAuth authentication
|
|
67
|
-
- **Cross-Platform Support**: Works on Windows, macOS, and Linux
|
|
54
|
+
1. Go to [claude.ai/settings/integrations](https://claude.ai/settings/integrations) (requires Claude Pro or Max)
|
|
55
|
+
2. Click "Add Integration" and enter:
|
|
56
|
+
- **Name**: "Pipeboard Meta Ads" (or any name you prefer)
|
|
57
|
+
- **Integration URL**: `https://mcp.pipeboard.co/meta-ads-mcp`
|
|
58
|
+
3. Click "Connect" next to the integration and follow the prompts to:
|
|
59
|
+
- Login to Pipeboard
|
|
60
|
+
- Connect your Facebook Ads account
|
|
68
61
|
|
|
69
|
-
|
|
62
|
+
That's it! You can now ask Claude to analyze your Meta ad campaigns, get performance insights, and manage your advertising.
|
|
70
63
|
|
|
71
|
-
###
|
|
64
|
+
### For Cursor Users
|
|
72
65
|
|
|
73
|
-
|
|
66
|
+
Add this to your `~/.cursor/mcp.json`:
|
|
74
67
|
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"mcpServers": {
|
|
71
|
+
"meta-ads-remote": {
|
|
72
|
+
"command": "npx",
|
|
73
|
+
"args": [
|
|
74
|
+
"mcp-remote",
|
|
75
|
+
"https://mcp.pipeboard.co/meta-ads-mcp"
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
78
80
|
```
|
|
79
81
|
|
|
80
|
-
|
|
82
|
+
### For Other MCP Clients
|
|
81
83
|
|
|
82
|
-
|
|
84
|
+
Use the Remote MCP URL: `https://mcp.pipeboard.co/meta-ads-mcp`
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
- Windows: `%APPDATA%\meta-ads-mcp\token_cache.json`
|
|
86
|
-
- macOS: `~/Library/Application Support/meta-ads-mcp/token_cache.json`
|
|
87
|
-
- Linux: `~/.config/meta-ads-mcp/token_cache.json`
|
|
86
|
+
**[📖 Get detailed setup instructions for your AI client here](https://pipeboard.co)**
|
|
88
87
|
|
|
89
|
-
|
|
88
|
+
## Local Installation (Technical Users Only)
|
|
90
89
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
### LLM Interface Testing
|
|
90
|
+
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)**.
|
|
94
91
|
|
|
95
|
-
|
|
92
|
+
### Quick Local Setup
|
|
96
93
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
## Troubleshooting
|
|
102
|
-
|
|
103
|
-
### Authentication Issues
|
|
104
|
-
|
|
105
|
-
If you encounter authentication issues:
|
|
106
|
-
|
|
107
|
-
1. Verify your Pipeboard setup:
|
|
108
|
-
- Check that `PIPEBOARD_API_TOKEN` is set correctly
|
|
109
|
-
- Verify your token in the Pipeboard dashboard
|
|
110
|
-
- Try forcing a new login: `python test_pipeboard_auth.py --force-login`
|
|
111
|
-
|
|
112
|
-
2. When using the LLM interface:
|
|
113
|
-
- Ensure the PIPEBOARD_API_TOKEN environment variable is set
|
|
114
|
-
- Check that the callback server is running properly
|
|
94
|
+
```bash
|
|
95
|
+
# Install via uvx (recommended)
|
|
96
|
+
uvx meta-ads-mcp
|
|
115
97
|
|
|
116
|
-
|
|
98
|
+
# Set your Pipeboard token
|
|
99
|
+
export PIPEBOARD_API_TOKEN=your_pipeboard_token
|
|
117
100
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
2. Check if there are rate limits or other restrictions
|
|
121
|
-
3. Verify your Pipeboard token hasn't expired
|
|
101
|
+
# Add to your MCP client configuration
|
|
102
|
+
```
|
|
122
103
|
|
|
123
|
-
|
|
104
|
+
For detailed step-by-step instructions, authentication setup, debugging, and troubleshooting, visit **[LOCAL_INSTALLATION.md](LOCAL_INSTALLATION.md)**.
|
|
124
105
|
|
|
125
|
-
|
|
106
|
+
## Features
|
|
126
107
|
|
|
127
|
-
- **
|
|
128
|
-
- **
|
|
129
|
-
- **
|
|
108
|
+
- **AI-Powered Campaign Analysis**: Let your favorite LLM analyze your campaigns and provide actionable insights on performance
|
|
109
|
+
- **Strategic Recommendations**: Receive data-backed suggestions for optimizing ad spend, targeting, and creative content
|
|
110
|
+
- **Automated Monitoring**: Ask any MCP-compatible LLM to track performance metrics and alert you about significant changes
|
|
111
|
+
- **Budget Optimization**: Get recommendations for reallocating budget to better-performing ad sets
|
|
112
|
+
- **Creative Improvement**: Receive feedback on ad copy, imagery, and calls-to-action
|
|
113
|
+
- **Campaign Management**: Request changes to campaigns, ad sets, and ads (all changes require explicit confirmation)
|
|
114
|
+
- **Cross-Platform Integration**: Works with Facebook, Instagram, and all Meta ad platforms
|
|
115
|
+
- **Universal LLM Support**: Compatible with any MCP client including Claude Desktop, Cursor, Cherry Studio, and more
|
|
116
|
+
- **Simple Authentication**: Easy setup with secure OAuth authentication
|
|
117
|
+
- **Cross-Platform Support**: Works on Windows, macOS, and Linux
|
|
130
118
|
|
|
131
119
|
## Configuration
|
|
132
120
|
|
|
133
|
-
###
|
|
121
|
+
### Remote MCP (Recommended)
|
|
134
122
|
|
|
135
|
-
|
|
123
|
+
**[✨ Get started with Remote MCP here](https://pipeboard.co)** - no technical setup required! Just connect your Facebook Ads account and start asking AI to analyze your campaigns.
|
|
136
124
|
|
|
137
|
-
|
|
138
|
-
2. Set the environment variable:
|
|
139
|
-
```bash
|
|
140
|
-
export PIPEBOARD_API_TOKEN=your_pipeboard_token
|
|
141
|
-
```
|
|
142
|
-
3. Run meta-ads-mcp - it will handle authentication automatically
|
|
125
|
+
### Local Installation (Technical Users)
|
|
143
126
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
Add this to your `claude_desktop_config.json` to integrate with Claude or `~/.cursor/mcp.json` to integrate with Cursor:
|
|
147
|
-
|
|
148
|
-
```json
|
|
149
|
-
"mcpServers": {
|
|
150
|
-
"meta-ads": {
|
|
151
|
-
"command": "uvx",
|
|
152
|
-
"args": ["meta-ads-mcp"],
|
|
153
|
-
"env": {
|
|
154
|
-
"PIPEBOARD_API_TOKEN": "your_pipeboard_token" // Get your token at https://pipeboard.co
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
```
|
|
127
|
+
For local installation configuration, authentication options, and advanced technical setup, see our **[Local Installation Guide](LOCAL_INSTALLATION.md)**.
|
|
159
128
|
|
|
160
129
|
### Available MCP Tools
|
|
161
130
|
|
|
@@ -368,3 +337,38 @@ Add this to your `claude_desktop_config.json` to integrate with Claude or `~/.cu
|
|
|
368
337
|
- `time_end`: Unix timestamp for when the high demand period should end.
|
|
369
338
|
- `access_token` (optional): Meta API access token.
|
|
370
339
|
- Returns: JSON string with the ID of the created budget schedule or an error message.
|
|
340
|
+
|
|
341
|
+
## Privacy and Security
|
|
342
|
+
|
|
343
|
+
Meta Ads MCP follows security best practices with secure token management and automatic authentication handling.
|
|
344
|
+
|
|
345
|
+
- **Remote MCP**: All authentication is handled securely in the cloud - no local token storage required
|
|
346
|
+
- **Local Installation**: Tokens are cached securely on your local machine - see [Local Installation Guide](LOCAL_INSTALLATION.md) for details
|
|
347
|
+
|
|
348
|
+
## Testing
|
|
349
|
+
|
|
350
|
+
### Basic Testing
|
|
351
|
+
|
|
352
|
+
Test your Meta Ads MCP connection with any MCP client:
|
|
353
|
+
|
|
354
|
+
1. **Verify Account Access**: Ask your LLM to use `mcp_meta_ads_get_ad_accounts`
|
|
355
|
+
2. **Check Account Details**: Use `mcp_meta_ads_get_account_info` with your account ID
|
|
356
|
+
3. **List Campaigns**: Try `mcp_meta_ads_get_campaigns` to see your ad campaigns
|
|
357
|
+
|
|
358
|
+
For detailed local installation testing, see [Local Installation Guide](LOCAL_INSTALLATION.md).
|
|
359
|
+
|
|
360
|
+
## Troubleshooting
|
|
361
|
+
|
|
362
|
+
### 💡 Quick Fix: Skip the Technical Setup!
|
|
363
|
+
|
|
364
|
+
The easiest way to avoid any setup issues is to **[🎯 use our Remote MCP instead](https://pipeboard.co)**. No downloads, no configuration - just connect your ads account and start getting AI insights on your campaigns immediately!
|
|
365
|
+
|
|
366
|
+
### Local Installation Issues
|
|
367
|
+
|
|
368
|
+
For comprehensive troubleshooting, debugging, and local installation issues, see our **[Local Installation Guide](LOCAL_INSTALLATION.md)** which includes:
|
|
369
|
+
|
|
370
|
+
- Authentication troubleshooting
|
|
371
|
+
- Installation issues and solutions
|
|
372
|
+
- API error resolution
|
|
373
|
+
- Debug logs and diagnostic commands
|
|
374
|
+
- Performance optimization tips
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
meta_ads_mcp/__init__.py,sha256=
|
|
1
|
+
meta_ads_mcp/__init__.py,sha256=xLEx7rYuC5qFr8s24x1w2jSjIndMHo5x4m-p_eh5NmY,1236
|
|
2
2
|
meta_ads_mcp/__main__.py,sha256=XaQt3iXftG_7f0Zu7Wop9SeFgrD2WBn0EQOaPMc27d8,207
|
|
3
|
-
meta_ads_mcp/
|
|
4
|
-
meta_ads_mcp/core/__init__.py,sha256=NvRA_socbKPEXFXIYdso5jBHb8cEEpF_2Mwhe3Obguw,1105
|
|
3
|
+
meta_ads_mcp/core/__init__.py,sha256=J9vO4rweKb9J-os2maiUy2R4gZGUH4bDSszLDqDCY6w,1174
|
|
5
4
|
meta_ads_mcp/core/accounts.py,sha256=Nmp7lPxO9wmq25jWV7_H0LIqnEbBhpCVBlLGW2HUaq0,2277
|
|
6
5
|
meta_ads_mcp/core/ads.py,sha256=b_81GlGHIM4jISvuDZmHNyc6uW7uD3ovX68ezBci9MM,29747
|
|
7
6
|
meta_ads_mcp/core/ads_library.py,sha256=onStn9UkRqYDC60gOPS-iKDtP1plz6DygUb7hUZ0Jw8,2807
|
|
@@ -12,13 +11,15 @@ meta_ads_mcp/core/authentication.py,sha256=PFqmN7ujtNsJCEDutDzs81peGWFJ8_0YLYI3-
|
|
|
12
11
|
meta_ads_mcp/core/budget_schedules.py,sha256=UxseExsvKAiPwfDCY9aycT4kys4xqeNytyq-yyDOxrs,2901
|
|
13
12
|
meta_ads_mcp/core/callback_server.py,sha256=AUymElaVwHqFyqB2wgqf6A68KsqwtKoYmY-7JZZt8Ks,43286
|
|
14
13
|
meta_ads_mcp/core/campaigns.py,sha256=Fd477GsD1Gx08Ve0uXUCvr4fC-xQCeVHPBwRVaeRQKk,10965
|
|
14
|
+
meta_ads_mcp/core/http_auth_integration.py,sha256=ZJHuxK1Kwtr9gvwfC5HZOLH5MW-HnDDKqJc4xuG5yVE,10060
|
|
15
15
|
meta_ads_mcp/core/insights.py,sha256=XAm4uu83gWp84PEGqAJ3GFIqlvg7prh6MdD71JfvBCo,18072
|
|
16
16
|
meta_ads_mcp/core/pipeboard_auth.py,sha256=VvbxEB8ZOhnMccLU7HI1HgaPWHCl5NGrzZCm-zzHze4,22798
|
|
17
|
+
meta_ads_mcp/core/reports.py,sha256=Dv3hfsPOR7IZ9WrYrKd_6SNgZl-USIphg7knva3UYAw,5747
|
|
17
18
|
meta_ads_mcp/core/resources.py,sha256=-zIIfZulpo76vcKv6jhAlQq91cR2SZ3cjYZt3ek3x0w,1236
|
|
18
|
-
meta_ads_mcp/core/server.py,sha256=
|
|
19
|
+
meta_ads_mcp/core/server.py,sha256=mmhtcyB7h1aO6jK4njLztPdAebPDmc3mhA7DksR1nlY,17583
|
|
19
20
|
meta_ads_mcp/core/utils.py,sha256=DsizDYuJnWUpkbShV1y5Qe8t47Qf59aPZ6O9v0hzdkY,6705
|
|
20
|
-
meta_ads_mcp-0.3.
|
|
21
|
-
meta_ads_mcp-0.3.
|
|
22
|
-
meta_ads_mcp-0.3.
|
|
23
|
-
meta_ads_mcp-0.3.
|
|
24
|
-
meta_ads_mcp-0.3.
|
|
21
|
+
meta_ads_mcp-0.3.9.dist-info/METADATA,sha256=9Rfkt5i08KSvCrqLNswQn9M_8ho-uRJxqUltgJoYlaU,17533
|
|
22
|
+
meta_ads_mcp-0.3.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
23
|
+
meta_ads_mcp-0.3.9.dist-info/entry_points.txt,sha256=Dv2RkoBjRJBqj6CyhwqGIiwPCD-SCL1-7B9-zmVRuv0,57
|
|
24
|
+
meta_ads_mcp-0.3.9.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
25
|
+
meta_ads_mcp-0.3.9.dist-info/RECORD,,
|