Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@linkedapi/mcp",
"version": "2.1.2",
"version": "2.1.3",
"description": "MCP server that lets AI assistants control LinkedIn accounts and retrieve real-time data.",
"main": "dist/index.js",
"bin": {
Expand Down Expand Up @@ -30,7 +30,7 @@
"author": "Linked API",
"license": "MIT",
"dependencies": {
"@linkedapi/node": "^2.0.4",
"@linkedapi/node": "^2.1.1",
"@modelcontextprotocol/sdk": "^1.17.4",
"zod": "^4.1.1"
},
Expand Down
6 changes: 6 additions & 0 deletions src/linked-api-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ import { FetchPersonTool } from './tools/fetch-person.js';
import { FetchPostTool } from './tools/fetch-post.js';
import { GetApiUsageTool } from './tools/get-api-usage-stats.js';
import { GetConversationTool } from './tools/get-conversation.js';
import { GetInboxTool } from './tools/get-inbox.js';
import { GetWorkflowResultTool } from './tools/get-workflow-result.js';
import { NvFetchCompanyTool } from './tools/nv-fetch-company.js';
import { NvFetchPersonTool } from './tools/nv-fetch-person.js';
import { NvGetConversationTool } from './tools/nv-get-conversation.js';
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 { ReactToPostTool } from './tools/react-to-post.js';
import { RemoveConnectionTool } from './tools/remove-connection.js';
import { RetrieveConnectionsTool } from './tools/retrieve-connections.js';
Expand All @@ -46,6 +48,7 @@ import { SearchJobsTool } from './tools/search-jobs.js';
import { SearchPeopleTool } from './tools/search-people.js';
import { SendConnectionRequestTool } from './tools/send-connection-request.js';
import { SendMessageTool } from './tools/send-message.js';
import { SyncInboxTool } from './tools/sync-inbox.js';
import { WithdrawConnectionRequestTool } from './tools/withdraw-connection-request.js';
import type { TLinkedApiToolResult } from './types/linked-api-tool-result.type.js';
import { AdminTool } from './utils/admin-tool.js';
Expand All @@ -70,6 +73,8 @@ export class LinkedApiTools {
// Standard tools
new SendMessageTool(),
new GetConversationTool(),
new SyncInboxTool(),
new GetInboxTool(),
new CheckConnectionStatusTool(),
new RetrieveConnectionsTool(),
new SendConnectionRequestTool(),
Expand All @@ -91,6 +96,7 @@ export class LinkedApiTools {
// Sales Navigator tools
new NvSendMessageTool(),
new NvGetConversationTool(),
new NvSyncInboxTool(),
new NvSearchCompaniesTool(),
new NvSearchPeopleTool(),
new NvFetchCompanyTool(),
Expand Down
58 changes: 58 additions & 0 deletions src/tools/get-inbox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import LinkedApi, { TInboxPollRequest, TInboxPollResult, TMappedResponse } from '@linkedapi/node';
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import z from 'zod';

import { LinkedApiTool } from '../utils/linked-api-tool.js';

export class GetInboxTool extends LinkedApiTool<TInboxPollRequest, TInboxPollResult> {
public readonly name = 'get_inbox';
protected readonly schema = z.object({
since: z.string().optional(),
type: z.enum(['st', 'nv']).optional(),
threadId: z.string().optional(),
});

public override async execute({
linkedapi,
args: { since, type, threadId },
}: {
linkedapi: LinkedApi;
args: TInboxPollRequest;
}): Promise<TMappedResponse<TInboxPollResult>> {
return linkedapi.pollInbox({
since,
type,
threadId,
});
}

public override getTool(): Tool {
return {
name: this.name,
description:
'Get messages from the monitored inbox across all conversations (standard and Sales Navigator), newest first. Requires inbox monitoring to be enabled once with sync_inbox (or nv_sync_inbox for Sales Navigator).',
inputSchema: {
type: 'object',
properties: {
since: {
type: 'string',
description:
"Optional ISO 8601 timestamp to only retrieve messages after this date (e.g., '2024-01-15T10:30:00Z'). If not provided, all captured messages are returned.",
},
type: {
type: 'string',
enum: ['st', 'nv'],
description:
'Optional inbox type filter: "st" for standard messages, "nv" for Sales Navigator messages. If omitted, both are returned.',
},
threadId: {
type: 'string',
description:
'Optional conversation thread identifier to restrict the result to a single thread.',
},
},
required: [],
},
};
}
}
17 changes: 12 additions & 5 deletions src/tools/nv-send-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,41 @@ export class NvSendMessageTool extends OperationTool<TNvSendMessageParams, unkno
public override readonly name = 'nv_send_message';
public override readonly operationName = OPERATION_NAME.nvSendMessage;
protected override readonly schema = z.object({
personUrl: z.string(),
personUrl: z.string().optional(),
text: z.string().min(1),
subject: z.string().optional(),
threadId: z.string().optional(),
});

public override getTool(): Tool {
return {
name: this.name,
description:
'Allows you to send a message to a person in Sales Navigator (nv.sendMessage action). If this workflow is still running, do not retry this tool; retrying can send duplicate Sales Navigator messages to the same person.',
'Allows you to send a message to a person in Sales Navigator (nv.sendMessage action). Provide either personUrl or threadId (threadId replies into an existing conversation thread and takes precedence). If this workflow is still running, do not retry this tool; retrying can send duplicate Sales Navigator messages to the same person.',
inputSchema: {
type: 'object',
properties: {
personUrl: {
type: 'string',
description:
"LinkedIn URL of the person you want to send a message to (e.g., 'https://www.linkedin.com/in/john-doe')",
"LinkedIn URL of the person you want to send a message to (e.g., 'https://www.linkedin.com/in/john-doe'). Optional if threadId is provided.",
},
text: {
type: 'string',
description: 'The message text, must be up to 1900 characters.',
},
subject: {
type: 'string',
description: 'Subject line, must be up to 80 characters.',
description:
'Subject line, must be up to 80 characters. Required when starting a new conversation; ignored when replying into an existing thread via threadId.',
},
threadId: {
type: 'string',
description:
'Optional conversation thread identifier to reply into, as returned by get_inbox. Provide this instead of personUrl to reply directly into a known thread.',
},
},
required: ['personUrl', 'text', 'subject'],
required: ['text'],
},
};
}
Expand Down
24 changes: 24 additions & 0 deletions src/tools/nv-sync-inbox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { OPERATION_NAME, TNvSyncInboxParams } from '@linkedapi/node';
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { z } from 'zod';

import { OperationTool } from '../utils/linked-api-tool.js';

export class NvSyncInboxTool extends OperationTool<TNvSyncInboxParams, unknown> {
public override readonly name = 'nv_sync_inbox';
public override readonly operationName = OPERATION_NAME.nvSyncInbox;
protected override readonly schema = z.object({});

public override getTool(): Tool {
return {
name: this.name,
description:
'Enable whole-inbox monitoring in Sales Navigator so every incoming conversation can be polled with get_inbox (nv.syncInbox action). Run once per account; only messages that arrive after it is enabled are captured.',
inputSchema: {
type: 'object',
properties: {},
required: [],
},
};
}
}
14 changes: 10 additions & 4 deletions src/tools/send-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,35 @@ export class SendMessageTool extends OperationTool<TSendMessageParams, unknown>
public override readonly name = 'send_message';
public override readonly operationName = OPERATION_NAME.sendMessage;
protected override readonly schema = z.object({
personUrl: z.string(),
personUrl: z.string().optional(),
text: z.string().min(1),
threadId: z.string().optional(),
});

public override getTool(): Tool {
return {
name: this.name,
description:
'Allows you to send a message to a person (st.sendMessage action). If this workflow is still running, do not retry this tool; retrying can send duplicate messages to the same person.',
'Allows you to send a message to a person (st.sendMessage action). Provide either personUrl or threadId (threadId replies into an existing conversation thread and takes precedence). If this workflow is still running, do not retry this tool; retrying can send duplicate messages to the same person.',
inputSchema: {
type: 'object',
properties: {
personUrl: {
type: 'string',
description:
"LinkedIn URL of the person you want to send a message to (e.g., 'https://www.linkedin.com/in/john-doe')",
"LinkedIn URL of the person you want to send a message to (e.g., 'https://www.linkedin.com/in/john-doe'). Optional if threadId is provided.",
},
text: {
type: 'string',
description: 'The message text, must be up to 1900 characters.',
},
threadId: {
type: 'string',
description:
'Optional conversation thread identifier to reply into, as returned by get_inbox. Provide this instead of personUrl to reply directly into a known thread.',
},
},
required: ['personUrl', 'text'],
required: ['text'],
},
};
}
Expand Down
24 changes: 24 additions & 0 deletions src/tools/sync-inbox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { OPERATION_NAME, TSyncInboxParams } from '@linkedapi/node';
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { z } from 'zod';

import { OperationTool } from '../utils/linked-api-tool.js';

export class SyncInboxTool extends OperationTool<TSyncInboxParams, unknown> {
public override readonly name = 'sync_inbox';
public override readonly operationName = OPERATION_NAME.syncInbox;
protected override readonly schema = z.object({});

public override getTool(): Tool {
return {
name: this.name,
description:
'Enable whole-inbox monitoring so every incoming conversation can be polled with get_inbox (st.syncInbox action). Run once per account; only messages that arrive after it is enabled are captured.',
inputSchema: {
type: 'object',
properties: {},
required: [],
},
};
}
}