Skip to main content
Glama

Salesbot - B2B outreach LinkedIn MCP Server with CRM and email

upsert_linkedin_contact

Idempotent

Use to save one person when you know their LinkedIn profile URL. Without a URL use add_crm_contact. Create a contact from a known LinkedIn profile URL, or return the existing contact when the profile was already imported. Use this when you already know the exact profile URL and do not need to run a search. The contact is saved to a dedicated CRM Imports list and can then be passed to add_contacts_to_campaign. Pass web_research (what you found about their company/person online) and personalization_note (a hook for the outreach message) — both are stored on the contact and fed to the LinkedIn message generator as facts to personalize on. On an existing contact these are MERGED in (they enrich, never blank out existing data).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
companyNoCurrent company. Optional.
list_idNoUUID of an existing lead list to put the contact into (from list_lead_lists). Optional — defaults to the 'CRM Imports' list. For an existing contact this MOVES it into that list.
headlineNoLinkedIn headline. Optional.
positionNoCurrent role/title. Optional.
full_nameNoContact name. Optional when it is not available yet.
profile_urlYesLinkedIn profile URL in the form https://www.linkedin.com/in/...
web_researchNoFree-text research about the person/company found online (news, website, recent events). Used as facts to personalize the outreach. Optional.
prospect_company_idNoUUID returned by list_companies. Links this employee to the stored company and, when that company is in CRM, also adds/links the person to the CRM company.
personalization_noteNoA short note/hook for writing the LinkedIn message (e.g. 'reference their new plant in Brno'). Fed to the message generator. Optional.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / prospect_company_id
      Added value: +{
      +  "description": "UUID returned by list_companies. Links this employee to the stored company and, when that company is in CRM, also adds/links the person to the CRM company.",
      +  "type": "string"
      +}
  2. Changed1 schema field changed
    • addedInput schema / properties / list_id
      Added value: +{
      +  "description": "UUID of an existing lead list to put the contact into (from list_lead_lists). Optional — defaults to the 'CRM Imports' list. For an existing contact this MOVES it into that list.",
      +  "type": "string"
      +}
  3. Changed2 schema fields changed
    • addedInput schema / properties / personalization_note
      Added value: +{
      +  "description": "A short note/hook for writing the LinkedIn message (e.g. 'reference their new plant in Brno'). Fed to the message generator. Optional.",
      +  "type": "string"
      +}
    • addedInput schema / properties / web_research
      Added value: +{
      +  "description": "Free-text research about the person/company found online (news, website, recent events). Used as facts to personalize the outreach. Optional.",
      +  "type": "string"
      +}
  4. Added

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnly=false, idempotentHint=true and destructiveHint=false, but the description adds substantial context beyond them: existing contacts are returned rather than duplicated, web_research/personalization_note are MERGED so they never blank existing data, and list_id MOVES an existing contact. This discloses real behavior the structured fields do not.

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

Conciseness4/5

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

Front-loaded with the primary use case and alternative, which is good structure, but it is somewhat long and partially repetitive ('when you know their LinkedIn profile URL' vs 'when you already know the exact profile URL'). Each sentence earns most of its place, but a little trimming would help.

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 9-parameter mutation with no output schema and no annotations-based return info, the description covers create-vs-return-existing behavior, list routing, the two semantic payload params and their merge rule, and downstream usage. An agent has everything needed to call it correctly.

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 the baseline is 3, but the description adds genuine semantics beyond the schema: web_research and personalization_note are stored on the contact and fed to the LinkedIn message generator as facts, and on an existing contact they merge rather than overwrite. It clarifies downstream effect, which the per-parameter descriptions do not.

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 (upsert a LinkedIn contact) and makes the scope explicit: create from a known profile URL, or return the existing contact if already imported. It also names the sibling to use when no URL exists (add_crm_contact), so the agent can distinguish it without opening schemas.

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

Usage Guidelines5/5

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

Gives explicit when-to-use ('when you already know the exact profile URL and do not need to run a search'), an explicit alternative ('Without a URL use add_crm_contact'), and downstream context (can be passed to add_contacts_to_campaign). Nothing is left to inference.

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.