Skip to main content
Glama

Fetch Linkedin Messages With Person

fetch_linkedin_messages_with_person
Read-only

Query the local store with search_linkedin_message_history first. Reach for this tool only when that misses, when you need messages older than the roughly two-week local backfill window, or when you must be certain whether a conversation exists — this reads LinkedIn's own synced history, so an empty result here means no such conversation, not merely "outside the local window". Fetched messages are written back to the local store, so a later search_linkedin_message_history sees them too — unless whoever's history this is keeps only prospects' data and this person isn't one of their prospects; then they're returned but not stored.

This is not a name-lookup tool: pass the person's LinkedIn provider_id, sourced from a prospect row, search_linkedin_connections, or a prior local message — never guessed from a name. On success, a dict with success=True, chat_id (the chat holding the newest message; pass to setup_linkedin_sequence with action_type='message' to reply), count, truncated (True when older messages exist beyond the fetch cap), messages — newest first, each with direction ('sent'/'received', or 'unknown' when LinkedIn omits the sender flag), message_datetime (ISO), and content (truncated to 1000 chars) — and connection_request_note: the note on your accepted connection request, which LinkedIn replays into the chat when they accept, as message_datetime + content (null when there's none). It's the invite, not a message you sent them, so it's kept out of messages and count. On failure, success=False and error; an error that mentions reconnecting means the user must reconnect LinkedIn in Settings.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
provider_idYesThe other person's LinkedIn provider_id (the `sender_provider_id` / `recipient_provider_id` on message and connection rows).
on_behalf_ofNoA teammate's email (one with conversation sharing turned on), or an agency client's from list_agency_clients, to run this call in that account: their agents, settings, connected accounts, and credits. Omit it to act on your own account.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / on_behalf_of / description
      Previous value: -"Read a consented teammate's LinkedIn history instead of\nyour own — pass their email. Gated on that teammate's\nconversation-sharing setting; a teammate who hasn't shared is\nrejected. Reads via the teammate's own LinkedIn connection and\ncaches the result to their local store. Omit for your own.\nOr pass an agency client's email, from list_agency_clients, to run the call in that client's account, where none of the teammate limits above apply."New value: +"A teammate's email (one with conversation sharing turned on), or an agency client's from list_agency_clients, to run this call in that account: their agents, settings, connected accounts, and credits. Omit it to act on your own account."
  2. Changed2 schema fields changed
    • removedInput schema / properties / as_teammate
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Read a consented teammate's LinkedIn history instead of\nyour own — pass their email. Gated on that teammate's\nconversation-sharing setting; a teammate who hasn't shared is\nrejected. Reads via the teammate's own LinkedIn connection and\ncaches the result to their local store. Omit for your own."
      -}
    • addedInput schema / properties / on_behalf_of
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Read a consented teammate's LinkedIn history instead of\nyour own — pass their email. Gated on that teammate's\nconversation-sharing setting; a teammate who hasn't shared is\nrejected. Reads via the teammate's own LinkedIn connection and\ncaches the result to their local store. Omit for your own.\nOr pass an agency client's email, from list_agency_clients, to run the call in that client's account, where none of the teammate limits above apply."
      +}
  3. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only supply readOnlyHint=true, but the description adds substantial behavior beyond that: fetched messages are written back to the local store (with a documented exception for non-prospect histories), empty results mean no conversation rather than a window miss, results can be truncated at a cap, the replayed connection-request note is kept out of `messages`/`count`, and reconnect errors require user action. These are exactly the side effects and edge cases annotations can't convey.

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 purpose and the routing rule, then side effects, then parameter sourcing, then returns — a logical order with no filler sentences. It is fairly long, but the length is justified by the tool's complexity and the absence of an output schema.

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?

No output schema exists, so the `<returns>` block carries the burden and does so thoroughly (success flag, chat_id, count, truncated, message fields, connection_request_note, failure/error semantics). Combined with the side-effect and sourcing notes, an agent has everything needed to call and interpret this tool 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, and the description goes further by specifying how to source `provider_id` (from a prospect row, `search_linkedin_connections`, or a prior local message) and warning never to guess it from a name. That sourcing guidance adds real meaning beyond the schema's field-level descriptions.

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 (fetch) and resource (LinkedIn message history with one person) with scope (full history, live via Unipile). It explicitly distinguishes itself from the sibling `search_linkedin_message_history` and even clarifies what it is NOT (a name-lookup tool), so an agent can separate it from neighbors without opening a schema.

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 (after the local store misses, for messages older than the ~2-week backfill, when certainty about conversation existence is required), names the alternative to try first, and states when-not to use it (name lookup). This is the when/when-not/alternatives trifecta.

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