mcp-server-linkedin
An MCP server that drives your own logged-in LinkedIn browser session so an AI assistant can read data and take actions on LinkedIn locally.
Profiles — read your own or another member's profile with optional extra sections (experience, education, skills, certifications, projects, contact info, posts); search people by keyword, location, connection degree, or company; get sidebar recommendations; follow/unfollow a member; update your headline and About.
Companies — read company profiles (about, posts, jobs), search companies, list employees with location/education/function demographics, fetch recent company posts, follow/unfollow a company page.
Messaging — list inbox conversations, read a thread by username or thread ID, keyword-search conversations, and send a message (with confirmation).
Connections — send or accept connection requests with an optional note, list pending invitations, accept/decline/withdraw invitations.
Jobs — search postings with filters (location, job type, work type, experience level, date posted, Easy Apply), get job details and the employer's apply link, list saved jobs, save/unsave, and start an application.
Posts & feed — read your home feed, search posts globally with recency filters, read a post's reaction summary, create text or image posts (with dry run), delete posts, react, comment, and reply to comments.
Notifications — list LinkedIn notifications and mark them all as read.
Settings — list settings sections, read settings rows, and change setting values.
Session & debug — close the browser session, dump visible profile controls, and remove a skill (debug tool).
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-server-linkedinlook up Jane Doe's LinkedIn profile and summarize her experience"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Server for LinkedIn
An MCP server that connects AI assistants like Claude to LinkedIn through your own logged-in browser session. Look up profiles and companies, send messages, manage your inbox, or search for jobs. All browser actions run locally on your machine.
This is an independent open-source project, not affiliated with, authorized by, endorsed by, or sponsored by LinkedIn or Microsoft. LinkedIn is a trademark of LinkedIn Corporation and is used here only to identify the service this software interacts with.
Prefer not to run a server? Cadenza is the hosted LinkedIn MCP server for your agents, on web, desktop, and mobile, with 100+ actions across LinkedIn Classic, Sales Navigator, and Recruiter. You decide how many requests of each type it sends to your account per minute and per day.
Use code FOUNDING20 for 20% off your first year. Try Cadenza →
This MCP server is supported by Unipile. Unipile is the fully managed cloud option for developers: a hosted LinkedIn API for Classic, Sales Navigator, and Recruiter that handles auth, sessions, and infrastructure for you.
Installation Methods - LinkedIn MCP Server
Tool | Description |
| Read profile sections such as experience, education, skills, projects and posts. |
| Read your own profile using the same selectable sections. |
| Send or accept a connection request, with an optional note. |
| Find recommended profile links in a person's sidebar. |
| List recent messaging conversations from your LinkedIn inbox. |
| Read a conversation by username or thread ID. |
| Search messages by keyword across your conversations. |
| Send after confirmation. Targeting a profile may start a separate DM instead of replying in a thread (#483). |
| Read posts and jobs; about references can include a |
| Read recent posts published on a company's LinkedIn page. |
| Find LinkedIn company profiles matching a keyword search. |
| List company employees, optionally filtered by keyword. |
| Find LinkedIn job postings by keyword and location. |
| List the job postings you have saved on LinkedIn. |
| Search by keyword, location, connection degree or company. |
| Read the details of a LinkedIn job posting by its job ID. |
| Read how a posting takes applications and the employer's link. |
| Read recent home-feed posts, with links in |
| Search posts by keyword with optional recency filters; |
| Close the active browser session and release its resources. |
Related MCP server: LinkedIn Intelligence MCP Server
Setup with uvx (Recommended)
Prerequisites: Install uv.
Installation
Add to your MCP client's mcpServers configuration
{
"mcpServers": {
"mcp-server-linkedin": {
"command": "uvx",
"args": ["mcp-server-linkedin@latest"],
"env": { "UV_HTTP_TIMEOUT": "300" }
}
}
}The @latest tag turns on automatic updates, which keep the server working with LinkedIn's current page structure. The server starts quickly and prepares the shared Patchright Chromium browser cache in the background under ~/.linkedin-mcp/patchright-browsers. On the first tool call that needs authentication, it reuses a LinkedIn session from a signed-in local browser if it finds one, and otherwise opens a LinkedIn login browser window.
AI agent? Get a quick confirmation from the user before enabling automatic updates.
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.
Setup Help
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
stdioAn interactive terminal without explicit transport shows a chooser prompt
Session:
--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,coccoc,opera,opera_gx,auto). Bare flag picksauto, the most recently used browser with a live LinkedIn session.--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.--logout- Clear the stored session--login-viewer- Docker only: show the--loginbrowser at a token-protected URL on port 6080 (see Authentication)--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.
Transport:
--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)
Timeouts:
--timeout MS- Timeout for a single page operation (default: 5000)--tool-timeout SECONDS- Timeout for a whole tool call (default: 180). Raise it for calls that read many pages, 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-viewerends the session after 30 minutes either way.--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)
Shared browser:
--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)
Browser:
--no-headless- Show the browser window (useful for debugging)--chrome-path PATH- Path to a Chrome/Chromium executable--proxy-server URL- Route browser traffic through a proxy, asscheme://host:port. Set it up before--login; see Using a proxy.
Other:
--log-level {DEBUG,INFO,WARNING,ERROR}- Logging level (default: WARNING)
If you are already signed into LinkedIn in Chrome, Chromium, Brave, Edge, Arc, Vivaldi, Helium, Yandex, Naver Whale, Cốc Cốc, Opera, or Opera GX, 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 braveThis 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--logininstead.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 DEBUGHTTP Mode Example (for web-based MCP clients):
uvx mcp-server-linkedin@latest --transport streamable-http --host 127.0.0.1 --port 8080 --path /mcpRuntime 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:
Install and run mcp inspector
bunx @modelcontextprotocol/inspectorClick pre-filled token url to open the inspector in your browser
Select
Streamable HTTPasTransport TypeSet
URLtohttp://localhost:8080/mcpConnect
Test tools
Ensure you have uv installed:
curl -LsSf https://astral.sh/uv/install.sh | shCheck uv version:
uv --version(should be 0.4.0 or higher)On first run,
uvxdownloads all Python dependencies. On slow connections, uv's default 30s HTTP timeout may be too short. The recommended config above already setsUV_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 freshuvxrun resolves that on its own; an environment that pins its dependencies needsuv lock --upgrade-package greenlet. Only greenlet 3.3.1 through 3.5.4 needMSVCP140.dll, which neither the python.org installer nor theuv-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.
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.
uvxkeeps 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
LinkedIn may require a login confirmation in the LinkedIn mobile app for
--loginLinkedIn may show a captcha challenge during login. Run
uvx mcp-server-linkedin@latest --loginwhich opens a browser where you can solve it manually.
Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout:
--timeout 10000orTIMEOUT=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 300orTOOL_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 toLOGIN_INLINE_WAITseconds (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-viewercommand.Users on slow connections may need higher values for either.
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=falseto override the detection;trueforces the opposite.
If Chrome is installed in a non-standard location, use
--chrome-path /path/to/chromeCan also set via environment variable:
CHROME_PATH=/path/to/chromeOn 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.--logoutalso 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_PATHat one turns the check off rather than producing a refusal nothing could satisfy.
Claude Desktop MCP Bundle (formerly DXT)
Prerequisites: Claude Desktop.
Installation
Download the latest
.mcpbartifact from releasesClick the downloaded
.mcpbfile to install it into Claude DesktopCall any LinkedIn tool
On startup, the MCP Bundle prepares the shared Patchright Chromium browser cache in the background. On the first tool call that needs authentication, the server reuses a LinkedIn session from a signed-in local browser if it finds one, and otherwise opens a LinkedIn login browser window.
Early tool calls may return a setup/authentication-in-progress error until browser setup or login finishes. Retry the tool call once the browser download or sign-in completes.
Setup Help
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 needsMSVCP140.dllfrom that redistributable, which neither the python.org installer nor theuv-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.
Make sure you have only one active LinkedIn session at a time
LinkedIn may require a login confirmation in the LinkedIn mobile app for
--loginLinkedIn may show a captcha challenge during login. Run
uvx mcp-server-linkedin@latest --loginwhich opens a browser where you can solve captchas manually. See the uvx setup for prerequisites.
Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout:
--timeout 10000orTIMEOUT=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 300orTOOL_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 toLOGIN_INLINE_WAITseconds (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-viewercommand.Users on slow connections may need higher values for either.
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=falseto override the detection;trueforces the opposite.
Codex Plugin
Installation
Run in a terminal
codex plugin marketplace add stickerdaniel/linkedin-mcp-server
codex plugin add linkedin-mcp-server@linkedin-mcp-serverThe plugin pins a server release, and Codex picks up each new one in the background when it starts. On the first tool call that needs authentication, the server reuses a LinkedIn session from a signed-in local browser or opens a login window.
Early tool calls may return a setup/authentication-in-progress error until browser setup or login finishes. Retry the tool call once the browser download or sign-in completes.
Setup with Docker
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.
macOS / Linux:
# 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 \
stickerdaniel/linkedin-mcp-server:latest \
--login --login-viewerPowerShell (Windows):
$sessionDir = Join-Path $env:USERPROFILE ".linkedin-mcp"
New-Item -ItemType Directory -Force -Path $sessionDir | Out-Null
docker run -it --rm `
-v "${sessionDir}:/home/pwuser/.linkedin-mcp" `
-p 127.0.0.1:6080:6080 `
stickerdaniel/linkedin-mcp-server:latest `
--login --login-viewerOpen 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 same host directory mounted at /home/pwuser/.linkedin-mcp on every later docker run, otherwise the server cannot find the session.
Add to your MCP client's mcpServers configuration
macOS / Linux (absolute path in JSON):
{
"mcpServers": {
"mcp-server-linkedin": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "/absolute/path/to/.linkedin-mcp:/home/pwuser/.linkedin-mcp",
"stickerdaniel/linkedin-mcp-server:latest"
]
}
}
}Spell that first path out in full. A client runs docker directly rather than through a shell, so a leading ~ reaches Docker unexpanded and it refuses the mount.
PowerShell (Windows): use a forward-slash JSON path. A backslash path like
C:\Users\Alice\.linkedin-mcp fails JSON parsing because \U is an invalid
escape. Use C:/Users/Alice/.linkedin-mcp instead, replacing Alice with your
username.
{
"mcpServers": {
"mcp-server-linkedin": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "C:/Users/Alice/.linkedin-mcp:/home/pwuser/.linkedin-mcp",
"stickerdaniel/linkedin-mcp-server:latest"
]
}
}
}In PowerShell,~ is not expanded inside a composite Docker -v argument.
Use C:/Users/<you>/.linkedin-mcp or build the path with
$env:USERPROFILE\.linkedin-mcp before passing it to Docker.
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.
Setup Help
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
stdioAn interactive terminal without explicit transport shows a chooser prompt
Session:
--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.--logout- Clear the stored session and every profile derived from it--login-viewer- With--login, show the login browser at a token-protected URL on port 6080. Needs the profile mount from Authentication.--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.
Transport:
--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)
Timeouts:
--timeout MS- Timeout for a single page operation (default: 5000)--tool-timeout SECONDS- Timeout for a whole tool call (default: 180). Raise it for calls that read many pages, 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-viewerends the session after 30 minutes either way.--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)
Shared browser:
--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)
Browser:
--chrome-path PATH- Path to a Chrome/Chromium executable (rarely needed in Docker)--proxy-server URL- Route browser traffic through a proxy, asscheme://host:port. Set it up before--login; see Using a proxy.
Other:
--log-level {DEBUG,INFO,WARNING,ERROR}- Logging level (default: WARNING)
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):
Bash / macOS / Linux:
docker run -it --rm \
-v ~/.linkedin-mcp:/home/pwuser/.linkedin-mcp \
-p 127.0.0.1:8080:8080 \
stickerdaniel/linkedin-mcp-server:latest \
--transport streamable-http --host 0.0.0.0 --port 8080 --path /mcpPowerShell (Windows):
$sessionDir = Join-Path $env:USERPROFILE ".linkedin-mcp"
docker run -it --rm `
-v "${sessionDir}:/home/pwuser/.linkedin-mcp" `
-p 127.0.0.1:8080:8080 `
stickerdaniel/linkedin-mcp-server:latest `
--transport streamable-http --host 0.0.0.0 --port 8080 --path /mcpBoth 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:
Install and run mcp inspector
bunx @modelcontextprotocol/inspectorClick pre-filled token url to open the inspector in your browser
Select
Streamable HTTPasTransport TypeSet
URLtohttp://localhost:8080/mcpConnect
Test tools
Make sure Docker is installed
Check if Docker is running:
docker psPermission errors on
~/.linkedin-mcp: an older rootful Docker run may have created the directory as root. Fix it withsudo chown -R "$(id -u):$(id -g)" ~/.linkedin-mcp.
Make sure you have only one active LinkedIn session at a time
LinkedIn may require a login confirmation in the LinkedIn mobile app for
--loginLinkedIn may show a captcha challenge during login. Run
uvx mcp-server-linkedin@latest --loginwhich 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.
Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout:
--timeout 10000orTIMEOUT=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 300orTOOL_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 toLOGIN_INLINE_WAITseconds (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-viewercommand.Users on slow connections may need higher values for either.
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=falseto override the detection;trueforces the opposite.
If Chrome is installed in a non-standard location, use
--chrome-path /path/to/chromeCan also set via environment variable:
CHROME_PATH=/path/to/chromeOn 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.--logoutalso 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_PATHat 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. WithEXPERIMENTAL_PERSIST_DERIVED_RUNTIMEthe 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--loginitself, which moves the old profile aside before it starts a browser and so can never trip it.
Using a proxy
Swiftproxy offers residential proxies with sticky sessions and worldwide geo-targeting. Its dedicated static ISP options include networks such as AT&T, Sky UK, and Rogers, with unlimited traffic and renewable addresses.
Use code PROXY90 for 10% off Try Swiftproxy →
RapidProxy offers 90M+ residential IPs worldwide for LinkedIn automation and browser workflows, with sticky sessions, geo-targeting, and high-concurrency support. Plans start at $0.55/GB with non-expiring traffic.
Use code RAPID10 for 10% off Try RapidProxy for free →
LinkedIn scores the address a session signs in from. Your account's usual IP address is the safe one. You should use a proxy in your country when the server cannot use it: a VPS, another country, or a second account that must not share the first one's address.
With a paid provider, use a sticky residential session that holds one address (never per-request rotation). A WireGuard full tunnel or Tailscale exit node on your home network works when the server should use your usual home address.
Setup Help
Set the proxy up before
--login. Moving an existing session to a new address triggers a LinkedIn checkpoint. That includes a session from--import-from-browser, which was created on your real address.--proxy-server scheme://host:portorPROXY_SERVER, withhttp,https,socks4orsocks5. Only browser traffic is routed, not the MCP transport.Pass credentials through
PROXY_USERNAMEandPROXY_PASSWORD, or include them inPROXY_SERVERusing the combinedhttp://user:pass@host:portform. The combined form is not accepted by the--proxy-serverCLI option.PROXY_BYPASS=localhost,127.0.0.1,::1reaches local targets directly. With a proxy set, Chromium routeslocalhostthrough it too.
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.A wrong proxy password shows up as a timeout or a failed sign-in, because Chromium retries the authentication challenge until the page times out. If sessions stop working right after you add a proxy, check the proxy credentials first.
Auto-import is skipped while a proxy is configured: the imported session would move from your real address to the proxy. Use
--login.Inside a container
127.0.0.1is the container itself, so a relay on the host ishost.docker.internal; native Linux Docker also needs--add-host=host.docker.internal:host-gateway.
Setup from Source (Develop & Contribute)
Contributions are welcome. See CONTRIBUTING.md for architecture guidelines and checklists. Search existing issues first, then use the issue forms for anything new. AI agents follow the issue-packet skill.
Prerequisites: Git and uv installed
Installation
Run in a terminal
# 1. Clone repository
git clone https://github.com/stickerdaniel/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_serverSetup Help
Session:
--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,coccoc,opera,opera_gx,auto). Bare flag picksauto, the most recently used browser with a live LinkedIn session.--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.--status- Check whether the stored session is valid, then exit--logout- Clear the stored session--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.
Transport:
--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)
Timeouts:
--timeout MS- Timeout for a single page operation (default: 5000)--tool-timeout SECONDS- Timeout for a whole tool call (default: 180). Raise it for calls that read many pages, 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-viewerends the session after 30 minutes either way.--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)
Shared browser:
--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)
Browser:
--no-headless- Show the browser window (useful for debugging)--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--installer-temp-dir PATH- Existing directory for browser installation temporary files (environment:INSTALLER_TEMP_DIR).--proxy-server URL- Route browser traffic through a proxy, asscheme://host:port. Set it up before--login; see Using a proxy.
Other:
--log-level {DEBUG,INFO,WARNING,ERROR}- Logging level (default: WARNING)--help- Show help
Note: Most CLI options have environment variable equivalents. See
.env.examplefor 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 /mcpClaude 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.
Make sure you have only one active LinkedIn session at a time
LinkedIn may require a login confirmation in the LinkedIn mobile app for
--loginLinkedIn may show a captcha challenge during login. The
--logincommand opens a browser where you can solve it manually.
Use
--no-headlessto watch the browser when a tool returns wrong or missing dataAdd
--log-level DEBUGto see more detailed logging
Browser profile is stored at
~/.linkedin-mcp/profile/Managed browser downloads are cached at
~/.linkedin-mcp/patchright-browsers/, shared with theuvxand MCP Bundle installationsThe browser cache keeps growing: Patchright keeps an old Chromium revision for as long as any installed version still references it, and a
uvarchive 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
--logoutto clear the profile and start fresh
Check Python version:
python --version(should be 3.12.4+)Reinstall Patchright:
uv run patchright install chromiumReinstall dependencies:
uv sync --reinstall
Page operations failing (elements not found, navigation hangs): increase the browser page-op timeout:
--timeout 10000orTIMEOUT=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 300orTOOL_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 toLOGIN_INLINE_WAITseconds (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-viewercommand.Users on slow connections may need higher values for either.
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=falseto override the detection;trueforces the opposite.
If Chrome is installed in a non-standard location, use
--chrome-path /path/to/chromeCan also set via environment variable:
CHROME_PATH=/path/to/chromeOn 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.--logoutalso 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_PATHat one turns the check off rather than producing a refusal nothing could satisfy.
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.
Contributors
Thanks to everyone who has contributed code, bug reports and fixes.
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.
Building on this project is welcome! See the license for terms and the NOTICE for attribution.
Available Tools
47 toolsaccept_invitationAccept InvitationADestructive
Accept a pending connection invitation by the sender's name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Sender display name as shown in the invitation row. | |
| dry_run | No | When True, locate the control but do not click. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the agent knows this mutates state. The description adds only the name-based lookup detail; it says nothing about irreversibility, whether a connection is created, permissions, or why dry_run exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the required key is stated immediately after the action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described, and annotations carry the safety profile. However, for an irreversible state-changing action the description leaves the consequence of accepting entirely unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both the name lookup semantics and dry_run behavior are already fully documented in the schema. The description restates the name key but adds no format or edge-case detail beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource (accept a pending connection invitation) with the identifying key stated (sender's name). An agent can immediately separate it from decline_invitation, withdraw_connection_request, and list_pending_invitations by the verb alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The word 'pending' implies the prerequisite that the invitation must already exist and be outstanding, but there is no explicit guidance on when to choose this over decline_invitation or withdraw_connection_request, and no mention of first locating the invitation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
apply_to_jobApply To JobBDestructive
Start the application flow for a LinkedIn job posting.
| Name | Required | Description | Default |
|---|---|---|---|
| job_url | Yes | Full URL of the job posting. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare openWorldHint=true and destructiveHint=true, covering the safety profile. The description adds that this kicks off an application flow, but does not clarify whether it actually submits, whether the action is reversible, or what authentication/redirect behavior follows — meaningful gaps for a destructive, open-world tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler or repetition. It is efficient, though the terseness borders on under-specification for a destructive action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be described, and annotations cover the safety profile. However, for a one-click destructive application action, the description should clarify what actually happens (submission vs. navigation) — a notable gap given the stakes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter (job_url) and schema description coverage is 100%, so the schema fully documents it. The description adds no format or sourcing details, which is the expected baseline when the schema does the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('start') and resource ('application flow for a LinkedIn job posting'), which distinguishes it from read-only siblings like get_job_details, get_job_apply_url, and save_job. It stops short of 5 because 'start the application flow' leaves ambiguity about whether an application is actually submitted or merely a flow is opened.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 versus alternatives such as get_job_apply_url, get_job_details, or save_job, and no prerequisites (login state, prior job retrieval) are stated. The agent must infer the calling context entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
close_sessionClose SessionADestructive
Close the current browser session and clean up resources.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The destructiveHint annotation already signals this is a destructive action, and the description confirms it by saying 'Close' and 'clean up resources'. It adds some scope detail ('current browser session') but does not describe side effects such as invalidating cookies, logging out the user, or making the session unusable. Since the annotations carry much of the safety signal, a mid-range score 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The entire description is a single, front-loaded sentence with no redundant words. It states the action and consequence efficiently, earning a top score for conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, destructive tool with an output schema and annotation coverage, the description is complete enough for an agent to know what will happen. The absence of an alternative, zero parameters, and existing destructiveHint mean no additional operational context is essential.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema is empty with 100% coverage, so there are no parameter semantics for the description to clarify. With no params, the baseline is 4, and the description does not need to add parameter-level explanation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Close') and names the resource ('current browser session') plus a clear secondary purpose ('clean up resources'). It is well-distinguished from all sibling tools, which focus on profiles, searches, messaging, and feed actions, not session lifecycle.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context that this tool ends the current browser session, implying it should be used when the session is no longer needed. There are no sibling tools providing an alternative session-close action, so explicit exclusions are unnecessary. A fully explicit 'use this when you are done' statement would improve clarity, but the context is already strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
comment_on_postComment On PostCDestructive
Add a comment to a LinkedIn post.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Comment body text. | |
| dry_run | No | When True, fill the comment but do not submit. | |
| post_url | Yes | Full URL of the post. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the bar is lower, but the description adds nothing beyond them. It omits that comments are publicly visible and persistent, and it never explains the dry_run preview behavior even though the schema exposes that flag.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero wasted words. It is efficient, though arguably too terse to carry much value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained, but for a public, annotation-flagged write action the description is too thin: no authentication requirements, no visibility/permanence notes, no mention of dry_run semantics beyond the flag name, and no failure behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so post_url, text, and dry_run are already documented in the schema; this is the baseline case. The description adds no syntax, formatting, or length constraints beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Add) and resource (comment on a LinkedIn post) in one clear sentence. However, it offers no differentiation from the sibling tool reply_to_comment, which an agent could easily confuse with this one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 reply_to_comment or react_to_post, and no mention of prerequisites such as being connected to the poster or needing an authenticated session. The agent must infer all usage context from the tool name alone.
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 PersonADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | Optional note to include with the invitation | |
| linkedin_username | Yes | LinkedIn username (e.g., "stickerdaniel", "williamhgates"). A full profile URL is accepted too and is reduced to the username. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description mostly restates the destructiveHint annotation by saying MCP clients will prompt for confirmation. It does not add meaningful behavioral context beyond that, such as irreversibility, notification to the recipient, authentication requirements, or rate-limit implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded with the primary action. The second sentence about destructiveHint is slightly redundant with the annotations, but it communicates the user-confirmation behavior clearly and does not add much bulk.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With two well-documented parameters and an output schema present, the description is mostly sufficient for invoking the tool correctly. It lacks explicit guidance on when to accept versus send, or on side effects, but these are not critical given the schema and annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameter docs already explain linkedin_username and note in detail. The description adds no additional parameter-level meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action: send or accept a LinkedIn connection request. It names the exact resource and distinguishes it from sibling tools like send_message or search_people.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes it clear this tool handles connection requests and acceptances, which provides usable context for when to choose it. It does not explicitly name alternatives or exclusions, but the action is specific enough to avoid major ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_postCreate PostBDestructive
Create a new text post on LinkedIn.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The post body text. | |
| dry_run | No | When True, compose the post but do not publish. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the write-to-external-service profile is partly covered. The description adds nothing beyond that: it doesn't say the post publishes publicly under the authenticated account, whether authentication is required, or what observable effect the call has. The only marginal addition is that it is text-only.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the action front-loaded and zero filler. Nothing is padded or redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and the parameters are fully described, so the description needn't cover return values. What is missing is the contrast with create_post_with_image and any note about the public/persistent nature of a published post, which matter for a mutation tool with destructiveHint=true.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both 'text' and 'dry_run' are already fully documented in the schema, including dry_run's compose-without-publishing behavior. The description's 'text post' phrasing adds no syntax, length, or formatting meaning beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Create a new text post on LinkedIn'), which is clear on its own. However, it does not distinguish itself from the sibling create_post_with_image, so an agent must infer the boundary between the text-only and image variants.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no prerequisites, and no mention of the obvious alternative (create_post_with_image) for posts that include media. The agent gets no routing help at all.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_post_with_imageCreate Post With ImageCDestructive
Create a new LinkedIn post with an attached image.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The post body text. | |
| dry_run | No | When True, compose the post but do not publish. | |
| image_path | Yes | Local path to the image file to attach. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the agent knows this publishes to an external network. The description adds nothing beyond that: it does not say the post is immediately live and publicly visible, whether it is reversible, what auth/scopes are required, or that dry_run exists as a safe preview path.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the action front-loaded and no filler. It is efficient, though arguably too terse for a tool that publishes externally.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the simple three-parameter schema is fully documented. Still, for an externally-publishing mutation the description omits any note about the dry_run preview, visibility of the published post, or failure modes (bad path, oversized image).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and all three parameters (text, image_path, dry_run) are documented in the schema, so the baseline of 3 applies. The description adds no format, size, or path-validity detail beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Create a new LinkedIn post') plus a distinguishing qualifier ('with an attached image') that separates it from the sibling create_post. It does not, however, explicitly name create_post as the text-only alternative, leaving that inference to the agent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use, when-not-to-use, or alternative guidance. Nothing tells the agent to pick this over create_post for text-only posts, and the built-in dry_run escape hatch for previewing is never mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
debug_profile_controlsDebug Profile ControlsCRead-only
Dump visible button/link controls on a profile page.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | https://www.linkedin.com/in/me/ | |
| after_click_aria_label | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds only 'visible' controls on a 'profile page' — it does not explain what the after-click behavior does, whether it navigates or mutates the page, or any rate/session constraints for a debug probe.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with no filler and the resource front-loaded. It is not overly long, though its brevity comes at the cost of the missing detail noted elsewhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. However, for a two-parameter diagnostic tool with zero schema documentation and a cryptic after_click_aria_label, the description leaves the agent without enough to call it correctly or know why it exists relative to its many siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description explains neither parameter. The 'url' param could be inferred from 'profile page', but 'after_click_aria_label' is completely opaque — the description does not say it selects a control to click before dumping, which is exactly the kind of meaning this description needed to supply.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Dump visible button/link controls on a profile page.' That is enough to distinguish it from the action-oriented siblings (create_post, follow_person, get_person_profile), though it never explicitly frames itself as a debugging/diagnostic tool despite the name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No indication of when an agent should reach for this tool rather than get_person_profile, get_my_profile, or the other profile-related siblings, and no mention of what conditions make dumping controls useful. The presence of after_click_aria_label hints at an interaction flow, but that hint is never explained.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
decline_invitationDecline InvitationADestructive
Decline (ignore) a pending connection invitation by sender name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Sender display name as shown in the invitation row. | |
| dry_run | No | When True, locate the control but do not click. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the safety profile is covered. The description adds only the '(ignore)' semantic gloss and says nothing about irreversibility, sender notification, or side effects beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence, front-loaded with the action verb and scoped by 'pending' and 'by sender name'. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and full parameter coverage, the description need not explain return values or argument formats. It states purpose and target clearly; only the destructive/irreversible nature of the action could have used a note, but annotations already flag it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the name and dry_run parameters are fully documented in the schema itself. The description's 'by sender name' merely echoes the name parameter and does not mention dry_run. Baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb (decline) plus resource (pending connection invitation) and even disambiguates the verb with '(ignore)'. That makes it clearly distinct from siblings like accept_invitation and withdraw_connection_request, though it never names those alternatives explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: it tells the agent to decline a pending invitation by sender name but never states when to choose this over accept_invitation or withdraw_connection_request, nor any prerequisites. Adequate for a self-explanatory verb but no explicit routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_postDelete PostCDestructive
Delete one of your LinkedIn posts.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | When True, navigate to the delete confirmation but do not confirm. | |
| post_url | Yes | Full URL of the post (e.g. /feed/update/urn:li:...). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond that – it does not warn of irreversibility, does not mention the dry_run option that the schema exposes, and offers no confirmation/rollback context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no wasted words. It is efficient, though its brevity borders on under-specification for a destructive operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema and annotations exist, so return values and safety are covered externally. However, for an irreversible delete the description omits any mention of the dry_run safeguard or expected effects, leaving a meaningful gap for an agent deciding how to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both post_url and dry_run are already documented in the schema. The description contributes no additional parameter meaning, which matches the baseline 3 when the schema carries the load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Delete one of your LinkedIn posts'), which clearly separates it from create_post and other post-related siblings. It stops short of naming any sibling or scoping nuance explicitly, but the action is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of alternatives, and no indication of when the dry_run safety path should be preferred. The phrase 'your LinkedIn posts' implies an ownership scope but gives no actionable selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
follow_companyFollow CompanyCDestructive
Follow a LinkedIn company page.
| Name | Required | Description | Default |
|---|---|---|---|
| company_slug | Yes | LinkedIn company URL slug (e.g. "acme-corp"). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare openWorldHint and destructiveHint=true, so the safety profile is technically covered. The description adds nothing beyond that — it doesn't explain the effect of following (notifications, feed changes), idempotency, or whether the action is reversible, and it offers no help interpreting the unusual destructiveHint on a follow action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence with zero waste, front-loading the verb and resource. The brevity is appropriate structurally, though it reads as under-specification rather than disciplined conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. For a mutation tool with siblings that invert the action, though, the definition is thin: no prerequisites (e.g. being logged in, page visibility) and no note on reversibility or side effects, leaving the agent to infer behavior from annotations alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With a single parameter at 100% schema description coverage, the schema already documents that company_slug is a LinkedIn URL slug with an example. The description adds no further naming, format, or resolution details, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Follow) and resource (a LinkedIn company page), which is clear and unambiguous on its own. However, it does nothing to distinguish itself from the very similar siblings follow_person and unfollow_company, which an agent must choose between.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 follow_person, unfollow_company, or get_company_profile. The agent gets no criteria, prerequisites, or exclusions — only the bare action.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
follow_personFollow PersonCDestructive
Follow a LinkedIn member.
| Name | Required | Description | Default |
|---|---|---|---|
| linkedin_username | Yes | LinkedIn username (e.g. "alice"). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the safety profile is covered externally. The description adds nothing beyond that: no mention of side effects (notifications to the target), idempotency, auth requirements, or rate limits for a state-changing action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence, front-loaded with the verb and resource, with zero filler. It is efficient, though its brevity is arguably under-specification rather than true conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, but for a mutation tool with destructiveHint=true the description is far too thin: it omits usage routing among siblings, side effects, and any failure/repeat-call behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter, and schema coverage is 100% ('LinkedIn username (e.g. "alice")'), so the schema fully documents the input. The description adds no meaning beyond it, which is the baseline-3 case when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Follow') and resource ('LinkedIn member'), so the core action is unambiguous. However, it does not distinguish itself from close siblings like connect_with_person or follow_company, which an agent must disambiguate by name alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance at all. The description never explains how following differs from connecting (connect_with_person) or following a company (follow_company), nor when following is appropriate versus sending an invitation.
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 EmployeesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | No | Optional filter by name, job title, or skill (e.g., "engineer", "sales") | |
| company_name | Yes | LinkedIn company URL slug (e.g., "docker", "anthropicresearch", "microsoft"). A full company URL is accepted too and is reduced to the slug. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the description does not need to restate safety. It adds meaningful behavioral context: the data comes from the /people/ page, demographics are unique to this view, and the company_name must be the exact URL slug, not the display name, with a concrete example. This goes beyond annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but every sentence earns its place: core purpose first, then usage routing, then keyword semantics, then the critical slug caveat. The Anthropic example is concrete and high-value, not filler. Structure is logical and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, annotations cover safety, and the description covers purpose, routing, param semantics, and a caveat with an example, the definition is complete for an agent to select and invoke the tool correctly. No critical gap is evident.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds substantial semantic value beyond the schema. It clarifies that company_name must be the exact LinkedIn URL slug, warns that display names often differ, gives the Anthropic example, and tells the agent to resolve ambiguity via search_companies. This is exactly the kind of parameter nuance that prevents incorrect calls.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'List employees at a company from the LinkedIn /people/ page' and uniquely identifies its value-add: the demographics aggregate (location, education, function breakdown). It distinguishes itself from siblings by noting these demographics are unique to this tool, so an agent can immediately tell it apart from search_people or get_company_profile.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is provided for when to use this tool vs alternatives: for filtered search by network degree or location, prefer search_people with current_company set. It even notes search_people returns more result pages, and instructs the agent to call search_companies first if the slug is uncertain. This is strong, actionable routing guidance.
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 PostsCRead-only
Get recent posts from a company's LinkedIn feed.
| Name | Required | Description | Default |
|---|---|---|---|
| max_scrolls | No | Maximum scroll-to-bottom iterations to load more posts. Default (None) uses 10. Increase to read further back in the feed. | |
| company_name | Yes | LinkedIn company name (e.g., "docker", "anthropic", "microsoft"). A full company URL is accepted too and is reduced to the slug. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds only the vague word 'recent' and says nothing about needing an active session (implied by the close_session sibling), how far back the feed is read, or how results are ordered — despite a scroll-budget parameter existing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with no wasted words and the resource front-loaded. It is efficient, though its brevity is closer to under-specification than to optimal information density.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. However, for a session-based scraping tool the description omits the prerequisites (active session) and the sibling-routing context an agent needs, leaving it only minimally viable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%: company_name and max_scrolls are both fully documented in the schema, including the default of 10 scrolls and URL-to-slug reduction. The description adds no parameter meaning beyond that, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get recent posts') and scopes it to 'a company's LinkedIn feed', which implicitly separates it from the personal-feed and search siblings. It does not, however, name get_feed or search_posts explicitly, so the differentiation must be inferred.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use guidance at all. With siblings get_feed and search_posts present, an agent is left to guess whether this is the right tool for reading a company's activity versus searching or reading its own feed.
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 ProfileCRead-only
Get a specific company's LinkedIn profile.
| Name | Required | Description | Default |
|---|---|---|---|
| sections | No | Comma-separated list of extra sections to read. The about page is always included. Available sections: posts, jobs Examples: "posts", "posts,jobs" Default (None) reads only the about page. | |
| company_name | Yes | LinkedIn company name (e.g., "docker", "anthropic", "microsoft"). A full company URL is accepted too and is reduced to the slug. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond that: it doesn't note authentication/scope requirements, rate limits, or the fact that requesting `sections` changes cost/behavior. With annotations present the bar is lower, but this description contributes essentially no extra behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero waste. It is appropriately sized, though its brevity comes at the cost of substance rather than being maximally informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Annotations and an output schema carry the return-value and safety burden, so much is delegated. However, for a tool with multiple overlapping company siblings, the description is too thin to help an agent route correctly, leaving a real gap in sibling differentiation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already fully documented in the schema, including the `sections` enum-like values and default. The description adds no syntax or format detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (get) and resource (a company's LinkedIn profile), making the core action unambiguous. It distinguishes the target as a company rather than a person, but does not differentiate from close siblings like get_company_posts, get_company_employees, or search_companies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 search_companies or get_company_employees. No prerequisites, no exclusions, and no mention of when the extra `sections` should be requested are provided.
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.
Username resolution scans matching rows from a requested compose page first. Its indexable sequence ends before the first unresolved click, missing matching click target, or admitted row that fails the existing exact display-name check. An index outside that verified prefix is refused with its reason. Search is a fallback only when the inbox scan has no observed matching result and no such barrier; it never substitutes a result after a stopped or gapped inbox scan. Pass a known thread_id to bypass username/index resolution.
| Name | Required | Description | Default |
|---|---|---|---|
| index | No | 0-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_id | No | LinkedIn messaging thread ID | |
| linkedin_username | No | LinkedIn username of the conversation participant; a full profile URL is accepted too |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only openWorldHint in annotations, the description carries the behavioral burden and does so well: it discloses that username resolution click-visits each row and 'may mark it as read' (a real side effect), describes the indexable-prefix limits, the refusal behavior for out-of-prefix indexes, and that search is only a fallback. This is exactly the kind of non-obvious operational context structured fields cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the two lookup paths are front-loaded, which is good, but the middle paragraphs are dense and hard to parse (e.g. 'indexable sequence ends before the first unresolved click, missing matching click target, or admitted row'), and the LinkedIn-sidebar implementation rationale is arguably more internal detail than an agent needs. It is informative but not tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described, and the description still covers resolution paths, side effects, failure/refusal conditions, and fallback ordering. For a 3-param read tool with light annotations, nothing material an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning: it explains the index resolution semantics, the prefix barrier that causes an index to be refused, and that a known thread_id bypasses resolution entirely. This goes beyond the schema's terse per-field notes.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read a specific messaging conversation') and immediately specifies the two identification paths, which cleanly separates it from get_inbox (list) and search_conversations (search). It does not name those siblings explicitly, so the differentiation is implied rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete guidance on when to use linkedin_username vs thread_id ('Pass thread_id directly to skip this enumeration') and points to search_conversations for enumerating thread IDs. It stops short of an explicit when-not-to-use or a direct contrast with get_inbox, so it is clear context without full routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_feedGet FeedARead-only
Get posts from the authenticated user's LinkedIn feed.
| Name | Required | Description | Default |
|---|---|---|---|
| num_posts | No | Number 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
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description does not disclose behavioral traits beyond the annotations: it only says 'Get posts', which is consistent with readOnlyHint=true but adds no new behavioral context. Notable behavior like batched loading and count overshooting appears only in the schema property description, not in the tool description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with no filler, front-loading the action and resource. It is concise without sacrificing clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only feed fetch with one optional parameter and an output schema, the description plus schema provide all necessary information. The feed scope is clear, and nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with the num_posts parameter fully documented including default, range, and batch behavior. The tool description itself adds no parameter detail, but the schema already carries the full semantic burden, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb 'Get' and a specific resource 'posts from the authenticated user's LinkedIn feed', which clearly distinguishes it from sibling tools like get_company_posts and search_posts. The phrase 'authenticated user' pins the scope unambiguously.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use — fetching the current user's LinkedIn feed — is reasonably implied by the description, but there is no explicit guidance about when to choose this over alternative tools such as search_posts or get_company_posts. No exclusions or routing hints are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_inboxGet InboxCRead-only
List recent conversations from the LinkedIn messaging inbox.
The returned inbox text and result URL come from the ordinary messaging inbox. Click-derived conversation references are collected separately after requesting the compose page, which avoided inbox auto-opening on the measured variant. A row contributes a click-derived reference only after its click is followed by an observed different thread path. The scan stops at its first unverifiable click. section_errors.inbox reports that stop or unavailable scan rows; captured inbox text and independently extracted anchors retain their normal handling. A known thread_id can bypass row attribution when calling get_conversation.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of conversations to load (1-50, default 20) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description does add behavioral context (scan can stop, section_errors.inbox reports that stop, captured text is retained), but it is buried in scraped-page implementation jargon rather than stated as caller-relevant behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence is well front-loaded, but the remaining three-to-four sentences dwell on internal scraping mechanics (compose page, measured variant, click-derived references, scan stopping) that a caller does not need. Significant bloat for a one-parameter read tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be spelled out, and for a single-parameter read tool the definition is more than long enough. However, it spends its length on implementation detail while omitting the one thing an agent needs: how this tool relates to search_conversations and get_conversation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (limit) exists and schema coverage is 100%, including range and default, so the schema carries the full burden. The description adds nothing about the limit semantics, matching the baseline for a fully documented schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a clear verb+resource ('List recent conversations from the LinkedIn messaging inbox'), so the agent immediately knows what the tool returns. It does not distinguish itself from the siblings search_conversations or get_conversation, which list/fetch similar data, 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this tool versus search_conversations or get_conversation. The only routing hint is an oblique trailing remark that 'a known thread_id can bypass row attribution when calling get_conversation,' which is not framed as guidance a caller can act on.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_job_apply_urlGet Job Apply URLARead-only
Get how a job posting takes applications, and the employer's application link.
Reads the posting without clicking anything.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | LinkedIn job ID (e.g., "4252026496", "3856789012") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds genuinely useful context beyond that: it clarifies the call inspects the posting without triggering any click/navigation or application flow, which tells the agent there are no side effects on the employer's page.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core purpose and followed by the behavioral qualifier. No filler or redundancy, though the second sentence is a minor stylistic flourish rather than essential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the single required parameter is fully documented in the schema. For a one-param read tool this is largely complete; only cross-tool routing guidance is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with a single job_id parameter, so the schema already carries the semantics. The description adds nothing about the identifier format or expected values, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (Get) and resource (how a job posting takes applications / the employer's application link), which is more precise than the bare title. It implicitly distinguishes itself from the sibling apply_to_job by describing retrieval of the application method rather than performing the application, though it never names that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is a preview step before applying, but there is no explicit when-to-use, when-not-to-use, or comparison against get_job_details or apply_to_job. 'Reads the posting without clicking anything' hints at the read-only context but does not route the agent between tools.
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 DetailsARead-only
Get job details for a specific job posting on LinkedIn.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | LinkedIn job ID (e.g., "4252026496", "3856789012") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the description does not need to restate basic safety. The description adds no meaningful behavioral context beyond the annotations, such as what kind of details are returned or whether the job must be publicly accessible. It is consistent with the annotations, so no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one short sentence with no filler. It front-loads the action and resource, and every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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, full schema coverage, output schema present, and read-only annotations—the description is nearly complete. The only minor gap is lack of explicit guidance on when to choose this over search_jobs, but the 'specific job posting' wording covers the core usage context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% coverage for the single parameter, including an example format for job_id. The description does not add additional parameter meaning beyond what the schema already provides, but with full schema coverage the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get'), the resource ('job details'), and the scope ('for a specific job posting on LinkedIn'). It distinguishes itself from sibling tools like search_jobs and get_saved_jobs by emphasizing a specific job ID rather than searching or listing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for a specific job posting' implies this tool should be used when you already have a job_id and need details, as opposed to searching for jobs. However, it does not explicitly state when not to use it or name alternative tools.
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 ProfileARead-only
Get the authenticated user's own LinkedIn profile.
Navigates to /in/me/ and resolves the redirect to obtain the real username before reading the profile, so the url field in the result is the actual profile URL (e.g. linkedin.com/in/johndoe/) rather than /in/me/.
| Name | Required | Description | Default |
|---|---|---|---|
| sections | No | Comma-separated list of extra sections to read. 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) reads only the main profile page. | |
| max_scrolls | No | Maximum pagination attempts per section (same as get_person_profile). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds real behavioral context beyond them: it navigates to /in/me/ and resolves the redirect so the returned url is the actual profile URL rather than /in/me/. That explains an otherwise surprising return value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the purpose followed by the redirect-resolution detail. No wasted text; the second sentence earns its place by explaining the url field, though it is somewhat implementation-level.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value documentation is not needed, and annotations cover the read-only/open-world profile. Purpose, scoping, and the non-obvious URL behavior are all covered, leaving only the missing explicit sibling routing as a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (sections, max_scrolls) are fully documented in the schema, including examples and defaults. The description adds nothing about parameters, which is acceptable given the schema's completeness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get') and resource ('the authenticated user's own LinkedIn profile'), and the word 'own' implicitly scopes it away from get_person_profile. It stops short of naming that sibling explicitly, so an agent must infer the distinction rather than being told it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the word 'own' – the agent can infer this is for the caller's profile versus get_person_profile for others. There is no explicit when-to-use/when-not statement or named alternative, leaving the routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_notificationsGet NotificationsBRead-only
List LinkedIn notifications.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond that: no pagination behavior, no result limit, no read/unread semantics. For a list tool that could return unbounded results, this is a real gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with no filler. It is not under-specified in length for a zero-param read, though it could have carried a few more words of useful scoping detail at negligible cost.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-shape explanation is unnecessary, and the annotations cover the safety and open-world nature. The only missing piece is behavioral scoping (ordering, pagination/limit, unread vs all), which keeps it short of a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, which sets the baseline at 4. There is nothing for the description to disambiguate, and schema coverage is 100%.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('LinkedIn notifications'), which is enough to distinguish it from the sibling mark_notifications_read. It does not explicitly contrast with that sibling, but the read-vs-mark distinction is unmistakable from the verb alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of the alternative mark_notifications_read, and no note about whether the list is filtered, paginated, or scoped to unread items. The agent must infer all routing from the name.
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 ProfileCRead-only
Get a specific person's LinkedIn profile.
| Name | Required | Description | Default |
|---|---|---|---|
| sections | No | Comma-separated list of extra sections to read. 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) reads only the main profile page. | |
| max_scrolls | No | Maximum 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_username | Yes | LinkedIn username (e.g., "stickerdaniel", "williamhgates"). A full profile URL is accepted too and is reduced to the username. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety and open-world profile are covered. The description adds nothing on top: no mention of authentication requirements, scraping/rate-limit behavior, latency implications of scrolling, or that it fetches a live public profile. For an open-world read tool this is a missed opportunity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler or repetition. It is efficiently sized, though arguably so terse that 'conciseness' shades into under-specification rather than tightness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. But for a tool with three parameters, a pagination knob, and several near-neighbor tools, the description omits all routing context and any hint that heavy sections should be requested separately, leaving the agent to rediscover schema-only guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so sections and max_scrolls are thoroughly documented in the schema (including defaults, limits, and trade-off advice). The description adds no parameter meaning beyond that, which is the expected baseline of 3 when the schema carries the full load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a clear verb ('Get') and resource ('a specific person's LinkedIn profile'), which is enough for an agent to know it retrieves a third party's profile rather than the caller's own. However, it never names the sibling it is distinguished from (get_my_profile) or clarifies the boundary with search_people, so differentiation is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no named alternative. With siblings like get_my_profile, get_company_profile, and search_people in the same family, some routing guidance would be cheap and valuable; the description supplies none.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_post_reactionsGet Post ReactionsCRead-only
Read the reaction summary of a LinkedIn post.
| Name | Required | Description | Default |
|---|---|---|---|
| post_url | Yes | Full URL of the post. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond the annotations: no note on whether authentication or a valid session is required, no indication of how many reactions are returned or whether the summary is aggregated versus paginated, and no mention of visibility restrictions on posts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no wasted words. It is efficient, though the brevity borders on under-specification rather than tightness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the tool is a simple one-parameter read whose annotations carry the safety profile. What remains missing is any routing context relative to react_to_post and the other post-reading siblings, which matters in a 40-tool namespace.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With a single parameter at 100% schema description coverage, the schema already documents post_url as 'Full URL of the post.' The description adds no format detail (e.g., activity URN vs full URL, whether share/ugc URLs are accepted), so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Read') and resource ('reaction summary of a LinkedIn post'), which is materially distinct from the write-side sibling react_to_post. It is clear what the tool returns, but it never names or contrasts itself with any sibling, so an agent must infer the distinction from the verb alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no when-to-use or when-not-to-use guidance, no prerequisites, and no pointer to alternatives such as react_to_post or get_feed. Usage is only implied by the phrase 'of a LinkedIn post'.
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 JobsARead-only
List job postings saved by the authenticated LinkedIn user.
Returns job_ids that can be passed to get_job_details for full info.
| Name | Required | Description | Default |
|---|---|---|---|
| max_pages | No | Maximum number of saved-jobs pages to load (1-10, default 3) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations declare readOnlyHint and openWorldHint, so the safety profile is already covered. The description adds value by clarifying that the result is limited to the authenticated user's saved job postings and that it returns job_ids, not full job details—an important behavioral distinction from get_job_details. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The first sentence states the action and scope, and the second sentence provides the important downstream usage detail about feeding job_ids into get_job_details. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with one optional parameter and an output schema, the description is complete. It identifies the authenticated-user scope, the return value, and the logical next step. The annotations cover read-only and open-world behavior, and the schema covers the only parameter. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully documents max_pages with type, default, range, and description, so the description does not need to repeat it. The tool has only one optional parameter, and the schema coverage is 100%. The description adds no parameter-specific meaning, but none is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and a clear resource ('job postings saved by the authenticated LinkedIn user'), which precisely distinguishes this tool from the sibling search_jobs and get_job_details. It also states the key output type (job_ids) and how they connect to another tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the right usage context: it is for the authenticated user's own saved jobs, not general job search. It also gives explicit guidance that the returned job_ids should be passed to get_job_details for full information, which effectively routes the agent to the correct follow-up tool. It does not explicitly list when not to use it, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_settingGet SettingCRead-only
Read settings rows from a settings section page.
| Name | Required | Description | Default |
|---|---|---|---|
| section_url | Yes | Full URL of the settings section (e.g. https://www.linkedin.com/settings/visibility/). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered by structured data. The description's word 'Read' merely restates that and adds nothing about authentication needs, how many rows are returned, or pagination behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler or redundancy. It is efficient, though the brevity borders on under-specification rather than disciplined conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the one parameter is fully documented. What is missing is routing context against the many settings-related siblings, which for a simple read tool is the main remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single parameter is fully documented with a concrete example URL. The description adds no format, constraint, or meaning beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Read) and resource (settings rows from a settings section page), so the operation is identifiable. However, it does not distinguish this tool from the closely related siblings list_settings_sections and update_setting, leaving the boundary between reading sections and reading settings rows to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance, no prerequisites, and no mention of alternatives such as list_settings_sections (to discover section URLs) or update_setting (to mutate rows). The only implicit cue is the required section_url parameter, which the schema already conveys.
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 ProfilesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| linkedin_username | Yes | LinkedIn username of the profile page to read; a full profile URL is accepted too (e.g., "stickerdaniel", "williamhgates") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds genuinely useful behavioral detail beyond that: it follows 'Show all' links to return the full list rather than a truncated preview, and it silently skips sections that redirect to linkedin.com/premium. That extra fan-out behavior is exactly the kind of context an agent needs, though it doesn't mention rate limits or failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with what it returns and where it reads from, then the fan-out behavior, then the skip rule. No filler, no repetition of the title or schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return payload shape need not be explained, and annotations carry the safety profile. The description covers source sections, expansion behavior, and skip logic, leaving only edge cases (e.g., empty sections, section ordering) unspecified — a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and there is only one parameter, so the schema already documents linkedin_username (including the URL-or-handle form and examples). The description adds nothing about the parameter, which is the expected baseline 3 when the schema does the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb+resource (get profile links) and narrows the scope precisely to sidebar recommendation sections on a profile page, enumerating the exact sections: 'More profiles for you', 'Explore premium profiles', 'People you may know'. This is enough for an agent to distinguish it from siblings like search_people or get_person_profile without inspecting their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the tightly scoped resource (sidebar recommendations only), but the description never states when to prefer this over get_person_profile, search_people, or get_feed, and gives no prerequisites or exclusions beyond the premium-redirect skip. Adequate but leaves routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pending_invitationsList Pending InvitationsBRead-only
List incoming pending connection invitations.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond that: no pagination behavior, no indication of result scope or ordering, no note about whether the list includes only received (not sent) requests beyond the single word 'incoming'. It largely restates what the name and annotations already convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no filler or redundancy in the prose itself. It is appropriately sized for a zero-argument list tool, though it is so terse that it adds little beyond the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only list tool with an output schema and annotations covering the safety profile, the description is sufficient to call it correctly. The return shape is documented by the output schema, so the description need not explain it. Only the absence of any routing hint toward accept/decline keeps this from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to clarify; the baseline for a no-parameter tool is 4. The description correctly implies no filtering inputs are required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List incoming pending connection invitations.' An agent immediately knows this returns pending invites, and the 'incoming' qualifier distinguishes it from anything outbound. It does not, however, name the sibling tools (accept_invitation, decline_invitation) it naturally precedes, so it stops short of full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to call this versus accept_invitation, decline_invitation, or withdraw_connection_request. The 'pending invitations' phrasing hints at the context, but the agent must infer that this is the read step before acting on an invitation. No exclusions or prerequisites are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_settings_sectionsList Settings SectionsBRead-only
List the sections available in LinkedIn settings.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true and openWorldHint=true, covering the safety profile. The description adds no behavioral context beyond the annotations, such as output format, pagination, or authentication requirements. It simply restates the basic purpose.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It is appropriately sized for a simple list operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters, an output schema, and the read-only annotation, the description is nearly sufficient. It could add a note about when to use it, but for a simple listing tool the basic statement is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, and schema description coverage is 100% (vacuously), so there is no parameter semantics to add. The baseline for zero parameters is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'List' and the resource 'sections available in LinkedIn settings', so an agent knows exactly what the tool does. It does not, however, explicitly differentiate from siblings like get_setting or update_setting, which prevents a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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. It does not mention that it should be used to discover section names before calling get_setting or update_setting, nor does it state any prerequisites. Usage is only implied by the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mark_notifications_readMark Notifications ReadBDestructive
Mark all LinkedIn notifications as read.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | When True, locate the control but do not click. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the agent knows this mutates state on an external site. The description's 'all' conveys the bulk scope, which the annotations do not, but it doesn't disclose whether the change is reversible, whether it requires a live session, or how dry_run affects behavior beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with zero filler. It is appropriately sized for a one-parameter tool, though it is so terse that it could have absorbed a clause of usage or safety context without bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and annotations cover the destructive/open-world profile. However, for a bulk state-changing tool, the description omits any note about irreversibility or session prerequisites, leaving a gap an agent would care about.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single optional dry_run parameter is fully documented in the schema itself. The description adds no additional parameter meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Mark') and resource ('LinkedIn notifications') with scope qualifier 'all', so the operation is unambiguous. It does not explicitly differentiate from the sibling get_notifications, but the write-oriented verb makes the distinction inferable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No indication of when to use this versus get_notifications, no prerequisites (e.g., authentication or session requirements), and no note on when marking-as-read is appropriate. The agent must infer all of that 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.
react_to_postReact To PostCDestructive
React to a LinkedIn post.
| Name | Required | Description | Default |
|---|---|---|---|
| post_url | Yes | Full URL of the post. | |
| reaction | Yes | Reaction type, e.g. "like", "celebrate", "love", "insightful", "funny", "support". "like" is the default. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare openWorldHint and destructiveHint, so some behavioral context exists. The description adds nothing beyond repeating the action, and notably does not explain why a reaction is flagged as destructive or what state changes it causes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It is appropriately sized, though its brevity means it cannot carry much informational weight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering safety traits, the description need not explain return values or risk. However, it omits any usage context relative to siblings and provides no behavioral nuance, leaving the definition minimally adequate for this simple action.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents post_url and reaction thoroughly, including examples and a default. The description adds no parameter meaning beyond what the schema provides, which is the baseline expectation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (react) and resource (LinkedIn post), making the core action clear. However, it does not differentiate from siblings like get_post_reactions or comment_on_post, 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use, when-not-to-use, or alternative tool guidance is provided. The description only states the action, leaving selection context to be inferred from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_skillRemove SkillCDestructive
Remove a skill from the profile's skills section.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | ||
| skill_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the safety profile is covered structurally. The description adds nothing beyond restating removal — it never says whether the removal is irreversible, whether a confirmation is required, or that dry_run can preview the change.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler. It is efficient, though the brevity comes at the cost of the missing behavioral and parameter detail noted elsewhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described, but for a destructive mutation with an undocumented dry_run flag and no permissions or confirmation context, the definition leaves too much unspecified for an agent to call it safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for two parameters. The description does not explain the format or matching semantics of skill_name, nor does it mention the dry_run flag at all, leaving a whole parameter undocumented in both schema and prose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Remove) and resource (skill from the profile's skills section), so the agent knows exactly what is mutated. It does not differentiate itself from any sibling, though no add_skill-style counterpart exists in the sibling list to confuse it with.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 versus alternatives, no prerequisites, and no mention of the dry_run preview path even though that flag exists. The agent must infer everything about invocation context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reply_to_commentReply To CommentCDestructive
Reply to a comment on a LinkedIn post.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Reply body text. | |
| dry_run | No | When True, fill the reply but do not submit. | |
| post_url | Yes | Full URL of the post. | |
| comment_index | Yes | Zero-based index of the target comment. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag openWorldHint and destructiveHint, so the safety profile is partly covered. But the description adds nothing about the one thing that matters most here: that the reply is published publicly and visibly under the target comment and is effectively irreversible. The dry_run escape hatch is never mentioned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the verb and resource front-loaded and zero filler. It is efficient, though so terse that conciseness shades into under-specification.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a public, destructive mutation with four parameters, the description omits the visibility/irreversibility of the action and the existence of dry_run. An output schema exists so return values need not be explained, but the behavioral context an agent needs before acting is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so post_url, comment_index, text and dry_run are all already documented in the schema. The description adds no extra meaning, which is the correct baseline when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (reply) and resource (a comment on a LinkedIn post), which is clearly distinct from comment_on_post in the sibling list. However, it does not explicitly distinguish itself from that sibling or clarify that the reply is nested under an existing comment thread.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this versus comment_on_post, nor any prerequisites (e.g., must be connected to or following the author, must have an existing comment). The agent must infer all selection conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_jobSave JobCDestructive
Save a LinkedIn job posting.
| Name | Required | Description | Default |
|---|---|---|---|
| job_url | Yes | Full URL of the job posting. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare openWorldHint=true and destructiveHint=true, but the description adds nothing beyond the title: no indication that saving is a persistent, idempotent write to the user's saved list, no note that it is reversible via unsave_job, and no auth or failure context. A one-line description for a mutating, open-world tool leaves behavior largely undisclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with no filler, so it is maximally concise. The tradeoff is that nothing is front-loaded beyond the bare purpose, but it does not waste words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and only one parameter exists, so the description covers the minimum needed to invoke the tool. It is still incomplete about mutation semantics, idempotency, and its relationship to unsave_job/get_saved_jobs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single parameter job_url is already documented as 'Full URL of the job posting.' The description adds no format hints (e.g., canonical LinkedIn job-view URL vs. tracking URL). Baseline 3 applies when the schema already carries the parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Save) and resource (LinkedIn job posting), which is unambiguous and matches the tool name. It does not, however, distinguish itself from close siblings like unsave_job, get_saved_jobs, or apply_to_job, so the agent must infer the routing itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use guidance, no mention of prerequisites (e.g., being logged in, whether the job must exist), and no pointer to the inverse tool unsave_job or to get_saved_jobs for verification. Usage is only implied by the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_companiesSearch CompaniesBRead-only
Search for companies on LinkedIn.
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | Yes | Search keywords (e.g., "fintech", "anthropic", "electric vehicles") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses no behavioral traits beyond what 'search' and 'LinkedIn' naturally imply. Annotations already declare readOnlyHint and openWorldHint, but the description adds no further context about result limits, matching behavior, or ordering. It is not contradictory, but it is also not informative beyond the basic action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact sentence that wastes no words and immediately states the core action and target resource. It is appropriately sized for a simple tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with an output schema and safety annotations, the description is minimally adequate. However, it does not clarify edge behavior, result scope, or how it differs from nearby company-related tools, so an agent may still need to infer intent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully documents the only parameter, keywords, with a useful example. The description adds no additional semantic detail beyond the schema, so a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the verb ('Search') and resource ('companies on LinkedIn'), so an agent can understand the basic function. However, it does not differentiate itself from sibling tools like get_company_profile or search_people, leaving some ambiguity about scope or result type.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 instead of search_people, get_company_profile, or get_company_employees. The description implies keyword-based discovery but provides no explicit context, prerequisites, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_conversationsSearch ConversationsC
Search messages by keyword.
Click-derived references require an observed different thread path after each row click. The first unverifiable click stops further row clicks and is reported in section_errors.search_results. Already-read text and independently extracted anchors retain their normal handling. A result without that diagnostic does not guarantee that every conversation was enumerated.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum 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. | |
| keywords | Yes | Search keywords to filter conversations |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations supply only openWorldHint=true, so the description must carry the behavioral load, and it does disclose two real traits: row clicks may mark conversations read, and an unverifiable click halts further enumeration with diagnostics in section_errors.search_results. However, this is expressed in opaque internal jargon ('click-derived references', 'observed different thread path') that an agent cannot readily act on, and it omits permissions or rate-limit context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence is properly front-loaded, but the second paragraph is long, jargon-heavy, and largely about the scraper's internals rather than what the caller needs. Those sentences do not earn their place for an agent selecting or invoking the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description correctly gestures at where errors surface. Still, it leaves the agent without a clear picture of result shape, ordering, or how this tool relates to get_inbox/get_conversation, which is a meaningful gap for a search tool with a truncation caveat.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and both parameters are already well documented in the schema, including the read-marking side effect of the limit parameter. The description adds no additional syntax, format, or matching semantics (e.g., how keywords are combined) beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a verb and resource ('Search messages by keyword'), but it names 'messages' while the tool is 'search_conversations', creating a small mismatch. It never distinguishes this tool from the closely related get_inbox and get_conversation siblings, and the rest of the description drifts into internal scraping mechanics rather than clarifying purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance and no named alternative, despite three plausible siblings (get_inbox, get_conversation, search_posts). The only quasi-guidance is the schema note about preferring a low cap for noisy queries, which lives in the schema, not the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_jobsSearch JobsARead-only
Search for jobs on LinkedIn.
Returns job_ids that can be passed to get_job_details for full info.
| Name | Required | Description | Default |
|---|---|---|---|
| sort_by | No | Sort results (date, relevance) | |
| job_type | No | Filter by job type, comma-separated (full_time, part_time, contract, temporary, volunteer, internship, other) | |
| keywords | Yes | Search keywords (e.g., "software engineer", "data scientist") | |
| location | No | Optional location filter (e.g., "San Francisco", "Remote") | |
| max_pages | No | Maximum number of result pages to load (1-10, default 3) | |
| work_type | No | Filter by work type, comma-separated (on_site, remote, hybrid) | |
| easy_apply | No | Only show Easy Apply jobs (default false) | |
| date_posted | No | Filter by posting date (past_hour, past_24_hours, past_week, past_month) | |
| experience_level | No | Filter by experience level, comma-separated (internship, entry, associate, mid_senior, director, executive) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and open-world. The description adds value by stating that the tool returns job_ids that serve as inputs to get_job_details, which is useful contextual behavior. It does not discuss pagination, max_pages behavior, or filtering limits, but the schema covers those details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no filler. The primary purpose is front-loaded, and the follow-up guidance about job_ids is immediately useful. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with a rich, fully documented schema and an output schema present, the description is sufficient: it states the purpose and the relationship to get_job_details. It does not need to explain parameters or return values in depth because those are already structured elsewhere.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the heavy lifting is already done by the input schema. The description adds no additional meaning about parameters beyond what the schema documents, matching the baseline for full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Search') on a specific resource ('jobs on LinkedIn') and adds the key behavioral result: it returns job_ids intended for get_job_details. This differentiates it from sibling search tools like search_people and search_companies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: use this tool when you want to search LinkedIn jobs, and use the returned IDs with get_job_details for fuller information. It does not explicitly list exclusions or compare against alternatives like get_saved_jobs, but the intended use case is obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_peopleSearch PeopleCRead-only
Search for people on LinkedIn.
| Name | Required | Description | Default |
|---|---|---|---|
| network | No | Optional 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. A single token ("F") or a comma-separated string ("F,S") is also accepted, for clients that cannot transmit an array. | |
| keywords | Yes | Search keywords (e.g., "software engineer", "recruiter at Google") | |
| location | No | Optional location filter (e.g., "New York", "Remote") | |
| current_company | No | Optional 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
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description adds nothing beyond them — no note on result limits, pagination, or filtering behavior. For a search tool with known facet quirks documented in the schema, the description contributes no behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler. It is efficient, though the brevity borders on under-specification rather than tight structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists and annotations cover the safety profile, so return values and side effects need not be explained. However, with four parameters including non-obvious facets (network degree tokens, company URN requirement) and no routing against abundant siblings, the description is thinner than the tool's complexity warrants.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already explains keywords, network, location, and the current_company URN caveat. The description adds no parameter meaning of its own, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a clear verb+resource ('search for people') and names the platform, so the agent knows exactly what it retrieves. It does not distinguish itself from siblings like search_companies, search_jobs, or get_person_profile, which is the only gap.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use, when-not-to-use, or alternative-tool guidance in the description. The sibling list contains several overlapping search/filter tools (search_companies, get_company_employees, get_person_profile) that an agent must disambiguate on its own.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_postsSearch PostsARead-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).
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | Yes | Search keywords (e.g., "Buscamos Unity", "AI automation hiring") | |
| max_pages | No | Scroll 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_posted | No | Optional 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
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint and openWorldHint already present, the description adds useful context: this is a global content search, not a feed or company-scoped search. It also implies results may include informal/unofficial hiring language, which is relevant behavioral context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: one sentence defines the action, the next gives a concrete use case, and the final sentence distinguishes it from siblings. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 100% parameter schema coverage, the presence of an output schema, and annotations covering safety and openness, the description covers all essential decision factors. It tells the agent what the tool does, when to use it, what alternatives exist, and how to craft effective queries.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by providing richer keyword examples and clarifying that content search is global rather than scoped, supplementing the schema's parameter descriptions. It meaningfully supports keyword selection without redundancy.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource: 'Search LinkedIn posts/content globally by keyword.' It also explicitly differentiates itself from get_feed and get_company_posts, so an agent can immediately identify what this tool is and what it is not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a concrete use case—catching informal hiring posts before formal job listings exist—and provides example keyword patterns. It also names the two sibling alternatives and explains why they are different, making the selection decision explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageSend MessageADestructive
Compose and send a new message to a LinkedIn user.
Profile-based targeting opens LinkedIn's compose flow. It is not a safe reply path for an existing recruiter/InMail or messaging thread: it may create a separate DM even after you inspect that thread with get_conversation or search_conversations. Those tools only read an existing thread; they do not send a reply. Until a thread-targeted send path is available, do not treat profile-based send_message as a reply.
The recipient must be directly messageable from the profile page. If
LinkedIn does not expose a normal Message action, use connect_with_person
first, then retry send_message only after the connection request is
accepted. A status of enter_to_send_enabled means the account
has LinkedIn's "Press Enter to Send" preference on, which hides the Send
button; relay the returned instructions to the user, who switches it to
"Click Send to send" before retrying. The dry run (confirm_send False)
reports it too. Recipient authorization comes from validating one
recipient-specific Message action carrying the target URN, then following
its browser navigation and pinning the exact final route. Visible profile
links or recipient URNs in the composer are optional corroboration; any
contradiction fails closed. No Voyager or other private API is used. This
is a write operation when confirm_send is True.
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | Single-line message text to send. C0 control characters and DEL are rejected, including CR, LF, and tab. | |
| profile_urn | No | Optional profile URN (e.g. ACoAAB...) to verify against the URN exposed by the loaded profile before opening its Message action. It never bypasses recipient verification. Obtain via get_person_profile. Note: inbox may not always show all messages; use search_conversations as a fallback. | |
| confirm_send | Yes | Must be True to send the message | |
| linkedin_username | Yes | LinkedIn username of the recipient; a full profile URL is accepted too |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give openWorldHint and destructiveHint, but the description discloses far more: it is a write only when confirm_send is True, the dry-run behavior of confirm_send False, the enter_to_send_enabled account-preference failure mode and its remedy, and the recipient-authorization validation with fail-closed contradiction handling. This is unusually rich behavioral context that goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and the later paragraphs are dense with actionable detail, so most sentences earn their place. It is, however, on the long side and repeats the read-only nature of the conversation tools, which could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return structure needn't be explained, and the annotations cover the safety profile. The description still completes the picture with authorization checks, failure-mode handling, prerequisite steps, and API-usage disclosure, leaving nothing an agent needs to call it correctly unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning: it clarifies that confirm_send False is a dry run that reports the send-readiness status, and that profile_urn never bypasses recipient verification. These are behavioral nuances the schema descriptions do not capture.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Compose and send a new message to a LinkedIn user') and immediately scopes it as profile-based targeting rather than a thread reply. It names the siblings it is not (get_conversation, search_conversations) and the alternative path (connect_with_person), so an agent can distinguish it without opening other schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when not to use it ('not a safe reply path for an existing recruiter/InMail or messaging thread') and names the read-only alternatives, plus the prerequisite flow: use connect_with_person first and retry only after the request is accepted. It also gives conditional retry guidance tied to the enter_to_send_enabled status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unfollow_companyUnfollow CompanyCDestructive
Unfollow a LinkedIn company page.
| Name | Required | Description | Default |
|---|---|---|---|
| company_slug | Yes | LinkedIn company URL slug (e.g. "acme-corp"). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the safety profile is covered by structured data. The description adds nothing beyond the name: it does not say what state is removed, whether an unfollow is reversible, whether it errors if the page was not followed, or that it mutates a remote account relationship.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence with zero filler and the action is front-loaded. It is arguably too terse for a destructive mutation, but as a matter of conciseness and structure it wastes nothing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and annotations carry the destructive signal. Still, a destructive remote mutation with a required identifier leaves the agent without any note on consequences or reversibility, which is a real gap for this operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single company_slug parameter is fully documented with an example in the schema. The description adds no format or validation detail beyond that, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Unfollow') and resource ('a LinkedIn company page'), which is clearer than a bare restatement of the name. It does not, however, reference the sibling follow_company or explain the relationship to it, so sibling differentiation is left to the tool name alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 versus follow_company, or when not to use it. Nothing addresses prerequisites such as being logged in or currently following the page, nor whether the call is idempotent. The agent must infer all usage conditions from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unfollow_personUnfollow PersonCDestructive
Unfollow a LinkedIn member.
| Name | Required | Description | Default |
|---|---|---|---|
| linkedin_username | Yes | LinkedIn username (e.g. "alice"). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond that: it does not say the action is reversible (re-followable), whether it requires an authenticated session, or what happens if the person is not currently followed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with no waste, front-loading the verb and resource. It is efficient, though its brevity borders on under-specification rather than true economy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (one required param) and an output schema exists, so return values need not be explained. However, with no usage guidance and no disclosure of reversibility or authentication needs, the definition is only minimally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single linkedin_username parameter is fully documented in the schema with an example. The description adds no parameter meaning at all, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Unfollow') and resource ('a LinkedIn member'), which is clear and, via the word 'member', implicitly distinguishes it from the sibling unfollow_company. It stops short of explicitly routing against follow_person or unfollow_company, so it does not fully earn a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as follow_person or unfollow_company. The agent is left to infer usage entirely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsave_jobUnsave JobBDestructive
Remove a saved LinkedIn job posting from your saved list.
| Name | Required | Description | Default |
|---|---|---|---|
| job_url | Yes | Full URL of the job posting. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the safety profile is covered. The description only restates the mutation ('Remove') and adds no behavioral context such as idempotency, error behavior for an unsaved job, or authentication requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler, appropriately sized for a one-parameter tool. It is efficient rather than padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained, and annotations cover the destructive nature. The gap is edge-case behavior (unsaving a job that is not in the saved list) for an otherwise simple tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With one parameter and 100% schema description coverage, the schema already documents job_url fully. The description adds no format or constraint detail beyond it, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Remove) and resource (a saved LinkedIn job posting) plus the scope of the operation (from your saved list). It is clear, but it never names the inverse sibling save_job, so sibling differentiation is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the name and description; an agent can infer you call this to undo a save. There is no explicit when-to-use guidance, no mention of save_job as the counterpart, and no note about what happens if the job was never saved.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_aboutUpdate AboutBDestructive
Update the About section of the LinkedIn profile at the given URL.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Full LinkedIn profile URL to edit (must be your own profile). | |
| new_about | Yes | The new About section text. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the write/network profile is covered. The description adds nothing beyond that: it does not say whether the new text replaces the existing About wholesale, what permissions are required, or what happens on failure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler; the verb and target resource come first and nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and annotations cover the safety profile, so the description need not explain returns. It is still thin for a mutation tool: the replace-vs-append semantics of the About update are left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (url, new_about) are already documented, including the 'must be your own profile' constraint. The description adds no format, length, or syntax detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Update) and resource (About section of the LinkedIn profile), which is unambiguous. However, it does not differentiate from the closely related sibling update_headline, leaving the agent to infer the boundary from names alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no when-to-use guidance, prerequisites, or alternatives. It does not point to update_headline or any other sibling, and the only constraint (own profile) lives in the schema, not the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_headlineUpdate HeadlineCDestructive
Update the headline of the LinkedIn profile at the given URL.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Full LinkedIn profile URL to edit (must be your own profile). | |
| new_headline | Yes | The new headline text. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the safety profile of this external mutation is covered. The description adds nothing beyond them: it never states that the existing headline is overwritten/replaced, nor any auth, session, or rate-limit behavior. With annotations doing the heavy lifting, this is a minimal but non-contradictory contribution.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. It is efficient, though it is terse to the point of omitting useful qualifiers rather than being perfectly calibrated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A return value is covered by the output schema and parameter meaning by the input schema, so the description's burden is mostly behavioral. It is adequate for a simple two-parameter mutation, but it omits that the prior headline is destroyed and any indication of failure modes for a destructive open-world operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for both parameters, so the schema already documents that 'url' must be the caller's own profile and that 'new_headline' is the replacement text. The description adds no format, length, or constraint detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Update) and resource (headline) on a LinkedIn profile, which is easily distinguished from the sibling update_about (different profile field). It does not name or contrast siblings explicitly, but the resource is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no mention of when to prefer update_about or other profile-editing tools, and no stated prerequisites (only 'must be your own profile', which lives in the schema, not the description). The agent gets the what but no context for the when.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_settingUpdate SettingCDestructive
Update a setting in a LinkedIn settings section.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The setting name as shown on the page. | |
| value | Yes | The desired value (matched against option text for selects; for checkboxes/switches the click toggles). | |
| dry_run | No | When True, locate the setting but do not change it. | |
| section_url | Yes | Full URL of the settings section. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and openWorldHint=true, so the mutation and external-effect profile is covered. The description adds nothing beyond that – it does not explain matching semantics, that values are clicked against option text, reversibility, or auth needs. With annotations carrying safety, this is a minimal contribution.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no wasted words. It is efficient, though the brevity borders on under-specification rather than pure conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values needn't be explained, and the schema covers all parameters. However, for a destructive write tool the description should at least hint at the dry_run option and the prerequisite of obtaining a section URL, which it omits.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters (including dry_run and the option-text matching for value) are documented in the schema itself. The description adds no parameter detail beyond what the schema provides, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (update) and resource (a setting within a LinkedIn settings section), which distinguishes it from read-only siblings like get_setting and list_settings_sections. It does not explicitly contrast itself with those siblings, but the mutation verb makes the intent clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no when-to-use guidance, no prerequisites (e.g., needing the section URL from list_settings_sections or verifying the current value with get_setting), and no mention of the dry_run workflow. The agent must infer usage entirely from the name and schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
withdraw_connection_requestWithdraw Connection RequestCDestructive
Withdraw a previously sent connection request.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Target display name as shown in the sent invitations list. | |
| dry_run | No | When True, locate the control but do not click. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and openWorldHint=true, so the safety profile is partly covered, but the description adds nothing beyond that: it does not say the withdrawal is irreversible, that the target must still have a pending request, or what happens if the request was already accepted. The schema's dry_run parameter is never mentioned in the description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler, which is appropriate for a narrow action. It is efficient, though its brevity contributes to the gaps noted in other dimensions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and annotations cover the destructive/open-world profile. Still, for a destructive mutation the description omits prerequisites and irreversibility, leaving it minimally adequate rather than complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters (name, dry_run) are documented in the schema itself, so the baseline is 3. The description adds no extra meaning about how 'name' is matched or what dry_run returns, so it does not rise above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (withdraw) and resource (a previously sent connection request), and the phrase 'previously sent' usefully scopes it to the user's own outgoing request rather than an inbound invitation. It does not, however, name the adjacent sibling (decline_invitation) or otherwise anchor itself against the many other connection-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
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 decline_invitation, list_pending_invitations, or connect_with_person, nor any stated prerequisite (e.g. the request must still be pending). The agent must infer the use case entirely from the tool name.
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.
47 tool updates
v4.26.2- First observed
accept_invitation - First observed
apply_to_job - First observed
close_session - First observed
comment_on_post - First observed
connect_with_person - First observed
create_post - First observed
create_post_with_image - First observed
debug_profile_controls - First observed
decline_invitation - First observed
delete_post - First observed
follow_company - First observed
follow_person - First observed
get_company_employees - First observed
get_company_posts - First observed
get_company_profile - First observed
get_conversation - First observed
get_feed - First observed
get_inbox - First observed
get_job_apply_url - First observed
get_job_details - First observed
get_my_profile - First observed
get_notifications - First observed
get_person_profile - First observed
get_post_reactions - First observed
get_saved_jobs - First observed
get_setting - First observed
get_sidebar_profiles - First observed
list_pending_invitations - First observed
list_settings_sections - First observed
mark_notifications_read - First observed
react_to_post - First observed
remove_skill - First observed
reply_to_comment - First observed
save_job - First observed
search_companies - First observed
search_conversations - First observed
search_jobs - First observed
search_people - First observed
search_posts - First observed
send_message - First observed
unfollow_company - First observed
unfollow_person - First observed
unsave_job - First observed
update_about - First observed
update_headline - First observed
update_setting - First observed
withdraw_connection_request
TDQS
Scored across 47 tools
Most tools map to a distinct resource+action (posts, jobs, invitations, messaging, profile, settings), so an agent can generally pick correctly. There is some overlap: connect_with_person claims it can also accept an incoming request, colliding with accept_invitation, and create_post vs create_post_with_image differ only by media attachment, but these are minor and descriptions clarify them.
Nearly every tool follows a clean verb_noun snake_case pattern (get_company_posts, create_post, delete_post, accept_invitation, search_jobs, update_headline). The few noun-leading outliers like close_session and debug_profile_controls still read as consistent imperative names, so the pattern is predictable throughout.
47 tools is very heavy for this surface and well past the 25+ threshold. While the LinkedIn domain is broad, the set is inflated by granular settings tools (list_settings_sections, get_setting, update_setting) and an internal debug_profile_controls that most agents would never need, suggesting the surface could be meaningfully consolidated.
Coverage is strong across posts, comments/reactions, jobs, invitations/connections, messaging, feed, and profile editing, covering the main write and read lifecycles. Minor gaps remain, such as listing your own connections/followers or retrieving your own authored posts, but these are workable limitations rather than dead ends.
Maintenance
Related MCP Connectors
LinkedIn for AI agents: inbox, invitations, Sales Navigator search, posts, jobs, quotas, webhooks.
Give AI agents the LinkedIn tools to find, qualify, engage, and follow up with prospects.
Run LinkedIn outreach from your AI chat: find leads, launch campaigns, send, and reply.
A hosted LinkedIn MCP server for your own account. Paste one address into Claude, ChatGPT, Cursor or n8n to read your inbox, send messages and invitations, and search people. Free to start. Not made by LinkedIn.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables AI assistants to interact with LinkedIn by scraping profiles, companies, job postings, and getting personalized job recommendations using authenticated browser automation.1714,037 PyPI3,785Apache 2.0
- AlicenseBqualityDmaintenanceConnects Claude Desktop to LinkedIn's data layer for AI-powered networking, enabling profile research, content creation and scheduling, engagement automation, analytics tracking, and messaging through natural language.8542MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude AI to interact with LinkedIn through browser automation, including profile reading, people and job search, company research, post publishing, and profile editing.MIT
- AlicenseAqualityBmaintenanceConnects LinkedIn to AI assistants, enabling lead search, profile analysis, messaging, and workflow automation through a cloud browser. Supports sales, recruiting, and market research tasks.59486 npmMIT