Skip to main content
Glama
605,552 tools. Updated 2026-09-24 00:54

"How to interact with people on LinkedIn" matching MCP tools:

  • Enrich existing contacts with their full LinkedIn profile data via the connected LinkedIn account (Unipile) — headline, location, current company & position, full experience, education and skills are scraped from each contact's profile URL and saved onto the contact (and merged into profile_data). Use after search_google_xray to flesh out lightly-saved leads. Each contact is a real LinkedIn profile view, so keep batches small; max 8 per call. Returns per-contact enrichment status.
    ConnectorNo auth
  • Cheap look at the actual people behind a count, before committing to a full search. BILLABLE — about $0.002 per returned row (Tier 0 list price; your account may pay a different rate — call get_balance for your real prices, and read cost.amount_charged in every response for what was actually spent). Preview rows carry a Generect `id`, so the intended flow is: preview many → pick the few that fit → enrich_lead / generate_email only on those. Per the API contract preview rows are masked (no LinkedIn URL, domain, email or phone); if your account returns more than that, treat it as a bonus and not something to rely on.
    ConnectorOAuth
  • <summary>Search LinkedIn for people — by name, by a specific person's connections, or by profile filters — and return the matching profiles. Provide `keywords` (a name or search term) or a scope filter (`connections_of` / `advanced_keywords`). One call runs one query, returning ~10 matches by default (one page). To go deeper on a single query — "find people in my network matching my ICP" — pass `max_results` (up to 100): the tool pages through the matches for you, each ~10-profile page counting as one search against the daily budget. To search *different* people — a list of names, or one filter per company — loop this tool inside a `run_code` block, one call per name or company (that's breadth; `max_results` is depth on one query). Searches are paced a few seconds apart and serialized across this user's LinkedIn work, so a deep search or a long loop can take a couple of minutes; tell the user to expect a short wait before a large run. If a search comes back paused or rate-limited, stop and tell the user which searches remain — the account is paused and further calls won't run until it lifts. Scope filters combine with `keywords` and can be used alone for a single filtered search: - `connections_of` — restrict to the first-degree connections of specific people, passed as their `provider_id`s (as returned by an earlier search or profile lookup). To work up to a buyer through someone the user just connected with, pass that person in `connections_of` and the target company in `advanced_keywords={'company': 'Acme Corp'}` to surface who they know there. `network_distance` is a separate filter on the user's *own* degree and combines with this — add [2] to keep just the connections the user isn't already directly linked to. - `advanced_keywords` — native LinkedIn keyword sub-filters: a dict with any of `first_name`, `last_name`, `title`, `company`, `school` (each a string). - `profile_language` — ISO 639-1 codes (e.g. ['en']) that narrow any of the above to profiles written in those languages. A refinement, not a search on its own — pair it with keywords or another filter. When this runs in an agent, the matches are saved and linked to the workspace Output tab automatically (deduped by profile). Pass `list_name` (a short slug) to name their list — a discovery search, the people connected to someone, prospects to work through; reuse the same slug across a loop or follow-up searches to gather everything into one list. Absent a slug, matches land in the 'default' list. Outside an agent, results are returned only. Returns up to `max_results` matching profiles with provider_id, name, headline, network_distance, location, and profile_url — each match's `headline` shows their current role and company (e.g. to see which companies 2nd-degree matches work at). `total_count` is LinkedIn's full match count for the query when it returns one, but LinkedIn now omits it on most Classic searches (so it's often null): only say "showing N of ~M" when it's a number exceeding the profiles returned, and never invent a total. Use `has_more` — True when more results exist beyond those returned — to decide whether to offer to pull more. Present the results to the user so they can pick the right person. An `error` about being "heavily queued" is transient pacing back-pressure — retry shortly rather than reporting it as not found. That field list is the whole of it — a search result carries no connection count, follower count, or employment history. Present what comes back as it is; a search the user wanted to look at is finished at that point. When the ask genuinely needs one of the missing fields — a connection-count threshold, employment history to personalize from — pass the matches' profile URLs to `enrich_linkedin_profiles`, which returns them for the whole list in one paid call (`connections_count` is the field a connection-count filter reads) and spends no LinkedIn account budget. When the decision also turns on whether the user is already connected to them, use `setup_linkedin_sequence(action_type='resolve')` instead; connection status is the one thing enrichment cannot answer. Rate-limited — shares one daily LinkedIn search budget with all other LinkedIn people searches.</summary> <returns> <description>On success, a dict `{'success': True, 'profiles': [...], 'total_count': int | None, 'has_more': bool, 'searches_remaining_today': int}`. `profiles` holds up to `max_results` matches; `total_count` is the query's full match count when LinkedIn returns one (often null since its Aug-2026 Classic Search change), so lean on `has_more` for whether more results exist; and `searches_remaining_today` is the post-search budget, so you can size a follow-up loop without re-checking. In an agent, also `saved_to_list` (the list the matches were saved to) and `saved_count`; outside an agent, a passed `list_name` yields a null `saved_to_list` with a `persist_note`. If the account tripped its pause partway through paging, the (still valid) partial results come back with `paused: True` and a `note` — surface it: further searches won't run until the pause lifts. On a failed search: `{'success': False, 'profiles': [], 'error': ..., 'searches_remaining_today': int}`. On a pre-flight refusal (daily limit reached or account paused), `searches_remaining_today` is omitted: `{'success': False, 'error': ...}`.</description> </returns>
    ConnectorOAuth
  • Lists LinkedIn Ads entities of any type (LinkedIn Ads tool). IMPORTANT — LinkedIn UI naming vs API naming: - LinkedIn UI "Campaigns" = API "campaign_groups" (use entity_type="campaign_groups") - LinkedIn UI "Ad sets" = API "campaigns" (use entity_type="campaigns") - LinkedIn UI "Ads" = API "creatives" (use entity_type="creatives") When a user asks about "campaigns", they usually mean campaign_groups. entity_type options: - "campaign_groups": Lists campaigns (LinkedIn UI name). Supports status filter: ACTIVE, PAUSED, ARCHIVED, DRAFT. Supports include_performance with start_date/end_date. - "campaigns": Lists ad sets (LinkedIn UI name). Supports status filter and campaign_group_id to show ad sets under a specific campaign. - "creatives": Lists ads (LinkedIn UI name) with format detection (DOCUMENT, VIDEO, SINGLE_IMAGE, CAROUSEL, etc.). Supports campaign_ids filter and include_content. IMPORTANT: When status="ACTIVE", auto-filters to only include ads from ACTIVE ad sets — so you get truly serving ads. - "conversions": Lists conversion tracking rules. Status filter = enabled_only (pass status="enabled"). - "campaign_conversions": Lists conversion-rule ↔ campaign associations. Requires campaign_ids. Returns one row per (campaign_id, conversion_id) pairing. - "lead_forms": Lists lead generation forms. Supports status filter: DRAFT, PUBLISHED, ARCHIVED. - "saved_audiences": Lists matched/DMP audiences. Paginates fully across the account (no 10-row cap). Returns the LINKEDIN destination's status as `status` (typical values: READY, BUILDING, PROCESSING, ARCHIVED, FAILED) plus `destinationSegmentId` (the `urn:li:adSegment:...` URN to use in targeting criteria). Supports `name_contains` for client-side substring search (matched audiences are NOT typeahead-searchable via the LinkedIn API — list and filter is the supported pattern). - "targeting_audiences": Lists saved targeting audience templates. Supports name_contains. - "targeting_facets": Lists all available targeting facets/dimensions. No account_id needed. Args: entity_type: What to list. One of: campaign_groups, campaigns, creatives, conversions, lead_forms, saved_audiences, targeting_audiences, targeting_facets. account_id: The LinkedIn Ad Account ID (required for most entity types, not needed for targeting_facets). status: Optional status filter (meaning varies by entity type). For creatives with status="ACTIVE", cascades through campaign status. campaign_ids: Optional campaign ID filter (for creatives/ads). campaign_group_id: Optional campaign group ID filter (for campaigns/ad sets — show ad sets under a specific campaign). include_content: Include raw content details for creatives. Default: false. include_performance: Include performance metrics for campaign_groups (requires start_date/end_date). Default: false. start_date: Start date for performance data (YYYY-MM-DD). end_date: End date for performance data (YYYY-MM-DD). limit: Maximum number of results to return. Default: 100. name_contains: Case-insensitive substring filter on entity name (saved_audiences, targeting_audiences).
    ConnectorOAuth
  • Search LinkedIn people. RECOMMENDED FOR PROSPECTING: set decisionMakers:true, provide company, departments and limit 20-30. Salesbot resolves the company, performs ONE company-scoped provider search (Sales Navigator also applies seniority), then ranks the returned senior employees locally by department. This is broader and safer than retrying exact titles. Use title/titles only when an exact role is required. EXISTING CONNECTIONS reads only the local cache and consumes zero search quota. The workspace setting selects Standard/Classic or Sales Navigator automatically. Respect retry_after; never immediately retry a protected or timed-out request. On LINKEDIN_PROVIDER_TIMEOUT use search_google_xray, then retry LinkedIn only after the stated delay.
    ConnectorNo auth
  • Send a one-off LinkedIn message to a specific saved contact outside any campaign. Prefer contact_id; Salesbot resolves the LinkedIn identifier internally. A random delay, daily/hourly limits, allowed hours and human approval are enforced. Refused with code DUPLICATE_RECENT_MESSAGE (and the campaign name + date) when a campaign of this LinkedIn account already messaged the person within the last 30 days; to continue an existing conversation use reply_to_chat.
    ConnectorNo auth

Matching MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Local-first memory for AI agents about the people in your life. MCP server + CLI on SQLite. Never phones home.
    41
    55
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Open MCP server for AI agents to discover people, jobs, collaborators and projects through semantic search over human-published context.
    MIT

Matching MCP Connectors

  • LinkedIn: The LinkedIn Data API offers access to detailed information on individuals, companies.

  • LinkedIn data for AI agents: search, profiles, companies, posts. Free key, self-minted, no signup.

  • Compute the tip and per-person split for a bill. FREE. Typical input {"bill": 86.40, "tip_pct": 20, "people": 4} returns {"tip": 17.28, "total": 103.68, "per_person": 25.92}. Use for one bill shared among a group. Not for recurring household budgeting (budget_split). Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "bill must be > 0 and people >= 1"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
    ConnectorNo auth
  • Compute the tip and per-person split for a bill. FREE. Typical input {"bill": 86.40, "tip_pct": 20, "people": 4} returns {"tip": 17.28, "total": 103.68, "per_person": 25.92}. Use for one bill shared among a group. Not for recurring household budgeting (budget_split). Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "bill must be > 0 and people >= 1"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
    ConnectorNo auth
  • List multi-step email sequences and how many people are currently in each, with the id each one is enrolled by. Newest first, at most 100 per call; while has_more is true, next_cursor passed back as cursor returns the next page. A 'paused' automation holds its people on their current step rather than ending their sequence: they stay 'active' and continue from that step once it is active again. list_automation_enrollments lists who is on one, and who left and why.
    ConnectorNo auth
  • Read a company's LinkedIn People page on one of the workspace's connected accounts (up to 1000 profiles, LinkedIn's own display ceiling; optionally filtered by job titles). Call this when the user asks who works at a company, or wants a company's people turned into leads. Employees land as shared leads tied to the company - re-running updates them, never duplicates. They are NOT added to any lead list; read them with campaignstack_list_company_employees and act with campaignstack_add_leads_to_list. The job runs in the background; one extraction per company at a time. Use campaignstack_list_companies to find company IDs.
    ConnectorAPI key
  • The user's LinkedIn post analytics from LinkedIn's own API (their connected account) — impressions, unique members reached, reactions, comments, and reshares. Use for questions like 'how many impressions did I get last month?' or 'how are my posts performing?'. Omit dates for lifetime totals; pass start_date/end_date for a window; set daily=true (with one specific metric) for a per-day series to describe trends. Numbers are live from LinkedIn, unlike get_my_linkedin_posts whose per-post counts come from a periodic sync.
    ConnectorNo auth
  • Search a global professional database in plain English (for example 'Heads of Marketing at Series B SaaS in New York') and get a sample of matching people plus the true total match count. Results are masked previews (a masked name, role, industry, company size and location) and each one carries an opaque `token`. Searching is FREE and spends no credits: use it to validate that the right people exist before you pay. To get a person's real name, LinkedIn and verified email, pass their token to reveal_profile, or use find_people to unlock a batch in one call.
    ConnectorNo auth
  • Synchronize one provider-safe page (at most 500) of the API-key owner's 1st-degree LinkedIn relations into the local workspace cache. This is a provider read, not a LinkedIn people search, and does not consume the search quota. The server persists continuation state and atomically enforces a 15–20 minute delay, four-page hourly cap, and twelve-page daily cap across UI and MCP. Respect RELATIONS_SYNC_PROTECTED retry_after_seconds before continuing.
    ConnectorNo auth
  • Returns who runs turva.dev and the official ways to reach it: the operator and business details, the email address, the Signal link, the LinkedIn profile, the correspondence languages, the first-reply time and the access an audit needs. Use this when a user asks who is behind turva.dev, how to contact it, how to start an audit or what access has to be granted. For what is sold and what it costs use get_services instead. Read-only: returns static JSON that is compiled into the Worker, so it changes nothing and updates only on deploy.
    ConnectorNo auth
  • <summary>Add and/or remove watched people on an existing `list`-mode LinkedIn monitor, incrementally — you pass only the profiles that are changing, never the whole list. `add` and `remove` are LinkedIn profile URLs or vanity slugs. A swap is one call (`add=[new]`, `remove=[old]`). Both forms of one profile (full URL and bare slug) collapse to a single watched member, so re-adding someone already watched is a no-op. The change takes effect on the monitor's next scheduled run. Use this instead of re-running `setup_linkedin_monitoring` whenever the user just wants to tweak who's watched ("also watch Bob", "drop Alice"): setup would force re-passing every existing member, and since each watched profile is billed per run, one dropped URL on the re-echo silently stops watching that person. To change schedule, voice, or the action flags, use `setup_linkedin_monitoring` (members are preserved there when omitted); adding the very first members or resetting the whole list is setup too.</summary> <returns> <description>Dict with status ('active'), name, members_count, added, removed, unresolved, and message.</description> </returns>
    ConnectorOAuth
  • <summary>Look up LinkedIn profiles in bulk — headline, title, company, location, connection count, follower count, plus the person's full employment and education history — for people you already have a LinkedIn URL, slug, or provider id for. Pass the whole list in one call; they are fetched in batches, not one at a time. This is the tool for questions about a list of people: filtering a list by connection count or seniority, labelling who works where, or filling in headlines before drafting. `experience` carries every role with its dates, so it also answers career-history questions — how long someone has been in seat, where they worked before, whether they were promoted internally, who is an alum of a given company — without a separate lookup. It does not touch the user's LinkedIn account, so it neither consumes their daily profile-lookup budget nor carries any account-safety risk — prefer it over per-person lookups whenever you have more than a couple of people to enrich. Costs 0.1 Sliq credits per profile returned; misses are free. A profile this user enriched in the last 24h is served from cache, so re-calling does not look up or charge again. Enriching a profile also links it to its primary employer's canonical company, which may need a one-time web-domain lookup: 0.05 credits the first time a given company is looked up (cached after, so it never charges twice for the same company). A batch spanning many unfamiliar employers costs a little beyond the per-profile total; fold that into any estimate you give the user. How many to run is a spend question: run a list of up to 500 straight away. Past 500, tell the user how many profiles it is and what that costs — the count times 0.1 credits — and wait for a go-ahead before running it; a batch that size also takes several minutes, so say so in the same breath. In a background run there is nobody to ask, so run it and report the spend in your summary. How to call it is a separate question, and the answer is almost always `run_code`. A direct return is truncated at 50KB, and one senior profile's career history can be a third of that on its own — so a direct call on a dozen executives shows you two of them, after charging for all twelve, since credits are spent inside the tool before anything is truncated. Only a handful of profiles fit. From `run_code` nothing is truncated: the rows stay in the sandbox and you print only the filter, count, or summary you need. Call it directly only for a few people whose full profiles you intend to read. What it cannot tell you: whether the user is already connected to someone, their network distance, or shared connections. Those describe the user's own relationship to the profile and only a LinkedIn-account lookup can answer them — use `setup_linkedin_sequence(action_type='resolve')` when the decision genuinely depends on connection status.</summary> <returns> <description>One entry per input, in input order — either a profile dict, or an `{'error': ...}` entry for a profile that could not be resolved. `experience` and `education` cover the person's whole history and are long for senior people — a 25-year career can run 20+ roles. They arrive in LinkedIn's display order, which is NOT sorted by date: roles at the same employer sit next to each other, so the first entry is not reliably the current one. Sort on `start_date.get('year')` when you need chronology. Consecutive entries at one employer are usually one tenure with internal promotions, but check the dates before saying so — a gap between them means they left and came back, which is a different story to tell. Dates are `{'year': 2014, 'month': 'Feb', 'text': 'Feb 2014'}`; `month` is missing when LinkedIn shows only a year, and a date can be empty entirely, so reach for `.get()` rather than indexing. An `end_date` of `{'text': 'Present'}` means the role is current, and someone can hold several at once.</description> </returns>
    ConnectorOAuth
  • Update the LinkedIn channel settings of an existing DRAFT wizard campaign: native objective, bidding optimization goal (including Reach), bid strategy with manual bid amount, and the LinkedIn conversion actions the campaign optimizes toward. These are the settings the platform UI shows in the LinkedIn channel drawer of the campaign draft page (Native Objective, Bidding Optimization Goal, Bid, Conversion Actions). The campaign MUST already have its LinkedIn channel enabled (via create_campaign / add_and_edit_campaign_elements with a `linkedin` block). WARNING: DRAFT-ONLY: the platform rejects these edits once the campaign is Launching/Launched. KEYWORDS: linkedin, linkedin campaign, linkedin settings, campaign settings, draft campaign, objective, native objective, brand awareness, website visits, engagement, video views, bidding optimization goal, optimization goal, reach, impressions, landing page clicks, engagement clicks, bid, bid strategy, auto bid, manual bid, maximum delivery, conversion, conversions, conversion actions, conversion tracking, insight tag, settings WHEN TO USE: - Set the LinkedIn native objective (e.g. Brand Awareness instead of the default Engagement) - Optimize a Brand Awareness campaign for REACH instead of IMPRESSIONS - Switch between auto bid (LinkedIn maximum delivery) and a manual bid - Pick which LinkedIn conversion actions the campaign optimizes toward and reports on PARAMETERS (campaign_id required; everything else optional, and an unspecified setting keeps its current value on the channel): - campaign_id: the wizard campaign ID - objective: BRAND_AWARENESS | WEBSITE_VISIT | ENGAGEMENT | VIDEO_VIEW, the LinkedIn native objective. Only selectable on Brand Awareness (CTR) campaigns: a Lead Gen (CPL) campaign derives it from its offer at launch (lead-gen form -> LEAD_GENERATION, landing page -> WEBSITE_CONVERSION). The platform default for a new LinkedIn channel is ENGAGEMENT. Every ad already on the channel must be supported by the objective (VIDEO_VIEW is video-only, MESSAGE ads only fit WEBSITE_VISIT, DOCUMENT ads lock the objective, a video-only channel accepts only ENGAGEMENT or VIDEO_VIEW). A channel holding CTV ads is always Brand Awareness / Reach at launch and cannot be changed here. Changing the objective also resets the cost type and the bidding optimization goal to the objective's default (BRAND_AWARENESS -> IMPRESSIONS, WEBSITE_VISIT -> LANDING_PAGE_CLICKS, ENGAGEMENT -> ENGAGEMENT_CLICKS, VIDEO_VIEW -> VIDEO_VIEWS), so pass bidding_optimization_goal in the same call when you want something else. - bidding_optimization_goal: what LinkedIn optimizes delivery for. Allowed per objective: BRAND_AWARENESS -> IMPRESSIONS | REACH; WEBSITE_VISIT -> LANDING_PAGE_CLICKS | IMPRESSIONS; ENGAGEMENT -> ENGAGEMENT_CLICKS | IMPRESSIONS; VIDEO_VIEW -> VIDEO_VIEWS | IMPRESSIONS. Conversation and Message ads are always IMPRESSIONS. CTR campaigns only. - bid_strategy: AUTO_BID (LinkedIn "maximum delivery", what the campaign builder applies by default) or MANUAL_BID (needs bid_amount). CTV ads REQUIRE AUTO_BID; Spotlight and Text ads REQUIRE MANUAL_BID. - bid_amount: manual bid in the account currency, used only with MANUAL_BID. - conversion_action_ids: ids of LinkedIn conversion actions (from list_linkedin_conversions) the campaign should optimize toward and count as conversions: website visits, URL-rule page views, lead form fills. REPLACES the current selection; pass [] to clear it (the campaign then falls back to the account's default Insight Tag URL match). Every id must exist and be enabled on the connected LinkedIn account, or launch validation fails. NOTE: the platform UI only shows this picker for campaigns with landing-page offers and an objective other than Brand Awareness; ids stored outside that case are still sent to LinkedIn at launch, but that path is not exercised by the UI. NOT SETTABLE ANYWHERE IN THE PLATFORM (say so instead of promising them): LinkedIn Audience Network on/off and its category exclusions, audience expansion (campaigns always launch with expansion OFF), frequency caps, Thought Leader ads. LinkedIn geo targeting is not a channel setting either: it lives on the audience / target group. EXAMPLES: Brand Awareness optimized for Reach on auto bid: update_linkedin_channel_settings({"campaign_id": 12345, "objective": "BRAND_AWARENESS", "bidding_optimization_goal": "REACH", "bid_strategy": "AUTO_BID"}) Track two conversion actions on a Website Visits campaign: update_linkedin_channel_settings({"campaign_id": 12345, "conversion_action_ids": ["123456", "234567"]}) RESPONSE: {success, campaign_id, channel_id, campaign_status, campaign_goal, channel_ad_types, applied:{...}, errors?}. `applied` echoes exactly what was pushed to the platform. INTEGRATION WITH OTHER TOOLS: - list_linkedin_conversions lists the conversion actions available on the account - search_campaigns_by_names / get_campaign_by_wizard_id to find the campaign - The LinkedIn channel is enabled by create_campaign or add_and_edit_campaign_elements - check_campaign_launch_readiness validates the result before launch
    Connector
    Destructive
    API key
  • Create a new or update an existing LinkedIn Document Ad on the Metadata platform. A LinkedIn Document Ad promotes a multi-page document (a PDF — e.g. a whitepaper, ebook, report, or guide) natively in the LinkedIn feed. Members preview the first few pages inline, then unlock the full document (typically gated behind a lead form). It is LinkedIn-only. IMPORTANT: This tool is ONLY for LinkedIn Document Ads (channelType=LINKEDIN, adType=DOCUMENT). For IMAGE/GIF ads use create_update_image_ad; for VIDEO ads use create_update_video_ad; for CONVO use create_update_convo_ad; for Sponsored Messaging use create_update_linkedin_message_ad. BEHAVIOR: - If `id` is NOT provided -> creates a new Document Ad. - If `id` IS provided -> updates the existing Document Ad with that ID. CREATIVE WORKFLOW (MUST DO BEFORE CALLING): 1. The document must already exist in the creative library as a DOCUMENT asset. Find it with `search_library_creatives_by_name(contentTypes="DOCUMENT")`, or confirm a specific id with `fetch_creative_details`. 2. Pass that asset's integer id as `libraryId`. It MUST be a DOCUMENT-type creative — an image or video id will be rejected by LinkedIn. Unlike IMAGE/VIDEO ads there is NO display URL: the gated document is the destination, so no link field is accepted. CHARACTER LIMITS (mirror the LinkedIn ad limits the platform UI enforces): - name <= 50 chars (ad name in the library) - headline <= 200 chars (the headline shown with the document) - text <= 3000 chars (the introductory text) INPUT PARAMETERS: - id (optional): Existing Document Ad ID. Provide to UPDATE; omit to CREATE. - name (required, <= 50): Ad name in the library. - libraryId (required): Integer id of the DOCUMENT creative in the library (contentType=DOCUMENT). NOT an image/video id. - headline (required, <= 200): Headline shown with the document. - text (required, <= 3000): Introductory text shown with the document. - ctaType (optional, default UNLOCK_FULL_DOCUMENT): the call-to-action. UNLOCK_FULL_DOCUMENT is the document-gate CTA. - maxPreviewPages (optional, default 1): how many pages of the document are previewable before the unlock gate. Positive integer. - completionStatus (optional, default DRAFT): "DRAFT" or "COMPLETED". Use COMPLETED only when every required field is final. WHEN TO USE: - User asks to "create a LinkedIn Document Ad" / "whitepaper ad" / "promote a PDF / ebook / report on LinkedIn". - User wants to update an existing Document Ad. WHEN NOT TO USE: - Feed image / GIF ad -> create_update_image_ad - Feed video ad -> create_update_video_ad - Branching conversation flow -> create_update_convo_ad - One-shot Sponsored Message -> create_update_linkedin_message_ad EXAMPLE USAGE (Create): create_update_document_ad( name="Q3_Whitepaper_LI_Document", libraryId=15791, headline="The 2026 State of B2B Marketing", text="Download our latest research on pipeline attribution.", maxPreviewPages=2, ) EXAMPLE USAGE (Update): create_update_document_ad( id=29144, name="Q3_Whitepaper_LI_Document_v2", libraryId=15791, headline="The 2026 State of B2B Marketing (Updated)", text="Now with fresh benchmarks.", ) COMMON MISTAKES: - Passing an IMAGE/VIDEO libraryId — the asset must be a DOCUMENT (use search_library_creatives_by_name(contentTypes="DOCUMENT")). - Passing a display / landing URL — Document Ads have no link field. - Using this tool for a non-LinkedIn channel — Document Ads are LinkedIn-only.
    Connector
    Destructive
    API key
  • Create a **LinkedIn Engagement Retargeting** audience: people who already engaged with the advertiser's LinkedIn ads, company page, or website. STEP 3 of the flow. This is NOT create_retargeting_audience, which imports an audience the ad account already has. This builds a NEW LinkedIn DMP segment from the engagement rule defined here. Once built it is a normal Metadata audience and can be attached to campaigns. **REQUIRED WORKFLOW — do not call this tool first:** 1. get_linkedin_engagement_source_types → choose `source_platform` + `engagement_trigger` 2. For every source type EXCEPT WEBSITE: search_linkedin_engagement_sources with that trigger and lookback → collect each chosen result's `id` into `engagement_source_urns` 3. Call this tool Source types, triggers and URNs are LinkedIn's own values, and only steps 1 and 2 can supply them. Do not invent, guess or reuse one from another account: a value that did not come from those steps either fails outright or, worse, is accepted and builds an audience that never populates. **TWO SHAPES, MUTUALLY EXCLUSIVE — mixing them is rejected:** A) NON-WEBSITE (VIDEO_ADS, SINGLE_IMAGE_ADS, DOCUMENT_ADS, CONVERSATION_ADS, LEAD_GEN_FORMS, ORGANIZATION_PAGES): pass `engagement_source_urns`. Do NOT pass page_set_name or url_match_groups. B) WEBSITE: pass `page_set_name` and `url_match_groups`. Do NOT pass engagement_source_urns. Metadata creates the LinkedIn page set from those URL rules for you. URL MATCH RULES (WEBSITE only) are a LIST OF GROUPS. Rules inside a group are ANDed; the groups are ORed. Each rule is {matchType, matchValue}, matchType being EXACT ("URL equals"), STARTS_WITH, or CONTAINS. [[A, B], [C]] means (A AND B) OR C Worked example — "anyone who hit pricing or any demo page": [[{"matchType": "STARTS_WITH", "matchValue": "https://example.com/pricing"}], [{"matchType": "CONTAINS", "matchValue": "/demo"}]] Use one rule per group for a simple OR list, which is what most requests mean. Reach for a multi-rule group only for a genuine AND, e.g. a path that also carries a campaign parameter. WHEN TO USE: - "Retarget everyone who watched our video ads in the last 90 days" - "Build an audience from people who submitted the lead form" - "Create an audience of visitors to our pricing and demo pages" - "Retarget people who visited our LinkedIn company page" - "Make a warm audience from last quarter's ad engagement" PARAMETERS: - name: audience name (required). Give it something descriptive of the rule, e.g. "Video 50% viewers 90d", so it is recognisable in the audience list later. - source_platform: the chosen `engagementSourceType` (required) - engagement_trigger: a trigger listed for THAT source type (required). NOTHING VALIDATES THE PAIRING — see the warning below. - lookback_window_days: 30, 60, 90, 180 or 365 — WEBSITE caps at 180 (required) - engagement_source_urns: LinkedIn URNs from search_linkedin_engagement_sources, copied verbatim. Required for every source type except WEBSITE. Several are normal: the audience is everyone who engaged with ANY of them. - page_set_name: internal label for the URL rule set (WEBSITE only, required there). Only ever seen inside LinkedIn, so a plain descriptive label is fine. - url_match_groups: the OR-of-ANDs URL expression (WEBSITE only, required there) RETURNS: Confirmation with the new audience `id` and name, the `criteria` that define it (source, trigger, lookback, how many sources), the channel, and a `note` on when it becomes usable. **WHAT TO TELL THE USER AFTER IT SUCCEEDS:** It is created but not yet populated. LinkedIn takes up to 48 hours to build the audience and a further 24 hours before it delivers, so it will show NO match count and NO contact or company numbers immediately. That is expected and correct, not a failure. Say so plainly rather than reporting the audience as empty or broken. IMPORTANT NOTES: - **THE TRIGGER MUST BELONG TO THE SOURCE TYPE, AND NOTHING CHECKS THAT FOR YOU.** A mismatched pair (e.g. VIDEO_ADS with LEAD_FORM_SUBMIT) is accepted by this tool, by the platform and by LinkedIn, with no error at any layer — it just builds an audience that can never populate, because the engagement it describes cannot happen. Verified on stage. Always take the trigger from the source type's own `triggers` list in step 1; never carry one over from another source type. - Requires a connected LinkedIn channel on the account. - **NEVER re-create the audience because it shows no members.** Zero right after creation is the normal state; creating it again just makes a duplicate. - This audience type NEVER reports contact or company counts the way a firmographic audience does. It lives on LinkedIn, so only LinkedIn's own match count applies. - WEBSITE additionally requires the LinkedIn Insight Tag installed and active on the pages the URL rules match. Without it the audience stays empty indefinitely, no matter how long you wait — mention this whenever you build a WEBSITE audience. - The lookback window doubles as the retention window: it sets both how far back engagement counts and how long someone stays in the audience. - Building from sources with no engagement produces an empty audience. If step 2 showed zeros everywhere, raise that with the user instead of creating anyway. - The rule cannot be edited afterwards. A different trigger or lookback means a new audience, so confirm the choice before creating when the user was vague. COMMON ERRORS AND WHAT THEY MEAN: - "engagement_source_urns is required" — you skipped step 2, or passed a WEBSITE-style payload for a non-website source type. - "must be one of [30, 60, 90, 180]" — WEBSITE was given a 365-day lookback. - "page_set_name / url_match_groups is required" — WEBSITE needs the URL rules, not URNs.
    ConnectorAPI key
  • A link the user clicks to connect a NEW LinkedIn or Google account. Connecting is a browser step by design: LinkedIn needs a session the extension captures, Google needs its consent screen, and neither a cookie nor a password should ever be pasted into a chat. For LinkedIn the link is the accounts page (with the extension the connect is one click; without it, an email and password or a session cookie entered on that page). For Google the link is a consent URL minted for this user, valid ten minutes. Send the link, then poll campaignstack_list_accounts until the account appears, and link it to the right workspace with campaignstack_link_account_to_workspace if it is not there already. Never ask the user for their credentials.
    ConnectorAPI key
  • Merge a duplicate CRM company into another one (e.g. 'Škoda JS' into 'Škoda Group'). All people move to keep_crm_company_id, empty details are filled from the duplicate, account notes are joined, the duplicate's name is remembered as an alias so future leads with that name land in the kept company, and the duplicate is deleted. Cannot be undone — only merge when both records are clearly the same organisation (check with get_crm_company), and confirm with the user when unsure. Prefer keeping the company imported from LinkedIn.
    Connector
    Destructive
    No auth