Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Flin Linkedin Ads

БесплатноНе проверен

A read-only MCP server for LinkedIn Ads that enables users to query ad accounts, campaigns, creatives, insights, and company intelligence via natural language.

GitHubEmbed

Описание

A read-only MCP server for LinkedIn Ads that enables users to query ad accounts, campaigns, creatives, insights, and company intelligence via natural language.

README

flin-linkedin-ads-mcp ist ein strikt read-only MCP Server für LinkedIn Ads. Er ist dafür gebaut, direkt in Claude über MCP eingebunden und getestet zu werden.

Features

  • Read-only Zugriff auf LinkedIn Ads Daten
  • Ad Accounts lesen
  • Campaign Groups lesen
  • Campaigns lesen
  • Creatives lesen
  • Share-Content lesen (get_share_content, best effort für Bild-URLs)
  • Insights/Analytics lesen
  • Company Intelligence lesen (/accountIntelligence, private API Access nötig)
  • Keine Schreiboperationen in v0.1.x

Scope v0.1.x (strict read-only)

  • Kein Create/Update/Delete
  • Kein Pause/Resume
  • Kein generischer Proxy-Endpunkt
  • Kein eingebauter OAuth-Refresh-Flow im MCP selbst

Direkt in Claude testen

Variante A: Lokal aus diesem Repo (empfohlen zum Entwickeln)

In Claude:

  1. Settings öffnen
  2. Developer öffnen
  3. MCP Config bearbeiten
  4. Diesen Server eintragen:
{
  "mcpServers": {
    "flin-linkedin-ads-mcp-local": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/Users/nicolasg/Antigravity/flin-linkedin-ads-mcp",
        "flin-linkedin-ads-mcp"
      ],
      "env": {
        "LINKEDIN_ACCESS_TOKEN": "AQX...",
        "LINKEDIN_API_VERSION": "202603",
        "LINKEDIN_RESTLI_PROTOCOL_VERSION": "2.0.0"
      }
    }
  }
}

Danach Claude neu starten.

Variante B: Via uvx (wenn Paket publiziert ist)

{
  "mcpServers": {
    "flin-linkedin-ads-mcp": {
      "command": "uvx",
      "args": ["--refresh", "flin-linkedin-ads-mcp"],
      "env": {
        "LINKEDIN_ACCESS_TOKEN": "AQX...",
        "LINKEDIN_API_VERSION": "202603",
        "LINKEDIN_RESTLI_PROTOCOL_VERSION": "2.0.0"
      }
    }
  }
}

2-Minuten Smoke Test in Claude

Nach dem Restart in Claude diese Calls testen:

  1. list_ad_accounts
  2. list_campaigns
  3. get_insights mit pivot=campaign

Wenn list_campaigns eine Auswahl zurückgibt, den Call mit einem vorgeschlagenen ad_account_id wiederholen.

Hinweis zu get_insights:

  • Der MCP nutzt den LinkedIn analytics Finder mit Single-Pivot.
  • Implementierung ist auf die Dokumentation view=li-lms-2026-03 ausgerichtet.
  • date_from ist Pflicht (LinkedIn adAnalytics erwartet dateRange).
  • Unterstützte fields folgen der Metrics-Tabelle aus der offiziellen Reporting-Schema-Doku (max. 20 Felder pro Request).
  • Der Server nutzt intern pivot.value / timeGranularity.value und hat zusätzlich einen Fallback auf Legacy-Parameternamen für bessere API-Kompatibilität.
  • Neuere Video/Event-Felder sind enthalten, z. B. videoWatchTime, averageVideoWatchTime, eventViews, eventWatchTime, averageEventWatchTime.

Beispiel für einen stabilen Test-Call:

{
  "ad_account_id": "508834004",
  "date_from": "2025-08-01",
  "date_to": "2025-12-31",
  "fields": [
    "impressions",
    "clicks",
    "costInLocalCurrency",
    "dateRange"
  ],
  "pivot": "account",
  "time_granularity": "MONTHLY"
}

get_insights Parameter (2026-03)

Wichtigste Parameter:

  • pivot: z. B. account, campaign_group, campaign, creative, member_company_size, member_industry, member_seniority, member_job_title, member_job_function, member_country_v2, member_region_v2, member_company, member_county, share, company, conversion
  • time_granularity: DAILY, MONTHLY, ALL, YEARLY
  • fields: Liste aus der offiziellen Metrics-Tabelle, maximal 20 Einträge, case-sensitive
    • Kompatibilitätsfelder: pivotValuepivotValues, clickThroughRate (berechnet als clicks / impressions), costPerClick (berechnet als costInLocalCurrency / clicks)
  • date_from: YYYY-MM-DD (Pflicht)
  • date_to: optional, YYYY-MM-DD

Facets/Filter:

  • ad_account_id (ein Konto) oder account_ids (mehrere Konten)
  • optional zusätzlich: campaign_ids, campaign_group_ids, creative_ids, share_ids, company_ids
  • optional: campaign_type, objective_type
  • optional Sortierung: sort_by_field + sort_order (müssen zusammen angegeben werden)

Kompatibilität:

  • entity_ids bleibt für Backward-Kompatibilität erhalten (z. B. bei pivot=campaign).

list_creatives / get_creative Bild-URL (optional)

Für Creative-Calls kann optional das Derived-Field imageUrl in fields angefordert werden.

  • imageUrl wird bevorzugt direkt aus dem Creative-content extrahiert.
  • Falls dort keine Bild-URL enthalten ist und eine content.reference auf urn:li:adDirectSponsoredContent:* zeigt, versucht der MCP zusätzlich eine Auflösung über adDirectSponsoredContents/{urn}.
  • Falls dort keine Bild-URL enthalten ist und eine Share-Referenz vorhanden ist, versucht der MCP zusätzlich eine Auflösung über die referenzierte Share/Post-Entity.
  • Wenn keine Bild-URL auflösbar ist, ist imageUrl null.

Beispiel:

{
  "ad_account_id": "508834004",
  "id": "urn:li:sponsoredCreative:935973186",
  "fields": ["id", "name", "imageUrl"]
}

list_account_intelligence (202603)

Neues Tool:

  • list_account_intelligence

Dieser Endpunkt nutzt GET /rest/accountIntelligence?q=account und ist laut LinkedIn private API (zusätzliche Freischaltung erforderlich).

Wichtige Parameter:

  • ad_account_id (oder Auto-Resolve bei genau einem Account)
  • lookback_window: LAST_7_DAYS, LAST_30_DAYS, LAST_60_DAYS, LAST_90_DAYS
  • optional: ad_segment_ids, campaign_id
  • optional: skip_company_decoration
  • optional: page_start, page_size (max. 1000)

Wichtige Response-Felder:

  • companyName, engagementLevel
  • paidImpressions, paidClicks, paidEngagements, paidLeads
  • paidQualifiedLeads, conversions (ab API-Version 202603)
  • organicImpressions, organicEngagements

Beispiel:

{
  "ad_account_id": "508834004",
  "lookback_window": "LAST_30_DAYS",
  "page_size": 100
}

get_share_content (best effort)

Neues Tool:

  • get_share_content

Wichtige Parameter:

  • share_urn (Pflicht, Format urn:li:share:<id>)
  • include_raw (optional, true gibt zusätzlich das rohe API-Payload zurück)

Response enthält u. a.:

  • share_urn, source_endpoint (shares oder posts)
  • post_url (LinkedIn Feed URL)
  • text
  • image_url (erstes gefundenes Bild oder null)
  • image_urls, thumbnail_urls

Beispiel:

{
  "share_urn": "urn:li:share:7379073146093568000",
  "include_raw": false
}

Troubleshooting get_insights

Bei ILLEGAL_ARGUMENT oder RESOURCE_NOT_FOUND bitte prüfen:

  1. Feldnamen sind exakt korrekt (clicks statt click, impressions statt impression).
  2. Maximal 20 fields.
  3. Mindestens ein gültiger Facet-Filter (ad_account_id/account_ids oder andere Facets).
  4. IDs im korrekten Format (Account/Campaign/Campaign Group/Creative numerisch oder URN; share_ids und company_ids als URN).
  5. Datum im Format YYYY-MM-DD.
  6. date_from ist gesetzt (ohne dateRange antwortet LinkedIn oft mit ILLEGAL_ARGUMENT).
  7. pivot ist einer der dokumentierten Werte (siehe oben).

Schneller API-Gegencheck (ohne MCP) für das Token:

curl -i 'https://api.linkedin.com/rest/adAccounts?q=search&pageSize=1' \
  -H 'Authorization: Bearer DEIN_ACCESS_TOKEN' \
  -H 'Linkedin-Version: 202603' \
  -H 'X-Restli-Protocol-Version: 2.0.0'

LinkedIn Access Token generieren (Schritt für Schritt)

Voraussetzung:

  • LinkedIn Developer App vorhanden
  • Marketing API Zugriff für die App freigeschaltet
  • Scope r_ads für Entities (Accounts/Campaigns/Creatives)
  • Scope r_ads_reporting für get_insights
  • Die Ad Accounts sind in der Developer App unter Products -> View Ad Accounts gemappt
  • Der authentifizierte User hat eine Ad-Account-Rolle (mind. VIEWER)

1) App in LinkedIn Developer Portal vorbereiten

  • In der App unter Auth:
    • Client ID und Client Secret notieren
    • Redirect URL hinzufügen, z. B. http://localhost:9876/callback
  • In der App sicherstellen, dass die Marketing/Ads Berechtigungen aktiviert sind (r_ads + r_ads_reporting)

2) Authorization Code holen

Im Browser öffnen (Werte ersetzen, redirect_uri URL-encoden).

Für diesen MCP müssen im Scope mindestens enthalten sein:

  • r_ads (Accounts/Campaigns/Creatives)
  • r_ads_reporting (get_insights)

Optional (nur wenn deine App dafür freigeschaltet ist):

  • offline_access (für Refresh-Token-Flow)

Empfohlene URL für den MCP (ohne Refresh-Token):

https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=DEIN_CLIENT_ID&redirect_uri=http%3A%2F%2Flocalhost%3A9876%2Fcallback&scope=r_ads%20r_ads_reporting&state=dein_csrf_state

Variante mit optionalem offline_access:

https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=DEIN_CLIENT_ID&redirect_uri=http%3A%2F%2Flocalhost%3A9876%2Fcallback&scope=r_ads%20r_ads_reporting%20offline_access&state=dein_csrf_state

Nach Login/Consent leitet LinkedIn auf deine Redirect-URL zurück:

http://localhost:9876/callback?code=AUTH_CODE&state=dein_csrf_state

Den code aus der URL kopieren.

3) Authorization Code gegen Access Token tauschen

curl -X POST 'https://www.linkedin.com/oauth/v2/accessToken' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'code=AUTH_CODE' \
  --data-urlencode 'redirect_uri=http://localhost:9876/callback' \
  --data-urlencode 'client_id=DEIN_CLIENT_ID' \
  --data-urlencode 'client_secret=DEIN_CLIENT_SECRET'

Beispiel-Response:

{
  "access_token": "AQX...",
  "expires_in": 5183999
}

access_token als LINKEDIN_ACCESS_TOKEN in die Claude MCP Config übernehmen.

Wichtig: Bei diesem MCP erfolgt Authentifizierung über env in der MCP Config. Es gibt hier keinen eingebauten OAuth-Refresh-Flow im Server selbst. Wenn der Token abläuft, musst du einen neuen Token erzeugen und in der Config ersetzen.

4) Ablauf / Erneuerung

  • Access Tokens laufen typischerweise nach ca. 60 Tagen ab.
  • Dann OAuth-Flow erneut durchführen.
  • Falls deine App für programmatic refresh tokens freigeschaltet ist, kannst du stattdessen per Refresh Token erneuern.

5) 401/403 schnell diagnostizieren

Token gegen Ads-Account-Endpunkt testen:

curl -i 'https://api.linkedin.com/rest/adAccounts?q=search&pageSize=1' \
  -H 'Authorization: Bearer DEIN_ACCESS_TOKEN' \
  -H 'Linkedin-Version: 202603' \
  -H 'X-Restli-Protocol-Version: 2.0.0'

Interpretation:

  • 401 Unauthorized: Token abgelaufen, widerrufen oder falscher Scope-Set wurde neu konsentiert
  • 403 Forbidden: Token ist gültig, aber Scope/Rolle/App-Mapping fehlt
  • 200 OK: Auth grundsätzlich korrekt

Environment Variablen

Pflicht:

  • LINKEDIN_ACCESS_TOKEN

Optional:

  • LINKEDIN_API_VERSION (Default: 202603)
  • LINKEDIN_RESTLI_PROTOCOL_VERSION (Default: 2.0.0)
  • LINKEDIN_TIMEOUT_SECONDS (Default: 30)
  • LINKEDIN_MAX_RETRIES (Default: 3)

Lokale Entwicklung

cd /Users/nicolasg/Antigravity/flin-linkedin-ads-mcp
python -m pip install -e ".[dev]"
pytest -q
ruff check .
mypy src

Sicherheit (wichtig)

  • Niemals LINKEDIN_ACCESS_TOKEN oder OAuth Secrets ins Repo committen
  • .env ist bereits in .gitignore
  • Token nur über MCP env in Claude oder über lokale Shell-Umgebung setzen
  • Vor jedem Push prüfen:
git status
git diff -- .env

Wenn eine Datei mit Secrets auftaucht: Commit abbrechen und Secrets rotieren.

GitHub Actions & Release (PyPI-ready)

Dieses Repo enthält:

  • CI Workflow: .github/workflows/ci.yml
  • Release Workflow: .github/workflows/release.yml

Der Release-Workflow macht bei v* Tags:

  1. Lint + Typecheck + Tests
  2. Build + twine check
  3. Trusted Publishing zu PyPI
  4. GitHub Release mit dist/* Artefakten

Node-20-Deprecation-Warnungen sind abgefangen durch:

  • aktuelle Actions-Majors (checkout@v6, setup-python@v6)
  • FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true in beiden Workflows

PyPI Trusted Publisher einmalig einrichten

  • PyPI Project: flin-linkedin-ads-mcp
  • Owner: flin-agency
  • Repository: flin-linkedin-ads-mcp
  • Workflow: release.yml
  • Environment: pypi

Release auslösen

git add -A
git commit -m "release: v0.1.0"
git tag v0.1.0
git push origin main --tags

Offizielle Referenzen

from github.com/flin-agency/flin-linkedin-ads-mcp

Установка Flin Linkedin Ads

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/flin-agency/flin-linkedin-ads-mcp

FAQ

Flin Linkedin Ads MCP бесплатный?

Да, Flin Linkedin Ads MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Flin Linkedin Ads?

Нет, Flin Linkedin Ads работает без API-ключей и переменных окружения.

Flin Linkedin Ads — hosted или self-hosted?

Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.

Как установить Flin Linkedin Ads в Claude Desktop, Claude Code или Cursor?

Открой Flin Linkedin Ads на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Flin Linkedin Ads with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории development