Skip to main content
Glama

Look Up LinkedIn Profiles

li_enrich_profiles

Look up who people are — name, headline, company, role, location — WITHOUT opening a browser at all. This reads a third-party data provider, so it costs enrichment lookups but takes NO browser time and cannot affect the LinkedIn account's standing. Lookups are SHARED across every account the owner holds: each account adds 400 for its whole trial or 1,500 a month once paid, so three accounts share one pool — sharedAcrossAccounts says how many, and remaining/allowance are the pool's. Each looked-up person also carries companyPage: their CURRENT employer read from its LinkedIn company page — name, website and domain, industry, size band, HQ, founding year, a one-line description, specialities and followers — at NO extra lookup (it comes with the profile, and a firm already read in the last 30 days is never re-fetched). Use it to judge ICP fit (industry, size, HQ) and to write the sequence (what the company does, in its own words). companyPage.status is ok/cached (facts present), not_found (the page returned nothing), failed (the read broke), skipped (not looked up) or no_company_page (the profile names no LinkedIn company page — self-employed, a typed-in employer) — never read a missing block as 'no company'; companyPages summarises the batch. Anyone already looked up in the last 30 days is returned FREE from a shared cache and costs nothing; pass refresh=true to force a re-fetch. Each profile comes back COMPACT by default — the flat fields plus what actually helps judge a person (about, audience size, open-to-work/hiring, account quality, current job, a short work and education history). The provider's own record is many times larger and is mostly people nobody asked about, followed companies and images, so it is never returned. For a LARGE batch, narrow it further with fields — e.g. fields: ['about','audience','currentRole'] — which keeps every person's identity and drops the rest; measured on real profiles, those three sections are about a FIFTH of the compact record and an empty fields list is about a TWELFTH, and the reply carries the payload twice — so a 46-profile batch that flooded a caller's context becomes something they can read. The reply then says which sections it carried and which it left out, so a trimmed record can never read as a whole one. Every row carries who the person is: publicProfileUrl (their public linkedin.com/in/ URL, the one to import; null when the provider named none), memberId (ACoAA…) and searchId (ACwAA…, when that is what you asked with). profileUrl stays the address you asked with, so rows pair with your list. Per-URL outcomes: 'ok' fetched, 'cached' free, 'not_found' means the provider looked and found nothing (a deleted, renamed or restricted profile — NOT an error), 'failed' means the lookup itself broke, 'skipped_no_credits' means the allowance ran out before reaching it. One caveat on not_found: if unmatched is above zero the provider DID return that many profiles which no requested URL could be tied to, so some of the not-found rows are a matching bug worth reporting rather than a fact about those people. Always relay message: it says what was charged and what is left. The reply also carries companies: the batch grouped by employer, on the LinkedIn company page where the provider gave one and a folded name otherwise, with counts for everyone it could NOT place. Relay companies.summary — a batch is usually far fewer firms than people, and that changes how it should be sent. It says nothing about your pipeline; li_check_targets with groupByCompany answers which of those firms you already have a contact at. Pass estimateOnly=true FIRST for a free preview of a big list — how many are already known, how many would actually be looked up, how many lookups that charges and what is left afterwards. It looks nothing up, charges nothing, and answers for a list longer than one real call takes, telling you how many calls to split it into. Use this before writing outreach, and before deciding whether to accept an inbound invitation. INPUTS: the only input passed to the data provider is the list of profile URLs (each person's employer page is then read from what comes back); the other inputs only preview the cost (estimateOnly), skip the cache (refresh), trim the reply (fields) or, when you have several LinkedIn accounts, say whose allowance pays (sessionId / sessionLabel).

Input Schema

NameRequiredDescriptionDefault
fieldsNoReturn only these parts of each profile, so a large batch does not flood the reply. The identity — profileUrl, publicProfileUrl, memberId, searchId, status, name, headline, company, role, location, fetchedAt, error — comes back on EVERY profile and never needs asking for. The sections you can add are: about, audience, signals, currentRole, experience, education, skills (audience is follower and connection counts; signals is open-to-work, hiring, premium, influencer, verified), plus companyPage for each person's employer block (it rides on the default view, and on this trimmed one only when named). Pass an empty array for identity only. An unknown name is refused naming the accepted set, and nothing is looked up or charged. Costs exactly the same as the full record — it only changes what is sent back.
refreshNoIgnore the cache and re-fetch, for when a cached profile is known to be out of date. Costs a lookup for every URL.
sessionIdNoOnly when you have more than one LinkedIn account: which one pays for the lookup (its plan and allowance gate the run). Account id from li_list_accounts. Never sent to the data provider.
profileUrlsYesThe LinkedIn profile URLs of the people to look up — the only input passed to the data provider. One real lookup takes at most 100 and a longer list is refused rather than silently truncated; estimateOnly answers for up to 500 and says how many calls to split it into.
estimateOnlyNoPreview instead of looking anything up. Reports how many are already known (free), how many would be fetched, how many lookups that charges and what is left. Charges nothing and reserves nothing.
sessionLabelNoSame as sessionId, by account label, LinkedIn name, profile slug or member id (li_list_accounts). Only when you have more than one account. Never sent to the data provider.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / fields / description
      Previous value: -"Return only these parts of each profile, so a large batch does not flood the reply. The identity — profileUrl, status, name, headline, company, role, location, fetchedAt, error — comes back on EVERY profile and never needs asking for. The sections you can add are: about, audience, signals, currentRole, experience, education, skills (audience is follower and connection counts; signals is open-to-work, hiring, premium, influencer, verified), plus companyPage for each person's employer block (it rides on the default view, and on this trimmed one only when named). Pass an empty array for identity only. An unknown name is refused naming the accepted set, and nothing is looked up or charged. Costs exactly the same as the full record — it only changes what is sent back."New value: +"Return only these parts of each profile, so a large batch does not flood the reply. The identity — profileUrl, publicProfileUrl, memberId, searchId, status, name, headline, company, role, location, fetchedAt, error — comes back on EVERY profile and never needs asking for. The sections you can add are: about, audience, signals, currentRole, experience, education, skills (audience is follower and connection counts; signals is open-to-work, hiring, premium, influencer, verified), plus companyPage for each person's employer block (it rides on the default view, and on this trimmed one only when named). Pass an empty array for identity only. An unknown name is refused naming the accepted set, and nothing is looked up or charged. Costs exactly the same as the full record — it only changes what is sent back."
  2. Changed7 schema fields changed
    • changedInput schema / properties / fields / description
      Previous value: -"Return only these parts of each profile, so a large batch does not flood the reply. The identity — profileUrl, status, name, headline, company, role, location, fetchedAt, error — comes back on EVERY profile and never needs asking for. The sections you can add are: about, audience, signals, currentRole, experience, education, skills (audience is follower and connection counts; signals is open-to-work, hiring, premium, influencer, verified), plus companyPage for each person's employer block (it rides on the default view, and on this trimmed one only when named). Pass an empty array for identity only. An unknown name is refused naming the accepted set, and nothing is looked up or charged. Costs exactly the same as the full record — it only changes what is sent back. Cannot be combined with includeRaw."New value: +"Return only these parts of each profile, so a large batch does not flood the reply. The identity — profileUrl, status, name, headline, company, role, location, fetchedAt, error — comes back on EVERY profile and never needs asking for. The sections you can add are: about, audience, signals, currentRole, experience, education, skills (audience is follower and connection counts; signals is open-to-work, hiring, premium, influencer, verified), plus companyPage for each person's employer block (it rides on the default view, and on this trimmed one only when named). Pass an empty array for identity only. An unknown name is refused naming the accepted set, and nothing is looked up or charged. Costs exactly the same as the full record — it only changes what is sent back."
    • removedInput schema / properties / includeRaw
      Removed value: -{
      -  "description": "Return the data provider's record verbatim instead of the compact profile. Costs NO extra lookups, but the reply is MUCH larger — one profile measured ~8KB, so twenty is ~160KB of mostly unrelated people, followed companies and image URLs. Ask for it only when the compact profile is genuinely missing something, and prefer a small batch when you do.",
      -  "type": "boolean"
      -}
    • removedInput schema / properties / maxAgeDays
      Removed value: -{
      -  "description": "Treat a cached profile older than this as stale. Default 30.",
      -  "maximum": 365,
      -  "minimum": 1,
      -  "type": "integer"
      -}
    • changedInput schema / properties / profileUrls / description
      Previous value: -"LinkedIn profile URLs. One real lookup takes at most 100 and a longer list is refused rather than silently truncated; estimateOnly answers for up to 500 and says how many calls to split it into."New value: +"The LinkedIn profile URLs of the people to look up — the only input passed to the data provider. One real lookup takes at most 100 and a longer list is refused rather than silently truncated; estimateOnly answers for up to 500 and says how many calls to split it into."
    • changedInput schema / properties / refresh / description
      Previous value: -"Ignore the cache and re-fetch. Costs a lookup for every URL."New value: +"Ignore the cache and re-fetch, for when a cached profile is known to be out of date. Costs a lookup for every URL."
    • changedInput schema / properties / sessionId / description
      Previous value: -"Account id from li_list_accounts. Needed (or sessionLabel) when you have more than one account; never guessed."New value: +"Only when you have more than one LinkedIn account: which one pays for the lookup (its plan and allowance gate the run). Account id from li_list_accounts. Never sent to the data provider."
    • changedInput schema / properties / sessionLabel / description
      Previous value: -"Account by label, LinkedIn name, profile slug or member id (li_list_accounts). Needed (or sessionId) when you have more than one account; never guessed."New value: +"Same as sessionId, by account label, LinkedIn name, profile slug or member id (li_list_accounts). Only when you have more than one account. Never sent to the data provider."
  3. Changed2 schema fields changed
    • addedInput schema / properties / sessionId / description
      Added value: +"Account id from li_list_accounts. Needed (or sessionLabel) when you have more than one account; never guessed."
    • addedInput schema / properties / sessionLabel / description
      Added value: +"Account by label, LinkedIn name, profile slug or member id (li_list_accounts). Needed (or sessionId) when you have more than one account; never guessed."
  4. First observed

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds enormous context beyond the annotations: credit cost and shared-pool semantics across accounts, 30-day shared cache and refresh override, per-URL outcome codes with the not_found/unmatched caveat, companyPage status vocabulary, and the requirement to relay `message`. With readOnlyHint=false and destructiveHint=false already set, this is far more than the annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the cost/no-browser distinction, but the body is an unusually dense wall of prose covering caching, statuses, trimming fractions, companyPage fields and batch grouping. Most sentences carry unique information, but the volume is heavy enough that scanning for a single fact is hard.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-output-schema tool with 6 params and substantial complexity, the description covers returns in detail: compact-by-default shape, the never-returned raw provider record, per-URL statuses, the `companies` grouping block, and the payload-duplication note. Nothing an agent needs in order to call it and interpret results is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds real meaning: fields trimming with concrete examples and measured size fractions, the fact trimming costs the same as the full record, empty-array identity-only behavior, and that sessionId/sessionLabel are never sent to the provider. Only refresh/estimateOnly largely restate their schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('look up who people are — name, headline, company, role, location') via a third-party provider with no browser, and explicitly contrasts the scope with li_check_targets and li_enrich_company. An agent can distinguish it from li_research_profiles and li_search_leads by the 'costs enrichment lookups / no browser time' framing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context ('Use this before writing outreach, and before deciding whether to accept an inbound invitation') and routes to an alternative for a related question (li_check_targets with groupByCompany). It also prescribes estimateOnly=true first for large lists. It does not explicitly say when NOT to use it versus li_research_profiles or li_search_leads, so it stops short of full when/when-not coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources