@lhremote/mcp 0.7.0 → 0.9.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 (236) hide show
  1. package/README.md +6 -3
  2. package/dist/helpers.d.ts +2 -15
  3. package/dist/helpers.d.ts.map +1 -1
  4. package/dist/helpers.js +15 -16
  5. package/dist/helpers.js.map +1 -1
  6. package/dist/server.test.js +22 -1
  7. package/dist/server.test.js.map +1 -1
  8. package/dist/tools/add-people-to-collection.test.d.ts +2 -0
  9. package/dist/tools/add-people-to-collection.test.d.ts.map +1 -0
  10. package/dist/tools/add-people-to-collection.test.js +61 -0
  11. package/dist/tools/add-people-to-collection.test.js.map +1 -0
  12. package/dist/tools/campaign-delete.d.ts.map +1 -1
  13. package/dist/tools/campaign-delete.js +7 -3
  14. package/dist/tools/campaign-delete.js.map +1 -1
  15. package/dist/tools/campaign-erase.d.ts +4 -0
  16. package/dist/tools/campaign-erase.d.ts.map +1 -0
  17. package/dist/tools/campaign-erase.js +28 -0
  18. package/dist/tools/campaign-erase.js.map +1 -0
  19. package/dist/tools/campaign-erase.test.d.ts +2 -0
  20. package/dist/tools/campaign-erase.test.d.ts.map +1 -0
  21. package/dist/tools/campaign-erase.test.js +87 -0
  22. package/dist/tools/campaign-erase.test.js.map +1 -0
  23. package/dist/tools/check-replies.d.ts.map +1 -1
  24. package/dist/tools/check-replies.js +11 -3
  25. package/dist/tools/check-replies.js.map +1 -1
  26. package/dist/tools/check-replies.test.js +10 -10
  27. package/dist/tools/check-replies.test.js.map +1 -1
  28. package/dist/tools/comment-on-post.d.ts +4 -0
  29. package/dist/tools/comment-on-post.d.ts.map +1 -0
  30. package/dist/tools/comment-on-post.js +26 -0
  31. package/dist/tools/comment-on-post.js.map +1 -0
  32. package/dist/tools/comment-on-post.test.d.ts +2 -0
  33. package/dist/tools/comment-on-post.test.d.ts.map +1 -0
  34. package/dist/tools/comment-on-post.test.js +64 -0
  35. package/dist/tools/comment-on-post.test.js.map +1 -0
  36. package/dist/tools/create-collection.test.d.ts +2 -0
  37. package/dist/tools/create-collection.test.d.ts.map +1 -0
  38. package/dist/tools/create-collection.test.js +55 -0
  39. package/dist/tools/create-collection.test.js.map +1 -0
  40. package/dist/tools/delete-collection.test.d.ts +2 -0
  41. package/dist/tools/delete-collection.test.d.ts.map +1 -0
  42. package/dist/tools/delete-collection.test.js +55 -0
  43. package/dist/tools/delete-collection.test.js.map +1 -0
  44. package/dist/tools/dismiss-errors.d.ts +4 -0
  45. package/dist/tools/dismiss-errors.d.ts.map +1 -0
  46. package/dist/tools/dismiss-errors.js +19 -0
  47. package/dist/tools/dismiss-errors.js.map +1 -0
  48. package/dist/tools/dismiss-errors.test.d.ts +2 -0
  49. package/dist/tools/dismiss-errors.test.d.ts.map +1 -0
  50. package/dist/tools/dismiss-errors.test.js +74 -0
  51. package/dist/tools/dismiss-errors.test.js.map +1 -0
  52. package/dist/tools/endorse-skills.d.ts +4 -0
  53. package/dist/tools/endorse-skills.d.ts.map +1 -0
  54. package/dist/tools/endorse-skills.js +53 -0
  55. package/dist/tools/endorse-skills.js.map +1 -0
  56. package/dist/tools/endorse-skills.test.d.ts +2 -0
  57. package/dist/tools/endorse-skills.test.d.ts.map +1 -0
  58. package/dist/tools/endorse-skills.test.js +58 -0
  59. package/dist/tools/endorse-skills.test.js.map +1 -0
  60. package/dist/tools/enrich-profile.d.ts +4 -0
  61. package/dist/tools/enrich-profile.d.ts.map +1 -0
  62. package/dist/tools/enrich-profile.js +60 -0
  63. package/dist/tools/enrich-profile.js.map +1 -0
  64. package/dist/tools/enrich-profile.test.d.ts +2 -0
  65. package/dist/tools/enrich-profile.test.d.ts.map +1 -0
  66. package/dist/tools/enrich-profile.test.js +66 -0
  67. package/dist/tools/enrich-profile.test.js.map +1 -0
  68. package/dist/tools/find-app.test.js +1 -1
  69. package/dist/tools/find-app.test.js.map +1 -1
  70. package/dist/tools/follow-person.d.ts +4 -0
  71. package/dist/tools/follow-person.d.ts.map +1 -0
  72. package/dist/tools/follow-person.js +47 -0
  73. package/dist/tools/follow-person.js.map +1 -0
  74. package/dist/tools/follow-person.test.d.ts +2 -0
  75. package/dist/tools/follow-person.test.d.ts.map +1 -0
  76. package/dist/tools/follow-person.test.js +66 -0
  77. package/dist/tools/follow-person.test.js.map +1 -0
  78. package/dist/tools/get-action-budget.d.ts +4 -0
  79. package/dist/tools/get-action-budget.d.ts.map +1 -0
  80. package/dist/tools/get-action-budget.js +19 -0
  81. package/dist/tools/get-action-budget.js.map +1 -0
  82. package/dist/tools/get-action-budget.test.d.ts +2 -0
  83. package/dist/tools/get-action-budget.test.d.ts.map +1 -0
  84. package/dist/tools/get-action-budget.test.js +59 -0
  85. package/dist/tools/get-action-budget.test.js.map +1 -0
  86. package/dist/tools/get-errors.js +1 -1
  87. package/dist/tools/get-errors.js.map +1 -1
  88. package/dist/tools/get-errors.test.js +3 -0
  89. package/dist/tools/get-errors.test.js.map +1 -1
  90. package/dist/tools/get-feed.d.ts +4 -0
  91. package/dist/tools/get-feed.d.ts.map +1 -0
  92. package/dist/tools/get-feed.js +37 -0
  93. package/dist/tools/get-feed.js.map +1 -0
  94. package/dist/tools/get-feed.test.d.ts +2 -0
  95. package/dist/tools/get-feed.test.d.ts.map +1 -0
  96. package/dist/tools/get-feed.test.js +72 -0
  97. package/dist/tools/get-feed.test.js.map +1 -0
  98. package/dist/tools/get-post-engagers.d.ts +4 -0
  99. package/dist/tools/get-post-engagers.d.ts.map +1 -0
  100. package/dist/tools/get-post-engagers.js +44 -0
  101. package/dist/tools/get-post-engagers.js.map +1 -0
  102. package/dist/tools/get-post-engagers.test.d.ts +2 -0
  103. package/dist/tools/get-post-engagers.test.d.ts.map +1 -0
  104. package/dist/tools/get-post-engagers.test.js +86 -0
  105. package/dist/tools/get-post-engagers.test.js.map +1 -0
  106. package/dist/tools/get-post-stats.d.ts +4 -0
  107. package/dist/tools/get-post-stats.d.ts.map +1 -0
  108. package/dist/tools/get-post-stats.js +23 -0
  109. package/dist/tools/get-post-stats.js.map +1 -0
  110. package/dist/tools/get-post-stats.test.d.ts +2 -0
  111. package/dist/tools/get-post-stats.test.d.ts.map +1 -0
  112. package/dist/tools/get-post-stats.test.js +64 -0
  113. package/dist/tools/get-post-stats.test.js.map +1 -0
  114. package/dist/tools/get-post.d.ts +4 -0
  115. package/dist/tools/get-post.d.ts.map +1 -0
  116. package/dist/tools/get-post.js +36 -0
  117. package/dist/tools/get-post.js.map +1 -0
  118. package/dist/tools/get-post.test.d.ts +2 -0
  119. package/dist/tools/get-post.test.d.ts.map +1 -0
  120. package/dist/tools/get-post.test.js +90 -0
  121. package/dist/tools/get-post.test.js.map +1 -0
  122. package/dist/tools/get-profile-activity.d.ts +4 -0
  123. package/dist/tools/get-profile-activity.d.ts.map +1 -0
  124. package/dist/tools/get-profile-activity.js +41 -0
  125. package/dist/tools/get-profile-activity.js.map +1 -0
  126. package/dist/tools/get-profile-activity.test.d.ts +2 -0
  127. package/dist/tools/get-profile-activity.test.d.ts.map +1 -0
  128. package/dist/tools/get-profile-activity.test.js +73 -0
  129. package/dist/tools/get-profile-activity.test.js.map +1 -0
  130. package/dist/tools/get-throttle-status.d.ts +4 -0
  131. package/dist/tools/get-throttle-status.d.ts.map +1 -0
  132. package/dist/tools/get-throttle-status.js +19 -0
  133. package/dist/tools/get-throttle-status.js.map +1 -0
  134. package/dist/tools/get-throttle-status.test.d.ts +2 -0
  135. package/dist/tools/get-throttle-status.test.d.ts.map +1 -0
  136. package/dist/tools/get-throttle-status.test.js +56 -0
  137. package/dist/tools/get-throttle-status.test.js.map +1 -0
  138. package/dist/tools/import-people-from-collection.test.d.ts +2 -0
  139. package/dist/tools/import-people-from-collection.test.d.ts.map +1 -0
  140. package/dist/tools/import-people-from-collection.test.js +86 -0
  141. package/dist/tools/import-people-from-collection.test.js.map +1 -0
  142. package/dist/tools/index.d.ts +22 -1
  143. package/dist/tools/index.d.ts.map +1 -1
  144. package/dist/tools/index.js +43 -1
  145. package/dist/tools/index.js.map +1 -1
  146. package/dist/tools/like-person-posts.d.ts +4 -0
  147. package/dist/tools/like-person-posts.d.ts.map +1 -0
  148. package/dist/tools/like-person-posts.js +86 -0
  149. package/dist/tools/like-person-posts.js.map +1 -0
  150. package/dist/tools/like-person-posts.test.d.ts +2 -0
  151. package/dist/tools/like-person-posts.test.d.ts.map +1 -0
  152. package/dist/tools/like-person-posts.test.js +72 -0
  153. package/dist/tools/like-person-posts.test.js.map +1 -0
  154. package/dist/tools/list-accounts.d.ts.map +1 -1
  155. package/dist/tools/list-accounts.js +19 -13
  156. package/dist/tools/list-accounts.js.map +1 -1
  157. package/dist/tools/list-collections.test.d.ts +2 -0
  158. package/dist/tools/list-collections.test.d.ts.map +1 -0
  159. package/dist/tools/list-collections.test.js +56 -0
  160. package/dist/tools/list-collections.test.js.map +1 -0
  161. package/dist/tools/message-person.d.ts +4 -0
  162. package/dist/tools/message-person.d.ts.map +1 -0
  163. package/dist/tools/message-person.js +71 -0
  164. package/dist/tools/message-person.js.map +1 -0
  165. package/dist/tools/message-person.test.d.ts +2 -0
  166. package/dist/tools/message-person.test.d.ts.map +1 -0
  167. package/dist/tools/message-person.test.js +101 -0
  168. package/dist/tools/message-person.test.js.map +1 -0
  169. package/dist/tools/query-messages.integration.test.js +24 -3
  170. package/dist/tools/query-messages.integration.test.js.map +1 -1
  171. package/dist/tools/react-to-post.d.ts +4 -0
  172. package/dist/tools/react-to-post.d.ts.map +1 -0
  173. package/dist/tools/react-to-post.js +34 -0
  174. package/dist/tools/react-to-post.js.map +1 -0
  175. package/dist/tools/react-to-post.test.d.ts +2 -0
  176. package/dist/tools/react-to-post.test.d.ts.map +1 -0
  177. package/dist/tools/react-to-post.test.js +64 -0
  178. package/dist/tools/react-to-post.test.js.map +1 -0
  179. package/dist/tools/remove-connection.d.ts +4 -0
  180. package/dist/tools/remove-connection.d.ts.map +1 -0
  181. package/dist/tools/remove-connection.js +39 -0
  182. package/dist/tools/remove-connection.js.map +1 -0
  183. package/dist/tools/remove-connection.test.d.ts +2 -0
  184. package/dist/tools/remove-connection.test.d.ts.map +1 -0
  185. package/dist/tools/remove-connection.test.js +58 -0
  186. package/dist/tools/remove-connection.test.js.map +1 -0
  187. package/dist/tools/remove-people-from-collection.test.d.ts +2 -0
  188. package/dist/tools/remove-people-from-collection.test.d.ts.map +1 -0
  189. package/dist/tools/remove-people-from-collection.test.js +60 -0
  190. package/dist/tools/remove-people-from-collection.test.js.map +1 -0
  191. package/dist/tools/scrape-messaging-history.d.ts.map +1 -1
  192. package/dist/tools/scrape-messaging-history.js +6 -2
  193. package/dist/tools/scrape-messaging-history.js.map +1 -1
  194. package/dist/tools/search-posts.d.ts +4 -0
  195. package/dist/tools/search-posts.d.ts.map +1 -0
  196. package/dist/tools/search-posts.js +43 -0
  197. package/dist/tools/search-posts.js.map +1 -0
  198. package/dist/tools/search-posts.test.d.ts +2 -0
  199. package/dist/tools/search-posts.test.d.ts.map +1 -0
  200. package/dist/tools/search-posts.test.js +86 -0
  201. package/dist/tools/search-posts.test.js.map +1 -0
  202. package/dist/tools/send-inmail.d.ts +4 -0
  203. package/dist/tools/send-inmail.d.ts.map +1 -0
  204. package/dist/tools/send-inmail.js +71 -0
  205. package/dist/tools/send-inmail.js.map +1 -0
  206. package/dist/tools/send-inmail.test.d.ts +2 -0
  207. package/dist/tools/send-inmail.test.d.ts.map +1 -0
  208. package/dist/tools/send-inmail.test.js +82 -0
  209. package/dist/tools/send-inmail.test.js.map +1 -0
  210. package/dist/tools/send-invite.d.ts +4 -0
  211. package/dist/tools/send-invite.d.ts.map +1 -0
  212. package/dist/tools/send-invite.js +57 -0
  213. package/dist/tools/send-invite.js.map +1 -0
  214. package/dist/tools/send-invite.test.d.ts +2 -0
  215. package/dist/tools/send-invite.test.d.ts.map +1 -0
  216. package/dist/tools/send-invite.test.js +80 -0
  217. package/dist/tools/send-invite.test.js.map +1 -0
  218. package/dist/tools/start-instance.d.ts.map +1 -1
  219. package/dist/tools/start-instance.js +32 -26
  220. package/dist/tools/start-instance.js.map +1 -1
  221. package/dist/tools/stop-instance.d.ts.map +1 -1
  222. package/dist/tools/stop-instance.js +28 -22
  223. package/dist/tools/stop-instance.js.map +1 -1
  224. package/dist/tools/testing/ephemeral-action-errors.d.ts +9 -0
  225. package/dist/tools/testing/ephemeral-action-errors.d.ts.map +1 -0
  226. package/dist/tools/testing/ephemeral-action-errors.js +48 -0
  227. package/dist/tools/testing/ephemeral-action-errors.js.map +1 -0
  228. package/dist/tools/visit-profile.d.ts +4 -0
  229. package/dist/tools/visit-profile.d.ts.map +1 -0
  230. package/dist/tools/visit-profile.js +37 -0
  231. package/dist/tools/visit-profile.js.map +1 -0
  232. package/dist/tools/visit-profile.test.d.ts +2 -0
  233. package/dist/tools/visit-profile.test.d.ts.map +1 -0
  234. package/dist/tools/visit-profile.test.js +164 -0
  235. package/dist/tools/visit-profile.test.js.map +1 -0
  236. package/package.json +2 -2
@@ -0,0 +1,80 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
+ vi.mock("@lhremote/core", async (importOriginal) => {
5
+ const actual = await importOriginal();
6
+ return {
7
+ ...actual,
8
+ sendInvite: vi.fn(),
9
+ };
10
+ });
11
+ import { sendInvite, } from "@lhremote/core";
12
+ import { registerSendInvite } from "./send-invite.js";
13
+ import { describeInfrastructureErrors } from "./testing/infrastructure-errors.js";
14
+ import { describeEphemeralActionErrors } from "./testing/ephemeral-action-errors.js";
15
+ import { createMockServer } from "./testing/mock-server.js";
16
+ const MOCK_RESULT = {
17
+ success: true,
18
+ personId: 100,
19
+ results: [{ id: 1, actionVersionId: 1, personId: 100, result: 1, platform: null, createdAt: "2026-01-01T00:00:00Z", profile: null }],
20
+ };
21
+ describe("registerSendInvite", () => {
22
+ beforeEach(() => {
23
+ vi.clearAllMocks();
24
+ });
25
+ afterEach(() => {
26
+ vi.restoreAllMocks();
27
+ });
28
+ it("registers a tool named send-invite", () => {
29
+ const { server } = createMockServer();
30
+ registerSendInvite(server);
31
+ expect(server.tool).toHaveBeenCalledOnce();
32
+ expect(server.tool).toHaveBeenCalledWith("send-invite", expect.any(String), expect.any(Object), expect.any(Function));
33
+ });
34
+ it("sends invite on success with personId", async () => {
35
+ const { server, getHandler } = createMockServer();
36
+ registerSendInvite(server);
37
+ vi.mocked(sendInvite).mockResolvedValue(MOCK_RESULT);
38
+ const handler = getHandler("send-invite");
39
+ const result = await handler({ personId: 100, cdpPort: 9222 });
40
+ expect(sendInvite).toHaveBeenCalledWith(expect.objectContaining({ personId: 100, cdpPort: 9222 }));
41
+ expect(result).toEqual({
42
+ content: [{ type: "text", text: JSON.stringify(MOCK_RESULT, null, 2) }],
43
+ });
44
+ });
45
+ it("sends invite with url", async () => {
46
+ const { server, getHandler } = createMockServer();
47
+ registerSendInvite(server);
48
+ vi.mocked(sendInvite).mockResolvedValue(MOCK_RESULT);
49
+ const handler = getHandler("send-invite");
50
+ await handler({ url: "https://www.linkedin.com/in/jane-doe", cdpPort: 9222 });
51
+ expect(sendInvite).toHaveBeenCalledWith(expect.objectContaining({ url: "https://www.linkedin.com/in/jane-doe" }));
52
+ });
53
+ it("returns error when neither personId nor url provided", async () => {
54
+ const { server, getHandler } = createMockServer();
55
+ registerSendInvite(server);
56
+ const handler = getHandler("send-invite");
57
+ const result = await handler({ cdpPort: 9222 });
58
+ expect(result).toEqual({
59
+ isError: true,
60
+ content: [{ type: "text", text: "Exactly one of personId or url must be provided." }],
61
+ });
62
+ });
63
+ it("returns error on invalid messageTemplate JSON", async () => {
64
+ const { server, getHandler } = createMockServer();
65
+ registerSendInvite(server);
66
+ const handler = getHandler("send-invite");
67
+ const result = await handler({
68
+ personId: 100,
69
+ messageTemplate: "not-json",
70
+ cdpPort: 9222,
71
+ });
72
+ expect(result).toEqual({
73
+ isError: true,
74
+ content: [{ type: "text", text: "Invalid JSON in messageTemplate." }],
75
+ });
76
+ });
77
+ describeInfrastructureErrors(registerSendInvite, "send-invite", () => ({ personId: 100, cdpPort: 9222 }), (error) => vi.mocked(sendInvite).mockRejectedValue(error), "Failed to send invite");
78
+ describeEphemeralActionErrors(registerSendInvite, "send-invite", () => ({ personId: 100, cdpPort: 9222 }), (error) => vi.mocked(sendInvite).mockRejectedValue(error), "Failed to send invite");
79
+ });
80
+ //# sourceMappingURL=send-invite.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-invite.test.js","sourceRoot":"","sources":["../../src/tools/send-invite.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"start-instance.d.ts","sourceRoot":"","sources":["../../src/tools/start-instance.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASzE,+GAA+G;AAC/G,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmE7D"}
1
+ {"version":3,"file":"start-instance.d.ts","sourceRoot":"","sources":["../../src/tools/start-instance.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUzE,+GAA+G;AAC/G,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwE7D"}
@@ -1,6 +1,6 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-only
2
2
  // Copyright (C) 2026 Oleksii PELYKH
3
- import { LauncherService, startInstanceWithRecovery, } from "@lhremote/core";
3
+ import { LauncherService, resolveLauncherPort, startInstanceWithRecovery, } from "@lhremote/core";
4
4
  import { z } from "zod";
5
5
  import { buildCdpOptions, cdpConnectionSchema, mcpCatchAll, mcpError, mcpSuccess } from "../helpers.js";
6
6
  /** Register the {@link https://github.com/alexey-pelykh/lhremote#start-instance | start-instance} MCP tool. */
@@ -14,40 +14,46 @@ export function registerStartInstance(server) {
14
14
  .describe("Account ID (omit to auto-select if single account)"),
15
15
  ...cdpConnectionSchema,
16
16
  }, async ({ accountId, cdpPort, cdpHost, allowRemote }) => {
17
- const launcher = new LauncherService(cdpPort, buildCdpOptions({ cdpHost, allowRemote }));
18
17
  try {
19
- await launcher.connect();
20
- }
21
- catch (error) {
22
- return mcpCatchAll(error, "Failed to connect to LinkedHelper");
23
- }
24
- try {
25
- let resolvedId = accountId;
26
- if (resolvedId === undefined) {
27
- const accounts = await launcher.listAccounts();
28
- if (accounts.length === 0) {
29
- return mcpError("No accounts found.");
18
+ const port = await resolveLauncherPort(cdpPort, cdpHost);
19
+ const launcher = new LauncherService(port, buildCdpOptions({ cdpHost, allowRemote }));
20
+ try {
21
+ await launcher.connect();
22
+ }
23
+ catch (error) {
24
+ return mcpCatchAll(error, "Failed to connect to LinkedHelper");
25
+ }
26
+ try {
27
+ let resolvedId = accountId;
28
+ if (resolvedId === undefined) {
29
+ const accounts = await launcher.listAccounts();
30
+ if (accounts.length === 0) {
31
+ return mcpError("No accounts found.");
32
+ }
33
+ if (accounts.length > 1) {
34
+ return mcpError("Multiple accounts found. Specify accountId. Use list-accounts to see available accounts.");
35
+ }
36
+ resolvedId = accounts[0].id;
30
37
  }
31
- if (accounts.length > 1) {
32
- return mcpError("Multiple accounts found. Specify accountId. Use list-accounts to see available accounts.");
38
+ const outcome = await startInstanceWithRecovery(launcher, resolvedId, port);
39
+ if (outcome.status === "timeout") {
40
+ return mcpError("Instance started but failed to initialize within timeout.");
33
41
  }
34
- resolvedId = accounts[0].id;
42
+ const verb = outcome.status === "already_running"
43
+ ? "already running"
44
+ : "started";
45
+ return mcpSuccess(`Instance ${verb} for account ${String(resolvedId)} on CDP port ${String(outcome.port)}`);
35
46
  }
36
- const outcome = await startInstanceWithRecovery(launcher, resolvedId, cdpPort);
37
- if (outcome.status === "timeout") {
38
- return mcpError("Instance started but failed to initialize within timeout.");
47
+ catch (error) {
48
+ return mcpCatchAll(error, "Failed to start instance");
49
+ }
50
+ finally {
51
+ launcher.disconnect();
39
52
  }
40
- const verb = outcome.status === "already_running"
41
- ? "already running"
42
- : "started";
43
- return mcpSuccess(`Instance ${verb} for account ${String(resolvedId)} on CDP port ${String(outcome.port)}`);
44
53
  }
45
54
  catch (error) {
46
55
  return mcpCatchAll(error, "Failed to start instance");
47
56
  }
48
- finally {
49
- launcher.disconnect();
50
- }
51
57
  });
52
58
  }
53
59
  //# sourceMappingURL=start-instance.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"start-instance.js","sourceRoot":"","sources":["../../src/tools/start-instance.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAEL,eAAe,EACf,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAExG,+GAA+G;AAC/G,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,qGAAqG,EACrG;QACE,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CACP,oDAAoD,CACrD;QACH,GAAG,mBAAmB;KACvB,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE;QACrD,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QAEzF,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,EAAE,mCAAmC,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,CAAC;YACH,IAAI,UAAU,GAAG,SAAS,CAAC;YAE3B,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;gBAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1B,OAAO,QAAQ,CAAC,oBAAoB,CAAC,CAAC;gBACxC,CAAC;gBACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,OAAO,QAAQ,CACb,0FAA0F,CAC3F,CAAC;gBACJ,CAAC;gBACD,UAAU,GAAI,QAAQ,CAAC,CAAC,CAAa,CAAC,EAAE,CAAC;YAC3C,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAC7C,QAAQ,EACR,UAAU,EACV,OAAO,CACR,CAAC;YAEF,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,OAAO,QAAQ,CACb,2DAA2D,CAC5D,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,GACR,OAAO,CAAC,MAAM,KAAK,iBAAiB;gBAClC,CAAC,CAAC,iBAAiB;gBACnB,CAAC,CAAC,SAAS,CAAC;YAEhB,OAAO,UAAU,CACf,YAAY,IAAI,gBAAgB,MAAM,CAAC,UAAU,CAAC,gBAAgB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CACzF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAAC;QACxD,CAAC;gBAAS,CAAC;YACT,QAAQ,CAAC,UAAU,EAAE,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"start-instance.js","sourceRoot":"","sources":["../../src/tools/start-instance.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAEL,eAAe,EACf,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAExG,+GAA+G;AAC/G,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,qGAAqG,EACrG;QACE,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CACP,oDAAoD,CACrD;QACH,GAAG,mBAAmB;KACvB,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE;QACrD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;YAEtF,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC3B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,WAAW,CAAC,KAAK,EAAE,mCAAmC,CAAC,CAAC;YACjE,CAAC;YAED,IAAI,CAAC;gBACH,IAAI,UAAU,GAAG,SAAS,CAAC;gBAE3B,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;oBAC7B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;oBAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAC1B,OAAO,QAAQ,CAAC,oBAAoB,CAAC,CAAC;oBACxC,CAAC;oBACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACxB,OAAO,QAAQ,CACb,0FAA0F,CAC3F,CAAC;oBACJ,CAAC;oBACD,UAAU,GAAI,QAAQ,CAAC,CAAC,CAAa,CAAC,EAAE,CAAC;gBAC3C,CAAC;gBAED,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAC7C,QAAQ,EACR,UAAU,EACV,IAAI,CACL,CAAC;gBAEF,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBACjC,OAAO,QAAQ,CACb,2DAA2D,CAC5D,CAAC;gBACJ,CAAC;gBAED,MAAM,IAAI,GACR,OAAO,CAAC,MAAM,KAAK,iBAAiB;oBAClC,CAAC,CAAC,iBAAiB;oBACnB,CAAC,CAAC,SAAS,CAAC;gBAEhB,OAAO,UAAU,CACf,YAAY,IAAI,gBAAgB,MAAM,CAAC,UAAU,CAAC,gBAAgB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CACzF,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,WAAW,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAAC;YACxD,CAAC;oBAAS,CAAC;gBACT,QAAQ,CAAC,UAAU,EAAE,CAAC;YACxB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAAC;QACxD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"stop-instance.d.ts","sourceRoot":"","sources":["../../src/tools/stop-instance.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQzE,6GAA6G;AAC7G,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoD5D"}
1
+ {"version":3,"file":"stop-instance.d.ts","sourceRoot":"","sources":["../../src/tools/stop-instance.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASzE,6GAA6G;AAC7G,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyD5D"}
@@ -1,6 +1,6 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-only
2
2
  // Copyright (C) 2026 Oleksii PELYKH
3
- import { LauncherService, } from "@lhremote/core";
3
+ import { LauncherService, resolveLauncherPort, } from "@lhremote/core";
4
4
  import { z } from "zod";
5
5
  import { buildCdpOptions, cdpConnectionSchema, mcpCatchAll, mcpError, mcpSuccess } from "../helpers.js";
6
6
  /** Register the {@link https://github.com/alexey-pelykh/lhremote#stop-instance | stop-instance} MCP tool. */
@@ -14,34 +14,40 @@ export function registerStopInstance(server) {
14
14
  .describe("Account ID (omit to stop the only running instance)"),
15
15
  ...cdpConnectionSchema,
16
16
  }, async ({ accountId, cdpPort, cdpHost, allowRemote }) => {
17
- const launcher = new LauncherService(cdpPort, buildCdpOptions({ cdpHost, allowRemote }));
18
17
  try {
19
- await launcher.connect();
20
- }
21
- catch (error) {
22
- return mcpCatchAll(error, "Failed to connect to LinkedHelper");
23
- }
24
- try {
25
- let resolvedId = accountId;
26
- if (resolvedId === undefined) {
27
- const accounts = await launcher.listAccounts();
28
- if (accounts.length === 0) {
29
- return mcpError("No accounts found.");
30
- }
31
- if (accounts.length > 1) {
32
- return mcpError("Multiple accounts found. Specify accountId. Use list-accounts to see available accounts.");
18
+ const port = await resolveLauncherPort(cdpPort, cdpHost);
19
+ const launcher = new LauncherService(port, buildCdpOptions({ cdpHost, allowRemote }));
20
+ try {
21
+ await launcher.connect();
22
+ }
23
+ catch (error) {
24
+ return mcpCatchAll(error, "Failed to connect to LinkedHelper");
25
+ }
26
+ try {
27
+ let resolvedId = accountId;
28
+ if (resolvedId === undefined) {
29
+ const accounts = await launcher.listAccounts();
30
+ if (accounts.length === 0) {
31
+ return mcpError("No accounts found.");
32
+ }
33
+ if (accounts.length > 1) {
34
+ return mcpError("Multiple accounts found. Specify accountId. Use list-accounts to see available accounts.");
35
+ }
36
+ resolvedId = accounts[0].id;
33
37
  }
34
- resolvedId = accounts[0].id;
38
+ await launcher.stopInstance(resolvedId);
39
+ return mcpSuccess(`Instance stopped for account ${String(resolvedId)}`);
40
+ }
41
+ catch (error) {
42
+ return mcpCatchAll(error, "Failed to stop instance");
43
+ }
44
+ finally {
45
+ launcher.disconnect();
35
46
  }
36
- await launcher.stopInstance(resolvedId);
37
- return mcpSuccess(`Instance stopped for account ${String(resolvedId)}`);
38
47
  }
39
48
  catch (error) {
40
49
  return mcpCatchAll(error, "Failed to stop instance");
41
50
  }
42
- finally {
43
- launcher.disconnect();
44
- }
45
51
  });
46
52
  }
47
53
  //# sourceMappingURL=stop-instance.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stop-instance.js","sourceRoot":"","sources":["../../src/tools/stop-instance.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAEL,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAExG,6GAA6G;AAC7G,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,CAAC,IAAI,CACT,eAAe,EACf,sCAAsC,EACtC;QACE,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CACP,qDAAqD,CACtD;QACH,GAAG,mBAAmB;KACvB,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE;QACrD,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QAEzF,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,EAAE,mCAAmC,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,CAAC;YACH,IAAI,UAAU,GAAG,SAAS,CAAC;YAE3B,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;gBAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1B,OAAO,QAAQ,CAAC,oBAAoB,CAAC,CAAC;gBACxC,CAAC;gBACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,OAAO,QAAQ,CACb,0FAA0F,CAC3F,CAAC;gBACJ,CAAC;gBACD,UAAU,GAAI,QAAQ,CAAC,CAAC,CAAa,CAAC,EAAE,CAAC;YAC3C,CAAC;YAED,MAAM,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;YAExC,OAAO,UAAU,CACf,gCAAgC,MAAM,CAAC,UAAU,CAAC,EAAE,CACrD,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAC;QACvD,CAAC;gBAAS,CAAC;YACT,QAAQ,CAAC,UAAU,EAAE,CAAC;QACxB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"stop-instance.js","sourceRoot":"","sources":["../../src/tools/stop-instance.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAEL,eAAe,EACf,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAExG,6GAA6G;AAC7G,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,CAAC,IAAI,CACT,eAAe,EACf,sCAAsC,EACtC;QACE,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CACP,qDAAqD,CACtD;QACH,GAAG,mBAAmB;KACvB,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE;QACrD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;YAEtF,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC3B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,WAAW,CAAC,KAAK,EAAE,mCAAmC,CAAC,CAAC;YACjE,CAAC;YAED,IAAI,CAAC;gBACH,IAAI,UAAU,GAAG,SAAS,CAAC;gBAE3B,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;oBAC7B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;oBAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAC1B,OAAO,QAAQ,CAAC,oBAAoB,CAAC,CAAC;oBACxC,CAAC;oBACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACxB,OAAO,QAAQ,CACb,0FAA0F,CAC3F,CAAC;oBACJ,CAAC;oBACD,UAAU,GAAI,QAAQ,CAAC,CAAC,CAAa,CAAC,EAAE,CAAC;gBAC3C,CAAC;gBAED,MAAM,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;gBAExC,OAAO,UAAU,CACf,gCAAgC,MAAM,CAAC,UAAU,CAAC,EAAE,CACrD,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,WAAW,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAC;YACvD,CAAC;oBAAS,CAAC;gBACT,QAAQ,CAAC,UAAU,EAAE,CAAC;YACxB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAC;QACvD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ /**
3
+ * Shared error tests for ephemeral-action-based MCP tools.
4
+ *
5
+ * Covers CampaignExecutionError and CampaignTimeoutError in addition to
6
+ * the infrastructure errors tested by describeInfrastructureErrors.
7
+ */
8
+ export declare function describeEphemeralActionErrors(registerTool: (server: McpServer) => void, toolName: string, getArgs: () => Record<string, unknown>, mockOperation: (error: Error) => void, errorPrefix: string): void;
9
+ //# sourceMappingURL=ephemeral-action-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ephemeral-action-errors.d.ts","sourceRoot":"","sources":["../../../src/tools/testing/ephemeral-action-errors.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,YAAY,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,EACzC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EACrC,WAAW,EAAE,MAAM,GAClB,IAAI,CA0CN"}
@@ -0,0 +1,48 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { CampaignExecutionError, CampaignTimeoutError } from "@lhremote/core";
4
+ import { describe, expect, it } from "vitest";
5
+ import { createMockServer } from "./mock-server.js";
6
+ /**
7
+ * Shared error tests for ephemeral-action-based MCP tools.
8
+ *
9
+ * Covers CampaignExecutionError and CampaignTimeoutError in addition to
10
+ * the infrastructure errors tested by describeInfrastructureErrors.
11
+ */
12
+ export function describeEphemeralActionErrors(registerTool, toolName, getArgs, mockOperation, errorPrefix) {
13
+ describe("ephemeral action errors", () => {
14
+ it("returns error on campaign execution failure", async () => {
15
+ const { server, getHandler } = createMockServer();
16
+ registerTool(server);
17
+ mockOperation(new CampaignExecutionError("Person 100 not found in database"));
18
+ const handler = getHandler(toolName);
19
+ const result = await handler(getArgs());
20
+ expect(result).toEqual({
21
+ isError: true,
22
+ content: [
23
+ {
24
+ type: "text",
25
+ text: `${errorPrefix}: Person 100 not found in database`,
26
+ },
27
+ ],
28
+ });
29
+ });
30
+ it("returns error on campaign timeout", async () => {
31
+ const { server, getHandler } = createMockServer();
32
+ registerTool(server);
33
+ mockOperation(new CampaignTimeoutError("Ephemeral action did not complete within 300000ms", 42));
34
+ const handler = getHandler(toolName);
35
+ const result = await handler(getArgs());
36
+ expect(result).toEqual({
37
+ isError: true,
38
+ content: [
39
+ {
40
+ type: "text",
41
+ text: `${errorPrefix}: Ephemeral action did not complete within 300000ms`,
42
+ },
43
+ ],
44
+ });
45
+ });
46
+ });
47
+ }
48
+ //# sourceMappingURL=ephemeral-action-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ephemeral-action-errors.js","sourceRoot":"","sources":["../../../src/tools/testing/ephemeral-action-errors.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,UAAU,6BAA6B,CAC3C,YAAyC,EACzC,QAAgB,EAChB,OAAsC,EACtC,aAAqC,EACrC,WAAmB;IAEnB,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,gBAAgB,EAAE,CAAC;YAClD,YAAY,CAAC,MAAM,CAAC,CAAC;YAErB,aAAa,CAAC,IAAI,sBAAsB,CAAC,kCAAkC,CAAC,CAAC,CAAC;YAE9E,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAExC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,GAAG,WAAW,oCAAoC;qBACzD;iBACF;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACjD,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,gBAAgB,EAAE,CAAC;YAClD,YAAY,CAAC,MAAM,CAAC,CAAC;YAErB,aAAa,CAAC,IAAI,oBAAoB,CAAC,mDAAmD,EAAE,EAAE,CAAC,CAAC,CAAC;YAEjG,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAExC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,GAAG,WAAW,qDAAqD;qBAC1E;iBACF;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ /** Register the {@link https://github.com/alexey-pelykh/lhremote#visit-profile | visit-profile} MCP tool. */
3
+ export declare function registerVisitProfile(server: McpServer): void;
4
+ //# sourceMappingURL=visit-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visit-profile.d.ts","sourceRoot":"","sources":["../../src/tools/visit-profile.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,6GAA6G;AAC7G,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwC5D"}
@@ -0,0 +1,37 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { visitProfile, } from "@lhremote/core";
4
+ import { z } from "zod";
5
+ import { cdpConnectionSchema, mcpCatchAll, mcpError, mcpSuccess } from "../helpers.js";
6
+ /** Register the {@link https://github.com/alexey-pelykh/lhremote#visit-profile | visit-profile} MCP tool. */
7
+ export function registerVisitProfile(server) {
8
+ server.tool("visit-profile", "Visit a LinkedIn profile via LinkedHelper's VisitAndExtract action and return the extracted profile data. Accepts either a person ID or a LinkedIn profile URL. Deducts from the daily action budget.", {
9
+ personId: z
10
+ .number()
11
+ .int()
12
+ .positive()
13
+ .optional()
14
+ .describe("Internal person ID to visit"),
15
+ url: z
16
+ .string()
17
+ .optional()
18
+ .describe("LinkedIn profile URL (e.g. https://www.linkedin.com/in/jane-doe-123). The person must already exist in the database."),
19
+ extractCurrentOrganizations: z
20
+ .boolean()
21
+ .optional()
22
+ .describe("Extract current company info during profile visit"),
23
+ ...cdpConnectionSchema,
24
+ }, async ({ personId, url, extractCurrentOrganizations, cdpPort, cdpHost, allowRemote }) => {
25
+ if ((personId == null) === (url == null)) {
26
+ return mcpError("Exactly one of personId or url must be provided.");
27
+ }
28
+ try {
29
+ const result = await visitProfile({ personId, url, extractCurrentOrganizations, cdpPort, cdpHost, allowRemote });
30
+ return mcpSuccess(JSON.stringify(result, null, 2));
31
+ }
32
+ catch (error) {
33
+ return mcpCatchAll(error, "Failed to visit profile");
34
+ }
35
+ });
36
+ }
37
+ //# sourceMappingURL=visit-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visit-profile.js","sourceRoot":"","sources":["../../src/tools/visit-profile.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EACL,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEvF,6GAA6G;AAC7G,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,CAAC,IAAI,CACT,eAAe,EACf,uMAAuM,EACvM;QACE,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CAAC,6BAA6B,CAAC;QAC1C,GAAG,EAAE,CAAC;aACH,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,sHAAsH,CACvH;QACH,2BAA2B,EAAE,CAAC;aAC3B,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CACP,mDAAmD,CACpD;QACH,GAAG,mBAAmB;KACvB,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,2BAA2B,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE;QACtF,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;YACzC,OAAO,QAAQ,CACb,kDAAkD,CACnD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,2BAA2B,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;YACjH,OAAO,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAC;QACvD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=visit-profile.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visit-profile.test.d.ts","sourceRoot":"","sources":["../../src/tools/visit-profile.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,164 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
+ vi.mock("@lhremote/core", async (importOriginal) => {
5
+ const actual = await importOriginal();
6
+ return {
7
+ ...actual,
8
+ visitProfile: vi.fn(),
9
+ };
10
+ });
11
+ import { AccountResolutionError, visitProfile, } from "@lhremote/core";
12
+ import { registerVisitProfile } from "./visit-profile.js";
13
+ import { describeInfrastructureErrors } from "./testing/infrastructure-errors.js";
14
+ import { createMockServer } from "./testing/mock-server.js";
15
+ const MOCK_PROFILE = {
16
+ id: 100,
17
+ miniProfile: {
18
+ firstName: "Jane",
19
+ lastName: "Doe",
20
+ headline: "Software Engineer",
21
+ avatar: null,
22
+ },
23
+ externalIds: [{ externalId: "jane-doe-123", typeGroup: "public", isMemberId: false }],
24
+ currentPosition: { company: "Acme Corp", title: "Senior Engineer" },
25
+ education: [],
26
+ skills: [{ name: "TypeScript" }],
27
+ emails: [],
28
+ };
29
+ describe("registerVisitProfile", () => {
30
+ beforeEach(() => {
31
+ vi.clearAllMocks();
32
+ });
33
+ afterEach(() => {
34
+ vi.restoreAllMocks();
35
+ });
36
+ it("registers a tool named visit-profile", () => {
37
+ const { server } = createMockServer();
38
+ registerVisitProfile(server);
39
+ expect(server.tool).toHaveBeenCalledOnce();
40
+ expect(server.tool).toHaveBeenCalledWith("visit-profile", expect.any(String), expect.any(Object), expect.any(Function));
41
+ });
42
+ it("returns profile on success with personId", async () => {
43
+ const { server, getHandler } = createMockServer();
44
+ registerVisitProfile(server);
45
+ vi.mocked(visitProfile).mockResolvedValue({
46
+ success: true,
47
+ actionType: "VisitAndExtract",
48
+ profile: MOCK_PROFILE,
49
+ });
50
+ const handler = getHandler("visit-profile");
51
+ const result = await handler({ personId: 100, cdpPort: 9222 });
52
+ expect(result).toEqual({
53
+ content: [
54
+ {
55
+ type: "text",
56
+ text: JSON.stringify({
57
+ success: true,
58
+ actionType: "VisitAndExtract",
59
+ profile: MOCK_PROFILE,
60
+ }, null, 2),
61
+ },
62
+ ],
63
+ });
64
+ });
65
+ it("returns profile on success with url", async () => {
66
+ const { server, getHandler } = createMockServer();
67
+ registerVisitProfile(server);
68
+ vi.mocked(visitProfile).mockResolvedValue({
69
+ success: true,
70
+ actionType: "VisitAndExtract",
71
+ profile: MOCK_PROFILE,
72
+ });
73
+ const handler = getHandler("visit-profile");
74
+ const result = await handler({ url: "https://www.linkedin.com/in/jane-doe-123", cdpPort: 9222 });
75
+ expect(visitProfile).toHaveBeenCalledWith(expect.objectContaining({ url: "https://www.linkedin.com/in/jane-doe-123", cdpPort: 9222 }));
76
+ expect(result).toEqual({
77
+ content: [
78
+ {
79
+ type: "text",
80
+ text: expect.any(String),
81
+ },
82
+ ],
83
+ });
84
+ });
85
+ it("returns error when neither personId nor url provided", async () => {
86
+ const { server, getHandler } = createMockServer();
87
+ registerVisitProfile(server);
88
+ const handler = getHandler("visit-profile");
89
+ const result = await handler({ cdpPort: 9222 });
90
+ expect(result).toEqual({
91
+ isError: true,
92
+ content: [{ type: "text", text: "Exactly one of personId or url must be provided." }],
93
+ });
94
+ expect(visitProfile).not.toHaveBeenCalled();
95
+ });
96
+ it("returns error when both personId and url provided", async () => {
97
+ const { server, getHandler } = createMockServer();
98
+ registerVisitProfile(server);
99
+ const handler = getHandler("visit-profile");
100
+ const result = await handler({ personId: 100, url: "https://www.linkedin.com/in/jane-doe", cdpPort: 9222 });
101
+ expect(result).toEqual({
102
+ isError: true,
103
+ content: [{ type: "text", text: "Exactly one of personId or url must be provided." }],
104
+ });
105
+ expect(visitProfile).not.toHaveBeenCalled();
106
+ });
107
+ it("passes correct arguments to operation", async () => {
108
+ const { server, getHandler } = createMockServer();
109
+ registerVisitProfile(server);
110
+ vi.mocked(visitProfile).mockResolvedValue({
111
+ success: true,
112
+ actionType: "VisitAndExtract",
113
+ profile: MOCK_PROFILE,
114
+ });
115
+ const handler = getHandler("visit-profile");
116
+ await handler({ personId: 100, extractCurrentOrganizations: true, cdpPort: 9222 });
117
+ expect(visitProfile).toHaveBeenCalledWith(expect.objectContaining({ personId: 100, extractCurrentOrganizations: true, cdpPort: 9222 }));
118
+ });
119
+ it("returns error when no accounts found", async () => {
120
+ const { server, getHandler } = createMockServer();
121
+ registerVisitProfile(server);
122
+ vi.mocked(visitProfile).mockRejectedValue(new AccountResolutionError("no-accounts"));
123
+ const handler = getHandler("visit-profile");
124
+ const result = await handler({ personId: 100, cdpPort: 9222 });
125
+ expect(result).toEqual({
126
+ isError: true,
127
+ content: [{ type: "text", text: "No accounts found." }],
128
+ });
129
+ });
130
+ it("returns error when multiple accounts found", async () => {
131
+ const { server, getHandler } = createMockServer();
132
+ registerVisitProfile(server);
133
+ vi.mocked(visitProfile).mockRejectedValue(new AccountResolutionError("multiple-accounts"));
134
+ const handler = getHandler("visit-profile");
135
+ const result = await handler({ personId: 100, cdpPort: 9222 });
136
+ expect(result).toEqual({
137
+ isError: true,
138
+ content: [
139
+ {
140
+ type: "text",
141
+ text: "Multiple accounts found. Cannot determine which instance to use.",
142
+ },
143
+ ],
144
+ });
145
+ });
146
+ it("returns error on unexpected failure", async () => {
147
+ const { server, getHandler } = createMockServer();
148
+ registerVisitProfile(server);
149
+ vi.mocked(visitProfile).mockRejectedValue(new Error("action timed out"));
150
+ const handler = getHandler("visit-profile");
151
+ const result = await handler({ personId: 100, cdpPort: 9222 });
152
+ expect(result).toEqual({
153
+ isError: true,
154
+ content: [
155
+ {
156
+ type: "text",
157
+ text: "Failed to visit profile: action timed out",
158
+ },
159
+ ],
160
+ });
161
+ });
162
+ describeInfrastructureErrors(registerVisitProfile, "visit-profile", () => ({ personId: 100, cdpPort: 9222 }), (error) => vi.mocked(visitProfile).mockRejectedValue(error), "Failed to visit profile");
163
+ });
164
+ //# sourceMappingURL=visit-profile.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visit-profile.test.js","sourceRoot":"","sources":["../../src/tools/visit-profile.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lhremote/mcp",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "MCP server for LinkedHelper automation",
5
5
  "type": "module",
6
6
  "engines": {
@@ -46,7 +46,7 @@
46
46
  "dependencies": {
47
47
  "@modelcontextprotocol/sdk": "^1.26.0",
48
48
  "zod": "^4.3.6",
49
- "@lhremote/core": "^0.7.0"
49
+ "@lhremote/core": "^0.9.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/node": "^25",