From 82c7ab9f6f548645dd4702a18a857b23bcb5cb48 Mon Sep 17 00:00:00 2001 From: Maksim Redzkin Date: Thu, 8 Oct 2026 18:38:52 +0300 Subject: [PATCH] pin post search filters by id & add reaction actor --- package-lock.json | 4 ++-- package.json | 2 +- src/tools/fetch-post.ts | 2 +- src/tools/search-posts.ts | 28 ++++++++++++---------------- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 948b86e..9d62d80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@linkedapi/mcp", - "version": "2.3.15", + "version": "2.3.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@linkedapi/mcp", - "version": "2.3.15", + "version": "2.3.16", "license": "MIT", "dependencies": { "@linkedapi/node": "^2.3.15", diff --git a/package.json b/package.json index a94aff1..d868def 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@linkedapi/mcp", - "version": "2.3.15", + "version": "2.3.16", "description": "MCP server that lets AI assistants control LinkedIn accounts and retrieve real-time data.", "main": "dist/index.js", "bin": { diff --git a/src/tools/fetch-post.ts b/src/tools/fetch-post.ts index 6c1e8ef..588c44c 100644 --- a/src/tools/fetch-post.ts +++ b/src/tools/fetch-post.ts @@ -30,7 +30,7 @@ export class FetchPostTool extends OperationTool { return { name: this.name, description: - 'Open a LinkedIn post and retrieve its data, with optional comments and reactions. (st.openPost action). The author and reposter carry urn — a member URN (urn:li:member:) for a person actor and an organization URN (urn:li:organization:) for a company actor — and retrieved reactions carry engagerUrn for the same identity; each is null when LinkedIn does not expose the identifier. This action reads identifiers from the post page itself, so it resolves actor URNs that post listings such as retrieve_feed cannot. Comment authors carry no URN.', + 'Open a LinkedIn post and retrieve its data, with optional comments and reactions. (st.openPost action). The author and reposter carry urn — a member URN (urn:li:member:) for a person actor and an organization URN (urn:li:organization:) for a company actor — and each retrieved reaction carries an actor object (type, name, urn, profileUrl or companyUrl, headline, and viewerState.connectionDegree for a person) with the same urn identity; each urn is null when LinkedIn does not expose the identifier. This action reads identifiers from the post page itself, so it resolves actor URNs that post listings such as retrieve_feed cannot. Comment authors carry no URN.', inputSchema: { type: 'object', properties: { diff --git a/src/tools/search-posts.ts b/src/tools/search-posts.ts index 6ae9399..2111bc0 100644 --- a/src/tools/search-posts.ts +++ b/src/tools/search-posts.ts @@ -8,6 +8,7 @@ const PERSON_FILTER_ENTRY_SCHEMA = z.union([ z.string().min(1).max(100), z.object({ name: z.string().min(1).max(100), + id: z.string().optional(), urn: z.string().optional(), personHashedUrl: z.string().optional(), }), @@ -17,6 +18,7 @@ const COMPANY_FILTER_ENTRY_SCHEMA = z.union([ z.string().min(1).max(100), z.object({ name: z.string().min(1).max(100), + id: z.string().optional(), urn: z.string().optional(), companyHashedUrl: z.string().optional(), }), @@ -37,15 +39,12 @@ const PERSON_FILTER_ENTRY_JSON_SCHEMA = { type: 'string', minLength: 1, maxLength: 100, - description: 'Required. Name to type into the LinkedIn filter panel.', + description: 'Required. Name of the person.', }, - urn: { + id: { type: 'string', - description: 'Optional. Member URN of the person, urn:li:member:.', - }, - personHashedUrl: { - type: 'string', - description: 'Optional. Hashed LinkedIn URL of the person.', + description: + 'Optional. Any identifier of the person: URN, or public or hashed LinkedIn URL. Pins the filter to exactly that person.', }, }, required: ['name'], @@ -68,15 +67,12 @@ const COMPANY_FILTER_ENTRY_JSON_SCHEMA = { type: 'string', minLength: 1, maxLength: 100, - description: 'Required. Name to type into the LinkedIn filter panel.', - }, - urn: { - type: 'string', - description: 'Optional. Organization URN of the company, urn:li:organization:.', + description: 'Required. Name of the company.', }, - companyHashedUrl: { + id: { type: 'string', - description: 'Optional. Hashed LinkedIn URL of the company.', + description: + 'Optional. Any identifier of the company: URN, public or hashed LinkedIn URL, or numeric ID. Pins the filter to exactly that company.', }, }, required: ['name'], @@ -165,13 +161,13 @@ export class SearchPostsTool extends OperationTool fromMembers: { type: 'array', 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 filterNotApplied rather than filtering by a namesake.', + 'Optional. Array of people whose posts to keep. Each entry is a name, or { name, id }; both forms can be mixed in one array. A name alone may match a namesake; id pins the exact person. When an entry cannot be applied, the action fails with filterNotApplied rather than filtering by somebody else.', items: PERSON_FILTER_ENTRY_JSON_SCHEMA, }, fromCompanies: { type: 'array', description: - 'Optional. Array of companies whose posts to keep. Same entry shape as fromMembers, with companyHashedUrl in place of personHashedUrl.', + 'Optional. Array of companies whose posts to keep. Same entry shape as fromMembers.', items: COMPANY_FILTER_ENTRY_JSON_SCHEMA, }, mentioningMembers: {