Skip to main content
Glama

Setup Linkedin Sequence

setup_linkedin_sequence
Destructive

A campaign already sending without a flow keeps calling this tool without node_id, as do a one-off send outside a campaign and a resolve look-up. Every other campaign sends through its flow, even a single message or connection requests with nothing after: create it with define_sequence and add the prospects with track_prospects, and the flow's steps call this tool with their node_id. A call without node_id on an agent that has no flow and hasn't sent any outreach yet is refused.

Only call this AFTER the user has explicitly confirmed the outreach.

BATCH: pass ALL recipients in a single call. The tool is designed to batch — provider_id recipients queue directly (resolving before send unless already verified) and URL/slug recipients route through the background resolving queue with rate-limited, business-hours pacing. Calling once per recipient multiplies prompt overhead by ~N and produces no observable benefit. If you have 27 prospects to queue, that's ONE call with identifiers of length 27, not 27 calls of length 1. Dict with known_queued (provider_id recipients queued directly), deferred_count (URL/slug recipients queued for background resolution), tracking_skipped (recipients already tracked in another campaign, so nothing queued for them — each entry names existing_agent_title / existing_agent_id; surface these and let the user place them), skipped (recipients the queue helper refused — each entry has target_name, provider_id, reason, error, plus existing_agent_id / existing_agent_title when a live row on another campaign is what blocked the send; name that campaign to the user rather than calling it a duplicate on this one), accept_followup (present only when connection requests queued to this agent but no sequence node or accept trigger will fire a message on acceptance — names how to wire one), and rate_limit_estimate — an ETA for the batch covering expected profile resolution and sending days given the user's current rate-limit budget.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
enrichNoWhen True, look up each prospect's verified work email via Apollo and stamp it on the tracking row. Requires each recipient to have `target_name` plus a URL-shaped `linkedin_url`. Costs 1 Sliq credit per verified hit; free with BYO Apollo. Recipients missing inputs and recipients past the credit limit are silently skipped.
notifyNoOnly for action_type='resolve'. False (default) = a silent data lookup the person is NOT notified of. True = a visible "View Profile" visit that DOES notify them ("X viewed your profile") — a no-message warm-up touch, typically placed later in a sequence, not a data read. Same paced lookup and daily cap either way. Rejected on non-resolve actions. On a sequenced call the resolve node's own `notify` field is authoritative and is OR'd in, so a "View Profile" node always visits.
node_idNoOptional. The id of the sequence-DAG node this batch enacts (a node in the agent's `sequence`, authored via `define_sequence`). Stamped on every queued row so the Campaign Flow view can place each prospect and count per node. Pass it whenever the agent has a sequence. Rejected with ModelRetry if it isn't a node in the agent's sequence.
agent_idNoOptional. Pass for campaigns or when inside an existing agent. Omit for ad hoc sends — the tool auto-uses the "LinkedIn Quick Actions" default agent. Every send lands in the agent you name; recipients already tracked in a different one are reported in `tracking_skipped` rather than queued (see Returns).
action_typeYes'resolve', 'connection_request', 'message', 'inmail', or 'follow'. For 'resolve' and 'follow', the `message` field is unused and rejected with ModelRetry. Follow auto-sends by default (its own `linkedin_follow` approval subtype); gate it via outbound-approval settings. 'resolve' commits NO outreach — it queues a paced profile lookup that fires a `resolved_profile` trigger event per person; use it when the per-person action depends on looked-up data (see the trigger-code skill for the branching example). Pair with `notify=True` for a visible "View Profile" visit (see `notify`). The event carries the looked-up profile — `already_connected`, `network_distance`, `connections_count`, `follower_count`, `headline`, `title`, `company` — and the same fields land on the prospect's row under `data`, so a later turn reads them with `query_prospects` instead of resolving again. A connection-count rule can read `connections_count` from here; when the rule turns on the count alone, `enrich_linkedin_profiles` returns it for the whole list in one call without spending account budget, so filter there first and queue only the recipients that pass.
identifiersYesList of recipient dicts. Each dict must carry one of `linkedin_url` (a profile URL or slug), `provider_id`, or `chat_id`, copied verbatim from the tool result that surfaced the person — never a slug rebuilt from a display name, which enrolls the wrong person. Freeform attributes go under `data`; unknown top-level keys are rejected. If you have no identifier for someone, omit them rather than guess. When a recipient's `target_name` shares no tokens with any LinkedIn name already held for that `provider_id` (a verified prospect or a post engager), the whole batch is rejected with ModelRetry before anything queues — fix the pairing and re-send (use the person's LinkedIn URL/identifier if the pid is wrong; use one consistent name if it's the same person). A pid with no held name isn't gated here — it resolves before send and the resolver adjudicates the name then.
linkedin_apiNoFor inmail only. Leave unset — the tool bills the InMail against the pool for the LinkedIn plan Sliq recorded when LinkedIn was connected. Only pass an explicit 'classic', 'sales_navigator', or 'recruiter' to force a pool.
on_behalf_ofNoAn agency client's email, from list_agency_clients, to run this call in that client's 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 / identifiers / items / properties / message / description
      Previous value: -"The final personalized body text, already resolved to literal words. The tool substitutes nothing and rejects any merge-field or placeholder syntax."New value: +"The final personalized body text, already resolved to literal words. The tool substitutes nothing and rejects any merge-field or placeholder syntax, apart from a [[slot]] in double square brackets the user asked to fill in themselves while approving."
  2. Changed2 schema fields changed
    • changedInput schema / properties / linkedin_api / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "classic",
      -      "sales_navigator",
      -      "recruiter"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "classic",
      +      "sales_navigator",
      +      "recruiter"
      +    ],
      +    "title": "LinkedInApi",
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / on_behalf_of
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "An agency client's email, from list_agency_clients, to run this call in that client's account: their agents, settings, connected accounts, and credits. Omit it to act on your own account."
      +}
  3. Changed1 schema field changed
    • changedInput schema / properties / linkedin_api / description
      Previous value: -"For inmail only. Leave unset — the tool bills the InMail\nagainst the pool the account's LinkedIn plan provides. Only pass an\nexplicit 'classic', 'sales_navigator', or 'recruiter' to force a pool."New value: +"For inmail only. Leave unset — the tool bills the InMail\nagainst the pool for the LinkedIn plan Sliq recorded when LinkedIn\nwas connected. Only pass an explicit 'classic', 'sales_navigator',\nor 'recruiter' to force a pool."
  4. Changed1 schema field changed
    • changedInput schema / properties / node_id / description
      Previous value: -"Optional. The id of the sequence-DAG node this batch enacts\n(a node in the agent's `sequence`, authored via `define_sequence`).\nStamped on every queued row so the Campaign Flow view can place\neach prospect and count per node. Pass it whenever the agent has a\nsequence; omit for flowless/ad-hoc sends. Rejected with ModelRetry\nif it isn't a node in the agent's sequence."New value: +"Optional. The id of the sequence-DAG node this batch enacts\n(a node in the agent's `sequence`, authored via `define_sequence`).\nStamped on every queued row so the Campaign Flow view can place\neach prospect and count per node. Pass it whenever the agent has a\nsequence. Rejected with ModelRetry if it isn't a node in the agent's\nsequence."
  5. Changed1 schema field changed
    • changedInput schema / properties / identifiers / description
      Previous value: -"List of recipient dicts. Each dict must carry one of\n`linkedin_url` (a profile URL or slug), `provider_id`, or `chat_id`,\ncopied verbatim from the tool result that surfaced the person — never a\nslug rebuilt from a display name, which enrolls the wrong person.\nFreeform attributes go under `data`; unknown top-level keys are\nrejected. If you have no identifier for someone, omit them rather than\nguess. When a recipient's\n`target_name` shares no tokens with the verified (resolved) name\nalready tracked for that `provider_id`, the whole batch is\nrejected with ModelRetry before anything queues — fix the pairing\nand re-send (use the person's LinkedIn URL/identifier if the pid\nis wrong; use one consistent name if it's the same person). An\nunverified pid isn't gated here — it resolves before send and the\nresolver adjudicates the name then."New value: +"List of recipient dicts. Each dict must carry one of\n`linkedin_url` (a profile URL or slug), `provider_id`, or `chat_id`,\ncopied verbatim from the tool result that surfaced the person — never a\nslug rebuilt from a display name, which enrolls the wrong person.\nFreeform attributes go under `data`; unknown top-level keys are\nrejected. If you have no identifier for someone, omit them rather than\nguess. When a recipient's\n`target_name` shares no tokens with any LinkedIn name already held\nfor that `provider_id` (a verified prospect or a post engager), the\nwhole batch is rejected with ModelRetry before anything queues —\nfix the pairing and re-send (use the person's LinkedIn\nURL/identifier if the pid is wrong; use one consistent name if it's\nthe same person). A pid with no held name isn't gated here — it\nresolves before send and the resolver adjudicates the name then."
  6. Changed3 schema fields changed
    • addedInput schema / properties / agent_id
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Optional. Pass for campaigns or when inside an existing agent.\nOmit for ad hoc sends — the tool auto-uses the \"LinkedIn Quick\nActions\" default agent. Every send lands in the agent you name;\nrecipients already tracked in a different one are reported in\n`tracking_skipped` rather than queued (see Returns)."
      +}
    • changedInput schema / properties / node_id / description
      Previous value: -"Optional. The id of the sequence-DAG node this batch enacts\n(a node in the task's `sequence`, authored via `define_sequence`).\nStamped on every queued row so the Campaign Flow view can place\neach prospect and count per node. Pass it whenever the task has a\nsequence; omit for flowless/ad-hoc sends. Rejected with ModelRetry\nif it isn't a node in the task's sequence."New value: +"Optional. The id of the sequence-DAG node this batch enacts\n(a node in the agent's `sequence`, authored via `define_sequence`).\nStamped on every queued row so the Campaign Flow view can place\neach prospect and count per node. Pass it whenever the agent has a\nsequence; omit for flowless/ad-hoc sends. Rejected with ModelRetry\nif it isn't a node in the agent's sequence."
    • removedInput schema / properties / task_id
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "integer"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "Optional. Pass for campaigns or when inside an existing task.\nOmit for ad hoc sends — the tool auto-uses the \"LinkedIn Quick\nActions\" default task. Every send lands in the task you name;\nrecipients already tracked in a different one are reported in\n`tracking_skipped` rather than queued (see Returns)."
      -}
  7. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already mark this as non-read-only and destructive, and the description adds substantial behavioral context beyond them: batching expectations, provider-id versus URL/slug handling, background resolution, rate limiting, business-hours pacing, tracking-item creation, skipped-recipient reasons, and accepted follow-up wiring. The mutation/destructive nature is consistent with annotations, with no contradiction.

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?

The summary is front-loaded and the description is structured into purpose, usage rules, batching guidance, and returns. It is long, but the length is mostly justified for a complex, high-impact outreach tool with no output schema; some portions could be tightened, but it is not padded.

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 complex 8-parameter, destructive outreach tool without an output schema, the description covers purpose, routing, prerequisites, batching, behavioral side effects, and return-value semantics thoroughly. It gives the agent enough context to invoke the tool correctly and interpret key outcomes.

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 parameter definitions already carry much of the burden. The description adds meaningful operational semantics beyond the schema, especially for `identifiers` batching, `node_id` flow usage, and `action_type` behavior in one-off versus sequenced campaigns, though it does not need to repeat every field-level detail.

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 and resource (queue LinkedIn outreach for connection requests, messages, or InMails) and distinguishes itself as the single LinkedIn outreach tool. It names related tools like `define_sequence`, `track_prospects`, and the underlying `linkedin_invite_queue`, so an agent can tell how it relates to siblings.

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 routing rules: use without `node_id` for one-off sends, `resolve` lookups, or campaigns already sending without a flow; use through a flow for every other campaign; create flows with `define_sequence` and prospects with `track_prospects`. It also states the call must happen only after explicit user confirmation and explains the refusal case when no flow exists.

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