Atlas / MCP servers / pipeboard-co / Meta Ads

Meta AdsCAUTION

mcp/pipeboard-co/meta-ads

Meta Ads (Facebook/Instagram) MCP server for Claude, ChatGPT, Perplexity & Cursor — the Meta node of Pipeboard’s 5-platform family (+ Google, TikTok, Snap, Reddit). Hosted remote MCP, badged Meta Business Partner, free plan — no self-hosting required.

Verdict
CAUTION
Grade
C
Trust score
73 /100
Exposed tools
—
Transport
stdio · streamable-http
License
NOASSERTION
Stars
1,275
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

A Model Context Protocol (MCP) server that lets AI assistants — Claude, ChatGPT, Perplexity, Cursor, or any MCP client — run your Meta Ads end to end: launch campaigns, upload creatives, update budgets, and analyze performance through natural conversation across Facebook, Instagram, and every Meta ad surface. Available as a hosted remote MCP — no developer token, no self-hosting required.

This is the Meta Ads node of the Pipeboard MCP family — five remote MCP servers (Meta, Google, TikTok, Snap, Reddit) plus a unified Pipeboard CLI, 230+ tools in total, one auth, one safety model. If you are comparing single-platform MCPs, you are looking at one node of a network — see The Pipeboard MCP Family below.

Note: This is an independent open-source project that uses Meta's public APIs. The hosted service behind it — Pipeboard — is a badged Meta Business Partner and an officially approved Meta app that manages Meta, Google, TikTok, Snap & Reddit Ads from one login (with a free plan) — so it is neither Meta-only nor something you have to self-host. Meta, Facebook, Instagram, and other Meta brand names are trademarks of their respective owners.

[](https://github.com/user-attachments/assets/3e605cee-d289-414b-814c-6299e7f3383e)

[](https://lobehub.com/mcp/nictuku-meta-ads-mcp)

mcp-name: co.pipeboard/meta-ads-mcp

Community & Support

  • Discord. Join the community.
  • Email Support. Email us for support.

Table of Contents

  • The Pipeboard MCP Family
  • [🚀 Getting started with Remote MCP (Recommended for Marketers
Read from source at commit 393aac861297OBSERVED · 2026-09-25
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add meta-ads-mcp --env META_ACCESS_TOKEN=${META_ACCESS_TOKEN} --env META_APP_SECRET=${META_APP_SECRET} --env PIPEBOARD_API_TOKEN=${PIPEBOARD_API_TOKEN} -- uvx meta-ads-mcp
claude-desktop
{
  "mcpServers": {
    "meta-ads-mcp": {
      "command": "uvx",
      "args": [
        "meta-ads-mcp"
      ],
      "env": {
        "META_ACCESS_TOKEN": "${META_ACCESS_TOKEN}",
        "META_APP_SECRET": "${META_APP_SECRET}",
        "PIPEBOARD_API_TOKEN": "${PIPEBOARD_API_TOKEN}"
      }
    }
  }
}
03

Trust audit

CAUTIONgrade C · trust 73/100 Install with care. The audit found things worth knowing before you trust its output.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeWARN
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (2 observation(s))
Network
declared (2 observation(s))
Shell
none-observed
Dependencies
not all pinned
Secrets in source
found

Findings (25)

MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
meta_ads_mcp/core/auth.py:494
logger.error(f"TOKEN VALIDATION FAILED: Token appears malformed (length: {len(token)})")
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
meta_ads_mcp/core/auth.py:498
logger.debug(f"Access token found in auth_manager ({redact_secret(token)})")
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/test_http_auth_security.py:217
secret = "FAKE_ACCESS_TOKEN_VALUE_FOR_TEST_123"
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
tests/test_logging_does_not_leak_credentials.py:32
TOKEN = "EAAGabcdefghijklmnopqrstuvwxyz0123456789"
LOWInventory / provenance · inv.hidden_file · CWE-1104
.email-allowlist
.email-allowlist
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.uv.toml
.uv.toml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_save_ad_image_path_confinement.py:56
"../../../../tmp/evil",
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_save_ad_image_path_confinement.py:57
"ad_images/../../outside",  # traversal after a legitimate-looking prefix
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_save_ad_image_path_confinement.py:69
"../../../../tmp/evil",     # traversal through the filename
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_save_ad_image_path_confinement.py:70
"123/../../etc/passwd",
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/test_save_ad_image_path_confinement.py:81
@pytest.mark.parametrize("image_hash", ["../../evil", "a/b", "", "hash with spaces"])
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
tests/test_callback_server_state.py:29
def callback_url():
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
tests/test_callback_server_state.py:54
def test_code_without_state_is_rejected(callback_url):
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
tests/test_callback_server_state.py:57
response = httpx.get(f"{callback_url}/callback?code=attacker-code")
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
tests/test_callback_server_state.py:64
def test_code_with_wrong_state_is_rejected(callback_url):
LOWNetwork egress · net.beacon_words · CWE-200, CWE-319
tests/test_callback_server_state.py:67
response = httpx.get(f"{callback_url}/callback?code=attacker-code&state=guessed")
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
SECURITY.md:28
1918 address, or `http://169.254.169.254/` (cloud instance metadata) and make
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
SECURITY.md:36
link-local (incl. `169.254.169.254`), reserved, multicast, and unspecified
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
tests/test_ssrf_url_validation.py:40
"http://169.254.169.254/latest/meta-data/",  # cloud metadata (link-local)
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
tests/test_ssrf_url_validation.py:50
"https://169.254.169.254/",            # https also blocked
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
tests/test_ssrf_url_validation.py:155
req = httpx.Request("GET", "http://169.254.169.254/latest/meta-data/")
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
SECURITY.md:27
host, or IP validation. A caller could supply `http://127.0.0.1/...`, an RFC
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
SECURITY.md:28
1918 address, or `http://169.254.169.254/` (cloud instance metadata) and make
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/test_ssrf_url_validation.py:38
"http://127.0.0.1/poc.jpg",            # loopback
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/test_ssrf_url_validation.py:39
"http://127.0.0.1:9009/x",             # loopback w/ port

Gates applied: no_behavioural_pass.

Audited 2026-09-25 · audit v0.4.1 · source sha 393aac861297full audit observations/trust-audit/mcp-server/pipeboard-co__meta-ads.json · Report an issue / request a re-scan
04

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-09-25393aac861297CAUTIONC73first audit
05

Questions

What is the Meta Ads MCP server?

Meta Ads (Facebook/Instagram) MCP server for Claude, ChatGPT, Perplexity & Cursor — the Meta node of Pipeboard’s 5-platform family (+ Google, TikTok, Snap, Reddit). Hosted remote MCP, badged Meta Business Partner, free plan — no self-hosting required.

Is Meta Ads safe to connect to an agent?

With care. The audit graded it C (73/100) and found 25 things worth knowing before you trust this server, listed below with the exact line each was found on.

What credentials does Meta Ads need?

It reads META_ACCESS_TOKEN, META_APP_SECRET and PIPEBOARD_API_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does Meta Ads run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on PyPI as meta-ads-mcp.

How current is this page?

The grade is for one exact copy of the source (393aac861297), read on 2026-09-25. The repository is watched and re-audited when it changes.

Advertisement