CLI and MCP server for LinkedHelper automation. This project is brought to you by Alexey Pelykh. 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, star
Add this skill
npx mdskills install alexey-pelykh/lhremote-mcpComprehensive LinkedHelper automation guide with clear workflows, tool discovery, and error handling patterns
1# lhremote MCP — Tool Surface & Workflow Guide23This skill teaches lhremote MCP workflow patterns, conventions, and error handling for automating LinkedHelper via Chrome DevTools Protocol (CDP).45## Prerequisites67LinkedHelper must be installed locally with an active license. The MCP server connects to it via CDP on a configurable port (default: 9222).89## Tool Discovery1011Tools are autodiscovered via the MCP protocol handshake (`tools/list`). Use the MCP tool listing to see available tools and their parameters.1213## Workflow Patterns1415### Discovery Flow1617Always start here when connecting to LinkedHelper for the first time in a session:1819```20find-app → list-accounts → check-status21```22231. **`find-app`** — Detect if LinkedHelper is running and get its CDP port242. **`list-accounts`** — See available accounts (needed for targeting)253. **`check-status`** — Verify instance health and database connectivity2627If `find-app` returns nothing, use `launch-app` first.2829### Instance Lifecycle3031An instance must be running before any campaign or query operations:3233```34launch-app → start-instance → [work] → stop-instance → quit-app35```3637- `start-instance` auto-selects the account when only one exists38- Most tools require a running instance (they will error if not started)39- `stop-instance` and `quit-app` are separate — stop the instance before quitting the app4041### Campaign Creation & Execution4243Full workflow for creating and running a campaign:4445```46describe-actions → campaign-create → import-people-from-urls → campaign-start → campaign-status / campaign-statistics47```4849**Step 1 — Discover action types:**5051Use `describe-actions` to see available action types and their configuration schemas before building a campaign config.5253**Step 2 — Create the campaign:**5455`campaign-create` accepts YAML (default) or JSON configuration:5657```yaml58version: "1"59name: "Visit & Connect"60actions:61 - type: "VisitAndExtract"62 cooldownMs: 6000063 maxActionsPerRun: 1064 - type: "InvitePerson"65 config:66 message: "Hi {firstName}, I'd like to connect!"67```6869**Step 3 — Import targets:**7071Use `import-people-from-urls` with LinkedIn profile URLs. This is idempotent — re-importing the same person is a no-op.7273**Step 4 — Start execution:**7475`campaign-start` requires both `campaignId` and `personIds` (the internal IDs, not LinkedIn URLs). It returns immediately — execution is asynchronous.7677**Step 5 — Monitor progress:**7879- `campaign-status` — Real-time execution state (with optional `includeResults`)80- `campaign-statistics` — Aggregated success/error counts per action8182### Campaign Action Chain Management8384Campaigns contain ordered action chains. Manage them with:8586- `campaign-add-action` — Append an action (use `describe-actions` to discover types)87- `campaign-remove-action` — Remove by action ID88- `campaign-reorder-actions` — Reorder by providing action IDs in desired order89- `campaign-move-next` — Advance specific persons to the next action9091### Messaging Workflow9293```94check-replies → query-messages95```9697- `check-replies` triggers LinkedHelper to fetch new replies from LinkedIn, then returns messages since a cutoff (default: last 24 hours)98- `query-messages` searches the local database — use `personId` to filter by contact, `chatId` for a specific thread, or `search` for text search99- `scrape-messaging-history` does a full scrape of all LinkedIn messages into the local database100101### Data Queries (No Campaign Needed)102103Profile and message queries work against the local LinkedHelper database — no campaign execution required, but an instance must be running:104105- `query-profile` — Look up by `personId` (internal) or `publicId` (LinkedIn URL slug like `jane-doe-12345`)106- `query-profiles` — Search by name/headline (`query`) or company, with `limit`/`offset` pagination107108## Parameter Conventions109110- **`cdpPort`**: Optional on all tools, defaults to `9222`. Only change if LinkedHelper runs on a non-default port.111- **`accountId`**: Optional when only one account exists (auto-resolved). Required when multiple accounts are configured.112- **`campaignId`** / **`actionId`** / **`personId`**: Internal LinkedHelper integer IDs (not LinkedIn public IDs).113- **`format`**: Campaign config format — `"yaml"` (default) or `"json"`.114- **`publicId`**: The LinkedIn profile URL slug (e.g., `jane-doe-12345` from `linkedin.com/in/jane-doe-12345`).115116## Error Patterns117118| Error | Cause | Fix |119|-------|-------|-----|120| "No running LinkedHelper instances found" | App not running | Use `launch-app` |121| "Failed to connect to LinkedHelper" | Wrong CDP port or app crashed | Use `find-app` to discover correct port |122| "Instance not running" | Instance not started for account | Use `start-instance` |123| "No accounts found" / "Multiple accounts" | Account resolution failed | Use `list-accounts`, then pass explicit `accountId` |124| "Campaign not found" | Invalid campaign ID | Use `campaign-list` to find valid IDs |125| "Campaign start timed out" | LinkedHelper unresponsive | Check `check-status`, retry |126127## Action Type Reference128129Use `describe-actions` to get full schemas. The available action types are:130131| Type | Category | Purpose |132|------|----------|---------|133| `VisitAndExtract` | people | Visit LinkedIn profile and extract data |134| `InvitePerson` | people | Send connection request |135| `MessageToPerson` | messaging | Send message to connection |136| `InMail` | messaging | Send InMail to non-connection |137| `CheckForReplies` | messaging | Check for new message replies |138| `Follow` | engagement | Follow a LinkedIn profile |139| `EndorseSkills` | engagement | Endorse skills on a profile |140| `PersonPostsLiker` | engagement | Like posts by a person |141| `FilterContactsOutOfMyNetwork` | people | Filter out non-connections |142| `RemoveFromFirstConnection` | people | Remove from first connections |143| `DataEnrichment` | crm | Enrich profile data |144| `ScrapeMessagingHistory` | messaging | Scrape messaging history |145| `Waiter` | workflow | Wait for a configured delay |146
Full transparency — inspect the skill content before installing.