Skip to main content
Glama

get_linkedin_profile

Retrieve LinkedIn profile details including headline, summary, experience, and education using the LinkedIn MCP Assistant server for professional insights.

Instructions

Retrieve the user's LinkedIn profile information including headline, summary, experience, and education.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • cli.js:777-911 (handler)
    The main handler function for the 'get_linkedin_profile' MCP tool. It authenticates with the API key, makes a POST request to the backend API endpoint to fetch the LinkedIn profile data, processes and formats the profile information (headline, summary, experience, education) into a readable text response, handles success and various error cases, and sends the MCP-formatted response.
    } else if (name === 'get_linkedin_profile') { console.error(`${packageName}: Received call for get_linkedin_profile tool.`); const apiKey = process.env.LINKEDIN_MCP_API_KEY; if (!apiKey) { sendResponse({ jsonrpc: "2.0", error: { code: -32001, message: "Server Configuration Error: API Key not set." }, id }); return; } try { const headers = { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json", "Accept": "application/json" }; console.error(`${packageName}: Calling LinkedIn profile API: ${backendLinkedinProfileApiUrl}`); const apiResponse = await axios.post(backendLinkedinProfileApiUrl, {}, { headers, timeout: 60000 }); console.error(`${packageName}: LinkedIn profile API response status: ${apiResponse.status}`); console.error(`${packageName}: LinkedIn profile API response data:`, JSON.stringify(apiResponse.data, null, 2)); if (apiResponse.data && apiResponse.data.success) { const profile = apiResponse.data.profile || {}; // Format profile as text to avoid "unsupported content type: data" error let profileHeadline = profile.headline || 'No headline'; let profileSummary = profile.summary || 'No summary'; // Format experience entries let experienceText = 'Experience:'; if (profile.experience && Array.isArray(profile.experience) && profile.experience.length > 0) { profile.experience.forEach((exp, index) => { experienceText += `\n\n${index + 1}. ${exp.title || 'Role'} at ${exp.companyName || 'Company'}`; if (exp.dateRange || exp.duration) { experienceText += `\n Duration: ${exp.dateRange || exp.duration || 'Not specified'}`; } if (exp.description) { experienceText += `\n Description: ${exp.description}`; } }); } else { experienceText += '\n No experience data available'; } // Format education entries let educationText = '\n\nEducation:'; if (profile.education && Array.isArray(profile.education) && profile.education.length > 0) { profile.education.forEach((edu, index) => { educationText += `\n\n${index + 1}. ${edu.schoolName || edu.school || 'Institution'}`; if (edu.degree || edu.fieldOfStudy) { educationText += `\n ${edu.degree || ''} ${edu.fieldOfStudy || ''}`.trim(); } if (edu.dateRange || edu.dates) { educationText += `\n Years: ${edu.dateRange || edu.dates || 'Not specified'}`; } }); } else { educationText += '\n No education data available'; } // Combine all text const profileText = `Headline: ${profileHeadline}\n\nSummary: ${profileSummary}\n\n${experienceText}${educationText}`; sendResponse({ jsonrpc: "2.0", result: { content: [ { type: "text", text: `LinkedIn profile data retrieved. Last updated: ${apiResponse.data.data_last_updated || 'Unknown'}` }, { type: "text", text: profileText } ], isError: false }, id }); } else { const errorMessage = apiResponse.data?.error || "Backend API Error (no detail)"; console.error(`${packageName}: LinkedIn profile API Error: ${errorMessage}`); sendResponse({ jsonrpc: "2.0", result: { content: [ { type: "text", text: `Failed to get LinkedIn profile: ${errorMessage}. This may occur if you haven't set your LinkedIn URL yet. Try using the set_linkedin_url tool first.` } ], isError: true }, id }); } } catch (error) { let errorMessage = `Failed to call LinkedIn profile API: ${error.message}`; if (error.response) { // Extract complete error details from the response const responseData = error.response.data || {}; const extractedError = responseData.error || responseData.message || (typeof responseData === 'string' ? responseData : null); // Include any suggestion provided const suggestion = responseData.suggestion ? `\n\nSuggestion: ${responseData.suggestion}` : ''; // Use the backend's full error message if (extractedError) { errorMessage = `${extractedError}${suggestion}`; } else { // Fallback with a generic message but including the status errorMessage = `Backend API Error (Status ${error.response.status}): Unknown error${suggestion}`; } console.error(`${packageName}: LinkedIn profile API Error Response:`, error.response.data); } else if (error.request) { errorMessage = "No response received from LinkedIn profile API. The server may be unavailable or experiencing issues."; } console.error(`${packageName}: ${errorMessage}`); sendResponse({ jsonrpc: "2.0", result: { content: [ { type: "text", text: `Failed to get LinkedIn profile: ${errorMessage}` } ], isError: true }, id }); }
  • The input schema definition for the 'get_linkedin_profile' tool, registered in the tools/list response. It defines an empty object schema indicating no input parameters are required.
    name: "get_linkedin_profile", description: "Retrieve the user's LinkedIn profile information including headline, summary, experience, and education.", inputSchema: { type: "object", properties: {} } },
  • cli.js:1187-1373 (registration)
    The tools/list handler registers all available tools, including 'get_linkedin_profile', by returning the static list of tool definitions with names, descriptions, and schemas.
    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"] } }, { name: "schedule_linkedin_post", description: "Schedule a text post for LinkedIn at a specific future date and time, optionally including media (images/videos) specified by URL.", inputSchema: { type: "object", properties: { post_text: { type: "string", description: "The text content of the LinkedIn post to be scheduled." }, scheduled_date: { type: "string", description: "The date and time to publish the post, in ISO 8601 format (e.g., '2025-12-31T10:00:00Z' or '2025-12-31T15:30:00+05:30'). Must be in the future." }, 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., 'meeting_notes.mp4')." } }, required: ["file_url", "filename"] } } }, required: ["post_text", "scheduled_date"] } }, { name: "publish_twitter_post", description: "Publish a text post (tweet) to Twitter.", inputSchema: { type: "object", properties: { post_text: { type: "string", description: "The text content of the tweet (maximum 280 characters)." } }, required: ["post_text"] } }, { name: "analyze_linkedin_chat", description: "Ask questions about the user's LinkedIn profile, content, or network, with support for multi-turn conversations.", inputSchema: { type: "object", properties: { query: { type: "string", description: "The question or request about LinkedIn data to be analyzed." }, conversation_history: { type: "array", description: "Optional. Previous messages in the conversation for context. Each message must have 'role' (user/assistant) and 'content' (text).", items: { type: "object", properties: { role: { type: "string", description: "The sender of the message: 'user' or 'assistant'." }, content: { type: "string", description: "The text content of the message." } }, required: ["role", "content"] } } }, required: ["query"] } }, { name: "generate_linkedin_post", description: "Generate three LinkedIn post variants from any content (article, newsletter, notes, etc.) to optimize engagement.", inputSchema: { type: "object", properties: { content: { type: "string", description: "The source content to transform into LinkedIn posts. Can be articles, emails, newsletters, notes, etc." }, content_type: { type: "string", description: "Optional. A short description of the content type (e.g., 'article', 'newsletter', 'notes'). Defaults to 'article'." } }, required: ["content"] } }, { name: "get_linkedin_posts", description: "Retrieve the user's recent LinkedIn posts with engagement metrics.", inputSchema: { type: "object", properties: { limit: { type: "number", description: "Optional. Number of posts to retrieve (1-20). Defaults to 5." } } } }, { name: "get_linkedin_profile", description: "Retrieve the user's LinkedIn profile information including headline, summary, experience, and education.", inputSchema: { type: "object", properties: {} } }, { name: "set_linkedin_url", description: "Set or update the LinkedIn profile URL to analyze. Required before using profile/posts retrieval tools if not set previously.", inputSchema: { type: "object", properties: { linkedin_url: { type: "string", description: "The full LinkedIn profile URL (e.g., https://www.linkedin.com/in/username/)" } }, required: ["linkedin_url"] } }, { name: "refresh_linkedin_profile", description: "Force a refresh of the LinkedIn profile data to update any recent changes.", inputSchema: { type: "object", properties: {} } }, { name: "refresh_linkedin_posts", description: "Force a refresh of LinkedIn posts data to capture recently published content.", inputSchema: { type: "object", properties: {} } } ] } });
  • cli.js:17-17 (helper)
    Constant defining the backend API endpoint URL specifically used by the get_linkedin_profile handler to fetch profile data.
    const backendLinkedinProfileApiUrl = 'https://ligo.ertiqah.com/api/mcp/linkedin/profile';

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ertiqah/linkedin-mcp-runner'

If you have feedback or need assistance with the MCP directory API, please join our Discord server