@linkedapi/mcp 2.3.11 → 2.3.13

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 (37) hide show
  1. package/dist/linked-api-tools.d.ts.map +1 -1
  2. package/dist/linked-api-tools.js +4 -0
  3. package/dist/linked-api-tools.js.map +1 -1
  4. package/dist/tools/comment-on-post.d.ts +2 -1
  5. package/dist/tools/comment-on-post.d.ts.map +1 -1
  6. package/dist/tools/comment-on-post.js +8 -3
  7. package/dist/tools/comment-on-post.js.map +1 -1
  8. package/dist/tools/create-post.d.ts +7 -0
  9. package/dist/tools/create-post.d.ts.map +1 -1
  10. package/dist/tools/create-post.js +41 -2
  11. package/dist/tools/create-post.js.map +1 -1
  12. package/dist/tools/create-repost.d.ts +22 -0
  13. package/dist/tools/create-repost.d.ts.map +1 -0
  14. package/dist/tools/create-repost.js +80 -0
  15. package/dist/tools/create-repost.js.map +1 -0
  16. package/dist/tools/fetch-post.d.ts +2 -1
  17. package/dist/tools/fetch-post.d.ts.map +1 -1
  18. package/dist/tools/fetch-post.js +8 -3
  19. package/dist/tools/fetch-post.js.map +1 -1
  20. package/dist/tools/get-workflow-result.d.ts +2 -0
  21. package/dist/tools/get-workflow-result.d.ts.map +1 -1
  22. package/dist/tools/react-to-post.d.ts +2 -1
  23. package/dist/tools/react-to-post.d.ts.map +1 -1
  24. package/dist/tools/react-to-post.js +8 -3
  25. package/dist/tools/react-to-post.js.map +1 -1
  26. package/dist/tools/search-posts.d.ts +64 -0
  27. package/dist/tools/search-posts.d.ts.map +1 -0
  28. package/dist/tools/search-posts.js +198 -0
  29. package/dist/tools/search-posts.js.map +1 -0
  30. package/package.json +3 -3
  31. package/src/linked-api-tools.ts +4 -0
  32. package/src/tools/comment-on-post.ts +9 -3
  33. package/src/tools/create-post.ts +49 -2
  34. package/src/tools/create-repost.ts +90 -0
  35. package/src/tools/fetch-post.ts +9 -3
  36. package/src/tools/react-to-post.ts +9 -3
  37. package/src/tools/search-posts.ts +213 -0
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SearchPostsTool = void 0;
4
+ const node_1 = require("@linkedapi/node");
5
+ const zod_1 = require("zod");
6
+ const linked_api_tool_js_1 = require("../utils/linked-api-tool.js");
7
+ const PERSON_FILTER_ENTRY_SCHEMA = zod_1.z.union([
8
+ zod_1.z.string().min(1).max(100),
9
+ zod_1.z.object({
10
+ name: zod_1.z.string().min(1).max(100),
11
+ urn: zod_1.z.string().optional(),
12
+ personHashedUrl: zod_1.z.string().optional(),
13
+ }),
14
+ ]);
15
+ const COMPANY_FILTER_ENTRY_SCHEMA = zod_1.z.union([
16
+ zod_1.z.string().min(1).max(100),
17
+ zod_1.z.object({
18
+ name: zod_1.z.string().min(1).max(100),
19
+ urn: zod_1.z.string().optional(),
20
+ companyHashedUrl: zod_1.z.string().optional(),
21
+ }),
22
+ ]);
23
+ const PERSON_FILTER_ENTRY_JSON_SCHEMA = {
24
+ oneOf: [
25
+ {
26
+ type: 'string',
27
+ minLength: 1,
28
+ maxLength: 100,
29
+ description: 'Name of the person, shorthand for { name }.',
30
+ },
31
+ {
32
+ type: 'object',
33
+ properties: {
34
+ name: {
35
+ type: 'string',
36
+ minLength: 1,
37
+ maxLength: 100,
38
+ description: 'Required. Name to type into the LinkedIn filter panel.',
39
+ },
40
+ urn: {
41
+ type: 'string',
42
+ description: 'Optional. Member URN of the person, urn:li:member:<id>.',
43
+ },
44
+ personHashedUrl: {
45
+ type: 'string',
46
+ description: 'Optional. Hashed LinkedIn URL of the person.',
47
+ },
48
+ },
49
+ required: ['name'],
50
+ },
51
+ ],
52
+ };
53
+ const COMPANY_FILTER_ENTRY_JSON_SCHEMA = {
54
+ oneOf: [
55
+ {
56
+ type: 'string',
57
+ minLength: 1,
58
+ maxLength: 100,
59
+ description: 'Name of the company, shorthand for { name }.',
60
+ },
61
+ {
62
+ type: 'object',
63
+ properties: {
64
+ name: {
65
+ type: 'string',
66
+ minLength: 1,
67
+ maxLength: 100,
68
+ description: 'Required. Name to type into the LinkedIn filter panel.',
69
+ },
70
+ urn: {
71
+ type: 'string',
72
+ description: 'Optional. Organization URN of the company, urn:li:organization:<id>.',
73
+ },
74
+ companyHashedUrl: {
75
+ type: 'string',
76
+ description: 'Optional. Hashed LinkedIn URL of the company.',
77
+ },
78
+ },
79
+ required: ['name'],
80
+ },
81
+ ],
82
+ };
83
+ class SearchPostsTool extends linked_api_tool_js_1.OperationTool {
84
+ name = 'search_posts';
85
+ operationName = node_1.OPERATION_NAME.searchPosts;
86
+ schema = zod_1.z
87
+ .object({
88
+ term: zod_1.z.string().min(1).max(50).optional(),
89
+ limit: zod_1.z.number().min(1).max(100).optional(),
90
+ filter: zod_1.z
91
+ .object({
92
+ sort: zod_1.z.enum(['topMatch', 'latest']).optional(),
93
+ datePosted: zod_1.z.enum(['past24Hours', 'pastWeek', 'pastMonth']).optional(),
94
+ contentType: zod_1.z
95
+ .enum(['videos', 'images', 'jobPosts', 'liveVideos', 'documents'])
96
+ .optional(),
97
+ postedBy: zod_1.z.array(zod_1.z.enum(['me', 'firstConnections', 'peopleYouFollow'])).optional(),
98
+ fromMembers: zod_1.z.array(PERSON_FILTER_ENTRY_SCHEMA).optional(),
99
+ fromCompanies: zod_1.z.array(COMPANY_FILTER_ENTRY_SCHEMA).optional(),
100
+ mentioningMembers: zod_1.z.array(PERSON_FILTER_ENTRY_SCHEMA).optional(),
101
+ mentioningCompanies: zod_1.z.array(COMPANY_FILTER_ENTRY_SCHEMA).optional(),
102
+ authorCompanies: zod_1.z.array(COMPANY_FILTER_ENTRY_SCHEMA).optional(),
103
+ authorIndustries: zod_1.z.array(zod_1.z.string()).optional(),
104
+ })
105
+ .optional(),
106
+ customSearchUrl: zod_1.z.string().optional(),
107
+ })
108
+ .refine(({ term, customSearchUrl }) => Boolean(term) || Boolean(customSearchUrl), {
109
+ message: 'Either term or customSearchUrl must be provided.',
110
+ });
111
+ getTool() {
112
+ return {
113
+ name: this.name,
114
+ description: 'Allows you to search posts applying various filtering criteria (st.searchPosts action). Either term or customSearchUrl must be provided, and when customSearchUrl is specified, filter is ignored entirely and only the facets already encoded in the URL are applied. LinkedIn widens a narrow query on its own, so a non-empty result does not mean the term matched — check the returned posts against your own criteria when an exact match matters. Unlike fetch_post, the author and reposter of a search result carry no urn, so fetch the post by its url when you need one.',
115
+ inputSchema: {
116
+ type: 'object',
117
+ properties: {
118
+ term: {
119
+ type: 'string',
120
+ minLength: 1,
121
+ maxLength: 50,
122
+ description: 'Optional. Keyword or phrase to search, from 1 to 50 characters. Required unless customSearchUrl is specified.',
123
+ },
124
+ limit: {
125
+ type: 'number',
126
+ description: 'Optional. Number of search results to return. Defaults to 10, with a maximum value of 100. A search may return fewer posts than limit, because how many results come back depends on what LinkedIn loads for that account on that search.',
127
+ },
128
+ filter: {
129
+ type: 'object',
130
+ description: 'Optional. Filtering criteria for posts. Every specified field is applied, or the action fails. When multiple filter fields are specified, they are combined using AND logic. Ignored entirely when customSearchUrl is specified.',
131
+ properties: {
132
+ sort: {
133
+ type: 'string',
134
+ enum: ['topMatch', 'latest'],
135
+ description: 'Optional. How to order the results.',
136
+ },
137
+ datePosted: {
138
+ type: 'string',
139
+ enum: ['past24Hours', 'pastWeek', 'pastMonth'],
140
+ description: 'Optional. How recently the post was published.',
141
+ },
142
+ contentType: {
143
+ type: 'string',
144
+ enum: ['videos', 'images', 'jobPosts', 'liveVideos', 'documents'],
145
+ description: 'Optional. Kind of content the post must carry.',
146
+ },
147
+ postedBy: {
148
+ type: 'array',
149
+ description: 'Optional. Array of author relationships to you. Matches if the post was published by any of the listed ones.',
150
+ items: {
151
+ type: 'string',
152
+ enum: ['me', 'firstConnections', 'peopleYouFollow'],
153
+ },
154
+ },
155
+ fromMembers: {
156
+ type: 'array',
157
+ description: 'Optional. Array of people whose posts to keep. Each entry is a plain name string, or an object with name plus an optional urn or personHashedUrl that pins the exact person; both forms can be mixed in one array. With a name alone LinkedIn takes whichever suggestion it ranked first, which may be a namesake. An identifier no suggestion resolves to fails the action with filterIdentityMismatch rather than filtering by a namesake.',
158
+ items: PERSON_FILTER_ENTRY_JSON_SCHEMA,
159
+ },
160
+ fromCompanies: {
161
+ type: 'array',
162
+ description: 'Optional. Array of companies whose posts to keep. Same entry shape as fromMembers, with companyHashedUrl in place of personHashedUrl.',
163
+ items: COMPANY_FILTER_ENTRY_JSON_SCHEMA,
164
+ },
165
+ mentioningMembers: {
166
+ type: 'array',
167
+ description: 'Optional. Array of people to look for in post text. Same entry shape as fromMembers.',
168
+ items: PERSON_FILTER_ENTRY_JSON_SCHEMA,
169
+ },
170
+ mentioningCompanies: {
171
+ type: 'array',
172
+ description: 'Optional. Array of companies to look for in post text. Same entry shape as fromCompanies.',
173
+ items: COMPANY_FILTER_ENTRY_JSON_SCHEMA,
174
+ },
175
+ authorCompanies: {
176
+ type: 'array',
177
+ description: 'Optional. Array of companies the author works at. Same entry shape as fromCompanies.',
178
+ items: COMPANY_FILTER_ENTRY_JSON_SCHEMA,
179
+ },
180
+ authorIndustries: {
181
+ type: 'array',
182
+ description: 'Optional. Array of industry names the author works in. An industry is a taxonomy value rather than an entity, so it is matched by name only. Takes specific values available in the LinkedIn interface.',
183
+ items: { type: 'string' },
184
+ },
185
+ },
186
+ },
187
+ customSearchUrl: {
188
+ type: 'string',
189
+ description: 'Optional. URL copied from a LinkedIn content search page after configuring filters. When specified, filter is ignored entirely.',
190
+ },
191
+ },
192
+ anyOf: [{ required: ['term'] }, { required: ['customSearchUrl'] }],
193
+ },
194
+ };
195
+ }
196
+ }
197
+ exports.SearchPostsTool = SearchPostsTool;
198
+ //# sourceMappingURL=search-posts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-posts.js","sourceRoot":"","sources":["../../src/tools/search-posts.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linkedapi/mcp",
3
- "version": "2.3.11",
3
+ "version": "2.3.13",
4
4
  "description": "MCP server that lets AI assistants control LinkedIn accounts and retrieve real-time data.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -30,7 +30,7 @@
30
30
  "author": "Linked API",
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
- "@linkedapi/node": "^2.3.11",
33
+ "@linkedapi/node": "^2.3.13",
34
34
  "@modelcontextprotocol/sdk": "^1.17.4",
35
35
  "zod": "^4.1.1"
36
36
  },
@@ -56,4 +56,4 @@
56
56
  "typescript": "^5.8.3",
57
57
  "typescript-eslint": "^8.38.0"
58
58
  }
59
- }
59
+ }
@@ -22,6 +22,7 @@ import { AdminSetSeatsTool } from './tools/admin-set-seats.js';
22
22
  import { CheckConnectionStatusTool } from './tools/check-connection-status.js';
23
23
  import { CommentOnPostTool } from './tools/comment-on-post.js';
24
24
  import { CreatePostTool } from './tools/create-post.js';
25
+ import { CreateRepostTool } from './tools/create-repost.js';
25
26
  import { ExecuteCustomWorkflowTool } from './tools/execute-custom-workflow.js';
26
27
  import { FetchCompanyTool } from './tools/fetch-company.js';
27
28
  import { FetchJobTool } from './tools/fetch-job.js';
@@ -56,6 +57,7 @@ import { RetrieveSSITool } from './tools/retrieve-ssi.js';
56
57
  import { SearchCompaniesTool } from './tools/search-companies.js';
57
58
  import { SearchJobsTool } from './tools/search-jobs.js';
58
59
  import { SearchPeopleTool } from './tools/search-people.js';
60
+ import { SearchPostsTool } from './tools/search-posts.js';
59
61
  import { SendConnectionRequestTool } from './tools/send-connection-request.js';
60
62
  import { SendFeedbackTool } from './tools/send-feedback.js';
61
63
  import { SendMessageTool } from './tools/send-message.js';
@@ -103,6 +105,7 @@ export class LinkedApiTools {
103
105
  new SearchCompaniesTool(),
104
106
  new SearchPeopleTool(),
105
107
  new SearchJobsTool(),
108
+ new SearchPostsTool(),
106
109
  new FetchCompanyTool(),
107
110
  new FetchPersonTool(),
108
111
  new FetchPostTool(),
@@ -112,6 +115,7 @@ export class LinkedApiTools {
112
115
  new ReactToCommentTool(),
113
116
  new ReplyToCommentTool(),
114
117
  new CreatePostTool(),
118
+ new CreateRepostTool(),
115
119
  new RetrieveFeedTool(),
116
120
  new RetrieveProfileViewersTool(),
117
121
  new RetrieveSSITool(),
@@ -8,7 +8,8 @@ export class CommentOnPostTool extends OperationTool<TCommentOnPostParams, TComm
8
8
  public override readonly name = 'comment_on_post';
9
9
  public override readonly operationName = OPERATION_NAME.commentOnPost;
10
10
  protected override readonly schema = z.object({
11
- postUrl: z.string(),
11
+ postUrl: z.string().optional(),
12
+ postUrn: z.string().optional(),
12
13
  text: z.string().min(1),
13
14
  companyUrl: z.string().optional(),
14
15
  });
@@ -24,7 +25,12 @@ export class CommentOnPostTool extends OperationTool<TCommentOnPostParams, TComm
24
25
  postUrl: {
25
26
  type: 'string',
26
27
  description:
27
- "The LinkedIn post URL to comment on (e.g., 'https://www.linkedin.com/posts/username_activity-id')",
28
+ "The LinkedIn post URL to comment on (e.g., 'https://www.linkedin.com/posts/username_activity-id') Provide this or postUrn.",
29
+ },
30
+ postUrn: {
31
+ type: 'string',
32
+ description:
33
+ "URN of the post to comment on, as an alternative to postUrl. (e.g., 'urn:li:activity:1234567890123456789')",
28
34
  },
29
35
  text: {
30
36
  type: 'string',
@@ -36,7 +42,7 @@ export class CommentOnPostTool extends OperationTool<TCommentOnPostParams, TComm
36
42
  "LinkedIn company page URL. If specified, the comment will be added on behalf of the company. (e.g., 'https://www.linkedin.com/company/acme-corp')",
37
43
  },
38
44
  },
39
- required: ['postUrl', 'text'],
45
+ required: ['text'],
40
46
  },
41
47
  };
42
48
  }
@@ -9,6 +9,17 @@ export class CreatePostTool extends OperationTool<TCreatePostParams, unknown> {
9
9
  public override readonly operationName = OPERATION_NAME.createPost;
10
10
  protected override readonly schema = z.object({
11
11
  text: z.string().min(1).max(3000),
12
+ mentions: z
13
+ .array(
14
+ z.object({
15
+ key: z.string(),
16
+ name: z.string(),
17
+ urn: z.string().optional(),
18
+ personHashedUrl: z.string().optional(),
19
+ companyHashedUrl: z.string().optional(),
20
+ }),
21
+ )
22
+ .optional(),
12
23
  companyUrl: z.string().optional(),
13
24
  attachments: z
14
25
  .array(
@@ -26,13 +37,49 @@ export class CreatePostTool extends OperationTool<TCreatePostParams, unknown> {
26
37
  return {
27
38
  name: this.name,
28
39
  description:
29
- 'Creates a new LinkedIn post with optional media attachments (st.createPost action). If this workflow is still running, do not retry this tool; retrying can create duplicate posts.',
40
+ 'Creates a new LinkedIn post with optional mentions and media attachments (st.createPost action). Returns the URL and URN of the new post. If this workflow is still running, do not retry this tool; retrying can create duplicate posts.',
30
41
  inputSchema: {
31
42
  type: 'object',
32
43
  properties: {
33
44
  text: {
34
45
  type: 'string',
35
- description: 'Post content, must be up to 3000 characters.',
46
+ description:
47
+ 'Post content, must be up to 3000 characters. Write "@[key]" where a mention should appear and describe that key in mentions.',
48
+ },
49
+ mentions: {
50
+ type: 'array',
51
+ description:
52
+ 'People and companies to mention in the text. Each item binds a "@[key]" placeholder to one entity.',
53
+ items: {
54
+ type: 'object',
55
+ properties: {
56
+ key: {
57
+ type: 'string',
58
+ description:
59
+ 'Placeholder name used in the text as "@[key]". 1-30 characters: letters, digits, underscore or hyphen.',
60
+ },
61
+ name: {
62
+ type: 'string',
63
+ description:
64
+ 'Name to find the person or company by. Always required: LinkedIn resolves a mention through its own name suggestions.',
65
+ },
66
+ urn: {
67
+ type: 'string',
68
+ description:
69
+ "URN of the entity (e.g., 'urn:li:member:123456789' or 'urn:li:organization:1234567'). Decides which of the offered namesakes is taken.",
70
+ },
71
+ personHashedUrl: {
72
+ type: 'string',
73
+ description:
74
+ 'Hashed LinkedIn profile URL of the person, as an alternative to urn.',
75
+ },
76
+ companyHashedUrl: {
77
+ type: 'string',
78
+ description: 'Hashed LinkedIn company page URL, as an alternative to urn.',
79
+ },
80
+ },
81
+ required: ['key', 'name'],
82
+ },
36
83
  },
37
84
  companyUrl: {
38
85
  type: 'string',
@@ -0,0 +1,90 @@
1
+ import { OPERATION_NAME, TCreateRepostParams } from '@linkedapi/node';
2
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
3
+ import { z } from 'zod';
4
+
5
+ import { OperationTool } from '../utils/linked-api-tool.js';
6
+
7
+ export class CreateRepostTool extends OperationTool<TCreateRepostParams, unknown> {
8
+ public override readonly name = 'create_repost';
9
+ public override readonly operationName = OPERATION_NAME.createRepost;
10
+ protected override readonly schema = z.object({
11
+ postUrl: z.string().optional(),
12
+ postUrn: z.string().optional(),
13
+ text: z.string().max(3000).optional(),
14
+ mentions: z
15
+ .array(
16
+ z.object({
17
+ key: z.string(),
18
+ name: z.string(),
19
+ urn: z.string().optional(),
20
+ personHashedUrl: z.string().optional(),
21
+ companyHashedUrl: z.string().optional(),
22
+ }),
23
+ )
24
+ .optional(),
25
+ });
26
+
27
+ public override getTool(): Tool {
28
+ return {
29
+ name: this.name,
30
+ description:
31
+ 'Reposts a LinkedIn post, either as is or with your own commentary (st.createRepost action). Returns the URL and URN of the repost itself, which is a post of your own account, not of the post that was reshared. Reposting the same post twice from the same account fails with alreadyReposted. If this workflow is still running, do not retry this tool; retrying can create duplicate reposts.',
32
+ inputSchema: {
33
+ type: 'object',
34
+ properties: {
35
+ postUrl: {
36
+ type: 'string',
37
+ description:
38
+ "LinkedIn URL of the post to repost. (e.g., 'https://www.linkedin.com/posts/username_activity-id') Provide this or postUrn.",
39
+ },
40
+ postUrn: {
41
+ type: 'string',
42
+ description:
43
+ "URN of the post to repost, as an alternative to postUrl. (e.g., 'urn:li:activity:1234567890123456789')",
44
+ },
45
+ text: {
46
+ type: 'string',
47
+ description:
48
+ 'Your own commentary, up to 3000 characters. Without it the post is reposted as is. Write "@[key]" where a mention should appear and describe that key in mentions.',
49
+ },
50
+ mentions: {
51
+ type: 'array',
52
+ description:
53
+ 'People and companies to mention in the commentary. Each item binds a "@[key]" placeholder to one entity.',
54
+ items: {
55
+ type: 'object',
56
+ properties: {
57
+ key: {
58
+ type: 'string',
59
+ description:
60
+ 'Placeholder name used in the text as "@[key]". 1-30 characters: letters, digits, underscore or hyphen.',
61
+ },
62
+ name: {
63
+ type: 'string',
64
+ description:
65
+ 'Name to find the person or company by. Always required: LinkedIn resolves a mention through its own name suggestions.',
66
+ },
67
+ urn: {
68
+ type: 'string',
69
+ description:
70
+ "URN of the entity (e.g., 'urn:li:member:123456789' or 'urn:li:organization:1234567'). Decides which of the offered namesakes is taken.",
71
+ },
72
+ personHashedUrl: {
73
+ type: 'string',
74
+ description:
75
+ 'Hashed LinkedIn profile URL of the person, as an alternative to urn.',
76
+ },
77
+ companyHashedUrl: {
78
+ type: 'string',
79
+ description: 'Hashed LinkedIn company page URL, as an alternative to urn.',
80
+ },
81
+ },
82
+ required: ['key', 'name'],
83
+ },
84
+ },
85
+ },
86
+ required: [],
87
+ },
88
+ };
89
+ }
90
+ }
@@ -8,7 +8,8 @@ export class FetchPostTool extends OperationTool<TFetchPostParams, unknown> {
8
8
  public override readonly name = 'fetch_post';
9
9
  public override readonly operationName = OPERATION_NAME.fetchPost;
10
10
  protected override readonly schema = z.object({
11
- postUrl: z.string(),
11
+ postUrl: z.string().optional(),
12
+ postUrn: z.string().optional(),
12
13
  retrieveComments: z.boolean().optional(),
13
14
  retrieveReactions: z.boolean().optional(),
14
15
  commentsRetrievalConfig: z
@@ -36,7 +37,12 @@ export class FetchPostTool extends OperationTool<TFetchPostParams, unknown> {
36
37
  postUrl: {
37
38
  type: 'string',
38
39
  description:
39
- "LinkedIn URL of the post. (e.g., 'https://www.linkedin.com/posts/username_activity-id')",
40
+ "LinkedIn URL of the post. (e.g., 'https://www.linkedin.com/posts/username_activity-id') Provide this or postUrn.",
41
+ },
42
+ postUrn: {
43
+ type: 'string',
44
+ description:
45
+ "URN of the post to fetch, as an alternative to postUrl. (e.g., 'urn:li:activity:1234567890123456789')",
40
46
  },
41
47
  retrieveComments: {
42
48
  type: 'boolean',
@@ -83,7 +89,7 @@ export class FetchPostTool extends OperationTool<TFetchPostParams, unknown> {
83
89
  },
84
90
  },
85
91
  },
86
- required: ['postUrl'],
92
+ required: [],
87
93
  },
88
94
  };
89
95
  }
@@ -8,7 +8,8 @@ export class ReactToPostTool extends OperationTool<TReactToPostParams, unknown>
8
8
  public override readonly name = 'react_to_post';
9
9
  public override readonly operationName = OPERATION_NAME.reactToPost;
10
10
  protected override readonly schema = z.object({
11
- postUrl: z.string(),
11
+ postUrl: z.string().optional(),
12
+ postUrn: z.string().optional(),
12
13
  type: z.enum(['like', 'love', 'celebrate', 'support', 'funny', 'insightful']).or(z.string()),
13
14
  companyUrl: z.string().optional(),
14
15
  });
@@ -24,7 +25,12 @@ export class ReactToPostTool extends OperationTool<TReactToPostParams, unknown>
24
25
  postUrl: {
25
26
  type: 'string',
26
27
  description:
27
- "LinkedIn URL of the post to react. (e.g., 'https://www.linkedin.com/posts/username_activity-id')",
28
+ "LinkedIn URL of the post to react. (e.g., 'https://www.linkedin.com/posts/username_activity-id') Provide this or postUrn.",
29
+ },
30
+ postUrn: {
31
+ type: 'string',
32
+ description:
33
+ "URN of the post to react to, as an alternative to postUrl. (e.g., 'urn:li:activity:1234567890123456789')",
28
34
  },
29
35
  type: {
30
36
  type: 'string',
@@ -37,7 +43,7 @@ export class ReactToPostTool extends OperationTool<TReactToPostParams, unknown>
37
43
  "LinkedIn company page URL. If specified, the reaction will be added on behalf of the company. (e.g., 'https://www.linkedin.com/company/acme-corp')",
38
44
  },
39
45
  },
40
- required: ['postUrl', 'type'],
46
+ required: ['type'],
41
47
  },
42
48
  };
43
49
  }