Skip to main content
Glama

MCP Server for LinkedIn

Disclaimer: This is an independent, community project. It is not affiliated with, authorized by, endorsed by, or sponsored by LinkedIn Corporation or Microsoft. "LinkedIn" is a registered trademark of LinkedIn Corporation and is used here only descriptively to identify the third-party service this software interoperates with.

An MCP server that lets AI assistants like Claude read LinkedIn data through your own logged-in browser session. Access profiles and companies, search for jobs, or get job details.


Installation Methods - MCP Server for LinkedIn

uvx Install MCP Bundle Docker Development

Tool

Description

Status

get_person_profile

Get profile info with explicit section selection (experience, education, interests, honors, languages, certifications, skills, projects, contact_info, posts)

#590

get_my_profile

Get the authenticated user's own LinkedIn profile (same sections as get_person_profile)

#590

connect_with_person

Send a connection request or accept an incoming one, with optional note

#407 #432 #454 #629

get_sidebar_profiles

Extract profile URLs from sidebar recommendation sections ("More profiles for you", "Explore premium profiles", "People you may know") on a profile page

working

get_inbox

List recent conversations from the LinkedIn messaging inbox

working

get_conversation

Read a specific messaging conversation by username or thread ID

working

search_conversations

Search messages by keyword

working

send_message

Send a message to a LinkedIn user (requires confirmation)

#433 #441 #483 #560 #573

get_company_profile

Extract company information with explicit section selection (posts, jobs); about-section references may include a company_urn entry carrying the numeric id used by LinkedIn's people-search currentCompany URL facet

working

get_company_posts

Get recent posts from a company's LinkedIn feed

working

search_companies

Search for companies on LinkedIn by keywords

working

get_company_employees

List employees at a company from the /people/ page, with optional keyword filter

working

search_jobs

Search for jobs with keywords and location filters

working

get_saved_jobs

List job postings saved by the authenticated user

working

search_people

Search for people by keywords, location, connection degree (1st/2nd/3rd), and current company

#526

get_job_details

Get detailed information about a specific job posting

working

get_feed

Get recent posts from the authenticated user's home feed

working

search_posts

Search posts/content globally by keyword (the "Posts" tab) with an optional recency filter (past-24h/past-week/past-month)

working

get_login_status

Read-only session preflight; reports whether the authenticated LinkedIn session is ready, missing, expired, conflicted, or unknown

working

begin_linkedin_login

Starts or explains the user-controlled login flow; never accepts a LinkedIn password

working

get_post_engagement_status

Read the account's visible standard reaction and optional exact self-comment on one direct post permalink

experimental

like_post

Add one standard Like only with confirm_like=true; reports success only after visible final-state verification

experimental

comment_on_post

Submit one comment only with confirm_comment=true; prevents exact duplicates and requires visible text-plus-authorship verification

experimental; #549

close_session

Close browser session and clean up resources

working

Related MCP server: MCP LinkedIn Sales Navigator

Login-First Engagement Workflow

Engagement actions are deliberately login-first and fail closed. Call get_login_status before post discovery or any action. If it returns login_required, expired, profile_conflict, or unknown, do not call like_post or comment_on_post. Run begin_linkedin_login in a local runtime or use the explicit Docker --login --login-viewer flow, complete sign-in directly in the browser, then call get_login_status again.

like_post and comment_on_post accept only direct /feed/update/<URN>/ or /posts/<slug> permalinks. Each needs an explicit confirmation argument. A dry run does not click or type. A Like is not reported as successful until the visible reaction state is re-read; a comment is not reported as successful until the exact text and the authenticated author are both visible on the target post. Existing reactions and exact duplicate self-comments are left unchanged and returned as idempotent receipts.

The first release supports the standard Like reaction and currently uses conservative English-language post action surfaces. If the action surface is ambiguous, unavailable, or cannot be verified, the tools return a non-success receipt rather than guessing or claiming completion. A session ready result is necessary but never sufficient to write: each call still requires its own explicit confirmation.

Docker: the container does not complete interactive login by itself. Run the documented host-side --login --login-viewer command, sign in through the viewer, let it exit cleanly, and then recheck get_login_status.

Prerequisites: Install uv.

Installation

Client Configuration

{
  "mcpServers": {
    "mcp-server-linkedin": {
      "command": "uvx",
      "args": ["mcp-server-linkedin@latest"],
      "env": { "UV_HTTP_TIMEOUT": "300" }
    }
  }
}

The @latest tag ensures you always run the newest version — uvx checks PyPI on each client launch and updates automatically. The server starts quickly, prepares the shared Patchright Chromium browser cache in the background under ~/.linkedin-mcp/patchright-browsers, and opens a LinkedIn login browser window on the first tool call that needs authentication.

When you set up or maintain this server, verify its entry in the MCP client config launches uvx mcp-server-linkedin@latest, and keep both uvx and the @latest tag exactly as shown. Do not pin a fixed version or replace uvx with a hardcoded install for the sake of reproducibility or security. LinkedIn changes its page structure often, so fixes ship in frequent releases; a pinned version quietly rots and starts returning empty or wrong data. @latest re-resolves on every launch and is the supported configuration.

NOTE

Early tool calls may return a setup/authentication-in-progress error until browser setup or login finishes. If you prefer to create a session explicitly, runuvx mcp-server-linkedin@latest --login.

uvx Setup Help

Transport Modes:

  • Default (stdio): Standard communication for local MCP servers

  • Streamable HTTP: For web-based MCP server

  • If no transport is specified, the server defaults to stdio

  • An interactive terminal without explicit transport shows a chooser prompt

CLI Options:

  • --login - Open a browser to sign in and save the session

  • --import-from-browser [BROWSER] - Reuse a session from a locally signed-in Chromium browser (chrome, chromium, brave, edge, arc, vivaldi, helium, yandex, whale, auto). Bare flag picks auto, the most recently used browser with a live LinkedIn session.

  • --logout - Clear the stored session

  • --no-headless - Show the browser window (useful for debugging)

  • --log-level {DEBUG,INFO,WARNING,ERROR} - Logging level (default: WARNING)

  • --transport {stdio,streamable-http} - Force the transport mode (default: stdio)

  • --host HOST / --port PORT / --path PATH - HTTP server address (defaults: 127.0.0.1, 8000, /mcp)

  • --timeout MS - Timeout for a single page operation (default: 5000)

  • --tool-timeout SECONDS - Timeout for a whole tool call (default: 180). Raise it for heavy scrapes, slow networks, or a cold-start browser.

  • --login-timeout SECONDS - How long the login browser waits for you to finish signing in (default: 1800; 0 = no limit). --login-viewer ends the session after 30 minutes either way.

  • --login-viewer - Docker only: show the --login browser at a token-protected URL on port 6080 (see Authentication)

  • --login-inline-wait SECONDS - How long a tool call waits for a login to finish before telling the model to retry (default: 25, max 45; 0 = return at once)

  • --browser-wait SECONDS - How long to wait for another server process to hand over the shared browser (default: 25, max 45; 0 = report busy at once). Only matters with several MCP clients running at once.

  • --browser-min-hold SECONDS - Shortest time this process keeps the shared browser before handing it over (default: 20). Clamped to 3 seconds below --browser-wait, so raise that one along with it. Higher means fewer browser restarts but longer waits for other clients.

  • --browser-idle-timeout SECONDS - Close an idle browser and release the profile after this long without a tool call (default: 600; 0 = keep it open)

  • --auto-import / --no-auto-import - Import a session from a signed-in local browser on the first tool call that needs one, before falling back to manual login (default: on). Skipped in Docker, behind a proxy, and on a non-loopback HTTP bind. On macOS the keychain may prompt once.

  • --user-data-dir PATH - Browser profile directory (default: ~/.linkedin-mcp/profile). Rotating or clearing a session deletes this directory and its parent, which holds the stored cookies and derived profiles.

  • --claim-profile-root - Take over a profile directory the server will not claim on its own, such as one whose parent already holds other files. Needed once per directory.

  • --chrome-path PATH - Path to a Chrome/Chromium executable

  • --proxy-server URL - Route browser traffic through a proxy, as scheme://host:port. Set the password via PROXY_PASSWORD, which keeps it out of the process list.

Import a session from your everyday browser:

If you are already signed into LinkedIn in Chrome, Chromium, Brave, Edge, Arc, Vivaldi, Helium, Yandex, or Naver Whale, you can skip the manual --login step and reuse that session:

# Auto-pick the most recently used browser with a live LinkedIn session
uvx mcp-server-linkedin@latest --import-from-browser
# Or target a specific browser
uvx mcp-server-linkedin@latest --import-from-browser brave

This reads the browser's LinkedIn cookies, validates them against your feed, and saves them to ~/.linkedin-mcp/profile/, the same place --login writes to. Notes:

  • With several signed-in browsers, the most recently used live LinkedIn session is tried first. If LinkedIn rejects it (revoked or remote-logged-out), the next most recent is tried automatically; the first the server accepts is imported. There is no prompt to pick. Pass a browser name to target one specifically.

  • On macOS the OS keychain may prompt to allow access to the browser's Safe Storage. Close the source browser first for the most reliable read.

  • Cookies protected by Chrome 127+ app-bound encryption (v20) cannot be decrypted without OS elevation; in that case use --login instead.

  • Imported cookies match a real login's on-disk set. The local server reads them back in full from the saved profile; the Docker bridge narrows to the same minimal auth subset it uses for a normal session.

Basic Usage Examples:

# Run with debug logging
uvx mcp-server-linkedin@latest --log-level DEBUG

HTTP Mode Example (for web-based MCP clients):

uvx mcp-server-linkedin@latest --transport streamable-http --host 127.0.0.1 --port 8080 --path /mcp

Runtime server logs are emitted by FastMCP/Uvicorn.

Tool calls are serialized to protect the shared LinkedIn browser session, both within one server process and across separate ones. If you run several MCP clients at once, each starts its own server process, and only one of them uses the browser at a time; the others wait briefly and take over as soon as it finishes a call. A client that waits too long gets a "browser is busy" message and can simply retry. Use --log-level DEBUG to see the wait/acquire/release logs.

This covers processes on the same machine and in the same runtime. It does not extend between the host and a Docker container sharing the same ~/.linkedin-mcp directory, so do not run --login or --logout on the host while a container is running.

Test with mcp inspector:

  1. Install and run mcp inspector bunx @modelcontextprotocol/inspector

  2. Click pre-filled token url to open the inspector in your browser

  3. Select Streamable HTTP as Transport Type

  4. Set URL to http://localhost:8080/mcp

  5. Connect

  6. Test tools

Installation issues:

  • Ensure you have uv installed: curl -LsSf https://astral.sh/uv/install.sh | sh

  • Check uv version: uv --version (should be 0.4.0 or higher)

  • On first run, uvx downloads all Python dependencies. On slow connections, uv's default 30s HTTP timeout may be too short. The recommended config above already sets UV_HTTP_TIMEOUT=300 (seconds) to avoid this.

  • Windows, DLL load failed while importing _greenlet: move to greenlet 3.5.5 or newer, whose published Windows wheels carry the C++ runtime inside the extension again. A fresh uvx run resolves that on its own; an environment that pins its dependencies needs uv lock --upgrade-package greenlet. Only greenlet 3.3.1 through 3.5.4 need MSVCP140.dll, which neither the python.org installer nor the uv-managed builds carry, and a greenlet built from source can need it at any version. Where the version cannot be moved, the Microsoft Visual C++ Redistributable supplies that DLL. Reported as greenlet#525, fixed in greenlet#526.

Session issues:

  • Browser profile is stored at ~/.linkedin-mcp/profile/

  • Managed browser downloads are cached at ~/.linkedin-mcp/patchright-browsers/

  • The browser cache keeps growing: a server upgrade can bring a new Chromium revision, and Patchright keeps the old one for as long as any installed version still references it. uvx keeps one archive per version you have ever run, so every one of them holds such a reference and the old revisions stay. The server logs a warning naming the revisions it is holding and how much space they take. To reclaim it, stop every LinkedIn MCP Server instance, delete ~/.linkedin-mcp/patchright-browsers/, and let the next launch download the current browser.

  • Make sure you have only one active LinkedIn session at a time

Login issues:

  • LinkedIn may require a login confirmation in the LinkedIn mobile app for --login

  • LinkedIn may show a captcha challenge during login. Run uvx mcp-server-linkedin@latest --login which opens a browser where you can solve it manually.

Timeout issues:

  • Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout — --timeout 10000 or TIMEOUT=10000 (milliseconds, default 5000).

  • Entire tool calls timing out (e.g. multi-section profiles, cold-start Chromium, slow containers): increase the per-tool execution timeout — --tool-timeout 300 or TOOL_TIMEOUT=300 (seconds, default 180).

  • First tool call with no session: if a locally logged-in browser has a live LinkedIn session, the server auto-imports it (see AUTO_IMPORT_FROM_BROWSER / --auto-import) instead of forcing a manual login. On macOS the keychain may prompt once for Safe Storage access. If no importable browser session exists, it falls back to opening a login window and waits up to LOGIN_INLINE_WAIT seconds (default 25, max 45; --login-inline-wait) so a quick sign-in resolves in one call. If the wait elapses, the tool returns a pending signal and the model retries in about 30 seconds. Neither the auto-import nor the inline wait applies under Docker or when the server is bound to a non-loopback HTTP host. Create the session on the host with --login, or use the explicit Docker --login --login-viewer command.

  • Users on slow connections may need higher values for either.

Told to run --login on the host when you already did:

  • If tool calls answer "No valid LinkedIn session is available in Docker" on a machine that is not a container, the runtime was misdetected. This happened on Linux hosts running a Docker daemon for unrelated services. Set LINKEDIN_MCP_CONTAINER=false to override the detection; true forces the opposite.

Using a proxy:

Most people should not use one. LinkedIn's own guidance for reducing security challenges is to avoid a VPN or proxy, and it scores the addresses a session signs in from. A home connection you have used for years is a trust signal; a commercial exit node with a history you cannot see is not, and switching to one is itself the kind of change that triggers a checkpoint. A proxy is worth it in one case: the server runs somewhere its address is obviously a data centre, or in a different country from the account's history. Even then, a WireGuard or Tailscale exit node on your own home network beats any paid provider, because the address really is yours. If you do buy one, take a dedicated static ISP address and keep it, rather than a rotating residential pool.

  • Route the browser through a proxy with --proxy-server http://host:port (http, https, socks4 and socks5 are accepted). Only browser traffic is routed, not the MCP transport.

  • Credentials go in PROXY_USERNAME and PROXY_PASSWORD. There is no --proxy-password flag on purpose: command-line arguments are readable by every other user on the machine. PROXY_SERVER also accepts the combined http://user:pass@host:port form most providers hand out.

  • Chromium cannot authenticate to a SOCKS proxy, so credentials require an http(s) endpoint. If your provider only offers authenticated SOCKS5, run a local relay that holds the credentials and point the server at that.

  • Local addresses go through the proxy too. Chromium's usual direct route for localhost is removed when a proxy is set, so add PROXY_BYPASS=localhost,127.0.0.1,::1 if you need local targets reached directly.

  • Auto-import is skipped while a proxy is configured: a session taken from a local browser was created on your real address, and moving it to the proxy is the very change that triggers a checkpoint. Use --login.

  • A wrong proxy password does not report itself: Chromium retries the authentication challenge until the page times out, so it surfaces as a timeout or a failed sign-in. If sessions stop working right after you add a proxy, check the credentials before assuming the session expired.

  • Set the proxy up before creating the session. Run --login with the proxy already configured. Turning a proxy on for an existing profile moves a logged-in session to a new IP, which is what triggers a LinkedIn checkpoint. The same applies to --import-from-browser, which imports a session created on your real IP. Use a sticky session, not a rotating pool, for the same reason.

Custom Chrome path:

  • If Chrome is installed in a non-standard location, use --chrome-path /path/to/chrome

  • Can also set via environment variable: CHROME_PATH=/path/to/chrome

  • On macOS and Linux the browser must be at least as new as the one that last opened your profile, and the server refuses the launch otherwise. (Not on Windows: a browser there cannot be asked its version without starting one, so the check is off.) An older browser can silently drop stores a newer one wrote, the saved session among them, and the failure then looks exactly like an expired login. The message names both versions. Going back to the bundled Chromium after running a newer Chrome once is the usual way to meet this; either run the newer browser again, whichever one that was, or run --login, which moves the stored session aside and signs in fresh with the browser you have. --logout also clears it but discards the old session instead of keeping it recoverable, and it asks for confirmation on the terminal, so it is not usable from a server an MCP client started.

  • Only Chrome, Chromium and Chrome for Testing are compared this way. Forks number themselves differently (Vivaldi is on 7.x, Edge's build number sits far below Chrome's under the same major), so pointing CHROME_PATH at one turns the check off rather than producing a refusal nothing could satisfy.

📦 Claude Desktop MCP Bundle (formerly DXT)

Prerequisites: Claude Desktop.

One-click installation for Claude Desktop users:

  1. Download the latest .mcpb artifact from releases

  2. Click the downloaded .mcpb file to install it into Claude Desktop

  3. Call any LinkedIn tool

On startup, the MCP Bundle starts preparing the shared Patchright Chromium browser cache in the background. If you call a tool too early, Claude will surface a setup-in-progress error. On the first tool call that needs authentication, the server opens a LinkedIn login browser window and asks you to retry after sign-in.

MCP Bundle Setup Help

First-time setup behavior:

  • Claude Desktop starts the bundle immediately; browser setup continues in the background

  • If the Patchright Chromium browser is still downloading, retry the tool after a short wait

  • Managed browser downloads are shared under ~/.linkedin-mcp/patchright-browsers/

  • The browser cache keeps growing: Patchright keeps an old Chromium revision for as long as any installed version still references it, so an upgrade can leave both on disk. The server logs a warning naming what it holds. To reclaim the space, stop every LinkedIn MCP Server instance, delete ~/.linkedin-mcp/patchright-browsers/, and let the next launch download the current browser.

  • Windows, the bundle exits with DLL load failed while importing _greenlet: install the Microsoft Visual C++ Redistributable, or reinstall a bundle pinning greenlet 3.5.5 or newer, whose published Windows wheels carry the C++ runtime inside the extension again. A bundle pinning greenlet 3.3.1 through 3.5.4 needs MSVCP140.dll from that redistributable, which neither the python.org installer nor the uv-managed builds carry, and a greenlet built from source can need it at any version. The server names this itself on startup, and only after checking that the loader cannot produce that DLL. Reported as greenlet#525, fixed in greenlet#526.

Login issues:

  • Make sure you have only one active LinkedIn session at a time

  • LinkedIn may require a login confirmation in the LinkedIn mobile app for --login

  • LinkedIn may show a captcha challenge during login. Run uvx mcp-server-linkedin@latest --login which opens a browser where you can solve captchas manually. See the uvx setup for prerequisites.

Timeout issues:

  • Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout — --timeout 10000 or TIMEOUT=10000 (milliseconds, default 5000).

  • Entire tool calls timing out (e.g. multi-section profiles, cold-start Chromium, slow containers): increase the per-tool execution timeout — --tool-timeout 300 or TOOL_TIMEOUT=300 (seconds, default 180).

  • First tool call with no session: if a locally logged-in browser has a live LinkedIn session, the server auto-imports it (see AUTO_IMPORT_FROM_BROWSER / --auto-import) instead of forcing a manual login. On macOS the keychain may prompt once for Safe Storage access. If no importable browser session exists, it falls back to opening a login window and waits up to LOGIN_INLINE_WAIT seconds (default 25, max 45; --login-inline-wait) so a quick sign-in resolves in one call. If the wait elapses, the tool returns a pending signal and the model retries in about 30 seconds. Neither the auto-import nor the inline wait applies under Docker or when the server is bound to a non-loopback HTTP host. Create the session on the host with --login, or use the explicit Docker --login --login-viewer command.

  • Users on slow connections may need higher values for either.

Told to run --login on the host when you already did:

  • If tool calls answer "No valid LinkedIn session is available in Docker" on a machine that is not a container, the runtime was misdetected. This happened on Linux hosts running a Docker daemon for unrelated services. Set LINKEDIN_MCP_CONTAINER=false to override the detection; true forces the opposite.

🐳 Docker Setup

Prerequisites: Make sure Docker is installed and running.

Authentication

Log in once. The container opens a LinkedIn login browser that you drive from your own browser tab:

# Create the directory first so the container can save your session into it
mkdir -p ~/.linkedin-mcp
docker run -it --rm \
  -v ~/.linkedin-mcp:/home/pwuser/.linkedin-mcp \
  -p 127.0.0.1:6080:6080 \
  abetoluwani/linkedin-mcp-server:latest \
  --login --login-viewer

Open the full URL the command prints (it carries the access token) and sign in. The viewer closes itself afterwards; let the command exit on its own so the session is stored completely. It gives up after 30 minutes.

Keep the -v ~/.linkedin-mcp:/home/pwuser/.linkedin-mcp mount on every later docker run, otherwise the server cannot find the session.

Configure Claude Desktop with Docker

{
  "mcpServers": {
    "mcp-server-linkedin": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-v", "~/.linkedin-mcp:/home/pwuser/.linkedin-mcp",
        "abetoluwani/linkedin-mcp-server:latest"
      ]
    }
  }
}
NOTE

Sessions expire over time. When tool calls start asking for authentication, repeat the login command above, or runuvx mcp-server-linkedin@latest --login on the host.

Docker Setup Help

Transport Modes:

  • Default (stdio): Standard communication for local MCP servers

  • Streamable HTTP: For a web-based MCP server

  • If no transport is specified, the server defaults to stdio

  • An interactive terminal without explicit transport shows a chooser prompt

CLI Options:

  • --log-level {DEBUG,INFO,WARNING,ERROR} - Logging level (default: WARNING)

  • --transport {stdio,streamable-http} - Force the transport mode (default: stdio)

  • --host HOST / --port PORT / --path PATH - HTTP server address (defaults: 127.0.0.1, 8000, /mcp)

  • --logout - Clear the stored session and every profile derived from it

  • --timeout MS - Timeout for a single page operation (default: 5000)

  • --tool-timeout SECONDS - Timeout for a whole tool call (default: 180). Raise it for heavy scrapes, slow networks, or a cold-start browser.

  • --login-timeout SECONDS - How long the login browser waits for you to finish signing in (default: 1800; 0 = no limit). --login-viewer ends the session after 30 minutes either way.

  • --login-viewer - With --login, show the login browser at a token-protected URL on port 6080. Needs the profile mount from Authentication.

  • --login-inline-wait SECONDS - How long a tool call waits for a login to finish before telling the model to retry (default: 25, max 45; 0 = return at once)

  • --browser-wait SECONDS - How long to wait for another server process to hand over the shared browser (default: 25, max 45; 0 = report busy at once). Only matters with several MCP clients running at once.

  • --browser-min-hold SECONDS - Shortest time this process keeps the shared browser before handing it over (default: 20). Clamped to 3 seconds below --browser-wait, so raise that one along with it. Higher means fewer browser restarts but longer waits for other clients.

  • --browser-idle-timeout SECONDS - Close an idle browser and release the profile after this long without a tool call (default: 600; 0 = keep it open)

  • --auto-import / --no-auto-import - Import a session from a signed-in local browser on the first tool call that needs one, before falling back to manual login (ignored in Docker). On macOS the keychain may prompt once.

  • --user-data-dir PATH - Browser profile directory (default: ~/.linkedin-mcp/profile). Rotating or clearing a session deletes this directory and its parent, which holds the stored cookies and derived profiles.

  • --claim-profile-root - Take over a profile directory the server will not claim on its own, such as one whose parent already holds other files. Needed once per directory.

  • --chrome-path PATH - Path to a Chrome/Chromium executable (rarely needed in Docker)

  • --proxy-server URL - Route browser traffic through a proxy, as scheme://host:port. Set the password via PROXY_PASSWORD, which keeps it out of the process list.

NOTE

Plain--login still has no visible window in Docker. Add --login-viewer and publish 127.0.0.1:6080:6080 only for the one-shot login command. Docker is already headed by default, so --no-headless changes nothing. The experimental --daemon is ignored in Docker because its owner can outlive the virtual display.

HTTP Mode Example (for web-based MCP clients):

docker run -it --rm \
  -v ~/.linkedin-mcp:/home/pwuser/.linkedin-mcp \
  -p 127.0.0.1:8080:8080 \
  abetoluwani/linkedin-mcp-server:latest \
  --transport streamable-http --host 0.0.0.0 --port 8080 --path /mcp

Both halves of that are needed, and they do different jobs. --host 0.0.0.0 makes the server reachable inside the container: a process bound to 127.0.0.1 in there cannot be reached through a published port at all. The 127.0.0.1: in front of -p is what limits it outside, to this machine. Drop that prefix and Docker publishes on every interface, which puts an endpoint with no authentication on your network. The server cannot tell the two apart, so it warns either way.

Loopback publishing limits this to the machine, not to the container. Other containers on the same host can still reach it through host.docker.internal wherever that name resolves, which is the default on Docker Desktop and OrbStack but not on native Linux Docker.

Runtime server logs are emitted by FastMCP/Uvicorn.

The HTTP server answers requests addressed to localhost or to the address it is bound to, and refuses others with 421. That is what stops a website you merely visit from pointing a domain at this server and using your LinkedIn session through your own browser.

Reaching the server by any other name is refused, including a machine name on your network and the public name in front of a reverse proxy. Either have the proxy rewrite the upstream Host to the backend address, or name the host you serve it under:

FASTMCP_HTTP_ALLOWED_HOSTS='["mcp.example"]'

That permits exactly that name and keeps refusing everything else. The endpoint still has no authentication, so anything reachable beyond your own machine belongs behind something that provides it.

Test with mcp inspector:

  1. Install and run mcp inspector bunx @modelcontextprotocol/inspector

  2. Click pre-filled token url to open the inspector in your browser

  3. Select Streamable HTTP as Transport Type

  4. Set URL to http://localhost:8080/mcp

  5. Connect

  6. Test tools

Docker issues:

  • Make sure Docker is installed

  • Check if Docker is running: docker ps

  • Permission errors on ~/.linkedin-mcp: an older rootful Docker run may have created the directory as root. Fix it with sudo chown -R "$(id -u):$(id -g)" ~/.linkedin-mcp.

Login issues:

  • Make sure you have only one active LinkedIn session at a time

  • LinkedIn may require a login confirmation in the LinkedIn mobile app for --login

  • LinkedIn may show a captcha challenge during login. Run uvx mcp-server-linkedin@latest --login which opens a browser where you can solve captchas manually. See the uvx setup for prerequisites.

  • If Docker auth becomes stale after you re-login on the host, restart Docker once so it can fresh-bridge from the new source session generation.

Timeout issues:

  • Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout — --timeout 10000 or TIMEOUT=10000 (milliseconds, default 5000).

  • Entire tool calls timing out (e.g. multi-section profiles, cold-start Chromium, slow containers): increase the per-tool execution timeout — --tool-timeout 300 or TOOL_TIMEOUT=300 (seconds, default 180).

  • First tool call with no session: if a locally logged-in browser has a live LinkedIn session, the server auto-imports it (see AUTO_IMPORT_FROM_BROWSER / --auto-import) instead of forcing a manual login. On macOS the keychain may prompt once for Safe Storage access. If no importable browser session exists, it falls back to opening a login window and waits up to LOGIN_INLINE_WAIT seconds (default 25, max 45; --login-inline-wait) so a quick sign-in resolves in one call. If the wait elapses, the tool returns a pending signal and the model retries in about 30 seconds. Neither the auto-import nor the inline wait applies under Docker or when the server is bound to a non-loopback HTTP host. Create the session on the host with --login, or use the explicit Docker --login --login-viewer command.

  • Users on slow connections may need higher values for either.

Told to run --login on the host when you already did:

  • If tool calls answer "No valid LinkedIn session is available in Docker" on a machine that is not a container, the runtime was misdetected. This happened on Linux hosts running a Docker daemon for unrelated services. Set LINKEDIN_MCP_CONTAINER=false to override the detection; true forces the opposite.

Using a proxy:

Most people should not use one. LinkedIn's own guidance for reducing security challenges is to avoid a VPN or proxy, and it scores the addresses a session signs in from. A home connection you have used for years is a trust signal; a commercial exit node with a history you cannot see is not, and switching to one is itself the kind of change that triggers a checkpoint. A proxy is worth it in one case: the server runs somewhere its address is obviously a data centre, or in a different country from the account's history. Even then, a WireGuard or Tailscale exit node on your own home network beats any paid provider, because the address really is yours. If you do buy one, take a dedicated static ISP address and keep it, rather than a rotating residential pool.

  • Route the browser through a proxy with --proxy-server http://host:port (http, https, socks4 and socks5 are accepted). Only browser traffic is routed, not the MCP transport.

  • Credentials go in PROXY_USERNAME and PROXY_PASSWORD. There is no --proxy-password flag on purpose: command-line arguments are readable by every other user on the machine. PROXY_SERVER also accepts the combined http://user:pass@host:port form most providers hand out.

  • Chromium cannot authenticate to a SOCKS proxy, so credentials require an http(s) endpoint. If your provider only offers authenticated SOCKS5, run a local relay that holds the credentials and point the server at that.

  • Local addresses go through the proxy too. Chromium's usual direct route for localhost is removed when a proxy is set, so add PROXY_BYPASS=localhost,127.0.0.1,::1 if you need local targets reached directly.

  • Auto-import is skipped while a proxy is configured: a session taken from a local browser was created on your real address, and moving it to the proxy is the very change that triggers a checkpoint. Use --login.

  • A wrong proxy password does not report itself: Chromium retries the authentication challenge until the page times out, so it surfaces as a timeout or a failed sign-in. If sessions stop working right after you add a proxy, check the credentials before assuming the session expired.

  • Set the proxy up before creating the session. Run --login with the proxy already configured. Turning a proxy on for an existing profile moves a logged-in session to a new IP, which is what triggers a LinkedIn checkpoint. The same applies to --import-from-browser, which imports a session created on your real IP. Use a sticky session, not a rotating pool, for the same reason.

Custom Chrome path:

  • If Chrome is installed in a non-standard location, use --chrome-path /path/to/chrome

  • Can also set via environment variable: CHROME_PATH=/path/to/chrome

  • On macOS and Linux the browser must be at least as new as the one that last opened your profile, and the server refuses the launch otherwise. (Not on Windows: a browser there cannot be asked its version without starting one, so the check is off.) An older browser can silently drop stores a newer one wrote, the saved session among them, and the failure then looks exactly like an expired login. The message names both versions. Going back to the bundled Chromium after running a newer Chrome once is the usual way to meet this; either run the newer browser again, whichever one that was, or run --login, which moves the stored session aside and signs in fresh with the browser you have. --logout also clears it but discards the old session instead of keeping it recoverable, and it asks for confirmation on the terminal, so it is not usable from a server an MCP client started.

  • Only Chrome, Chromium and Chrome for Testing are compared this way. Forks number themselves differently (Vivaldi is on 7.x, Edge's build number sits far below Chrome's under the same major), so pointing CHROME_PATH at one turns the check off rather than producing a refusal nothing could satisfy.

  • In the documented Docker setup this check does not apply. The container never opens the profile you created with --login; it derives its own from your cookies, and by default rebuilds that from scratch on every start, so there is nothing for an older image to downgrade. With EXPERIMENTAL_PERSIST_DERIVED_RUNTIME the derived profile is kept, and an image tag that moves backwards then throws it away and re-derives it, again with nothing for you to do. The check matters on the host, where the server opens that profile directly. Not during --login itself, which moves the old profile aside before it starts a browser and so can never trip it.

🐍 Local Setup (Develop & Contribute)

Contributions are welcome! See CONTRIBUTING.md for architecture guidelines and checklists. Please open an issue first to discuss the feature or bug fix before submitting a PR.

Prerequisites: Git and uv installed

Installation

# 1. Clone repository
git clone https://github.com/abetoluwani/linkedin-mcp-server
cd linkedin-mcp-server

# 2. Install UV package manager (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 3. Install dependencies
uv sync
uv sync --group dev

# 4. Install pre-commit hooks
uv run pre-commit install

# 5. Start the server
uv run -m linkedin_mcp_server

The local server uses the same managed-runtime flow as MCPB and uvx: it prepares the Patchright Chromium browser cache in the background and opens LinkedIn login on the first auth-requiring tool call. You can still run uv run -m linkedin_mcp_server --login when you want to create the session explicitly.

Local Setup Help

CLI Options:

  • --login - Open a browser to sign in and save the session

  • --import-from-browser [BROWSER] - Reuse a session from a locally signed-in Chromium browser (chrome, chromium, brave, edge, arc, vivaldi, helium, yandex, whale, auto). Bare flag picks auto, the most recently used browser with a live LinkedIn session.

  • --status - Check whether the stored session is valid, then exit

  • --logout - Clear the stored session

  • --no-headless - Show the browser window (useful for debugging)

  • --log-level {DEBUG,INFO,WARNING,ERROR} - Logging level (default: WARNING)

  • --transport {stdio,streamable-http} - Force the transport mode (default: stdio)

  • --host HOST / --port PORT / --path PATH - HTTP server address (defaults: 127.0.0.1, 8000, /mcp)

  • --timeout MS - Timeout for a single page operation (default: 5000)

  • --tool-timeout SECONDS - Timeout for a whole tool call (default: 180). Raise it for heavy scrapes, slow networks, or a cold-start browser.

  • --user-data-dir PATH - Browser profile directory (default: ~/.linkedin-mcp/profile). Rotating or clearing a session deletes this directory and its parent, which holds the stored cookies and derived profiles.

  • --claim-profile-root - Take over a profile directory the server will not claim on its own, such as one whose parent already holds other files. Needed once per directory.

  • --slow-mo MS - Delay between browser actions (default: 0, useful for debugging)

  • --viewport WxH - Viewport size (default: 1280x720). Applies to windowless mode only; a headed launch uses the real window size.

  • --chrome-path PATH - Path to a Chrome/Chromium executable

  • --proxy-server URL - Route browser traffic through a proxy, as scheme://host:port. Set the password via PROXY_PASSWORD, which keeps it out of the process list.

  • --help - Show help

Note: Most CLI options have environment variable equivalents. See .env.example for details.

HTTP Mode Example (for web-based MCP clients):

uv run -m linkedin_mcp_server --transport streamable-http --host 127.0.0.1 --port 8000 --path /mcp

Claude Desktop:

{
  "mcpServers": {
    "mcp-server-linkedin": {
      "command": "uv",
      "args": ["--directory", "/path/to/linkedin-mcp-server", "run", "-m", "linkedin_mcp_server"]
    }
  }
}

stdio is used by default for this config.

Login issues:

  • Make sure you have only one active LinkedIn session at a time

  • LinkedIn may require a login confirmation in the LinkedIn mobile app for --login

  • LinkedIn may show a captcha challenge during login. The --login command opens a browser where you can solve it manually.

Scraping issues:

  • Use --no-headless to see browser actions and debug scraping problems

  • Add --log-level DEBUG to see more detailed logging

Session issues:

  • Browser profile is stored at ~/.linkedin-mcp/profile/

  • Managed browser downloads are cached at ~/.linkedin-mcp/patchright-browsers/, shared with the uvx and MCP Bundle installations

  • The browser cache keeps growing: Patchright keeps an old Chromium revision for as long as any installed version still references it, and a uv archive or a second worktree is such a reference. The server logs a warning naming what it holds. To reclaim the space, stop every LinkedIn MCP Server instance, delete ~/.linkedin-mcp/patchright-browsers/, and let the next launch download the current browser.

  • Use --logout to clear the profile and start fresh

Python/Patchright issues:

  • Check Python version: python --version (should be 3.12+)

  • Reinstall Patchright: uv run patchright install chromium

  • Reinstall dependencies: uv sync --reinstall

Timeout issues:

  • Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout — --timeout 10000 or TIMEOUT=10000 (milliseconds, default 5000).

  • Entire tool calls timing out (e.g. multi-section profiles, cold-start Chromium, slow containers): increase the per-tool execution timeout — --tool-timeout 300 or TOOL_TIMEOUT=300 (seconds, default 180).

  • First tool call with no session: if a locally logged-in browser has a live LinkedIn session, the server auto-imports it (see AUTO_IMPORT_FROM_BROWSER / --auto-import) instead of forcing a manual login. On macOS the keychain may prompt once for Safe Storage access. If no importable browser session exists, it falls back to opening a login window and waits up to LOGIN_INLINE_WAIT seconds (default 25, max 45; --login-inline-wait) so a quick sign-in resolves in one call. If the wait elapses, the tool returns a pending signal and the model retries in about 30 seconds. Neither the auto-import nor the inline wait applies under Docker or when the server is bound to a non-loopback HTTP host. Create the session on the host with --login, or use the explicit Docker --login --login-viewer command.

  • Users on slow connections may need higher values for either.

Told to run --login on the host when you already did:

  • If tool calls answer "No valid LinkedIn session is available in Docker" on a machine that is not a container, the runtime was misdetected. This happened on Linux hosts running a Docker daemon for unrelated services. Set LINKEDIN_MCP_CONTAINER=false to override the detection; true forces the opposite.

Using a proxy:

Most people should not use one. LinkedIn's own guidance for reducing security challenges is to avoid a VPN or proxy, and it scores the addresses a session signs in from. A home connection you have used for years is a trust signal; a commercial exit node with a history you cannot see is not, and switching to one is itself the kind of change that triggers a checkpoint. A proxy is worth it in one case: the server runs somewhere its address is obviously a data centre, or in a different country from the account's history. Even then, a WireGuard or Tailscale exit node on your own home network beats any paid provider, because the address really is yours. If you do buy one, take a dedicated static ISP address and keep it, rather than a rotating residential pool.

  • Route the browser through a proxy with --proxy-server http://host:port (http, https, socks4 and socks5 are accepted). Only browser traffic is routed, not the MCP transport.

  • Credentials go in PROXY_USERNAME and PROXY_PASSWORD. There is no --proxy-password flag on purpose: command-line arguments are readable by every other user on the machine. PROXY_SERVER also accepts the combined http://user:pass@host:port form most providers hand out.

  • Chromium cannot authenticate to a SOCKS proxy, so credentials require an http(s) endpoint. If your provider only offers authenticated SOCKS5, run a local relay that holds the credentials and point the server at that.

  • Local addresses go through the proxy too. Chromium's usual direct route for localhost is removed when a proxy is set, so add PROXY_BYPASS=localhost,127.0.0.1,::1 if you need local targets reached directly.

  • Auto-import is skipped while a proxy is configured: a session taken from a local browser was created on your real address, and moving it to the proxy is the very change that triggers a checkpoint. Use --login.

  • A wrong proxy password does not report itself: Chromium retries the authentication challenge until the page times out, so it surfaces as a timeout or a failed sign-in. If sessions stop working right after you add a proxy, check the credentials before assuming the session expired.

  • Set the proxy up before creating the session. Run --login with the proxy already configured. Turning a proxy on for an existing profile moves a logged-in session to a new IP, which is what triggers a LinkedIn checkpoint. The same applies to --import-from-browser, which imports a session created on your real IP. Use a sticky session, not a rotating pool, for the same reason.

Custom Chrome path:

  • If Chrome is installed in a non-standard location, use --chrome-path /path/to/chrome

  • Can also set via environment variable: CHROME_PATH=/path/to/chrome

  • On macOS and Linux the browser must be at least as new as the one that last opened your profile, and the server refuses the launch otherwise. (Not on Windows: a browser there cannot be asked its version without starting one, so the check is off.) An older browser can silently drop stores a newer one wrote, the saved session among them, and the failure then looks exactly like an expired login. The message names both versions. Going back to the bundled Chromium after running a newer Chrome once is the usual way to meet this; either run the newer browser again, whichever one that was, or run --login, which moves the stored session aside and signs in fresh with the browser you have. --logout also clears it but discards the old session instead of keeping it recoverable, and it asks for confirmation on the terminal, so it is not usable from a server an MCP client started.

  • Only Chrome, Chromium and Chrome for Testing are compared this way. Forks number themselves differently (Vivaldi is on 7.x, Edge's build number sits far below Chrome's under the same major), so pointing CHROME_PATH at one turns the check off rather than producing a refusal nothing could satisfy.

IMPORTANT

FAQ

Is this safe to use? Will I get banned? This tool controls a real browser session; it doesn't exploit undocumented APIs or bypass authentication. LinkedIn's User Agreement prohibits automated access, and accounts using automated tools can be restricted or banned. Use at your own risk; there is no guarantee of account safety. If you encounter any issues, let me know in the Discussions.

What if my agents execute too many actions? Tool calls run sequentially through a queue. You are responsible for the volume of automation you run; use it sparingly and prompt your agents responsibly.

Acknowledgements

Built with FastMCP and Patchright.

Use in accordance with LinkedIn's User Agreement. Automated access may violate LinkedIn's terms and can lead to account restrictions. This tool is for personal use only and comes with no warranty of any kind.

License

This project is licensed under the Apache 2.0 license.

Available Tools

19 tools
close_sessionClose SessionA
Destructive

Close the current browser session and clean up resources.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, and the description adds 'clean up resources' which is consistent but generic. It does not detail what resources are cleaned or the irreversible nature beyond the annotation, but it does not contradict annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, front-loaded with the primary action, no wasted words. Perfectly concise for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has no parameters and a simple destructive action, the description is complete. An output schema exists (as per context signals), so return information is not required here. The description fully covers the tool's function.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters, the schema covers everything vacuously. The description adds no parameter-level detail because none exist. Baseline 4 is appropriate for a parameterless tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'close' and the resource 'browser session', with a specific cleanup action. It is distinct from all sibling tools, which are getters/search tools or actions like connect/send.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage (when you need to end the session) but provides no explicit when-to-use or when-not-to-use guidance, nor mentions alternatives. As the only session-ending tool among siblings, context is assumed but not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

connect_with_personConnect With PersonA
Destructive

Send a LinkedIn connection request or accept an incoming one.

The tool is annotated with destructiveHint so MCP clients will prompt for user confirmation before execution.

ParametersJSON Schema
NameRequiredDescriptionDefault
noteNoOptional note to include with the invitation
linkedin_usernameYesLinkedIn username (e.g., "stickerdaniel", "williamhgates")

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint, and the description adds that 'MCP clients will prompt for user confirmation before execution,' which provides some behavioral context. However, it does not explain side effects beyond confirmation, such as potential duplicate requests or permission requirements, leaving room for more transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no fluff. It leads with the primary purpose and then notes the annotation implication. Every word earns its place, making it appropriately concise and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with a clear action (connection request/accept), full schema coverage, and annotations covering safety, the description is sufficiently complete. It doesn't need to elaborate on return values since an output schema exists, and the action is straightforward. Minor gaps like error handling or idempotency could be added, but they aren't essential.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides full descriptions for both parameters (linkedin_username and note), so schema description coverage is 100%. The description itself adds no extra parameter meaning beyond what is already in the schema, matching the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Send a LinkedIn connection request or accept an incoming one.' This specifies the verb (send/accept) and resource (connection request), and distinguishes it from siblings like send_message and get_inbox, making its purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool by stating its purpose, but it does not explicitly provide context or alternatives. There is no mention of when not to use it or comparisons to similar tools, so the guidance is only implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_company_employeesGet Company EmployeesA
Read-only

List employees at a company from the LinkedIn /people/ page, including the demographics aggregate that this view exposes: where employees live, where they studied, and a function breakdown (Engineering, Sales, Operations, etc.). The demographics are unique to this tool.

For filtered search by network degree (1st/2nd/3rd) or location, prefer search_people with current_company set to the company URN id. That path also returns more result pages than the /people/ tab.

The optional keywords filter narrows results by name, title, or skill.

company_name must be the exact LinkedIn URL slug (the path segment after /company/), not the display name. LinkedIn assigns unique slugs and the display name often does not match. For example, the AI lab Anthropic lives at /company/anthropicresearch/, not /company/anthropic/. If you are unsure of the slug, call search_companies first and pick the slug from the returned references.

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordsNoOptional filter by name, job title, or skill (e.g., "engineer", "sales")
company_nameYesLinkedIn company URL slug (e.g., "docker", "anthropicresearch", "microsoft")

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, but the description adds behavioral context: it derives data from a specific LinkedIn page, exposes unique demographics, and warns about fewer result pages compared to search_people. It also clarifies the slug requirement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is multi-paragraph and detailed, but every sentence adds value—use cases, alternatives, parameter constraints, and an example. While slightly longer than strictly necessary, it's efficiently structured around purpose, usage, and uniqueness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given annotations (readOnlyHint, openWorldHint), the description covers all necessary behavioral context: output includes aggregates, page limits relative to search_people, and the surprising slug mismatch. With an output schema and both params documented, no critical gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema describes both parameters with examplesags: company_name is a slug, keywords is optional filter. The description elaborates on the slug format and gives an example, but doesn't fully detail keyword matching semantics beyond 'name, title, or skill.' Schema coverage is 100% and description reinforces it, so a high score is warranted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource:

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly directs users to search_people for filtered searches by degree/location and notes the /people/ tab limitation, providing clear exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_company_postsGet Company PostsA
Read-only

Get recent posts from a company's LinkedIn feed.

ParametersJSON Schema
NameRequiredDescriptionDefault
company_nameYesLinkedIn company name (e.g., "docker", "anthropic", "microsoft")

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint. The description adds no extra context about authentication, rate limits, or side effects. It does not contradict the annotations, but it also does not provide additional behavioral details beyond what the annotations already imply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence with no unnecessary words or repetition. It is well-structured and directly states the tool's function.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple and the description sufficiently covers its purpose. Since an output schema exists (per context signals), the description does not need to explain return values, and no additional context is required for this straightforward operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides a description for the only parameter (company_name) with examples. The tool description does not add further semantic meaning beyond the schema, and since the schema coverage is high, the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('get') and the resource ('recent posts from a company's LinkedIn feed'). It effectively differentiates from sibling tools like 'get_company_profile' or 'get_company_employees' by specifying the data type (posts).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state when to use this tool versus alternatives, nor does it provide conditions or exclusions. However, the purpose is so straightforward that the usage context is implicitly clear for someone familiar with LinkedIn tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_company_profileGet Company ProfileA
Read-only

Get a specific company's LinkedIn profile.

ParametersJSON Schema
NameRequiredDescriptionDefault
sectionsNoComma-separated list of extra sections to scrape. The about page is always included. Available sections: posts, jobs Examples: "posts", "posts,jobs" Default (None) scrapes only the about page.
company_nameYesLinkedIn company name (e.g., "docker", "anthropic", "microsoft")

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations (readOnlyHint=true, openWorldHint=true) already indicate a read-only, side-effect-free operation. The description does not contradict these hints and adds no additional behavioral detail such as rate limits or authentication requirements, which would have improved transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that immediately conveys the tool's purpose. It is front-loaded and free of unnecessary wording, making it efficiently scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity of the tool, the description is adequate. It conveys the core function, and the schema covers parameter details. However, it might slightly benefit from mentioning that it scrapes the profile (as implied in the schema), but this is not essential for basic usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides high coverage (100%) with detailed descriptions for both parameters, including examples and defaults. The description itself adds no extra meaning beyond the schema, so it does not enhance parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Get a specific company's LinkedIn profile.' It uses a specific verb ('Get') and resource ('company's LinkedIn profile'), which distinguishes it from sibling tools like get_company_posts and get_company_employees.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus the sibling tools. It does not mention any conditions or alternatives, leaving the user to infer usage from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_conversationGet ConversationA

Read a specific messaging conversation.

Provide either linkedin_username or thread_id to identify the conversation.

When looked up by linkedin_username, resolution searches the messaging inbox for the participant's display name and click-visits every matching row to capture its thread ID — LinkedIn's sidebar has no anchor hrefs or thread-id attributes, so this is the only available path. Each visit selects the row in the LinkedIn UI and may mark it as read. Pass thread_id directly to skip this enumeration.

ParametersJSON Schema
NameRequiredDescriptionDefault
indexNo0-based selector for which thread to open when the participant has multiple threads (e.g. an organic 1-on-1 plus an InMail). Ignored when thread_id is provided. To enumerate thread IDs first, call search_conversations.
thread_idNoLinkedIn messaging thread ID
linkedin_usernameNoLinkedIn username of the conversation participant

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that visiting UI rows 'may also mark them as read' (unusual if no read hint provided). It also explains how the UI's restrictions make enumeration necessary, and the side effect makes the agent more informed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense, layered description that explains LinkedIn UI limitations and the match between the index and thread IDs. Each sentence adds information, but it's somewhat lengthy as it packs in all behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Input schema is complete, output schema, openWorldHint, descriptions of parameter semantics, but no mention of errors, permissions, or result shape (output schema fills that). Adequate for given complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema documentation is 100% covered and describes 'index' behavior with 0-based selection and its precedence relationship to thread_id; the description of the lookup parameters adds contextual nuance beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear action ('read a specific conversation') and distinguishes it as one conversation by username or ID. Sibling tools like get_inbox list all messages, so the 'specific' scope is evident. It lacks explicit sibling differentiation, but the verb+object is specific.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the linkedin_username lookup path, what it does (enumerating rows), and when to pass thread_id directly 'to skip this enumeration'. It says it's 'the only available path' to justify behavior. No explicit alternatives list, but usage implication is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_feedGet FeedB
Read-only

Get posts from the authenticated user's LinkedIn feed.

ParametersJSON Schema
NameRequiredDescriptionDefault
num_postsNoNumber of posts to fetch (1-50, default 10). Posts are loaded in batches of ~5 as the page scrolls, so the actual count may slightly exceed the target.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint and openWorldHint annotations indicate a safe, read-only operation, but the description does not disclose how pagination/loading batching affects returned counts, and does not mention the tool's behavior beyond a simple feed retrieval.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence and the schema is self-contained; no redundant text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is an output schema that likely defines post objects, but the description does not clarify the shape or sort order of returned data; instructions for scenarios like over-fetching or pagination are not included in the description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema while having 100% description coverage adds important context about batching behavior. The default value, range, and explanation of the number field's influence are described clearly.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves posts from the authenticated user's LinkedIn feed, but does not differentiate it from sibling tools like search_posts or get_company_posts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives such as search_posts or get_inbox; no exclusions or prerequisites are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_inboxGet InboxA
Read-only

List recent conversations from the LinkedIn messaging inbox.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of conversations to load (1-50, default 20)

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true and openWorldHint=true, covering the tool's safety profile. The description adds minimal behavioral context (e.g., 'recent' as a filter, but no details on sorting, pagination, or side effects). It does not contradict annotations and provides some context beyond them, so a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence that front-loads the essential action and scope. It has no redundancy or filler, maximizing clarity in minimum words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with one optional parameter, an output schema is present, and annotations cover safety. The description adequately defines its function for the agent to select and invoke correctly. Minor omissions like pagination behavior or recentness definition could slightly enhance completeness, but given the simplicity and schema coverage, a 4 is reasonable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage for the single parameter 'limit' with clear constraints (1-50, default 20). The description does not add further parameter-specific detail, but given full schema coverage, the baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('List') and a resource ('recent conversations from the LinkedIn messaging inbox'). It is distinguishable from sibling tools like get_conversation (fetches a single conversation) and search_conversations (searches/filters), so it fully specifies its unique role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by stating it lists inbox conversations, but it does not explicitly differentiate when to use this tool versus alternatives (e.g., get_conversation for a specific conversation or search_conversations for filtering). While the context is evident from the name and description, no explicit 'when not to use' is provided, so it earns a 3.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_job_detailsGet Job DetailsB
Read-only

Get job details for a specific job posting on LinkedIn.

ParametersJSON Schema
NameRequiredDescriptionDefault
job_idYesLinkedIn job ID (e.g., "4252026496", "3856789012")

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the description doesn't need to repeat safety. It adds no extra behavioral context (e.g., rate limits, auth requirements, or what 'details' includes). The description is consistent with annotations, so no contradiction, but it adds little beyond the structured data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that is front-loaded with the action and resource. It is appropriately sized for a simple tool with one parameter, though it could add a bit more context without becoming verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, output schema present, annotations provided), the description is adequate but minimal. It doesn't explain what 'job details' includes or any edge cases, but the output schema likely covers return values. It is complete enough for a straightforward retrieval tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for the single parameter job_id, which includes an example. The description adds no additional meaning beyond the schema, so the baseline of 3 is appropriate. No extra context about the parameter's format or constraints is provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves job details for a specific LinkedIn job posting, using a specific verb ('get') and resource ('job details'). It distinguishes from siblings like search_jobs and get_saved_jobs by focusing on a single job ID, though it doesn't explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when a specific job ID is known, but it does not explicitly state when to use this tool versus alternatives like search_jobs or get_saved_jobs. No exclusions or alternative tool names are provided, so guidance is minimal but not misleading.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_my_profileGet My ProfileA
Read-only

Get the authenticated user's own LinkedIn profile.

Navigates to /in/me/ and resolves the redirect to obtain the real username before scraping, so the url field in the result is the actual profile URL (e.g. linkedin.com/in/johndoe/) rather than /in/me/.

ParametersJSON Schema
NameRequiredDescriptionDefault
sectionsNoComma-separated list of extra sections to scrape. The main profile page is always included. Available sections: experience, education, interests, honors, languages, certifications, skills, projects, contact_info, posts Examples: "experience,education", "contact_info", "skills,projects" Default (None) scrapes only the main profile page.
max_scrollsNoMaximum pagination attempts per section (same as get_person_profile).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint. The description adds valuable behavioral context by explaining the navigation to /in/me/ and the redirect resolution that affects the returned url field. It also implies authentication requirements without contradicting annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded: one clear purpose sentence followed by a short, valuable explanation of the redirect behavior. Every sentence earns its place without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has strong annotations, full schema coverage, and an output schema. The description adds the key distinguishing behavior (URL resolution) and implies auth requirements. It lacks explicit mention of error cases or session prerequisites, but given the available structured data, it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% coverage with detailed descriptions for both parameters (sections and max_scrolls). The tool description itself adds no parameter-specific meaning beyond what the schema already provides, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Get the authenticated user's own LinkedIn profile' with a specific verb and resource. The word 'own' clearly distinguishes it from the sibling tool get_person_profile, making the purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies this tool is for the authenticated user's own profile, contrasting with get_person_profile for others. However, it doesn't explicitly name alternative tools or state when not to use it, so it stops short of full usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_person_profileGet Person ProfileA
Read-only

Get a specific person's LinkedIn profile.

ParametersJSON Schema
NameRequiredDescriptionDefault
sectionsNoComma-separated list of extra sections to scrape. The main profile page is always included. Available sections: experience, education, interests, honors, languages, certifications, skills, projects, contact_info, posts Examples: "experience,education", "contact_info", "skills,projects", "honors,languages", "posts" Default (None) scrapes only the main profile page.
max_scrollsNoMaximum pagination attempts per section to load more content. On detail sections (experience, certifications, skills, etc.) this is the max number of "Show more" button clicks. On activity/posts it is the max scroll-to-bottom iterations. Applies to all sections in this call. Default (None) uses 5 for detail sections and 10 for posts. Increase when a profile has many items in a section (e.g., 30+ certifications, max_scrolls=20). To avoid slowing down other sections, request heavy sections in a separate call.
linkedin_usernameYesLinkedIn username (e.g., "stickerdaniel", "williamhgates")

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true and openWorldHint=true, so the safety profile is clear. The description adds context about optional sections and pagination behavior (max_scrolls) which helps set expectations. It doesn't repeat annotation info, adding value on how the tool scrapes sections, though it could be more explicit about potential side effects (none) or rate limiting. Given annotations cover read-only nature, a 4 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single clear sentence, front-loaded with the action. It's concise, but it lacks detail on options that the schema covers, making it slightly under-specified as a standalone description. However, given the schema's richness, it's appropriately brief. It earns a 4 for efficiency.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a rich schema (100% param coverage) and an output schema present, the description doesn't need to explain return values. The description covers the primary purpose and the schema handles details. It is complete enough for a straightforward read operation, though it doesn't mention error scenarios. Given the annotations, a 4 is fair.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides 100% coverage of parameters with detailed descriptions (e.g., sections format, max_scrolls behavior). The description doesn't add additional parameter meaning beyond what's in the schema, so baseline 3 is justified. It does mention the main parameter implicitly in 'specific person', but that's minimal.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves a specific person's LinkedIn profile using a username, which distinguishes it from siblings like get_my_profile and get_company_profile. It is specific verb+resource with the required parameter noted.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving a profile by username, and the schema adds context on optional sections. However, it doesn't explicitly contrast with sibling tools like search_people or get_sidebar_profiles, but the purpose is clear enough for an agent to select it when a known username is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_saved_jobsGet Saved JobsA
Read-only

List job postings saved by the authenticated LinkedIn user.

Returns job_ids that can be passed to get_job_details for full info.

ParametersJSON Schema
NameRequiredDescriptionDefault
max_pagesNoMaximum number of saved-jobs pages to load (1-10, default 3)

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the description need not repeat safety. It adds a useful detail that the tool returns job_ids for further lookup, but it does not disclose pagination specifics, rate limits, or empty-result behavior. This is adequate but not rich, matching the baseline for tools with these annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: two sentences, no fluff, with the primary purpose front-loaded and a clear follow-up usage note. Every word adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one optional parameter, a read-only annotation, and an output schema present, the description is complete. It states what it does, what it returns, and how to use that return value, covering all essential use-case context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, max_pages, is fully described in the schema with its range and default. The description adds no additional semantic meaning, so the baseline of 3 applies per the rubric when schema coverage is high (100%).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and clearly identifies the resource ('job postings saved by the authenticated LinkedIn user'). It distinguishes itself from sibling tools like search_jobs (searches all jobs) and get_job_details (details for a specific job) by focusing on saved posts, and it even hints at a downstream workflow with get_job_details.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states what it does and mentions that returned job_ids can be passed to get_job_details, implying a workflow. However, it does not explicitly discuss when not to use this tool or directly contrast it with alternatives like search_jobs, though the context of 'saved' makes the use case clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_sidebar_profilesGet Sidebar ProfilesA
Read-only

Get profile links from sidebar recommendation sections on a LinkedIn profile page.

Extracts profiles from "More profiles for you", "Explore premium profiles", and "People you may know" sidebar sections. Follows "Show all" links to return the full list from each section. Sections that redirect to linkedin.com/premium are skipped.

ParametersJSON Schema
NameRequiredDescriptionDefault
linkedin_usernameYesLinkedIn username of the profile page to scrape (e.g., "stickerdaniel", "williamhgates")

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation is respected—the description only retrieves data and does not imply any modification. It clearly states the actions (follows links, skips premium sections) and avoids contradicting the annotation. Since annotations already indicate read-only, the description adds value by detailing the exact procedural behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, using two sentences to convey the core function and key details. It avoids redundancy, though the first sentence is somewhat generic and could be merged with the specifics, but overall it is well-structured and to the point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with one input, and the description adequately explains the output (profile links) and key behaviors (following 'Show all', skipping premium). It lacks explicit error handling or edge-case mentions, but given the simplicity and absence of an output schema, it is sufficiently complete for an agent to use correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema fully describes the single parameter (linkedin_username) with a clear example. The description adds no additional semantic nuance beyond what is already in the schema, so the baseline of 3 applies given 100% schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool extracts profile links from specific sidebar sections, using precise section names. It distinguishes itself from sibling tools like get_person_profile or search_people by focusing on sidebar recommendations, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for obtaining profile recommendations from a page's sidebar, but does not explicitly contrast with alternatives like get_person_profile or search_people. However, the detailed behavior (following 'Show all', skipping premium) provides implicit context for when this tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_companiesSearch CompaniesB
Read-only

Search for companies on LinkedIn.

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordsYesSearch keywords (e.g., "fintech", "anthropic", "electric vehicles")

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true and openWorldHint=true, but the description adds no additional behavioral context—it does not mention what the search returns (e.g., a list of matches, basic company info), pagination, rate limits, or how results relate to other tools. With annotations covering the safety and scope, the description contributes nothing beyond them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no redundancy or filler, making it maximally concise. Every word contributes to the core purpose, and it is appropriately sized for a simple search tool with one parameter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter), the presence of an output schema (so return format is covered), and annotations for read-only/open-world, the description is minimally adequate. However, it lacks any indication of what types of results to expect or how they relate to other endpoints, which could leave the agent without enough context to decide if this is the right search tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% because the single parameter 'keywords' has an adequate description with examples. The tool description does not add any extra meaning about the parameter beyond what the schema already provides, aligning with the baseline of 3 for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Search for companies on LinkedIn' clearly identifies the action (search) and resource (companies) within a specific platform, distinguishing it from sibling search tools like search_people or search_jobs. However, it does not explicitly mention any filtering or scope beyond the resource type, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives, such as get_company_profile for detailed company information or get_company_employees for employee lists. The description provides no context about use cases, prerequisites, or typical scenarios, leaving the agent to infer when this search is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_conversationsSearch ConversationsA

Search messages by keyword.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of search-result rows to enumerate as conversation references (1-50, default 20). Each enumeration selects the row in LinkedIn's UI and may mark it as read, so a low cap is preferable for noisy queries.
keywordsYesSearch keywords to filter conversations

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are minimal (only openWorldHint), so the limit parameter's note adds important context: each enumerated result selects a row in LinkedIn's UI and may mark it as read. This is a valuable behavioral disclosure beyond annotations. No contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. It is appropriately concise for a simple search tool and avoids redundancy with the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity tool with full schema coverage and an output schema, the combination of the terse description and the limit-parameter side-effect warning is sufficiently complete. It would benefit from explicit scoping (e.g., searches only the user's conversations) and sibling differentiation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline applies. The tool description adds little beyond the schema: 'keywords' is self-explanatory, and the detailed limit behavior is already part of the input schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Search') and resource ('messages'), and the tool name clarifies the target is conversations. It is distinguishable from sibling tools like search_people and search_posts by resource, but it doesn't explicitly mention that results are conversation references.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'Search messages by keyword'—use when you need to find conversations by keyword rather than listing all via get_inbox. However, no explicit when-to-use or alternative guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_jobsSearch JobsA
Read-only

Search for jobs on LinkedIn.

Returns job_ids that can be passed to get_job_details for full info.

ParametersJSON Schema
NameRequiredDescriptionDefault
sort_byNoSort results (date, relevance)
job_typeNoFilter by job type, comma-separated (full_time, part_time, contract, temporary, volunteer, internship, other)
keywordsYesSearch keywords (e.g., "software engineer", "data scientist")
locationNoOptional location filter (e.g., "San Francisco", "Remote")
max_pagesNoMaximum number of result pages to load (1-10, default 3)
work_typeNoFilter by work type, comma-separated (on_site, remote, hybrid)
easy_applyNoOnly show Easy Apply jobs (default false)
date_postedNoFilter by posting date (past_hour, past_24_hours, past_week, past_month)
experience_levelNoFilter by experience level, comma-separated (internship, entry, associate, mid_senior, director, executive)

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations include readOnlyHint: true and openWorldHint: true, indicating this is a read-only operation. The description adds minimal extra context about the returned job_ids being used for get_job_details, which is helpful. It doesn't contradict annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is brief, two sentences, and immediately states the core function. The second sentence provides a valuable integration note about get_job_details. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and annotations are present, the description is adequately complete for a search operation. The integration note about job_ids adds important context. Minor gap: could mention if results are paginated or any default sorting, but not critical.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all parameters. The description adds a helpful note about job_ids for get_job_details. The description mentions 'job_ids' but doesn't detail all parameters, which is acceptable since the schema covers everything else.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with 'Search for jobs on LinkedIn' which is a clear verb+resource. It distinguishes this tool from siblings by describing it simply. However, it could do more to differentiate from other search tools like search_people or search_posts, though the context of 'jobs' helps.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description doesn't explicitly state when to use this over alternatives, but the context of searching LinkedIn jobs is clear. It doesn't give exclusions or alternatives, but the sibling list shows search tools for other entities, making the usage intent somewhat implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_peopleSearch PeopleA
Read-only

Search for people on LinkedIn.

ParametersJSON Schema
NameRequiredDescriptionDefault
networkNoOptional connection-degree filter. Each element is one of "F" (1st-degree), "S" (2nd-degree), "O" (3rd-degree and beyond). Example: ["F"] to only return 1st-degree connections.
keywordsYesSearch keywords (e.g., "software engineer", "recruiter at Google")
locationNoOptional location filter (e.g., "New York", "Remote")
current_companyNoOptional current-employer filter. LinkedIn's currentCompany facet only filters on the numeric company URN id (e.g. "1115" for SAP); plain company names are accepted by the URL but ignored by LinkedIn and return the unfiltered result set. Look up a company's URN via get_company_profile -- it is exposed under references["about"]. For company-wide employee demographics (location/education/function breakdown) plus a slug-based lookup, use get_company_employees instead.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the description need not repeat those. The current_company parameter description adds significant behavioral transparency by disclosing that plain company names are ignored by LinkedIn and only numeric URNs work, which is valuable real-world behavior beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The main description is a single, direct sentence with no filler. The parameter descriptions are detailed but clearly structured, front-loading the required keyword parameter first. Every element earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema and annotations that cover the safety profile. The description is minimal but sufficient when combined with schema descriptions, which explain key filtering behaviors. Some overview of result characteristics is missing, but the output schema likely covers that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all parameters already have detailed descriptions. The main description adds no parameter semantics. The schema descriptions thoroughly explain network codes and the current_company URN requirement, meeting the baseline but not exceeding it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Search for people on LinkedIn' uses a specific verb and resource, clearly distinguishing it from sibling tools like search_companies and search_jobs. The scope is explicit, making the tool's purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The main description lacks explicit when-to-use guidance, but the current_company parameter description provides a concrete alternative: use get_company_employees for company-wide demographics and get_company_profile for URN lookup. This gives situational context, though overall usage guidance is limited to edge cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_postsSearch PostsA
Read-only

Search LinkedIn posts/content globally by keyword (the "Posts" tab).

Use this to catch informal hiring posts ("we're hiring", "Buscamos ...", "estamos contratando", "join our team") that often appear before a formal job listing exists. This is global content search, distinct from get_feed (your own home feed) and get_company_posts (one company's page).

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordsYesSearch keywords (e.g., "Buscamos Unity", "AI automation hiring")
max_pagesNoScroll depth as result "pages" of ~5 scrolls each (1-10, default 3). Content search is an infinite scroll, so this caps how far the page is scrolled rather than fetching discrete pages.
date_postedNoOptional recency filter. One of "past-24h", "past-week", "past-month"; the "past_24_hours" / "past_week" / "past_month" spellings used by search_jobs are accepted too. Omit for any time.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes beyond the readOnlyHint and openWorldHint annotations by explaining that content search is an infinite scroll and that max_pages caps the scroll depth rather than fetching discrete pages. This is critical operational behavior that the annotations alone would not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded with the core purpose in the first line, then expands with usage context and differentiations. Every sentence adds value—the hiring-use case example, the global vs. feed distinction, and the infinite-scroll caveat all earn their place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema, the description need not explain return values. The combination of description, annotations (read-only, open-world), and thorough schema (all parameters documented with defaults and constraints) covers everything an agent needs to decide when and how to use this tool correctly. Actual use-case guidance and behavioral details complete the picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, so the baseline is 3. The description adds value for keywords by providing example patterns ('Buscamos Unity', 'AI automation hiring') and clarifies the infinite-scroll semantics of max_pages. The date_posted parameter is fully documented in the schema with accepted spellings.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches LinkedIn posts/content globally by keyword, specifically the 'Posts' tab. It distinctly differentiates from siblings like get_feed (own home feed) and get_company_posts (one company's page), making it unambiguous what this tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains when to use this tool: to catch informal hiring posts that often precede formal job listings. It also provides clear exclusions by naming alternative tools (get_feed and get_company_posts) for different use cases, giving agents direct decision criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_messageSend MessageA
Destructive

Send a message to a LinkedIn user.

The recipient must be directly messageable from the profile page. This is a write operation when confirm_send is True.

ParametersJSON Schema
NameRequiredDescriptionDefault
messageYesThe message text to send
profile_urnNoOptional profile URN (e.g. ACoAAB...) to construct the compose URL directly. Providing this bypasses the Message-button lookup and is more reliable when available. Obtain via get_person_profile. Note: inbox may not always show all messages; use search_conversations as a fallback.
confirm_sendYesMust be True to send the message
linkedin_usernameYesLinkedIn username of the recipient

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (destructiveHint and openWorldHint), the description clarifies that the write happens only when confirm_send is True, which is a safeguard. It also adds the requirement for direct messageability. This extra context helps the agent understand the tool's behavior without relying solely on annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: two sentences that immediately state the purpose and key constraint. It front-loads the core function and avoids unnecessary elaboration, making it easy for an agent to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a write operation, the description covers the essential behavioral prerequisites (messageability, confirm_send flag) and relies on the schema for parameter details. It does not mention authentication or output, but those are supplied by annotations and the presence of an output schema. The description is adequate for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides complete descriptions for all four parameters (100% coverage), so the tool description does not need to repeat them. It does not add any additional meaning beyond what the schema gives, which is the baseline expectation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (send) and target (a LinkedIn user), with an important qualifier about direct messageability from the profile page. This establishes the tool's core purpose and differentiates it from read-only LinkedIn tools by explicitly labeling it a write operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a prerequisite (the recipient must be directly messageable) and notes that the send only occurs when confirm_send is True, implicitly advising caution. However, it does not mention when to choose this tool over alternatives like connecting first or using the inbox, so guidance on context and exclusions is limited.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 19 tool updatesv4.22.0
    • First observedclose_session
    • First observedconnect_with_person
    • First observedget_company_employees
    • First observedget_company_posts
    • First observedget_company_profile
    • First observedget_conversation
    • First observedget_feed
    • First observedget_inbox
    • First observedget_job_details
    • First observedget_my_profile
    • First observedget_person_profile
    • First observedget_saved_jobs
    • First observedget_sidebar_profiles
    • First observedsearch_companies
    • First observedsearch_conversations
    • First observedsearch_jobs
    • First observedsearch_people
    • First observedsearch_posts
    • First observedsend_message

TDQS

A3.8/5.0
Disambiguation5/5

Each tool targets a distinct LinkedIn resource or action: people, companies, jobs, posts, conversations, profile, saved jobs, and feed. Even potentially overlapping tools like get_company_employees, search_people, search_posts, get_feed, and get_company_posts include explicit descriptions that clarify the differences.

Naming Consistency4/5

The tools mostly follow a clear get_<resource> or search_<resource> convention using snake_case, making the set predictable. The main exceptions are connect_with_person, send_message, and close_session, which are still easily readable but break the predominant get_/search_ pattern.

Tool Count4/5

With 19 tools, the server is on the higher side of the ideal range, but the count is justified by the breadth of LinkedIn data exposed: people, companies, jobs, posts, messaging, and profile discovery. Each tool has a clearly separate purpose, so the larger surface does not feel padded.

Completeness4/5

Core workflows are well covered: search for people or companies, view profiles, inspect jobs via search or saved jobs, and read or send messages. Minor gaps exist, such as no post interaction, no job application, and no broader profile editing, but these do not break the main LinkedIn research and outreach use cases.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

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/abetoluwani/linkedin-mcp-server'

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