lhremote 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +171 -16
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -57,7 +57,7 @@ Add to your Claude Desktop configuration (`claude_desktop_config.json`):
57
57
  }
58
58
  ```
59
59
 
60
- Once configured, Claude can use all 32 tools directly. A typical workflow:
60
+ Once configured, Claude can use all 44 tools directly. A typical workflow:
61
61
 
62
62
  1. **`find-app`** — Detect a running LinkedHelper instance (or **`launch-app`** to start one)
63
63
  2. **`list-accounts`** — See available LinkedIn accounts
@@ -77,7 +77,7 @@ The `lhremote` command provides the same functionality as the MCP server. Every
77
77
 
78
78
  ```sh
79
79
  lhremote find-app [--json]
80
- lhremote launch-app [--cdp-port <port>]
80
+ lhremote launch-app [--cdp-port <port>] [--force]
81
81
  lhremote quit-app [--cdp-port <port>]
82
82
  ```
83
83
 
@@ -99,11 +99,12 @@ lhremote campaign-get <campaignId> [--cdp-port <port>] [--json]
99
99
  lhremote campaign-export <campaignId> [--format yaml|json] [--output <path>] [--cdp-port <port>]
100
100
  lhremote campaign-update <campaignId> [--name <name>] [--description <text>] [--clear-description] [--cdp-port <port>] [--json]
101
101
  lhremote campaign-delete <campaignId> [--cdp-port <port>] [--json]
102
- lhremote campaign-start <campaignId> [--person-ids <ids>] [--person-ids-file <path>] [--cdp-port <port>] [--json]
102
+ lhremote campaign-start <campaignId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
103
103
  lhremote campaign-stop <campaignId> [--cdp-port <port>] [--json]
104
104
  lhremote campaign-status <campaignId> [--include-results] [--limit <n>] [--cdp-port <port>] [--json]
105
105
  lhremote campaign-statistics <campaignId> [--action-id <id>] [--max-errors <n>] [--cdp-port <port>] [--json]
106
- lhremote campaign-retry <campaignId> [--person-ids <ids>] [--person-ids-file <path>] [--cdp-port <port>] [--json]
106
+ lhremote campaign-retry <campaignId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
107
+ lhremote campaign-list-people <campaignId> [--action-id <id>] [--status <status>] [--limit <n>] [--offset <n>] [--cdp-port <port>] [--json]
107
108
  ```
108
109
 
109
110
  ### Campaign Actions
@@ -111,8 +112,9 @@ lhremote campaign-retry <campaignId> [--person-ids <ids>] [--person-ids-file <pa
111
112
  ```sh
112
113
  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]
113
114
  lhremote campaign-remove-action <campaignId> <actionId> [--cdp-port <port>] [--json]
115
+ 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]
114
116
  lhremote campaign-reorder-actions <campaignId> --action-ids <ids> [--cdp-port <port>] [--json]
115
- lhremote campaign-move-next <campaignId> <actionId> [--person-ids <ids>] [--person-ids-file <path>] [--cdp-port <port>] [--json]
117
+ lhremote campaign-move-next <campaignId> <actionId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
116
118
  ```
117
119
 
118
120
  ### Campaign Targeting
@@ -121,23 +123,38 @@ lhremote campaign-move-next <campaignId> <actionId> [--person-ids <ids>] [--pers
121
123
  lhremote campaign-exclude-list <campaignId> [--action-id <id>] [--cdp-port <port>] [--json]
122
124
  lhremote campaign-exclude-add <campaignId> --person-ids <ids> | --person-ids-file <path> [--action-id <id>] [--cdp-port <port>] [--json]
123
125
  lhremote campaign-exclude-remove <campaignId> --person-ids <ids> | --person-ids-file <path> [--action-id <id>] [--cdp-port <port>] [--json]
126
+ lhremote campaign-remove-people <campaignId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
124
127
  lhremote import-people-from-urls <campaignId> --urls <urls> | --urls-file <path> [--cdp-port <port>] [--json]
128
+ lhremote collect-people <campaignId> <sourceUrl> [--limit <n>] [--max-pages <n>] [--page-size <n>] [--source-type <type>] [--cdp-port <port>] [--json]
129
+ ```
130
+
131
+ ### Collections
132
+
133
+ ```sh
134
+ lhremote list-collections [--json]
135
+ lhremote create-collection <name> [--cdp-port <port>] [--json]
136
+ lhremote delete-collection <collectionId> [--cdp-port <port>] [--json]
137
+ lhremote add-people-to-collection <collectionId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
138
+ lhremote remove-people-from-collection <collectionId> --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
139
+ lhremote import-people-from-collection <collectionId> <campaignId> [--cdp-port <port>] [--json]
125
140
  ```
126
141
 
127
142
  ### Profiles & Messaging
128
143
 
129
144
  ```sh
130
- lhremote query-profile --person-id <id> | --public-id <slug> [--json]
131
- lhremote query-profiles [--query <text>] [--company <name>] [--limit <n>] [--offset <n>] [--json]
145
+ lhremote query-profile --person-id <id> | --public-id <slug> [--include-positions] [--json]
146
+ lhremote query-profiles [--query <text>] [--company <name>] [--include-history] [--limit <n>] [--offset <n>] [--json]
147
+ lhremote query-profiles-bulk --person-id <id>... | --public-id <slug>... [--include-positions] [--json]
132
148
  lhremote query-messages [--person-id <id>] [--chat-id <id>] [--search <text>] [--limit <n>] [--offset <n>] [--json]
133
149
  lhremote check-replies [--since <timestamp>] [--cdp-port <port>] [--json]
134
- lhremote scrape-messaging-history [--cdp-port <port>] [--json]
150
+ lhremote scrape-messaging-history --person-ids <ids> | --person-ids-file <path> [--cdp-port <port>] [--json]
135
151
  ```
136
152
 
137
153
  ### Utilities
138
154
 
139
155
  ```sh
140
156
  lhremote describe-actions [--category <category>] [--type <type>] [--json]
157
+ lhremote get-errors [--cdp-port <port>] [--json]
141
158
  ```
142
159
 
143
160
  ## MCP Tools
@@ -169,6 +186,7 @@ Launch the LinkedHelper application with remote debugging enabled.
169
186
  | Parameter | Type | Required | Default | Description |
170
187
  |-----------|------|----------|---------|-------------|
171
188
  | `cdpPort` | number | No | auto-select | CDP port to use |
189
+ | `force` | boolean | No | false | Kill existing LinkedHelper processes before launching |
172
190
 
173
191
  #### `quit-app`
174
192
 
@@ -227,12 +245,12 @@ List existing campaigns with summary statistics.
227
245
 
228
246
  #### `campaign-create`
229
247
 
230
- Create a new campaign from YAML or JSON configuration. Provide exactly one of `yamlConfig` or `jsonConfig`.
248
+ Create a new campaign from YAML or JSON configuration.
231
249
 
232
250
  | Parameter | Type | Required | Default | Description |
233
251
  |-----------|------|----------|---------|-------------|
234
- | `yamlConfig` | string | No | — | YAML campaign configuration |
235
- | `jsonConfig` | string | No | | JSON campaign configuration |
252
+ | `config` | string | Yes | — | Campaign configuration in YAML or JSON format |
253
+ | `format` | string | No | yaml | Configuration format (`yaml` or `json`) |
236
254
  | `cdpPort` | number | No | 9222 | CDP port |
237
255
 
238
256
  #### `campaign-get`
@@ -276,12 +294,12 @@ Delete (archive) a campaign.
276
294
 
277
295
  #### `campaign-start`
278
296
 
279
- Start a campaign with specified target persons.
297
+ Start a campaign with specified target persons. Returns immediately (async execution).
280
298
 
281
299
  | Parameter | Type | Required | Default | Description |
282
300
  |-----------|------|----------|---------|-------------|
283
301
  | `campaignId` | number | Yes | — | Campaign ID |
284
- | `personIds` | number[] | No | — | Person IDs to target |
302
+ | `personIds` | number[] | Yes | — | Person IDs to target |
285
303
  | `cdpPort` | number | No | 9222 | CDP port |
286
304
 
287
305
  #### `campaign-stop`
@@ -322,7 +340,7 @@ Reset specified people for re-run in a campaign.
322
340
  | Parameter | Type | Required | Default | Description |
323
341
  |-----------|------|----------|---------|-------------|
324
342
  | `campaignId` | number | Yes | — | Campaign ID |
325
- | `personIds` | number[] | No | — | Person IDs to retry |
343
+ | `personIds` | number[] | Yes | — | Person IDs to retry |
326
344
  | `cdpPort` | number | No | 9222 | CDP port |
327
345
 
328
346
  ### Campaign Actions
@@ -352,6 +370,21 @@ Remove an action from a campaign's action chain.
352
370
  | `actionId` | number | Yes | — | Action ID to remove |
353
371
  | `cdpPort` | number | No | 9222 | CDP port |
354
372
 
373
+ #### `campaign-update-action`
374
+
375
+ Update an existing action's configuration in a campaign. Only provided fields are changed.
376
+
377
+ | Parameter | Type | Required | Default | Description |
378
+ |-----------|------|----------|---------|-------------|
379
+ | `campaignId` | number | Yes | — | Campaign ID |
380
+ | `actionId` | number | Yes | — | Action ID to update |
381
+ | `name` | string | No | — | New display name |
382
+ | `description` | string \| null | No | — | New description (null to clear) |
383
+ | `coolDown` | number | No | — | Milliseconds between executions |
384
+ | `maxActionResultsPerIteration` | number | No | — | Max results per iteration (-1 for unlimited) |
385
+ | `actionSettings` | string | No | — | Action-specific settings as JSON (merged with existing) |
386
+ | `cdpPort` | number | No | 9222 | CDP port |
387
+
355
388
  #### `campaign-reorder-actions`
356
389
 
357
390
  Reorder actions in a campaign's action chain.
@@ -370,7 +403,7 @@ Move people from one action to the next in a campaign.
370
403
  |-----------|------|----------|---------|-------------|
371
404
  | `campaignId` | number | Yes | — | Campaign ID |
372
405
  | `actionId` | number | Yes | — | Action ID to move people from |
373
- | `personIds` | number[] | No | — | Person IDs to move |
406
+ | `personIds` | number[] | Yes | — | Person IDs to move |
374
407
  | `cdpPort` | number | No | 9222 | CDP port |
375
408
 
376
409
  ### Campaign Targeting
@@ -407,6 +440,29 @@ Remove people from a campaign or action exclude list.
407
440
  | `actionId` | number | No | — | Action ID (for action-level list) |
408
441
  | `cdpPort` | number | No | 9222 | CDP port |
409
442
 
443
+ #### `campaign-list-people`
444
+
445
+ List people assigned to a campaign with their processing status.
446
+
447
+ | Parameter | Type | Required | Default | Description |
448
+ |-----------|------|----------|---------|-------------|
449
+ | `campaignId` | number | Yes | — | Campaign ID |
450
+ | `actionId` | number | No | — | Filter to a specific action |
451
+ | `status` | string | No | — | Filter by status (`queued`, `processed`, `successful`, `failed`) |
452
+ | `limit` | number | No | 20 | Max results |
453
+ | `offset` | number | No | 0 | Pagination offset |
454
+ | `cdpPort` | number | No | 9222 | CDP port |
455
+
456
+ #### `campaign-remove-people`
457
+
458
+ Remove people from a campaign's target list entirely. This is the inverse of `import-people-from-urls`.
459
+
460
+ | Parameter | Type | Required | Default | Description |
461
+ |-----------|------|----------|---------|-------------|
462
+ | `campaignId` | number | Yes | — | Campaign ID |
463
+ | `personIds` | number[] | Yes | — | Person IDs to remove |
464
+ | `cdpPort` | number | No | 9222 | CDP port |
465
+
410
466
  #### `import-people-from-urls`
411
467
 
412
468
  Import LinkedIn profile URLs into a campaign action target list. Idempotent — previously imported URLs are skipped.
@@ -417,6 +473,78 @@ Import LinkedIn profile URLs into a campaign action target list. Idempotent —
417
473
  | `urls` | string[] | Yes | — | LinkedIn profile URLs |
418
474
  | `cdpPort` | number | No | 9222 | CDP port |
419
475
 
476
+ #### `collect-people`
477
+
478
+ Collect people from a LinkedIn page into a campaign. Detects the source type from the URL automatically.
479
+
480
+ | Parameter | Type | Required | Default | Description |
481
+ |-----------|------|----------|---------|-------------|
482
+ | `campaignId` | number | Yes | — | Campaign ID to collect into |
483
+ | `sourceUrl` | string | Yes | — | LinkedIn page URL (search results, company people, group members) |
484
+ | `limit` | number | No | — | Max profiles to collect |
485
+ | `maxPages` | number | No | — | Max pages to process |
486
+ | `pageSize` | number | No | — | Results per page |
487
+ | `sourceType` | string | No | — | Explicit source type (bypasses URL detection) |
488
+ | `cdpPort` | number | No | 9222 | CDP port |
489
+
490
+ ### Collections
491
+
492
+ #### `list-collections`
493
+
494
+ List all LinkedHelper collections (Lists) with people counts.
495
+
496
+ | Parameter | Type | Required | Default | Description |
497
+ |-----------|------|----------|---------|-------------|
498
+ | `cdpPort` | number | No | 9222 | CDP port |
499
+
500
+ #### `create-collection`
501
+
502
+ Create a new named LinkedHelper collection (List).
503
+
504
+ | Parameter | Type | Required | Default | Description |
505
+ |-----------|------|----------|---------|-------------|
506
+ | `name` | string | Yes | — | Name for the new collection |
507
+ | `cdpPort` | number | No | 9222 | CDP port |
508
+
509
+ #### `delete-collection`
510
+
511
+ Delete a LinkedHelper collection (List) and all its people associations.
512
+
513
+ | Parameter | Type | Required | Default | Description |
514
+ |-----------|------|----------|---------|-------------|
515
+ | `collectionId` | number | Yes | — | Collection ID to delete |
516
+ | `cdpPort` | number | No | 9222 | CDP port |
517
+
518
+ #### `add-people-to-collection`
519
+
520
+ Add people to a LinkedHelper collection. Idempotent — adding an already-present person is a no-op.
521
+
522
+ | Parameter | Type | Required | Default | Description |
523
+ |-----------|------|----------|---------|-------------|
524
+ | `collectionId` | number | Yes | — | Collection ID |
525
+ | `personIds` | number[] | Yes | — | Person IDs to add |
526
+ | `cdpPort` | number | No | 9222 | CDP port |
527
+
528
+ #### `remove-people-from-collection`
529
+
530
+ Remove people from a LinkedHelper collection.
531
+
532
+ | Parameter | Type | Required | Default | Description |
533
+ |-----------|------|----------|---------|-------------|
534
+ | `collectionId` | number | Yes | — | Collection ID |
535
+ | `personIds` | number[] | Yes | — | Person IDs to remove |
536
+ | `cdpPort` | number | No | 9222 | CDP port |
537
+
538
+ #### `import-people-from-collection`
539
+
540
+ Import all people from a LinkedHelper collection into a campaign. Large sets are automatically chunked.
541
+
542
+ | Parameter | Type | Required | Default | Description |
543
+ |-----------|------|----------|---------|-------------|
544
+ | `collectionId` | number | Yes | — | Collection ID to import from |
545
+ | `campaignId` | number | Yes | — | Campaign ID to import into |
546
+ | `cdpPort` | number | No | 9222 | CDP port |
547
+
420
548
  ### Profiles & Messaging
421
549
 
422
550
  #### `query-profile`
@@ -427,6 +555,7 @@ Look up a cached LinkedIn profile from the local database by person ID or public
427
555
  |-----------|------|----------|---------|-------------|
428
556
  | `personId` | number | No | — | Internal person ID |
429
557
  | `publicId` | string | No | — | LinkedIn public ID (URL slug) |
558
+ | `includePositions` | boolean | No | false | Include full position history (career history) |
430
559
 
431
560
  #### `query-profiles`
432
561
 
@@ -436,9 +565,20 @@ Search for profiles in the local database with name, headline, or company filter
436
565
  |-----------|------|----------|---------|-------------|
437
566
  | `query` | string | No | — | Search name or headline |
438
567
  | `company` | string | No | — | Filter by company |
568
+ | `includeHistory` | boolean | No | false | Also search past positions (company history), not just current |
439
569
  | `limit` | number | No | 20 | Max results |
440
570
  | `offset` | number | No | 0 | Pagination offset |
441
571
 
572
+ #### `query-profiles-bulk`
573
+
574
+ Look up multiple cached LinkedIn profiles in a single call.
575
+
576
+ | Parameter | Type | Required | Default | Description |
577
+ |-----------|------|----------|---------|-------------|
578
+ | `personIds` | number[] | No | — | Look up by internal person IDs |
579
+ | `publicIds` | string[] | No | — | Look up by LinkedIn public IDs (URL slugs) |
580
+ | `includePositions` | boolean | No | false | Include full position history |
581
+
442
582
  #### `query-messages`
443
583
 
444
584
  Query messaging history from the local database.
@@ -462,10 +602,11 @@ Check for new message replies from LinkedIn.
462
602
 
463
603
  #### `scrape-messaging-history`
464
604
 
465
- Scrape all messaging history from LinkedIn into the local database. This is a long-running operation that navigates LinkedIn's messaging interface.
605
+ Scrape messaging history from LinkedIn for specified people into the local database. This is a long-running operation that may take several minutes.
466
606
 
467
607
  | Parameter | Type | Required | Default | Description |
468
608
  |-----------|------|----------|---------|-------------|
609
+ | `personIds` | number[] | Yes | — | Person IDs whose messaging history should be scraped |
469
610
  | `cdpPort` | number | No | 9222 | CDP port |
470
611
 
471
612
  ### Utilities
@@ -479,6 +620,14 @@ List available LinkedHelper action types with descriptions and configuration sch
479
620
  | `category` | string | No | — | Filter by category (`people`, `messaging`, `engagement`, `crm`, `workflow`) |
480
621
  | `actionType` | string | No | — | Get details for a specific action type |
481
622
 
623
+ #### `get-errors`
624
+
625
+ Query current LinkedHelper UI errors, dialogs, and blocking popups.
626
+
627
+ | Parameter | Type | Required | Default | Description |
628
+ |-----------|------|----------|---------|-------------|
629
+ | `cdpPort` | number | No | 9222 | CDP port |
630
+
482
631
  ## Known Limitations
483
632
 
484
633
  - **Platform support**: LinkedHelper runs on macOS, Windows, and Linux. Binary paths are detected automatically but can be overridden with the `LINKEDHELPER_PATH` environment variable.
@@ -495,6 +644,12 @@ List available LinkedHelper action types with descriptions and configuration sch
495
644
 
496
645
  **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.
497
646
 
647
+ ### LinkedHelper is unreachable
648
+
649
+ **Error**: `LinkedHelper processes detected but CDP endpoint is unreachable`
650
+
651
+ **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.
652
+
498
653
  ### Application binary not found
499
654
 
500
655
  **Error**: `LinkedHelper application binary not found. Set LINKEDHELPER_PATH to override.`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lhremote",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "LinkedHelper automation toolkit — CLI & MCP server",
5
5
  "type": "module",
6
6
  "engines": {
@@ -37,8 +37,8 @@
37
37
  "dist"
38
38
  ],
39
39
  "dependencies": {
40
- "@lhremote/cli": "^0.6.0",
41
- "@lhremote/mcp": "^0.6.0"
40
+ "@lhremote/cli": "^0.8.0",
41
+ "@lhremote/mcp": "^0.8.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^25",