Skip to main content
Glama
620,015 tools. Updated 2026-09-28 21:27

"A guide to finding people on LinkedIn by their names" 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
  • <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
  • Get available criteria and their supported values (names and IDs) for target group creation/updates. USE FOR: "what targeting criteria are available?", "what options for [criteria type]?", "supported values for industries/seniority/job functions", "how to search job titles/interests/member groups?", validate criteria before creating target group, get valid IDs for create_target_group. CRITERIA TYPES: 1. LIST-BASED (returns predefined options): - age-ranges: Age range options - company-categories: Company classifications - company-growth-rates: Growth rate ranges - revenues: Revenue ranges - employees: Employee count ranges - industry-taxonomy: Industry codes/names - jobFunctions: Job function categories - seniority: Seniority levels - followed-companies: Company follow options - locations: Geographic data (MANDATORY as FIRST criteria for LinkedIn) - use search_terms for filtering 2. SEARCH-BASED (use search_terms): - job-title: Search job titles (reference_type: LINKEDIN_JOB_TITLES) - member-groups: Search LinkedIn groups (reference_type: LINKEDIN_MEMBER_GROUPS) - member-skills: Search professional skills - interests: Search interests (reference_type: LINKEDIN_INTERESTS) - traits: Search behaviors (reference_type: LINKEDIN_TRAITS) 3. NUMERIC: years-of-experience (0-12, not retrieved via this tool) OPERATION MODES: - List: search_target_group_criteria(channel="LINKEDIN", criteria_type="seniority") - Search: search_target_group_criteria(channel="LINKEDIN", criteria_type="job-title", search_terms=["engineer"], exact_match=false) - Direct: search_target_group_criteria(channel="LINKEDIN", reference_type="LINKEDIN_JOB_TITLES", search_terms=["engineer"]) RESPONSE: Array of {externalId, name}. Use externalId in target group config, show name to users. CHANNEL: Only LINKEDIN supported.
    ConnectorAPI key
  • 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
  • Create new guides Create one or more new guides based on provided queries. Each guide targets exactly ONE engine and ONE analysis mode, chosen with the optional `source` field (default `google`). How to request each guide type: 1. Google SERP guide (1 credit per guide): omit `source`, or pass `source: "google"`. Example payload: {"queries": ["best crm"], "lang": "en-us"} 1bis. Google AI Overview guide (1 credit per guide). Two modes, like AI engines: `source: "google_ai_overview"` builds the guide from the TEXT of Google's AI answers (AI Overview, completed with AI Mode answers) ; `source: "google_ai_overview_citations"` builds it from the content of the web SOURCES those answers cite (recommended for GEO). Same language/country parameters as a Google SERP guide, 1 credit per guide in both modes. Example payload: {"queries": ["best crm"], "lang": "en-us", "source": "google_ai_overview_citations"} 2. LLM ANSWER guide (4 credits per guide): pass the engine name alone, e.g. `source: "chatgpt"`. The guide is built from the answer text the AI generates for the query. Example payload: {"queries": ["best crm"], "lang": "en-us", "source": "chatgpt"} 3. LLM CITATIONS guide (4 credits per guide) [RECOMMENDED AI mode]: pass the engine name with the `_citations` suffix, e.g. `source: "chatgpt_citations"`. The guide is built from the content of the web pages the AI cites in its answer. Example payload: {"queries": ["best crm"], "lang": "en-us", "source": "chatgpt_citations"} Which AI mode to pick? For GEO (getting a page visible in AI answers), prefer `<engine>_citations`: AI engines send traffic by CITING pages as sources, so the winning move is to look like the pages they cite. The answer-text mode (`<engine>` alone) is mostly useful to analyze how the AI phrases its own answer. When in doubt, pick `<engine>_citations`. The same two modes exist for every AI engine (chatgpt, perplexity, claude, gemini, grok, mistral, deepseek). To optimize the same page for several engines or modes (e.g. Google AND ChatGPT answers AND ChatGPT sources), create one guide per source value on the same query. IMPORTANT, HOW TO READ THE RESPONSE OF THIS ENDPOINT, WHICH SPENDS CREDITS. Queries listed in `guidesFailed` are PROVEN not to have produced a guide and their credit was given back (unless the account has unlimited credits, where nothing was reserved): re-sending them is free and correct. Queries listed in `guidesUnknown` have an UNDECIDABLE outcome and their credit is deliberately KEPT, because the guide was most likely written: DO NOT re-send them, you would pay for the same guide twice. Look them up in `GET /api/v1/guides` after a few minutes instead, and contact support if nothing shows up. Finally, a `200` is NOT a promise that every query produced a guide: compare `guides.length` with the number of queries you sent, never read `success` alone, and never re-send a query just because it is missing from `guides`.
    ConnectorNo auth
  • List taxonomy facets and their value slugs across TCLP content. Facets are taxonomy categories like `sector`, `practice_area`, `application`, and `jurisdiction`. Each facet returns the list of slugs that actually appear on the graph, with counts. Use this to discover the vocabulary, then call `taxonomy_content` with chosen slugs. Args: scope: Which labels to include — `clause` (ClauseName only), `guide` (Guide only), or `all` (both, the default). Returns: JSON with "meta" and "facets". Each facet has `name`, `applies_to` (list of Neo4j labels carrying it), and `values` (list of `{slug, count}`, sorted by count desc).
    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
    236 PyPI
    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.

  • List taxonomy facets and their value slugs across TCLP content. Facets are taxonomy categories like `sector`, `practice_area`, `application`, and `jurisdiction`. Each facet returns the list of slugs that actually appear on the graph, with counts. Use this to discover the vocabulary, then call `taxonomy_content` with chosen slugs. Args: scope: Which labels to include — `clause` (ClauseName only), `guide` (Guide only), or `all` (both, the default). Returns: JSON with "meta" and "facets". Each facet has `name`, `applies_to` (list of Neo4j labels carrying it), and `values` (list of `{slug, count}`, sorted by count desc).
    ConnectorNo auth
  • Resolve what a person describes into AcuiQ symptom names – the first step before search_protocols. Plain description works ("trouble sleeping", "my lower back hurts"): filler words are stripped and the search retries on the clinical words, reporting which term matched. Set popular=true for trending symptoms instead. Always returns an object with a `symptoms` array, empty when nothing matched. When the symptom is covered by a $5 mini-guide, the result carries a `guide` pointer – mention it only if the person wants something to follow away from a screen, then call create_checkout with that `product` id.
    ConnectorNo auth
  • Find acupuncture protocols for given symptom names – the same ranked pipeline behind GET /api/protocols. Returns `matches` (each with point codes, cred, dosage and provenance: sourceKind, source, caveat) plus a `points` dictionary giving each referenced code its name, meridian, location and warnings ONCE. Ten matches by default; raise `limit` (max 50) if you need more. `directMatches` lists indicated points when no protocol covers the query – index entries, not prescriptions. Pass symptom names from search_symptoms, not a description. When the symptom is covered by a $5 mini-guide, the result carries a `guide` pointer – mention it only if the person wants something to follow away from a screen, then call create_checkout with that `product` id.
    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. If nothing matches exactly, the least essential filters are dropped automatically and `broadenedBy` names them. 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
  • <summary>Find phone numbers for one or more people from their LinkedIn URLs, via Airscale. Pass a list of LinkedIn profile URLs — one entry for a single person, all of them at once for a batch (they are looked up in parallel, costing one tool call against the loop guard, not N). Returns one result per URL in the same order. Airscale brokers providers like RocketReach. Persists nothing — use the returned numbers however the agent needs them (e.g. tell the user, or stash them on prospects via `update_prospect`). A LinkedIn profile URL is the only accepted input — this tool cannot look a person up by email or name. When a record (a HubSpot/CRM contact, a prospect row, a spreadsheet line) has no LinkedIn URL but does have the person's email, first call `find_linkedin_url(email=...)` to resolve one, then pass that URL here. Apply this resolve-then-lookup step to every record, not just the first; skip the phone lookup for any person you cannot get a URL for. Costs 8 Sliq credits per number found, when run on Sliq's shared Airscale account. Misses (no number on file) and upstream failures are free. A worst-case check runs up front on the Sliq path: the whole batch is refused unless the balance covers 8 credits per URL (any URL *could* be a hit). So no API call is ever spent on a lookup that can't be billed, and a user low on credits is told to top up or connect their own key. If the user has connected their own Airscale key (BYO, via the integrations page), lookups run against that account instead — no Sliq credit gate and no Sliq credit charge.</summary> <returns> <description>A list of result dicts in input order. Per hit: `{status: 'success', found: True, phone_number, phone_numbers, provider, linkedin_url, credits_charged: 8}` (0 on the BYO path) — `phone_number` is the first number, `phone_numbers` the full list. Per miss: `{..., found: False, phone_number: None, phone_numbers: [], credits_charged: 0}`. A malformed (non-LinkedIn) URL or an upstream failure on one URL becomes a per-item `{found: False, error, credits_charged: 0}` in that slot — it never aborts the rest of the batch. If the up-front worst-case credit check fails, it raises `InsufficientCreditsError` (no lookups are attempted).</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
  • General-purpose Google search — returns organic results for any query. Unlike search_google_xray (LinkedIn-only), this searches the entire web. Useful for finding job postings on portals (jobs.cz, prace.cz, profesia.sk, indeed.com), company info, news, or any other web content. Results are NOT saved to contacts — use this for research and discovery. Capped at 4 calls per minute to protect the Serper/Google budget.
    ConnectorNo auth
  • Creates a Zeekeo LinkedIn campaign: sends a connection invite using invite_template_id, and optionally — if followup_template_id is given — waits for the invite to be accepted, then sends a follow-up message using that template. Create templates first with zeekeo_create_template. Provide exactly one of filter_url (a LinkedIn search results URL) or profile_urls (specific profiles) as the target. This starts REAL LinkedIn automation once the campaign has profiles in it — confirm with the user before calling. Requires the user to have connected their own Zeekeo Launchpad account. Direct them to rankparse.com/dashboard/integrations to connect it.
    ConnectorNo auth
  • Get the full profile for one of the user's LinkedIn connections: work history, education, skills, and their About summary. Use this after search_connections when you need depth on a specific person. Identify them by name, or by linkedin_url for an exact match. A found:false response carries the user's imported-connection count: if no_imported_data is set, nothing was searched, so report the missing import rather than a missing person.
    ConnectorNo auth
  • <summary>Fetch the people who reacted to or commented on a LinkedIn post — the user's own post or anyone else's — and store them as queryable engagement rows. Use when the user wants to turn a post's engagers into leads ("everyone who liked this post", "who commented on her launch post"). Visibility follows the user's LinkedIn account: any post it can view works, and private or deleted posts return a plain error. The list is capped at 500 reactions + 500 comments per post; on a bigger post the return flags the cut-off. Data fetched within the last 6 hours is served from the database at no cost; a real fetch counts one action against the shared daily engagement-fetch budget and paces its LinkedIn requests, so a post with hundreds of engagers takes around half a minute — set that expectation with the user before calling this on a big post. When this runs in an agent, every engager is materialized as a reviewable `agent_search_results` row (entity_type='person', data carries headline, reaction_value, comment_text, provider_id, source_post_url), rendered in the agent's Output tab and queryable via `query_search_results`. Re-running updates existing rows rather than duplicating them. Pass `list_name` to name their list; absent, they land in the 'default' list. By default the full unfiltered list materializes — to act on only a subset (ICP fit, founders only, a specific role), qualify the stored rows first (headline triage via query_linkedin_post_engagements) and queue outreach on just the keepers. After this returns, filter and slice the full list with `query_linkedin_post_engagements` using `post_id = <post_analytics_id>`, then queue outreach with one batched `setup_linkedin_sequence` call passing each person's `provider_id`. Send-time resolution skips anyone already connected, so they don't need pre-filtering here.</summary> <returns> <description>On success, a dict {'success': True, 'post_analytics_id': int, 'author_name': str, 'is_own_post': bool, 'post_text_snippet': str, 'from_cache': bool, 'reactions_stored': int, 'comments_stored': int, 'unique_engagers': int, 'truncated': bool, 'budget': {'used_today': int, 'limit': int}, 'engagers_preview': [first 10 people], 'next_step': str, 'list'?: {'list_name', 'created', 'updated', 'total'}}. On failure, {'success': False, 'error': str} when the post isn't visible to the user's account, the daily budget is exhausted, or LinkedIn actions are paused after a rate limit.</description> </returns>
    ConnectorOAuth
  • List the LinkedIn conversion actions (Insight Tag conversions) available on the connected LinkedIn ad account, with id, name, type and whether each is enabled. Use it to pick the ids for update_linkedin_channel_settings.conversion_action_ids (which conversions a campaign optimizes toward and reports on), and to answer "which LinkedIn conversions do we track?" or "is the /pricing page conversion set up?". KEYWORDS: linkedin, conversions, conversion actions, conversion tracking, insight tag, website visit conversion, lead gen form conversion, url conversion, page visit, pixel Requires a connected LinkedIn channel (check get_integrations_status). Conversion actions are created in LinkedIn Campaign Manager, not here: when the one the user needs (for example a URL rule for /pricing) is missing, say so and point them at Campaign Manager instead of inventing an id. RESPONSE: {success, count, conversions:[{id, name, type, enabled, last_received_at}]} `enabled: false` conversions cannot be attached to a campaign (launch validation rejects them). `last_received_at` is when LinkedIn last recorded a hit; null means the conversion has never fired.
    ConnectorAPI key
  • List the LinkedIn engagement source types and their triggers. STEP 1 of building a LinkedIn Engagement Retargeting audience. WHAT THIS AUDIENCE TYPE IS: An audience of people who ALREADY interacted with this advertiser on LinkedIn or on their website: watched a video ad, opened a lead form, clicked a document ad, visited the company page, or hit specific URLs. It is warm-traffic retargeting, built from first-party engagement, and it needs no contact list and no CSV. NOT THE SAME AS create_retargeting_audience. That tool IMPORTS an audience that already exists inside the native ad account. This flow BUILDS a new LinkedIn DMP segment from an engagement rule you define. If the user says "import my existing LinkedIn audience", use the other tool. If they describe PEOPLE WHO DID SOMETHING ("watched", "clicked", "visited", "opened", "engaged with"), use this flow. **THE THREE-STEP FLOW:** 1. get_linkedin_engagement_source_types (this tool) — choose a source type + trigger 2. search_linkedin_engagement_sources — choose which campaigns / pages to retarget (SKIP THIS STEP for the WEBSITE source type, which uses URL rules instead) 3. create_linkedin_engagement_retargeting_audience — build it SOURCE TYPES AND WHAT EACH RETARGETS (verified live; the response is authoritative and may differ per account, so never assume a value that is not in it): - VIDEO_ADS ........... viewers of the account's video ads - SINGLE_IMAGE_ADS .... people who engaged with single-image ads - DOCUMENT_ADS ........ people who engaged with or downloaded document ads - CONVERSATION_ADS .... people who opened or clicked a conversation ad - LEAD_GEN_FORMS ...... people who opened or submitted a lead gen form - ORGANIZATION_PAGES .. visitors to the LinkedIn company page - WEBSITE ............. visitors to specific URLs on the advertiser's own site TRIGGERS DEFINE INTENT DEPTH, and each source type has its own set: - VIDEO_ADS: FIRST_QUARTILE (>=25% viewed, the default) · MIDPOINT (>=50%) · THIRD_QUARTILE (>=75%) · FULL_COMPLETE (>=97%). Deeper means smaller and warmer. - SINGLE_IMAGE_ADS / DOCUMENT_ADS: ENGAGEMENT (any interaction, default) · CLICK (chargeable clicks only). DOCUMENT_ADS adds DOWNLOAD_CLICK (downloaded it). - CONVERSATION_ADS: OPEN (default) · ANY_CTA_CLICK (clicked a call-to-action). - LEAD_GEN_FORMS: VIEW_FORM (opened it, includes submitters, default) · LEAD_FORM_SUBMIT (submitted only — the hottest signal available). - ORGANIZATION_PAGES: VIEW (visited the page, default) · CTA_CLICK (clicked the page header CTA). - WEBSITE: VISIT. CHOOSING FOR THE USER'S INTENT: - "warm up a broad audience" / top of funnel → a shallow trigger (ENGAGEMENT, VIEW, FIRST_QUARTILE, VIEW_FORM) and a long lookback. - "high intent" / "ready to buy" / bottom of funnel → a deep trigger (LEAD_FORM_SUBMIT, FULL_COMPLETE, DOWNLOAD_CLICK, ANY_CTA_CLICK) and a short one. - When the user does not say, prefer the trigger marked `default` — it is LinkedIn's own recommended choice for that source type. - **Only ever use a trigger from the source type you picked.** The pairing is not validated anywhere downstream, so a trigger borrowed from another source type builds a permanently empty audience with no error to warn you. LOOKBACK WINDOW is both how far back engagement counts AND how long someone stays in the audience. Longer means bigger and colder; shorter means smaller and warmer. 30 / 60 / 90 / 180 / 365 days, except WEBSITE which LinkedIn caps at 180. 90 is a reasonable default when the user does not say. WHEN TO USE: - "Create an engagement retargeting audience" - "Retarget people who watched my LinkedIn video ads" - "Build an audience of people who opened / submitted my lead gen form" - "Retarget visitors to our pricing page" (WEBSITE) - "Who visited our LinkedIn company page?" (ORGANIZATION_PAGES) - "Retarget everyone who engaged with our ads last quarter" - Any request to retarget people by something they DID, on LinkedIn or the site PARAMETERS: none. It always reports the whole catalog for the caller's account. RETURNS: - sourceTypes[]: `engagementSourceType`, a human `description`, and the `triggers` valid for it (`engagementTrigger`, `description`, `default`). Only entries LinkedIn reports as ACTIVE are returned; inactive ones are filtered out. - lookbackWindowDays: the windows the platform accepts, with WEBSITE listed separately because of its 180-day cap. - next_step: which tool to call next. IMPORTANT NOTES: - Requires a connected LinkedIn channel. With none connected this returns nothing useful, and the fix is to connect LinkedIn (connect_channel), not to retry. - The catalog is LinkedIn's own and is read live, so it can change. Treat the response as the only source of truth and never pass a value absent from it. - EVENT_PAGES is deliberately not offered. LinkedIn advertises it but returns no sources for it, so an audience cannot be built from it. - A source type may come back with `triggersError` instead of `triggers` if its trigger list could not be read. The other source types are still usable; either retry or choose one of them.
    ConnectorAPI key
  • Create a **G2 Intent - LinkedIn Native (Dynamic)** audience (platform `customAudienceType=DYNAMIC_G2`). AUDIENCE TYPE (mirrors the UI's "Audience Type" dropdown): • UI label: "G2 Intent - LinkedIn Native (Dynamic)" • Platform enum: DYNAMIC_G2 • Refreshes daily as G2 intent signals update; targets LinkedIn natively. PREREQUISITE: • Both G2 and LinkedIn integrations MUST be connected. If either is missing, do NOT call this tool — recommend `create_firmographic_audience` instead. WHEN TO USE (exact user phrasing this tool should match): • "G2 Intent - LinkedIn Native (Dynamic)" • "G2 LinkedIn Native Dynamic" • "LinkedIn native G2 intent audience" • The user explicitly mentions BOTH G2 intent AND LinkedIn native targeting. WHEN NOT TO USE: • If the user asked for "G2 Intent (Dynamic)" without "LinkedIn Native" → use `create_g2_intent_dynamic_audience`. • If the user asked for "G2 Intent (Static)" → use `create_g2_intent_static_audience`. BUYING STAGES — REQUIRED BY THE PLATFORM: The platform UI marks Buying Stages as required. If the user did not name any stages, STOP and ask the user which of AWARENESS / CONSIDERATION / DECISION to target. DO NOT silently default — that produced wrong audiences in PRD-29702 / PRD-29703. CRITERIA (LinkedIn-native shapes; free-text fields are resolved server-side via the LinkedIn references API): • employees — LinkedIn-native employee ranges. Valid labels: see the schema (e.g. "201-500", "501-1000", "1001-5000"). • revenues — LinkedIn-native revenue ranges (e.g. "$1M-$10M", "$10M-$100M"). • company_names — free-text company names (resolved to LinkedIn company IDs). • location_country_ids — country IDs (e.g. 229=US, 228=UK). • job_titles — free-text titles (resolved to LinkedIn job-title IDs). • skills — free-text professional skills (resolved to LinkedIn skill IDs). PARAMETERS: • name (required, ≤ 50 chars) • intent_days (required, 1-365) • buying_stages (REQUIRED by platform — ask the user if missing; do NOT default) • employees, revenues, company_names, location_country_ids, job_titles, skills (all optional) RETURNS: id, audience_id, audience_name, audience_type (DYNAMIC_G2), status, buying_stages, intent_days, expectedNumberOfCompanies, expectedNumberOfContacts.
    ConnectorAPI key
  • List the people who engaged with THIS user's own LinkedIn posts — their name, headline, LinkedIn profile, how they engaged, what they commented, which posts pulled them in, and ContentIn's ICP fit score. Use it to answer 'who is engaging with me', to find warm contacts, or to see which posts attract the right audience. REACTIONS ARE INCLUDED: a single like creates a lead, so a lead with no comments is completely normal and does not mean something is missing. ABOUT THE SCORE: icp_score is computed BY CONTENTIN, by comparing the person's LinkedIn headline against this user's stated ideal customer profile. It is an estimate from a headline, not verified data about who they are. classified: false with icp_score: null means ContentIn HAS NOT SCORED THIS LEAD YET — report it exactly that way. It does NOT mean the person is a poor fit; those are different claims and only one of them is supported. When icp_score_source is 'user_override' the number is the user's own labelling, not ContentIn's. Results are ordered by ContentIn's computed score when you sort by icp_score, so a lead the user has manually re-labelled keeps its computed position while reporting their number. Page with before/before_id; profiles routinely have thousands of leads.
    ConnectorNo auth
  • <summary>Read one agent's People tab: the people its searches found plus the prospects it tracks, one row per person, with the same columns and group counts the user sees there. It is the only read that carries each person's LinkedIn degree and warm-intro connectors. Use it for questions about the people on an agent: who is 1st-degree, who can introduce the user to someone, how many people are in each list, source or outreach stage, and who belongs to any one of those groups. Each row: `id` (the person id query_people uses), `display_name`, `spine` (title, company, location, headline), `linkedin_url`, `linkedin_provider_id`, `email`, and: - `degree`: the user's LinkedIn degree to the person, '1', '2', '3' or 'out_of_network'; null when unknown. A person the user is connected to reads '1'. - `intro`: the warm-intro check. `state` is one of not_checked, checking, queued, found, cold, connected, unresolved. `connectors` lists the user's 1st-degree connections who know the person (name, headline, identifier, provider_id). `mutual_connections_truncated` true means `connectors` is a sample of a longer list. `shared_connections_count` is LinkedIn's total. `result_id` is the search row the check read, null when the person has none. - `outreach_stage`: the person's lead-funnel bucket on this agent, '' when not in outreach here. `prospect_id`, `email_stage` and `linkedin_stage` are their prospect row on this agent, null when not enrolled. `removal_reason` says why they were removed from the campaign, '' when they weren't or no reason was recorded. - `lists` and `sources`: the search lists and discovery tools that surfaced the person. `columns` holds the researched [label, value] pairs. - `criteria`, only with `include_criteria`: why the person matched, as their opened row shows it. Per list they're in, {list_name, evaluations}; each evaluation is a `criterion` with the `reasoning`, a verdict (`satisfied` 'yes', 'no' or 'unclear', or a numeric `score` where 7 and up is met) and http(s) `references`. Criteria run about 2KB per person, so ask for them on a narrow read (a `q`, one bucket, or a small `limit`) or from run_code. To count people per group, pass `group_by` alone. To list one group's people, pass `group_by` plus a `bucket` key taken from those counts. Otherwise you get everyone, sorted by name. Page until `next_cursor` is null by passing it back as `cursor`. A direct call returns 25 rows by default; for a wide pull, call this from run_code with `limit` up to 200 (nothing truncates there) and print only the fields you need.</summary> <returns> <description>A dict. A `group_by` without a `bucket` returns only `group_counts`, a list of {key, count} with the largest group first and the '' group last ("degree" keeps closest-first order; "connector" entries add `label`). Every other call returns `results` (rows shaped as above) and `next_cursor`, plus `total` (every matching person) when `group_by` is omitted.</description> </returns>
    ConnectorOAuth