publish_linkedin_post
Post text and optional media to LinkedIn. Specify post text plus image or video URLs to attach media.
Instructions
Publish a text post to LinkedIn, optionally including media (images/videos) specified by URL.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| post_text | Yes | The text content of the LinkedIn post. | |
| media | No | Optional. A list of media items to attach to the post. Each item must have a 'file_url' pointing to a direct image or video URL and a 'filename'. |
Implementation Reference
- cli.js:159-253 (handler)The handler function for 'publish_linkedin_post' tool. Validates API key, post_text, and optional media arguments, then calls the backend API at https://ligosocial.com/api/mcp/publish-linkedin-post via axios POST and returns success/error response.
if (name === 'publish_linkedin_post') { console.error(`${packageName}: Received call for publish_linkedin_post tool.`); const apiKey = process.env.LINKEDIN_MCP_API_KEY; const postText = args?.post_text; const media = args?.media; if (!apiKey) { sendResponse({ jsonrpc: "2.0", error: { code: -32001, message: "Server Configuration Error: API Key not set." }, id }); return; } if (typeof postText !== 'string' || postText.trim() === '') { sendResponse({ jsonrpc: "2.0", error: { code: -32602, message: "Invalid arguments: 'post_text' (string) required." }, id }); return; } if (media && (!Array.isArray(media) || media.some(item => !item || typeof item !== 'object' || typeof item.file_url !== 'string' || typeof item.filename !== 'string'))) { sendResponse({ jsonrpc: "2.0", error: { code: -32602, message: "Invalid arguments: 'media' must be an array of objects, each with 'file_url' and 'filename' strings." }, id }); return; } try { const headers = { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json", "Accept": "application/json" }; const payload = { "post_text": postText, "media": media || [] }; console.error(`${packageName}: Calling backend API: ${backendApiUrl} with payload:`, JSON.stringify(payload, null, 2)); const apiResponse = await axios.post(backendApiUrl, payload, { headers, timeout: 60000 }); console.error(`${packageName}: Backend API response status: ${apiResponse.status}`); console.error(`${packageName}: Backend API response data:`, JSON.stringify(apiResponse.data, null, 2)); if (apiResponse.data && apiResponse.data.success) { // Include post_urn from backend if available const postDetails = apiResponse.data.post_urn ? ` (Post ID: ${apiResponse.data.post_urn})` : ''; sendResponse({ jsonrpc: "2.0", result: { content: [ { type: "text", text: `✅ Successfully published post to LinkedIn${postDetails}.` } ], isError: false }, id }); } else { const errorMessage = apiResponse.data?.error || "Backend API Error (no detail)"; console.error(`${packageName}: Backend API Error: ${errorMessage}`); // Report error within the result object sendResponse({ jsonrpc: "2.0", result: { content: [ { type: "text", text: `Failed to publish post to LinkedIn: ${errorMessage}` } ], isError: true // Indicate tool execution error }, id }); } } catch (error) { let errorMessage = `Failed to call backend API: ${error.message}`; // Preserve the original error message from the backend if available if (error.response) { // Extract the error message directly from the backend response const backendError = error.response.data?.error || error.response.data?.message; errorMessage = backendError || `Backend API Error (Status ${error.response.status})`; console.error(`${packageName}: Backend API Error Response:`, error.response.data); } else if (error.request) { errorMessage = "No response received from backend API."; } console.error(`${packageName}: ${errorMessage}`); // Report error within the result object sendResponse({ jsonrpc: "2.0", result: { content: [ { type: "text", text: `Failed to publish post to LinkedIn: ${errorMessage}` } ], isError: true // Indicate tool execution error }, id }); } - cli.js:1206-1238 (registration)Tool registration (tools/list response) for 'publish_linkedin_post' tool. Defines name, description, and inputSchema including post_text (required string) and media (optional array of objects with file_url and filename).
tools: [ { name: "publish_linkedin_post", description: "Publish a text post to LinkedIn, optionally including media (images/videos) specified by URL.", inputSchema: { type: "object", properties: { post_text: { type: "string", description: "The text content of the LinkedIn post." }, media: { type: "array", description: "Optional. A list of media items to attach to the post. Each item must have a 'file_url' pointing to a direct image or video URL and a 'filename'.", items: { type: "object", properties: { file_url: { type: "string", description: "A direct URL to the image or video file (e.g., ending in .jpg, .png, .mp4)." }, filename: { type: "string", description: "A filename for the media item (e.g., 'promo_video.mp4')." } }, required: ["file_url", "filename"] } } }, required: ["post_text"] } }, - cli.js:11-11 (helper)Backend API URL constant used by the publish_linkedin_post handler to make the HTTP POST request.
const backendApiUrl = 'https://ligosocial.com/api/mcp/publish-linkedin-post';