Skip to main content
Glama
gtm-api

gtm-api: LinkedIn MCP Server

gtm-api: LinkedIn MCP Server

Site Protocol License Smithery

gtm-api is a managed LinkedIn MCP server. It gives an AI agent one endpoint, three MCP tools and 160+ typed LinkedIn actions over the Model Context Protocol, so Claude, ChatGPT or Cursor can search, connect, message and enrich on a LinkedIn account you own, with account safety enforced server side.

This repository holds the public interface: what the server exposes, how to connect a client, and how the safety layer works.

What is a LinkedIn MCP server?

A LinkedIn MCP server exposes LinkedIn actions as Model Context Protocol tools, so an AI agent calls them directly, the way a person would click through the UI. LinkedIn publishes no official API for invitations, member messages or open profile search, so a LinkedIn MCP server works through an account you own rather than through LinkedIn's developer platform.

Two shapes exist today. Cookie-driven open-source servers run a browser session with your own cookie and no pacing. Managed servers run each account in isolated infrastructure with limits enforced before every action. gtm-api is the second kind.

Related MCP server: LinkedIn Buddy

Which clients it works with

Any MCP-compatible client:

  • Claude (Desktop, Code, and the API)

  • Cursor

  • ChatGPT (via connectors)

  • LangChain, n8n, and custom agent runtimes

Not using MCP? Every tool is also a typed REST endpoint with webhooks. One schema generates all three surfaces.

Quickstart

1. Sign up. Create an account at app.gtm-api.com (forever free plan, no card) and connect a LinkedIn account. It opens in a dedicated anti-detect cloud browser with its own proxy.

2. Add the server to your MCP client. For Claude Desktop, edit claude_desktop_config.json (example in examples/):

{
  "mcpServers": {
    "gtm-api": {
      "url": "https://mcp.gtm-api.com/mcp"
    }
  }
}

There is no key to paste. The endpoint authenticates with OAuth: your client gets a WWW-Authenticate challenge on the first call, registers itself with the authorization server (dynamic client registration), and opens a consent page in your browser.

Headless clients can skip the browser. The same API key (gtm_live_...) that authenticates the REST API also works on this endpoint as a plain bearer token, which is what makes it usable from CI and servers:

claude mcp add --transport http gtm-api https://mcp.gtm-api.com/mcp --header "Authorization: Bearer gtm_live_..."

For command-spawning clients, the launcher below reads the key from GTM_API_KEY instead (1.3.0 or newer; older pins ignore it and do OAuth only). Pick one mode per connection: with a key attached, the OAuth flow never starts. Interactive clients such as claude.ai connectors have no header field and always use OAuth. Full matrix: docs.gtm-api.com/mcp/connect.

Client can only spawn a command, not open a URL? The @gtm-api/linkedin-mcp launcher bridges stdio clients to the same endpoint and runs the same OAuth flow (config in examples/):

{
  "mcpServers": {
    "gtm-api": {
      "command": "npx",
      "args": ["-y", "@gtm-api/linkedin-mcp"]
    }
  }
}

For Claude Code it is one line: claude mcp add --transport http gtm-api https://mcp.gtm-api.com/mcp.

The same launcher also ships as a Docker image, gtmapi/linkedin-mcp (config in examples/). Mount a volume on the token cache so the consent step runs once rather than on every container:

{
  "mcpServers": {
    "gtm-api": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-v", "gtm-mcp-auth:/home/node/.mcp-auth", "gtmapi/linkedin-mcp"]
    }
  }
}

3. Restart the client and prompt in plain English:

"Every morning, accept new connection invitations from founders, reply with a short welcome, and add anyone hiring SDRs to a warm list."

The agent discovers the actions and chains them: fetch the latest connection invitations, accept the ones that match, send each new contact a short message. Every outward action runs a preview-then-confirm step and a server-side daily-limit check before it reaches LinkedIn.

Cursor plugin

This repository is also a Cursor plugin (.cursor-plugin/plugin.json). Installing it adds two things:

  • The hosted MCP server, https://mcp.gtm-api.com/mcp, declared in .mcp.json.

  • The gtm-api-linkedin skill. It tells the agent to discover tools before calling them, to show you the preview of every send before it commits, and to stop on a limit refusal instead of retrying it.

Install it from the Cursor Marketplace: open Customize, search for gtm-api, select Install. To run it from this repository instead, copy the plugin into Cursor's local plugin folder:

git clone https://github.com/gtm-api/linkedin-mcp.git /tmp/linkedin-mcp
mkdir -p ~/.cursor/plugins/local/gtm-api
cp -R /tmp/linkedin-mcp/.cursor-plugin /tmp/linkedin-mcp/.mcp.json /tmp/linkedin-mcp/skills /tmp/linkedin-mcp/assets ~/.cursor/plugins/local/gtm-api/

Then run Developer: Reload Window and check that Customize lists the skill and the MCP server.

The plugin carries no key and needs no configuration. The first tool call opens a consent page in your browser: you sign in to app.gtm-api.com (forever free plan, no card) and pick the workspace the agent acts in. Cursor registers itself as an OAuth client on that first call, so there is no client ID to create. To add the server without the skill, use the one-click Cursor link on docs.gtm-api.com/mcp/connect.

MCP tools

The server exposes exactly three MCP tools. Discovery is progressive: an agent lists the toolsets, inspects one, then invokes an action. The 160+ LinkedIn actions never load into the model's context at once, so the schema footprint stays around 400 tokens.

[
  {
    "name": "list_toolsets",
    "description": "List the available toolsets (domains) on this server. Each toolset groups related tools (e.g. linkedin.messaging, id.billing). Start here, then get_toolset_tools to inspect one, then call_tool to run a tool. Requires OAuth authorization (Bearer token).",
    "input_schema": { "type": "object", "properties": {} }
  },
  {
    "name": "get_toolset_tools",
    "description": "List the tools in a toolset. Default (lite) returns name + title + one-line summary; pass verbose:true for full descriptions, safety flags, and parameter names. Run one via call_tool.",
    "input_schema": {
      "type": "object",
      "properties": {
        "toolset": { "type": "string", "description": "Toolset id from list_toolsets, e.g. \"linkedin.messaging\"." },
        "verbose": { "type": "boolean", "description": "Include full descriptions + parameter names." }
      },
      "required": ["toolset"]
    }
  },
  {
    "name": "call_tool",
    "description": "Invoke a tool by name (discovered via get_toolset_tools) with its arguments object. Behaves exactly like calling the tool on its domain mount. Dangerous tools still require the two-step preview→confirm (pass commit_token inside arguments on the confirm call).",
    "input_schema": {
      "type": "object",
      "properties": {
        "name": { "type": "string", "description": "Exact tool name." },
        "arguments": { "type": "object", "description": "The tool's arguments object." }
      },
      "required": ["name"]
    }
  }
]

call_tool validates arguments against the target action's own input schema, so preview-then-confirm, rate limits and typed errors apply exactly as if the action were mounted directly.

What the agent can do

160+ typed actions across 11 LinkedIn toolsets, grouped here into seven areas:

Toolset

What it covers

Messaging

member messages, voice notes, InMail, Sales Navigator chats, inbox search and sync

Network

connection requests, accept or ignore invitations, withdraw, connections and followers

Content

track posts and metrics, comment, react, get engagers and commenters

Enrichment

lite and full profile, experience, skills, education, company data

Search

people, company and post search, similar profiles, employees, decision-makers, saved searches

Account health

smart limits, health snapshots, quota-hit, block and activity logs

Infrastructure

anti-detect cloud browsers, dedicated proxies, webhooks

The same endpoint also serves the account, billing and orchestration toolsets, 250+ typed actions in total. This repo documents the LinkedIn half.

LinkedIn is the live channel today. Email (Gmail, Outlook, IMAP), messengers (WhatsApp, Telegram, Instagram DMs) and calendars (Google, Microsoft) are on the roadmap on the same typed contract.

Is it safe for my LinkedIn account?

Safety is enforced by the server itself, under every tool call. Six mechanisms:

  • Owned accounts. The agent acts through an account you connected and control. There is no shared account pool.

  • Session isolation. Each account runs in its own anti-detect cloud browser with a dedicated proxy. One account, one session, one device signature.

  • Warm-up. A new account starts at a fraction of platform maximum, and its allowance is raised programmatically as the account ages and builds history.

  • Server-side limits. Per-action daily budgets are checked before dispatch, across 16 action buckets.

  • Randomized pacing. Bulk work is spread with per-gap randomized intervals, because a fixed cadence is itself a detectable pattern.

  • Preview then confirm. Outward actions return a preview and require confirmation, so an over-eager agent cannot burn an account.

On this setup, 20,000+ LinkedIn accounts run on gtm-api.com, and under 1% of them have ever been restricted. Full method: gtm-api.com/safe-linkedin-automation.

How it compares to open-source LinkedIn MCP servers

Cookie-driven servers such as stickerdaniel/linkedin-mcp-server run a browser session with your own LinkedIn cookie and leave pacing to you: the project's README documents the cookie login flow and lists no rate limiting. Apify's LinkedIn actors are a different shape, hosted scrapers priced per result and focused on pulling data out.

gtm-api (managed)

Cookie-driven open source

Account model

Owned, warmed, isolated

Your live cookie session

Safety layer

Anti-detect browser, dedicated proxy, limits

Not built in

Limit enforcement

Server side, before every action

You build it

Sends (connect, message, InMail)

Yes, with preview then confirm

Partial or none

Published restriction figure

Under 1% of 20,000+ accounts ever restricted

Not published

Support

Managed

Community

Price

From $39 per connected account per month, $10 at volume

Free, run it yourself

Self-hosted, auditable code

No, managed service

Yes

Pricing

Volume pricing per connected account per month, from $10/account at scale, with unlimited API calls and no per-action fees. Forever free plan, no card: gtm-api.com/pricing.

A note on LinkedIn's terms

LinkedIn's User Agreement does not permit third-party automation, so every tool in this space carries risk and no vendor can honestly promise otherwise. gtm-api reduces that risk by acting only on accounts you own, with warm-up, human-like pacing and enforced limits, which is why under 1% of the accounts on it have ever been restricted. This is not legal advice.


gtm-api.com, the LinkedIn API and MCP server for AI agents.

Available Tools

3 tools
call_toolAInspect

Invoke a tool by name (discovered via get_toolset_tools) with its arguments object. Behaves exactly like calling the tool on its domain mount. Dangerous tools still require the two-step preview→confirm (pass commit_token inside arguments on the confirm call). To act in another of your teams, set the top-level team_sid: the edge swaps the token for that team (the OAuth grant must cover it); every response echoes the team it ran in as meta.team_sid.

NameRequiredDescriptionDefault
nameYesExact tool name.
_metaNo
team_sidNoRun this call in another of your teams. The edge exchanges the request token for a sibling installation token (RFC 8693); the OAuth grant must cover that team and you must be a live member. Omit to act in the token team (see meta.team_sid on any response).
argumentsNoThe tool's arguments object.

TDQS

A4.5/5.0
Behavior5/5

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

Adds substantial behavior beyond the annotations: the preview tick confirm guard for dangerous tools, the RFC 8693 token swap when team_sid is set, the requirement that the OAuth grant covers the target team and that the caller be a live member, and the meta.team_sid echo on every response. None of this is recoverable from readOnlyHint/idempotentHint alone.

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?

Three sentences, front-loaded with the core action and then the two exceptional paths (confirm flow, cross-team). It is dense and every clause carries information, though the final team_sid sentence is long enough that a reader must parse it carefully.

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

Completeness4/5

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

For a polymorphic dispatcher with no output schema, the description covers dispatch, the confirmation handshake, and cross-team auth, plus one concrete return detail (meta.team_sid). It does not describe error/denial behavior or how results of the invoked tool are surfaced, which is the remaining gap.

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 75%, and the description still adds real meaning: it explains where `name` must come from, that commit_token rides inside `arguments` on the confirm call, and the full semantics and preconditions of `team_sid` (token exchange, grant coverage, live membership, omit-for-default). Only `_meta.user_goal` is left to the schema, which documents it adequately.

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 ('Invoke a tool by name') and immediately scopes it with the discovery prerequisite ('discovered via get_toolset_tools'), which cleanly separates it from both siblings. An agent can tell this is the dispatch/execution tool, not the discovery or listing tool, 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 Guidelines4/5

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

Gives a clear entry condition (name must come from get_toolset_tools) and the special flow for dangerous tools (two-step preview tick confirm with commit_token inside arguments). It also routes the cross-team case to team_sid. It never states when *not* to use it, but the prerequisites are explicit enough that an agent will not misfire.

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

get_toolset_toolsA
Read-onlyIdempotent
Inspect

List the tools in a toolset. Default (lite) returns name + title + one-line summary; pass verbose:true for full descriptions, safety flags, and parameter names. Run one via call_tool.

NameRequiredDescriptionDefault
_metaNo
toolsetYesToolset id from list_toolsets, e.g. "linkedin.messaging".
verboseNoInclude full descriptions + parameter names.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is covered. The description still adds real value by specifying that the default response is a truncated (lite) view and what verbose mode expands to include, which is behavior an agent cannot infer from annotations.

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

Conciseness5/5

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

Three short sentences, front-loaded with the core action, followed by the mode distinction and the handoff to call_tool. No filler and every sentence carries information.

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

Completeness4/5

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

With no output schema, the description correctly takes on the burden of describing return shape for both modes, which it does well. It omits any mention of toolset size limits or pagination, a minor gap for a listing tool.

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 67%, so the schema covers most of the surface, and the description adds meaning beyond it: it defines the default state of verbose (false/lite) and enumerates what verbose reveals, including "safety flags" not mentioned in the schema text. The toolset parameter's origin is only implied, hence not a 5.

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?

The description states a specific verb and resource ("List the tools in a toolset") and immediately disambiguates output modes. It also distinguishes itself from the sibling it would be confused with ("Run one via call_tool"), so an agent knows this enumerates rather than executes.

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?

It gives clear operating context: use the default lite mode for a quick scan, pass verbose:true when full descriptions/parameter names are needed, and use call_tool to actually invoke a listed tool. It does not explicitly name list_toolsets as the prerequisite for obtaining a toolset id, but the routing guidance is otherwise strong.

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

list_toolsetsA
Read-onlyIdempotent
Inspect

List the available toolsets (domains) on this server. Each toolset groups related tools (e.g. linkedin.messaging, id.billing). Start here, then get_toolset_tools to inspect one, then call_tool to run a tool. Requires OAuth authorization (Bearer token).

NameRequiredDescriptionDefault
_metaNo

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, non-destructive, and closed-world, so the safety profile is covered. The description adds a genuinely useful behavioral fact beyond them: the call 'Requires OAuth authorization (Bearer token)', which signals an auth failure mode agents must handle. It stops short of describing the shape or size of the returned list.

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

Conciseness5/5

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

Four short sentences, each with a distinct job: what the tool is, what a toolset contains, the workflow, and the auth prerequisite. The core purpose is front-loaded with zero filler.

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

Completeness4/5

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

For a no-argument, read-only listing tool with no output schema, the description covers purpose, sequencing, and the auth requirement — enough to call it correctly. Only the return shape (names only vs. names plus descriptions) is left unstated, a minor gap.

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

Parameters3/5

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

The schema's single parameter (_meta.user_goal) is an optional, client-side analytics field that does not affect tool behavior, and the description says nothing about parameters — it does not compensate for the reported 0% coverage. Since that lone param is inert metadata and cannot be misused, the omission is low-impact rather than harmful, warranting a baseline 3.

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 ('List the available toolsets (domains) on this server') and clarifies the concept with concrete examples ('linkedin.messaging, id.billing'). It also distinguishes itself from siblings by placing itself first in the workflow, so an agent can tell it apart from get_toolset_tools and call_tool immediately.

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?

Explicitly prescribes the call order: 'Start here, then get_toolset_tools to inspect one, then call_tool to run a tool.' This names both alternatives and the condition under which each is used, leaving nothing to inference.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv1.3.1
    • First observedcall_tool
    • First observedget_toolset_tools
    • First observedlist_toolsets

TDQS

A4.4/5.0

Scored across 3 tools

Disambiguation5/5

The three tools form an explicit, non-overlapping discovery→inspection→invocation pipeline, and each description states its position in that sequence. There is no realistic way to confuse listing toolsets, listing tools in a toolset, and invoking a tool.

Naming Consistency4/5

All names are snake_case verb_noun pairs (list_toolsets, get_toolset_tools, call_tool), which is predictable and readable. The only minor wrinkle is that the object noun shifts between 'toolsets' and 'tool', though the intent is obvious from context.

Tool Count4/5

Three tools is at the low end, but for a dynamic gateway that proxies an unbounded catalog, a small fixed surface is exactly right and each tool earns its place. Nothing is redundant or missing at the plumbing layer.

Completeness4/5

Discovery, schema retrieval (lite vs verbose), and execution including the preview→confirm commit_token flow and team_sid override are all covered. Minor gaps: no cross-toolset keyword search and no dedicated authorization/introspection tool, so an agent must walk toolsets sequentially to find a capability.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for LinkedIn automation that enables AI agents to perform LinkedIn actions (search, inbox, feed, jobs, etc.) safely with human-like evasion and two-phase commit preview.
    4 npm
    3
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server that lets AI agents operate a real LinkedIn account in plain English with safety controls and approval queues.
    12 npm
    1
    MIT