linkedin-ads-audit — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited linkedin-ads-audit (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Perform a comprehensive LinkedIn Ads account audit using live data from the connected LinkedIn Ads MCP.
/linkedin-ads-audit — audit the connected LinkedIn Ads account
LinkedIn Ads is required; everything else sharpens the verdict. Call mcp__cogny__list_integrations once and name any unhealthy integration in the report.
| Job | Primary | Also answers it | What differs |
|---|---|---|---|
| Structure, targeting, creatives, spend | LinkedIn Ads | — | No substitute; this skill audits LinkedIn only |
| Pipeline / revenue per campaign | Fibbler (app-fibbler-co) | LinkedIn tool_get_conversions + analytics | Fibbler matches campaigns to CRM deals (impression-matched influence, not last click); LinkedIn only sees on-platform conversions |
| Who the ads reached (titles) | Fibbler get_audience_titles | LinkedIn tool_get_analytics with pivot: "MEMBER_JOB_TITLE" | Fibbler adds whether each title is currently included/excluded; LinkedIn's demographic pivots return impressions, clicks and engagements only (no cost) |
| Target-account coverage (ABM) | LinkedIn tool_get_company_engagement + CRM account list | HubSpot, Pipedrive or Upsales as the list source; Fibbler get_company_engagement if the LinkedIn tool is missing | Matching is done by the tool (page slug → domain → name); LinkedIn drops companies with <3 events, so absence isn't proof of no exposure |
list_integrations can read healthy for a revoked LinkedIn token. Step 1's tool_list_ad_accounts is the cheap read: if it (or any later LinkedIn call) returns 401, "unauthorized", Forbidden or a scope error, mark LinkedIn Ads 🔴 and stop the audit. Don't retry the call and don't run the remaining steps on partial data./linkedin-ads-audit.create_ticket, title "[Critical] Reconnect LinkedIn Ads — token revoked", expected_outcome "LinkedIn Ads reads succeed and the audit can run"; Solo: create_finding). One ticket per run, not one per failed call.tool_get_company_engagement isn't exposed by the workspace (older connections cache their tool list), call mcp__cogny__refresh_mcp_discovery once, then use Fibbler get_company_engagement for this run if Fibbler is connected, and mark the source ⚠ "needs reconnect". Without Fibbler, skip target-account coverage with a one-line note. Never loop on refresh.Report money in the account's own currency (tool_list_ad_accounts returns it). The benchmarks below are USD; convert before scoring, and never add Fibbler pipeline to LinkedIn-reported conversion value.
Use these LinkedIn Ads benchmarks for scoring:
| Metric | Poor | Average | Good |
|---|---|---|---|
| CTR | <0.3% | 0.4-0.6% | >0.8% |
| CPC | >$10 | $5-8 | <$4 |
| CPM | >$40 | $25-35 | <$20 |
| Conversion Rate | <1% | 2-4% | >5% |
| Engagement Rate | <0.3% | 0.5-1% | >1.5% |
If no mcp__cogny__* tools exist (no list_integrations, no cogny_status), print this and stop before calling anything else:
LinkedIn Ads Audit needs your marketing data through Cogny's MCP gateway.
1. Sign up at https://cogny.com and connect LinkedIn Ads (plus Fibbler and HubSpot,
Pipedrive or Upsales if you use them).
2. Add Cogny to .mcp.json in your project:
{"mcpServers": {"cogny": {"type": "http", "url": "https://app.cogny.com/mcp"}}}
3. Restart Claude Code; it opens a browser for the OAuth login on first use.
Nothing to run without Cogny.If Cogny is connected but mcp__cogny__mcp__LinkedIn_Ads__tool_list_ad_accounts is missing, say "connect LinkedIn Ads in Cogny" and stop. A revoked or broken connection is handled under Failure handling above ("reconnect LinkedIn Ads in Cogny").
Call mcp__cogny__mcp__LinkedIn_Ads__tool_list_ad_accounts. If multiple exist, note which is active and its currency.
Campaigns, creatives and metrics then come from tool_get_campaign_groups, tool_get_campaigns (ad_account_id, status_filter: ["ACTIVE", "PAUSED"]), tool_get_creatives and tool_get_analytics (ad_account_id, start_date, end_date, pivot: "CAMPAIGN" or "CREATIVE", time_granularity: "ALL" or "MONTHLY"). Cost comes back as costInLocalCurrency.
Get all campaigns (active + recently paused). For each:
Flag:
Across all active campaigns:
Flag:
For each active campaign, analyze:
Flag:
Enhanced when connected — who actually saw the ads:
get_audience_titles (scope: "by_campaign", time_period: "90d") lists the titles reached per campaign and whether each is targeted or excluded. Flag campaigns where >30% of impressions went to titles outside the ICP.tool_get_analytics with pivot: "MEMBER_JOB_TITLE" or "MEMBER_SENIORITY" (impressions, clicks, engagements only).Enhanced when connected — target-account coverage: pull the CRM's target or open-deal companies (HubSpot search_crm_objects on companies; Pipedrive list_organizations; Upsales list_accounts) and pass them as crm_records (id, name, domain) to mcp__cogny__mcp__LinkedIn_Ads__tool_get_company_engagement (ad_account_id, start_date, end_date = the audit window). If that tool is missing, use mcp__cogny__mcp__app-fibbler-co__get_company_engagement instead (⚠, see Failure handling) and match its companies to the CRM list yourself. Report % of target accounts reached and engaged. If several CRMs are connected, report each list separately.
Analyze ad creatives across campaigns:
Flag:
Check:
Flag:
Enhanced when connected — pipeline, not just clicks (Fibbler):
get_deal_attribution_summary (source: "LINKEDIN", time_period: "last_quarter", compare: true): influenced pipeline, won revenue, cost per opportunity.get_campaign_performance (sort_by: "influenced_pipeline", time_period: "90d"): spend vs influenced pipeline per campaign.get_deal_campaign_breakdown (group_by: "campaign", source: "LINKEDIN"): which campaigns touch deals that close.Flag campaigns with top-quartile spend and zero influenced deals in 90 days, and campaigns with poor CTR but strong influenced pipeline (don't cut those on CTR alone). Fibbler uses calendar quarters and its own period echo; quote the period it returns. Its pipeline is influence, not credit: never sum it across channels or add it to LinkedIn conversion value.
For each campaign:
Flag:
Present as a scored audit:
LinkedIn Ads Audit
Score: X/100
Campaign Structure: X/20
- [PASS/FAIL] Campaign organization
- [PASS/FAIL] Objective alignment
- [PASS/FAIL] Budget allocation
Targeting: X/20
- [PASS/FAIL] Audience specificity
- [PASS/FAIL] Audience overlap
- [PASS/FAIL] Exclusions
Creative: X/20
- [PASS/FAIL] Format diversity
- [PASS/FAIL] Creative freshness
- [PASS/FAIL] A/B testing
Performance: X/20
- [PASS/FAIL] CPC vs benchmark
- [PASS/FAIL] CTR vs benchmark
- [PASS/FAIL] Conversion rate
Tracking & Budget: X/20
- [PASS/FAIL] Conversion tracking
- [PASS/FAIL] Budget pacing
- [PASS/FAIL] Attribution setup
- [PASS/FAIL/N/A] Spend reaches pipeline (Fibbler; N/A when not connected)
Top 3 Actions:
1. [Highest impact fix]
2. [Second highest]
3. [Third highest]For EVERY actionable issue found, record it. On Cloud call mcp__cogny__create_ticket first (fields mapped per section 2 of the routing guide); on Solo call mcp__cogny__create_finding:
{
"title": "High CPC on 'Decision Makers' campaign ($12.40 vs $5-8 benchmark)",
"body": "Campaign targeting C-suite titles with single image ads. CPC is 55% above LinkedIn average. Recommend: 1) Test carousel format 2) Narrow to VP+ titles only 3) Add company size >500 filter",
"action_type": "campaign_optimization",
"expected_outcome": "Reduce CPC to <$8 within 2 weeks",
"estimated_impact_usd": 800,
"priority": "high"
}Action types for LinkedIn Ads:
campaign_optimization — budget, bidding, pacing changestargeting_refinement — audience, exclusion, geo changescreative_refresh — new ads, format tests, copy updatesconversion_tracking — pixel, events, attribution fixesaudience_management — overlap, expansion, exclusion updatesUse create_ticket when the workspace has it (Cloud) and create_finding otherwise (Solo). The fields differ; see section 2 of ../marketing-engineer/references/mcp-routing.md.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.