Skip to main content
Glama

lhremote: LinkedHelper Automation Toolkit

CI codecov npm version npm downloads GitHub Repo stars License

CLI and MCP server for LinkedHelper automation.

This project is brought to you by Alexey Pelykh.

What It Does

lhremote lets AI assistants (Claude, etc.) control LinkedHelper through the Model Context Protocol. It can:

  • App management — detect, launch, and quit LinkedHelper instances

  • Account & instance control — list accounts, start/stop instances, check status

  • Campaign automation — create, configure, start, stop, and monitor campaigns with full action-chain management

  • People import — import LinkedIn profile URLs into campaign target lists

  • Profile queries — look up and search cached LinkedIn profiles from the local database

  • Messaging — send direct messages, InMails, and connection requests; query messaging history and check for replies

  • LinkedIn engagement — visit profiles, endorse skills, follow/unfollow, like posts, comment, and react

  • Feed & post intelligence — read the LinkedIn feed, search posts, get post details, engagement stats, and engager lists

  • Profile enrichment — extract emails, phones, socials, and company data from LinkedIn profiles

  • LinkedIn search — build search URLs, resolve entity IDs, and query reference data for search filters

  • Budget & throttle monitoring — check daily action limits and LinkedIn throttling status

  • Action discovery — list available LinkedHelper action types with configuration schemas

Quick Start

npm install -g lhremote        # or: npx lhremote --help
lhremote launch-app            # start LinkedHelper with remote debugging
lhremote list-accounts         # find your LinkedIn account ID
lhremote start-instance        # start an instance (auto-selects single account)
lhremote campaign-create --file my-campaign.yaml   # create a campaign
lhremote import-people-from-urls <campaignId> --urls "https://www.linkedin.com/in/..."
lhremote campaign-start <campaignId> --person-ids <id1,id2,...>
lhremote campaign-status <campaignId>              # monitor progress

Pacing: LinkedIn monitors automated activity. See the Rate Limiting guide for recommended settings.

Prerequisites

  • Node.js >= 24

  • LinkedHelper desktop application (requires a paid subscription)

Installation

npm install -g lhremote

Or run directly with npx:

npx lhremote --help

Usage with Claude Desktop

Add to your Claude Desktop configuration (claude_desktop_config.json):

{
    "mcpServers": {
        "lhremote": {
            "command": "npx",
            "args": ["lhremote", "mcp"]
        }
    }
}

Once configured, Claude can use all 68 tools directly. A typical workflow:

  1. find-app — Detect a running LinkedHelper instance (or launch-app to start one)

  2. list-accounts — See available LinkedIn accounts

  3. start-instance — Start an instance for an account

  4. describe-actions — Explore available action types

  5. campaign-create — Create a campaign from YAML/JSON configuration

  6. import-people-from-urls — Import target LinkedIn profiles into the campaign

  7. campaign-start — Run the campaign

  8. campaign-status / campaign-statistics — Monitor progress

  9. query-messages / check-replies — Review messaging results

CLI Usage

The lhremote command provides the same functionality as the MCP server. Every MCP tool has a corresponding CLI command.

App Management

lhremote find-app [--json]
lhremote launch-app
lhremote quit-app

Account & Instance

lhremote list-accounts [--cdp-port <port>] [--json]
lhremote start-instance <accountId> [--cdp-port <port>]
lhremote stop-instance <accountId> [--cdp-port <port>]
lhremote check-status [--cdp-port <port>] [--json]

Campaigns

lhremote campaign-list [--include-archived] [--json]
lhremote campaign-create --file <path> | --yaml <config> | --json-input <config> [--cdp-port <port>] [--json]
lhremote campaign-get <campaignId> [--cdp-port <port>] [--json]
lhremote campaign-export <campaignId> [--format yaml|json] [--output <path>] [--cdp-port <port>]
lhremote campaign-update <campaignId> [--name <name>] [--description <text>] [--clear-description] [--cdp-port <port>] [--json]
lhremote campaign-delete <campaignId> [--cdp-port <port>] [--json]
lhremote campaign-erase <campaignId> [--cdp-port <port>] [--json]
lhremote campaign-start <campaignId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
lhremote campaign-stop <campaignId> [--cdp-port <port>] [--json]
lhremote campaign-status <campaignId> [--include-results] [--limit <n>] [--cdp-port <port>] [--json]
lhremote campaign-statistics <campaignId> [--action-id <id>] [--max-errors <n>] [--cdp-port <port>] [--json]
lhremote campaign-retry <campaignId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
lhremote campaign-list-people <campaignId> [--action-id <id>] [--status <status>] [--limit <n>] [--offset <n>] [--cdp-port <port>] [--json]

Campaign Actions

lhremote campaign-add-action <campaignId> --name <name> --action-type <type> [--description <text>] [--cool-down <ms>] [--max-results <n>] [--action-settings <json>] [--cdp-port <port>] [--json]
lhremote campaign-remove-action <campaignId> <actionId> [--cdp-port <port>] [--json]
lhremote campaign-update-action <campaignId> <actionId> [--name <name>] [--description <text>] [--clear-description] [--cool-down <ms>] [--max-results <n>] [--action-settings <json>] [--cdp-port <port>] [--json]
lhremote campaign-reorder-actions <campaignId> --action-ids <ids> [--cdp-port <port>] [--json]
lhremote campaign-move-next <campaignId> <actionId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]

Campaign Targeting

lhremote campaign-exclude-list <campaignId> [--action-id <id>] [--cdp-port <port>] [--json]
lhremote campaign-exclude-add <campaignId> --person-ids <ids> | --person-ids-file <path> [--action-id <id>] [--cdp-port <port>] [--json]
lhremote campaign-exclude-remove <campaignId> --person-ids <ids> | --person-ids-file <path> [--action-id <id>] [--cdp-port <port>] [--json]
lhremote campaign-remove-people <campaignId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
lhremote import-people-from-urls <campaignId> --urls <urls> | --urls-file <path> [--cdp-port <port>] [--json]
lhremote collect-people <campaignId> <sourceUrl> [--limit <n>] [--max-pages <n>] [--page-size <n>] [--source-type <type>] [--cdp-port <port>] [--json]

Collections

lhremote list-collections [--json]
lhremote create-collection <name> [--cdp-port <port>] [--json]
lhremote delete-collection <collectionId> [--cdp-port <port>] [--json]
lhremote add-people-to-collection <collectionId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
lhremote remove-people-from-collection <collectionId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
lhremote import-people-from-collection <collectionId> <campaignId> [--cdp-port <port>] [--json]

Profiles & Messaging

lhremote query-profile --person-id <id> | --public-id <slug> [--include-positions] [--json]
lhremote query-profiles [--query <text>] [--company <name>] [--include-history] [--limit <n>] [--offset <n>] [--json]
lhremote query-profiles-bulk --person-id <id>... | --public-id <slug>... [--include-positions] [--json]
lhremote query-messages [--person-id <id>] [--chat-id <id>] [--search <text>] [--limit <n>] [--offset <n>] [--json]
lhremote check-replies [--since <timestamp>] [--cdp-port <port>] [--json]
lhremote scrape-messaging-history --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]

LinkedIn Actions

lhremote visit-profile --person-id <id> | --url <url> [--extract-current-organizations] [--cdp-port <port>] [--json]
lhremote endorse-skills --person-id <id> | --url <url> [--skill-name <name>]... [--limit <n>] [--skip-if-not-endorsable] [--keep-campaign] [--cdp-port <port>] [--json]
lhremote enrich-profile --person-id <id> | --url <url> [--enrich-profile-info] [--enrich-phones] [--enrich-emails] [--enrich-socials] [--enrich-companies] [--keep-campaign] [--cdp-port <port>] [--json]
lhremote follow-person --person-id <id> | --url <url> [--mode <follow|unfollow>] [--skip-if-unfollowable] [--keep-campaign] [--cdp-port <port>] [--json]
lhremote like-person-posts --person-id <id> | --url <url> [--number-of-articles <n>] [--number-of-posts <n>] [--max-age-of-articles <days>] [--max-age-of-posts <days>] [--should-add-comment] [--message-template <json>] [--skip-if-not-liked] [--keep-campaign] [--cdp-port <port>] [--json]
lhremote message-person --person-id <id> | --url <url> --message-template <json> [--subject-template <json>] [--reject-if-replied] [--reject-if-messaged] [--keep-campaign] [--cdp-port <port>] [--json]
lhremote send-invite --person-id <id> | --url <url> [--message-template <json>] [--save-as-lead-sn] [--keep-campaign] [--cdp-port <port>] [--json]
lhremote send-inmail --person-id <id> | --url <url> --message-template <json> [--subject-template <json>] [--reject-if-replied] [--proceed-on-out-of-credits] [--keep-campaign] [--cdp-port <port>] [--json]
lhremote remove-connection --person-id <id> | --url <url> [--keep-campaign] [--cdp-port <port>] [--json]

Feed & Posts

lhremote get-feed [--count <n>] [--cursor <token>] [--cdp-port <port>] [--json]
lhremote get-post <postUrl> [--comment-count <n>] [--cdp-port <port>] [--json]
lhremote get-post-stats <postUrl> [--cdp-port <port>] [--json]
lhremote get-profile-activity <profile> [--count <n>] [--cursor <token>] [--cdp-port <port>] [--json]
lhremote search-posts <query> [--count <n>] [--cursor <n>] [--cdp-port <port>] [--json]
lhremote comment-on-post --url <url> --text <text> [--cdp-port <port>] [--json]
lhremote react-to-post <postUrl> [--type <like|celebrate|support|love|insightful|funny>] [--cdp-port <port>] [--json]
lhremote react-to-comment <postUrl> <commentUrn> [--type <like|celebrate|support|love|insightful|funny>] [--dry-run] [--cdp-port <port>] [--json]

LinkedIn Search & Reference

lhremote build-url <sourceType> [--keywords <keywords>] [--current-company <id>]... [--past-company <id>]... [--geo <id>]... [--industry <id>]... [--school <id>]... [--network <code>]... [--profile-language <code>]... [--service-category <id>]... [--filter <spec>]... [--slug <slug>] [--id <id>] [--json]
lhremote resolve-entity <entityType> <query> [--limit <n>] [--json]
lhremote list-reference-data <dataType> [--json]

Utilities

lhremote describe-actions [--category <category>] [--type <type>] [--json]
lhremote get-errors [--cdp-port <port>] [--json]
lhremote dismiss-errors [--cdp-port <port>] [--json]
lhremote get-action-budget [--cdp-port <port>] [--json]
lhremote get-throttle-status [--cdp-port <port>] [--json]

MCP Tools

Common Parameters

Most tools and CLI commands connect to LinkedHelper via the Chrome DevTools Protocol (CDP). In addition to the tool-specific parameters listed below, all CDP-connected tools accept:

Parameter

CLI Flag

Type

Default

Description

cdpPort

--cdp-port

number

9222

CDP debugging port

cdpHost

--cdp-host

string

127.0.0.1

CDP host address

allowRemote

--allow-remote

boolean

false

Allow connections to non-loopback addresses

Security warning: Enabling allowRemote permits CDP connections to remote hosts. CDP is an unsandboxed protocol that grants full control over the target browser — equivalent to remote code execution. Only enable this when the network path between your machine and the target host is fully secured (e.g., SSH tunnel, VPN, or trusted LAN).

App Management

find-app

Detect running LinkedHelper application instances and their CDP connection details.

No parameters.

launch-app

Launch the LinkedHelper application with remote debugging enabled.

Parameter

Type

Required

Default

Description

cdpPort

number

No

auto-select

CDP port to use

force

boolean

No

false

Kill existing LinkedHelper processes before launching

quit-app

Quit the LinkedHelper application.

Parameter

Type

Required

Default

Description

cdpPort

number

No

9222

CDP port

Account & Instance

list-accounts

List available LinkedHelper accounts. Returns account ID, LinkedIn ID, name, and email for each account.

Parameter

Type

Required

Default

Description

cdpPort

number

No

9222

CDP port

start-instance

Start a LinkedHelper instance for a LinkedIn account.

Parameter

Type

Required

Default

Description

accountId

number

No

auto-select if single account

Account ID

cdpPort

number

No

9222

CDP port

stop-instance

Stop a running LinkedHelper instance.

Parameter

Type

Required

Default

Description

accountId

number

No

auto-select if single account

Account ID

cdpPort

number

No

9222

CDP port

check-status

Check LinkedHelper connection status, running instances, and database health.

Parameter

Type

Required

Default

Description

cdpPort

number

No

9222

CDP port

Campaigns

campaign-list

List existing campaigns with summary statistics.

Parameter

Type

Required

Default

Description

includeArchived

boolean

No

false

Include archived campaigns

cdpPort

number

No

9222

CDP port

campaign-create

Create a new campaign from YAML or JSON configuration.

Parameter

Type

Required

Default

Description

config

string

Yes

Campaign configuration in YAML or JSON format

format

string

No

yaml

Configuration format (yaml or json)

cdpPort

number

No

9222

CDP port

campaign-get

Get detailed campaign information including action chain.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

cdpPort

number

No

9222

CDP port

campaign-export

Export campaign configuration as YAML or JSON.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

format

string

No

yaml

Export format (yaml or json)

cdpPort

number

No

9222

CDP port

campaign-update

Update a campaign's name and/or description.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

name

string

No

New campaign name

description

string

No

New description (empty string to clear)

cdpPort

number

No

9222

CDP port

campaign-delete

Delete (archive) a campaign.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

cdpPort

number

No

9222

CDP port

campaign-erase

Permanently erase a campaign and all related data from the database. This is irreversible — unlike campaign-delete (which archives), this removes all campaign data permanently.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

cdpPort

number

No

9222

CDP port

campaign-start

Start a campaign with specified target persons. Returns immediately (async execution).

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

personIds

number[]

Yes

Person IDs to target

cdpPort

number

No

9222

CDP port

campaign-stop

Stop a running campaign.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

cdpPort

number

No

9222

CDP port

campaign-status

Check campaign execution status and results.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

includeResults

boolean

No

false

Include execution results

limit

number

No

20

Max results to return

cdpPort

number

No

9222

CDP port

campaign-statistics

Get per-action statistics for a campaign.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

actionId

number

No

Filter to a specific action

maxErrors

number

No

5

Max top errors per action

cdpPort

number

No

9222

CDP port

campaign-retry

Reset specified people for re-run in a campaign.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

personIds

number[]

Yes

Person IDs to retry

cdpPort

number

No

9222

CDP port

Campaign Actions

campaign-add-action

Add a new action to a campaign's action chain. Use describe-actions to explore available action types.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

name

string

Yes

Display name for the action

actionType

string

Yes

Action type (e.g., VisitAndExtract, MessageToPerson)

description

string

No

Action description

coolDown

number

No

Milliseconds between executions

maxResults

number

No

Max results per iteration (-1 for unlimited)

actionSettings

object

No

Action-specific settings

cdpPort

number

No

9222

CDP port

campaign-remove-action

Remove an action from a campaign's action chain.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

actionId

number

Yes

Action ID to remove

cdpPort

number

No

9222

CDP port

campaign-update-action

Update an existing action's configuration in a campaign. Only provided fields are changed.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

actionId

number

Yes

Action ID to update

name

string

No

New display name

description

string | null

No

New description (null to clear)

coolDown

number

No

Milliseconds between executions

maxActionResultsPerIteration

number

No

Max results per iteration (-1 for unlimited)

actionSettings

string

No

Action-specific settings as JSON (merged with existing)

cdpPort

number

No

9222

CDP port

campaign-reorder-actions

Reorder actions in a campaign's action chain.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

actionIds

number[]

Yes

Action IDs in desired order

cdpPort

number

No

9222

CDP port

campaign-move-next

Move people from one action to the next in a campaign.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

actionId

number

Yes

Action ID to move people from

personIds

number[]

Yes

Person IDs to move

cdpPort

number

No

9222

CDP port

Campaign Targeting

campaign-exclude-list

View the exclude list for a campaign or action.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

actionId

number

No

Action ID (for action-level list)

cdpPort

number

No

9222

CDP port

campaign-exclude-add

Add people to a campaign or action exclude list.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

personIds

number[]

Yes

Person IDs to exclude

actionId

number

No

Action ID (for action-level list)

cdpPort

number

No

9222

CDP port

campaign-exclude-remove

Remove people from a campaign or action exclude list.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

personIds

number[]

Yes

Person IDs to remove from exclude list

actionId

number

No

Action ID (for action-level list)

cdpPort

number

No

9222

CDP port

campaign-list-people

List people assigned to a campaign with their processing status.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

actionId

number

No

Filter to a specific action

status

string

No

Filter by status (queued, processed, successful, failed)

limit

number

No

20

Max results

offset

number

No

0

Pagination offset

cdpPort

number

No

9222

CDP port

campaign-remove-people

Remove people from a campaign's target list entirely. This is the inverse of import-people-from-urls.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

personIds

number[]

Yes

Person IDs to remove

cdpPort

number

No

9222

CDP port

import-people-from-urls

Import LinkedIn profile URLs into a campaign action target list. Idempotent — previously imported URLs are skipped.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID

urls

string[]

Yes

LinkedIn profile URLs

cdpPort

number

No

9222

CDP port

collect-people

Collect people from a LinkedIn page into a campaign. Detects the source type from the URL automatically.

Parameter

Type

Required

Default

Description

campaignId

number

Yes

Campaign ID to collect into

sourceUrl

string

Yes

LinkedIn page URL (search results, company people, group members)

limit

number

No

Max profiles to collect

maxPages

number

No

Max pages to process

pageSize

number

No

Results per page

sourceType

string

No

Explicit source type (bypasses URL detection)

cdpPort

number

No

9222

CDP port

Collections

list-collections

List all LinkedHelper collections (Lists) with people counts.

Parameter

Type

Required

Default

Description

cdpPort

number

No

9222

CDP port

create-collection

Create a new named LinkedHelper collection (List).

Parameter

Type

Required

Default

Description

name

string

Yes

Name for the new collection

cdpPort

number

No

9222

CDP port

delete-collection

Delete a LinkedHelper collection (List) and all its people associations.

Parameter

Type

Required

Default

Description

collectionId

number

Yes

Collection ID to delete

cdpPort

number

No

9222

CDP port

add-people-to-collection

Add people to a LinkedHelper collection. Idempotent — adding an already-present person is a no-op.

Parameter

Type

Required

Default

Description

collectionId

number

Yes

Collection ID

personIds

number[]

Yes

Person IDs to add

cdpPort

number

No

9222

CDP port

remove-people-from-collection

Remove people from a LinkedHelper collection.

Parameter

Type

Required

Default

Description

collectionId

number

Yes

Collection ID

personIds

number[]

Yes

Person IDs to remove

cdpPort

number

No

9222

CDP port

import-people-from-collection

Import all people from a LinkedHelper collection into a campaign. Large sets are automatically chunked.

Parameter

Type

Required

Default

Description

collectionId

number

Yes

Collection ID to import from

campaignId

number

Yes

Campaign ID to import into

cdpPort

number

No

9222

CDP port

Profiles & Messaging

query-profile

Look up a cached LinkedIn profile from the local database by person ID or public ID.

Parameter

Type

Required

Default

Description

personId

number

No

Internal person ID

publicId

string

No

LinkedIn public ID (URL slug)

includePositions

boolean

No

false

Include full position history (career history)

query-profiles

Search for profiles in the local database with name, headline, or company filters.

Parameter

Type

Required

Default

Description

query

string

No

Search name or headline

company

string

No

Filter by company

includeHistory

boolean

No

false

Also search past positions (company history), not just current

limit

number

No

20

Max results

offset

number

No

0

Pagination offset

query-profiles-bulk

Look up multiple cached LinkedIn profiles in a single call.

Parameter

Type

Required

Default

Description

personIds

number[]

No

Look up by internal person IDs

publicIds

string[]

No

Look up by LinkedIn public IDs (URL slugs)

includePositions

boolean

No

false

Include full position history

query-messages

Query messaging history from the local database.

Parameter

Type

Required

Default

Description

personId

number

No

Filter by person ID

chatId

number

No

Show specific conversation thread

search

string

No

Search message text

limit

number

No

20

Max results

offset

number

No

0

Pagination offset

check-replies

Check for new message replies from LinkedIn.

Parameter

Type

Required

Default

Description

since

string

No

Only show replies after this ISO timestamp

cdpPort

number

No

9222

CDP port

scrape-messaging-history

Scrape messaging history from LinkedIn for specified people into the local database. This is a long-running operation that may take several minutes.

Parameter

Type

Required

Default

Description

personIds

number[]

Yes

Person IDs whose messaging history should be scraped

cdpPort

number

No

9222

CDP port

LinkedIn Actions

visit-profile

Visit a LinkedIn profile via LinkedHelper's VisitAndExtract action and return the extracted profile data. Deducts from the daily action budget.

Parameter

Type

Required

Default

Description

personId

number

No

Internal person ID (provide this or url)

url

string

No

LinkedIn profile URL (provide this or personId)

extractCurrentOrganizations

boolean

No

false

Extract current company info during visit

cdpPort

number

No

9222

CDP port

endorse-skills

Endorse skills on a LinkedIn profile via an ephemeral campaign. Deducts from the daily action budget.

Parameter

Type

Required

Default

Description

personId

number

No

Internal person ID (provide this or url)

url

string

No

LinkedIn profile URL (provide this or personId)

skillNames

string[]

No

Specific skill names to endorse (mutually exclusive with limit)

limit

number

No

Max number of skills to endorse (mutually exclusive with skillNames)

skipIfNotEndorsable

boolean

No

true

Skip if person has no endorsable skills

keepCampaign

boolean

No

false

Archive the ephemeral campaign instead of deleting it

cdpPort

number

No

9222

CDP port

enrich-profile

Enrich a LinkedIn profile by extracting additional data (emails, phones, socials, company info) via an ephemeral campaign. Deducts from the daily action budget.

Parameter

Type

Required

Default

Description

personId

number

No

Internal person ID (provide this or url)

url

string

No

LinkedIn profile URL (provide this or personId)

profileInfo

object

No

Enrich profile info (shouldEnrich required)

phones

object

No

Enrich phone numbers (shouldEnrich required)

emails

object

No

Enrich email addresses (shouldEnrich required)

socials

object

No

Enrich social profiles (shouldEnrich required)

companies

object

No

Enrich company data (shouldEnrich required)

keepCampaign

boolean

No

false

Archive the ephemeral campaign instead of deleting it

cdpPort

number

No

9222

CDP port

follow-person

Follow or unfollow a LinkedIn profile via an ephemeral campaign. Deducts from the daily action budget.

Parameter

Type

Required

Default

Description

personId

number

No

Internal person ID (provide this or url)

url

string

No

LinkedIn profile URL (provide this or personId)

mode

string

No

follow

follow or unfollow

skipIfUnfollowable

boolean

No

true

Skip if person cannot be unfollowed

keepCampaign

boolean

No

false

Archive the ephemeral campaign instead of deleting it

cdpPort

number

No

9222

CDP port

like-person-posts

Like and optionally comment on posts and articles by a LinkedIn profile via an ephemeral campaign. Deducts from the daily action budget.

Parameter

Type

Required

Default

Description

personId

number

No

Internal person ID (provide this or url)

url

string

No

LinkedIn profile URL (provide this or personId)

numberOfArticles

number

No

Number of articles to like

numberOfPosts

number

No

Number of posts to like

maxAgeOfArticles

number

No

Maximum age of articles in days

maxAgeOfPosts

number

No

Maximum age of posts in days

shouldAddComment

boolean

No

false

Also add a comment to liked posts/articles

messageTemplate

string

No

Comment text template as JSON (required when shouldAddComment is true)

skipIfNotLiked

boolean

No

true

Skip if nothing was liked

keepCampaign

boolean

No

false

Archive the ephemeral campaign instead of deleting it

cdpPort

number

No

9222

CDP port

message-person

Send a direct message to a 1st-degree LinkedIn connection via an ephemeral campaign. Deducts from the daily action budget.

Parameter

Type

Required

Default

Description

personId

number

No

Internal person ID (provide this or url)

url

string

No

LinkedIn profile URL (provide this or personId)

messageTemplate

string

Yes

Message template as JSON

subjectTemplate

string

No

Subject line template as JSON

rejectIfReplied

boolean

No

false

Skip if person already replied

rejectIfMessaged

boolean

No

false

Skip if already messaged

keepCampaign

boolean

No

false

Archive the ephemeral campaign instead of deleting it

cdpPort

number

No

9222

CDP port

send-invite

Send a LinkedIn connection request via an ephemeral campaign. Deducts from the daily action budget.

Parameter

Type

Required

Default

Description

personId

number

No

Internal person ID (provide this or url)

url

string

No

LinkedIn profile URL (provide this or personId)

messageTemplate

string

No

Invitation message template as JSON (empty for no message)

saveAsLeadSN

boolean

No

false

Save as lead in Sales Navigator

keepCampaign

boolean

No

false

Archive the ephemeral campaign instead of deleting it

cdpPort

number

No

9222

CDP port

send-inmail

Send an InMail message to a LinkedIn member (no connection required) via an ephemeral campaign. Deducts from the daily action budget.

Parameter

Type

Required

Default

Description

personId

number

No

Internal person ID (provide this or url)

url

string

No

LinkedIn profile URL (provide this or personId)

messageTemplate

string

Yes

InMail body template as JSON

subjectTemplate

string

No

InMail subject line template as JSON

rejectIfReplied

boolean

No

false

Skip if person already replied

proceedOnOutOfCredits

boolean

No

false

Continue even when InMail credits are exhausted

keepCampaign

boolean

No

false

Archive the ephemeral campaign instead of deleting it

cdpPort

number

No

9222

CDP port

remove-connection

Remove a person from 1st-degree LinkedIn connections (unfriend) via an ephemeral campaign. Deducts from the daily action budget.

Parameter

Type

Required

Default

Description

personId

number

No

Internal person ID (provide this or url)

url

string

No

LinkedIn profile URL (provide this or personId)

keepCampaign

boolean

No

false

Archive the ephemeral campaign instead of deleting it

cdpPort

number

No

9222

CDP port

Feed & Posts

get-feed

Read the LinkedIn home feed. Returns structured post data with cursor-based pagination.

Parameter

Type

Required

Default

Description

count

number

No

10

Number of posts per page

cursor

string

No

Cursor token from a previous call for the next page

cdpPort

number

No

9222

CDP port

get-post

Get detailed data for a single LinkedIn post including its comment thread.

Parameter

Type

Required

Default

Description

postUrl

string

Yes

LinkedIn post URL or URN

commentCount

number

No

100

Maximum number of comments to load (0 to skip)

cdpPort

number

No

9222

CDP port

get-post-stats

Get engagement statistics for a LinkedIn post: reaction count (broken down by type), comment count, and share count.

Parameter

Type

Required

Default

Description

postUrl

string

Yes

LinkedIn post URL or URN

cdpPort

number

No

9222

CDP port

get-post-engagers

List people who engaged with a LinkedIn post (reacted, etc.) with their profile info and engagement type. Supports pagination. MCP tool only — no CLI command.

Parameter

Type

Required

Default

Description

postUrl

string

Yes

LinkedIn post URL or URN

start

number

No

0

Pagination offset

count

number

No

20

Number of engagers per page

cdpPort

number

No

9222

CDP port

get-profile-activity

Get recent posts/activity from a LinkedIn profile with cursor-based pagination.

Parameter

Type

Required

Default

Description

profile

string

Yes

LinkedIn profile public ID or URL

count

number

No

10

Number of posts per page

cursor

string

No

Cursor token from a previous call for the next page

cdpPort

number

No

9222

CDP port

search-posts

Search LinkedIn for posts by keyword or hashtag. Returns structured post data with cursor-based pagination.

Parameter

Type

Required

Default

Description

query

string

Yes

Search query — keywords or hashtag

count

number

No

10

Number of results per page

cursor

number

No

Index-based cursor from a previous call for the next page

cdpPort

number

No

9222

CDP port

comment-on-post

Post a comment on a LinkedIn post. Checks action budget before attempting.

Parameter

Type

Required

Default

Description

postUrl

string

Yes

LinkedIn post URL

text

string

Yes

Comment text to post

cdpPort

number

No

9222

CDP port

react-to-post

React to a LinkedIn post with a specific reaction type.

Parameter

Type

Required

Default

Description

postUrl

string

Yes

LinkedIn post URL

reactionType

string

No

like

like, celebrate, support, love, insightful, or funny

cdpPort

number

No

9222

CDP port

react-to-comment

React to a specific LinkedIn comment with a specific reaction type. Use this for the organic-engagement pattern of acknowledging a reply (e.g., the post author replied to your comment) without extending the thread. Mirrors react-to-post semantics scoped to one comment via its URN (as returned by get-post's commentUrn field).

Parameter

Type

Required

Default

Description

postUrl

string

Yes

LinkedIn post URL containing the target comment

commentUrn

string

Yes

Comment URN (e.g. urn:li:comment:(activity:1234567890,9876543210))

reactionType

string

No

like

like, celebrate, support, love, insightful, or funny

dryRun

boolean

No

false

When true, detects current reaction state without clicking

cdpPort

number

No

9222

CDP port

LinkedIn Search & Reference

build-linkedin-url

Build a LinkedIn URL for any supported source type. Supports SearchPage (basic search with faceted filters), SNSearchPage (Sales Navigator), and parameterised templates for company, school, group, and event pages. CLI command: build-url.

Parameter

Type

Required

Default

Description

sourceType

string

Yes

LinkedIn source type (e.g., SearchPage, SNSearchPage, OrganizationPeople)

keywords

string

No

Search keywords

currentCompany

string[]

No

Current company IDs (SearchPage)

pastCompany

string[]

No

Past company IDs (SearchPage)

geoUrn

string[]

No

Geographic URN IDs (SearchPage)

industry

string[]

No

Industry IDs (SearchPage)

school

string[]

No

School IDs (SearchPage)

network

string[]

No

Connection degree codes: F, S, O (SearchPage)

profileLanguage

string[]

No

Profile language codes (SearchPage)

serviceCategory

string[]

No

Service category IDs (SearchPage)

filters

object[]

No

Sales Navigator filters (SNSearchPage) — each with type, values[]

slug

string

No

Company or school slug (OrganizationPeople, Alumni)

id

string

No

Entity ID (Group, Event, SNListPage, etc.)

resolve-linkedin-entity

Resolve human-readable names (company names, locations, schools) to LinkedIn entity IDs via LinkedIn's public typeahead endpoint. No authentication and no running LinkedHelper instance required. CLI command: resolve-entity.

Parameter

Type

Required

Default

Description

query

string

Yes

Search query (e.g., company name, city)

entityType

string

Yes

COMPANY, GEO, or SCHOOL

list-linkedin-reference-data

List LinkedIn reference data for finite enumerations (industries, seniority levels, functions, company sizes, connection degrees, profile languages). Use this to discover valid IDs for search filters. CLI command: list-reference-data.

Parameter

Type

Required

Default

Description

dataType

string

Yes

INDUSTRY, SENIORITY, FUNCTION, COMPANY_SIZE, CONNECTION_DEGREE, or PROFILE_LANGUAGE

Utilities

describe-actions

List available LinkedHelper action types with descriptions and configuration schemas.

Parameter

Type

Required

Default

Description

category

string

No

Filter by category (people, messaging, engagement, crm, workflow)

actionType

string

No

Get details for a specific action type

get-errors

Query current LinkedHelper UI errors, dialogs, and blocking popups.

Parameter

Type

Required

Default

Description

cdpPort

number

No

9222

CDP port

dismiss-errors

Dismiss closable error popups in the LinkedHelper instance UI by clicking their close/OK buttons. Recommended after UIBlockedError.

Parameter

Type

Required

Default

Description

cdpPort

number

No

9222

CDP port

get-action-budget

Get daily action budget showing limit types, thresholds, and today's usage from LH campaigns and CDP-direct actions.

Parameter

Type

Required

Default

Description

cdpPort

number

No

9222

CDP port

get-throttle-status

Check if LinkedIn is currently throttling the account.

Parameter

Type

Required

Default

Description

cdpPort

number

No

9222

CDP port

Known Limitations

  • Platform support: LinkedHelper runs on macOS, Windows, and Linux. Binary paths are detected automatically but can be overridden with the LINKEDHELPER_PATH environment variable.

  • Instance startup time: Starting an instance loads LinkedIn, which may take up to 45 seconds.

  • Profile data is cached: query-profile and query-profiles search the local LinkedHelper database. Profiles must have been visited or imported by LinkedHelper to appear in results.

  • Messaging scrape is slow: scrape-messaging-history navigates LinkedIn's messaging UI and can take several minutes depending on conversation volume.

  • Same-machine requirement: lhremote must run on the same machine as LinkedHelper. CDP connections are localhost-only by default (for security), and database access requires direct file system access to the LinkedHelper SQLite database.

Troubleshooting

LinkedHelper is not running

Error: LinkedHelper is not running (no CDP endpoint at port 9222)

Solution: Use launch-app to start LinkedHelper, or start it manually. lhremote communicates with LinkedHelper via the Chrome DevTools Protocol (CDP), which requires the application to be running.

LinkedHelper is unreachable

Error: LinkedHelper processes detected but CDP endpoint is unreachable

Solution: LinkedHelper is running but its CDP port is not responding. This typically means a stale or zombie process. Use launch-app --force to kill stale processes and relaunch, or manually restart LinkedHelper.

Application binary not found

Error: LinkedHelper application binary not found. Set LINKEDHELPER_PATH to override.

Solution: Install LinkedHelper from linkedhelper.com. If installed in a non-standard location, set the LINKEDHELPER_PATH environment variable to the binary path.

No accounts found

Error: No accounts found.

Solution: Open LinkedHelper and configure at least one LinkedIn account before using lhremote.

Multiple accounts found

Error: Multiple accounts found. Specify accountId. Use list-accounts to see available accounts.

Solution: Use list-accounts to see available accounts, then pass the desired accountId to start-instance, stop-instance, or other tools.

No instance running

Error: No LinkedHelper instance is running. Use start-instance first.

Solution: Run start-instance before using campaign or messaging tools. An instance must be running to interact with LinkedIn.

Instance initialization timeout

Error: Instance started but failed to initialize within timeout.

Solution: The instance was started but took too long to finish loading. This can happen on slow connections. Try again; the instance may still be starting in the background. Use check-status to verify.

Database not found

Error: No database found for account

Solution: The LinkedHelper database file is missing for the specified account. Ensure the account has been used at least once in LinkedHelper so that a local database has been created.

Disclaimer

lhremote is an independent project not affiliated with, endorsed by, or officially connected to:

  • LinkedIn or LinkedIn Corporation

  • LinkedHelper or its parent company

LinkedIn is a trademark of LinkedIn Corporation. LinkedHelper is a trademark of its respective owner.

Purpose

This project enables interoperability between automation tools and LinkedHelper, as permitted under DMCA § 1201(f). Implementation is based on publicly observable behavior (Chrome DevTools Protocol) without access to protected source code.

What This Project Does NOT Do

  • Circumvent copy protection or licensing

  • Bypass LinkedHelper authentication

  • Enable use without a valid LinkedHelper subscription

  • Provide access to LinkedIn without LinkedHelper

User Responsibility

Use of lhremote requires a valid LinkedHelper subscription and is subject to LinkedHelper's and LinkedIn's terms of service. Users accept all responsibility for compliance.

Ethical Use

This tool is for legitimate productivity. Do NOT use for spam, scraping at scale, or harassment.

License

AGPL-3.0-only — For commercial licensing, contact the maintainer.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
14hResponse time
4dRelease cycle
23Releases (12mo)
Issues opened vs closed

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/alexey-pelykh/lhremote'

If you have feedback or need assistance with the MCP directory API, please join our Discord server