diff --git a/package-lock.json b/package-lock.json index bf5c82c..304fd3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@linkedapi/mcp", - "version": "2.3.4", + "version": "2.3.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@linkedapi/mcp", - "version": "2.3.4", + "version": "2.3.5", "license": "MIT", "dependencies": { - "@linkedapi/node": "^2.3.4", + "@linkedapi/node": "^2.3.5", "@modelcontextprotocol/sdk": "^1.17.4", "zod": "^4.1.1" }, @@ -921,10 +921,9 @@ } }, "node_modules/@linkedapi/node": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@linkedapi/node/-/node-2.3.4.tgz", - "integrity": "sha512-OTzyknxwLpx01vBOA8FVTTpehkjm9Z+jAVGCmYc7S4hdUUsEWC28dhHeq4/1hIVq93fGZ82ItJF5Par2YfPT8A==", - "license": "MIT" + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@linkedapi/node/-/node-2.3.5.tgz", + "integrity": "sha512-55d6qshZKJRopk9vTm8g5Mso+X4O7plTa+rmdbiIVYhpc7JciNrT4JLhS58oeEvgTwxC159udIrlfQEDXPO+xw==" }, "node_modules/@modelcontextprotocol/sdk": { "version": "1.26.0", diff --git a/package.json b/package.json index 4c7df3b..ba42192 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@linkedapi/mcp", - "version": "2.3.4", + "version": "2.3.5", "description": "MCP server that lets AI assistants control LinkedIn accounts and retrieve real-time data.", "main": "dist/index.js", "bin": { @@ -30,7 +30,7 @@ "author": "Linked API", "license": "MIT", "dependencies": { - "@linkedapi/node": "^2.3.4", + "@linkedapi/node": "^2.3.5", "@modelcontextprotocol/sdk": "^1.17.4", "zod": "^4.1.1" }, diff --git a/src/linked-api-tools.ts b/src/linked-api-tools.ts index 0881823..9888a34 100644 --- a/src/linked-api-tools.ts +++ b/src/linked-api-tools.ts @@ -42,8 +42,10 @@ import { NvSearchCompaniesTool } from './tools/nv-search-companies.js'; import { NvSearchPeopleTool } from './tools/nv-search-people.js'; import { NvSendMessageTool } from './tools/nv-send-message.js'; import { NvSyncInboxTool } from './tools/nv-sync-inbox.js'; +import { ReactToCommentTool } from './tools/react-to-comment.js'; import { ReactToPostTool } from './tools/react-to-post.js'; import { RemoveConnectionTool } from './tools/remove-connection.js'; +import { ReplyToCommentTool } from './tools/reply-to-comment.js'; import { RetrieveConnectionsTool } from './tools/retrieve-connections.js'; import { RetrieveFeedTool } from './tools/retrieve-feed.js'; import { RetrieveInvitationsTool } from './tools/retrieve-invitations.js'; @@ -104,6 +106,8 @@ export class LinkedApiTools { new FetchJobTool(), new ReactToPostTool(), new CommentOnPostTool(), + new ReactToCommentTool(), + new ReplyToCommentTool(), new CreatePostTool(), new RetrieveFeedTool(), new RetrieveSSITool(), diff --git a/src/tools/comment-on-post.ts b/src/tools/comment-on-post.ts index 6bf79e9..adf0577 100644 --- a/src/tools/comment-on-post.ts +++ b/src/tools/comment-on-post.ts @@ -1,10 +1,10 @@ -import { OPERATION_NAME, TCommentOnPostParams } from '@linkedapi/node'; +import { OPERATION_NAME, TCommentOnPostParams, TCommentOnPostResult } from '@linkedapi/node'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import { z } from 'zod'; import { OperationTool } from '../utils/linked-api-tool.js'; -export class CommentOnPostTool extends OperationTool { +export class CommentOnPostTool extends OperationTool { public override readonly name = 'comment_on_post'; public override readonly operationName = OPERATION_NAME.commentOnPost; protected override readonly schema = z.object({ @@ -17,7 +17,7 @@ export class CommentOnPostTool extends OperationTool { + public override readonly name = 'react_to_comment'; + public override readonly operationName = OPERATION_NAME.reactToComment; + protected override readonly schema = z.object({ + commentUrl: z.string(), + type: z.enum(['like', 'love', 'support', 'celebrate', 'insightful', 'funny']).optional(), + }); + + public override getTool(): Tool { + return { + name: this.name, + description: + 'React to a comment by commentUrl (like, love, support, celebrate, insightful, funny). If this workflow is still running, do not retry this tool; retrying can queue duplicate reaction attempts.', + inputSchema: { + type: 'object', + properties: { + commentUrl: { + type: 'string', + description: 'LinkedIn URL of the comment to react to.', + }, + type: { + type: 'string', + description: 'Optional. Enum describing the reaction type. Defaults to "like".', + enum: ['like', 'love', 'support', 'celebrate', 'insightful', 'funny'], + }, + }, + required: ['commentUrl'], + }, + }; + } +} diff --git a/src/tools/reply-to-comment.ts b/src/tools/reply-to-comment.ts new file mode 100644 index 0000000..c5d813c --- /dev/null +++ b/src/tools/reply-to-comment.ts @@ -0,0 +1,39 @@ +import { OPERATION_NAME, TReplyToCommentParams, TReplyToCommentResult } from '@linkedapi/node'; +import { Tool } from '@modelcontextprotocol/sdk/types.js'; +import { z } from 'zod'; + +import { OperationTool } from '../utils/linked-api-tool.js'; + +export class ReplyToCommentTool extends OperationTool< + TReplyToCommentParams, + TReplyToCommentResult +> { + public override readonly name = 'reply_to_comment'; + public override readonly operationName = OPERATION_NAME.replyToComment; + protected override readonly schema = z.object({ + commentUrl: z.string(), + text: z.string().min(1), + }); + + public override getTool(): Tool { + return { + name: this.name, + description: + "Reply to a comment by commentUrl; returns the reply's URN and URL. If this workflow is still running, do not retry this tool; retrying can post duplicate replies.", + inputSchema: { + type: 'object', + properties: { + commentUrl: { + type: 'string', + description: 'LinkedIn URL of the comment to reply to.', + }, + text: { + type: 'string', + description: 'Reply text, must be up to 1000 characters.', + }, + }, + required: ['commentUrl', 'text'], + }, + }; + } +}