linkedin-mcp-server@4.30.0
CAUTION· not startedPublisher claims: "This MCP server allows Claude and other AI assistants to access your LinkedIn. Scrape LinkedIn profiles and companies, get your recommended jobs, and perform job searches. Set your li_at LinkedIn cookie to use this server." Observed in sandbox: no network, touches nothing outside the project, writes no memory.
Coverage
Not started: dependency install failed; the server itself was not observed.- Tested
- the dependency install step · every file read, file written and host contacted by what ran
- Not tested
- server startup · the tool list · tool behavior
What this means for the label: Caution here covers what ran. The server's tools were not exercised with a real credential, so nothing about their behavior is asserted; the credential summary below says what to do with that.
Before you give it your token
- It will ask for
- no credential variables read in the code
- Where it talks to
- no vendor host named in the codeAlso linkedin.com — not the publisher's domain; check what for before connecting.
- What the honeypot saw
- no credential files read · no network
- What we could not test
- server startup · the tool list · tool behavior
Connect it under the guard. Not started: dependency install failed; the server itself was not observed. The code names no credential variable; the guard pins the network to what the honeypot saw and logs every call.
Never paste a credential into a chat, a ticket or a report, including ours. How the guard holds it.
Is [email protected] safe to install?
KillerSkills ran it in the KillerSkills honeypot sandbox (2 scenarios; not started: dependency install failed; the server itself was not observed) on 2026-11-13 and scored it 69/100 (Caution). It is not known to be malicious, but it has behaviour or code a security policy should decide on before install. Notable findings: Collapsed <details> block carrying instructions; Destructive file system command detected; Credential pass-through configuration. Summary: no network, touches nothing outside the project, writes no memory.
Behavior trace
Honeypot run · 0 s · 2 scenarios · 0 deviationsStatic findings
<summary>Session issues</summary> - Browser profile is stored at `~/.linkedin-mcp/profile/` - Managed browser downloads are cached at `~/.linkedin-mcp/patchrighFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.rm -f /tmp/verify-pr-$PR.json /tmp/verify-pr-$PR-headers /tmp/verify-pr-$PR.log /tmp/verify-pr-$PR-init.json /tmp/verify-pr-$PR-initialized.jsonFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.treats every converted secret as required. The three optional proxy credentialsFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.rm -f /tmp/repro-$NUM-headers /tmp/repro-$NUM.log /tmp/repro-$NUM.port /tmp/repro-$NUM.pid /tmp/repro-$NUM-init.json /tmp/repro-$NUM-initialized.jsonFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.<summary>Told to run <code>--login</code> on the host when you already did</summary> - If tool calls answer "No valid LinkedIn session is available in Docker" oFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.<summary>Told to run <code>--login</code> on the host when you already did</summary> - If tool calls answer "No valid LinkedIn session is available in Docker" oFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.kill $SERVER_PID 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.chown -R pwuser:pwuser /opt/patchright && \Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.# Never os.kill there: any signal but the console ones terminates.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.uv run -m linkedin_mcp_server --transport streamable-http --log-level DEBUGFix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them."https://ci-bot:s3cr3t@[email protected]/x.zip",Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.kill $SERVER_PID 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.kill -TERM "$xvfb_pid" 2>/dev/null || trueFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.completed = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.child = subprocess.Popen(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.uv run -m linkedin_mcp_server --transport streamable-http --port $PORT --log-level INFO > /tmp/verify-pr-$PR.log 2>&1 &Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.# .env file. For a relay on the host use host.docker.internal, notFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.[ -z "$SESSION_ID" ] && { echo "MCP initialize returned no Mcp-Session-Id. Tail of /tmp/verify-pr-$PR.log:" >&2; tail -20 /tmp/verify-pr-$PR.log >&2; kill $SERVER_PID 2>/dev/null; exit 1; }Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.run = subprocess.run([sys.executable, "-c", script], capture_output=True)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.kill -0 $SERVER_PID 2>/dev/null || { echo "Server died during startup. Tail of /tmp/verify-pr-$PR.log:" >&2; tail -20 /tmp/verify-pr-$PR.log >&2; exit 1; }Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.kill -TERM "$server_pid" 2>/dev/null || trueFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.whatever ``.env`` the checkout holds. The whole environment is restoredFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.kill -0 $SERVER_PID 2>/dev/null || { echo "Server died during startup. Tail of /tmp/repro-$NUM.log:" >&2; tail -20 /tmp/repro-$NUM.log >&2; exit 1; }Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.<summary>Use your own Chrome</summary> - Set **Chrome executable** in the extension's settings to a Chrome, Chromium or Chrome for Testing binary, such as `/usrFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct."""No gate variable set, and the ``.env`` lookup finding *dotenv_path*.Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.[ -z "$SESSION_ID" ] && { echo "MCP initialize returned no Mcp-Session-Id. Tail of /tmp/repro-$NUM.log:" >&2; tail -20 /tmp/repro-$NUM.log >&2; kill $SERVER_PID 2>/dev/null; exit 1; }Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.``.env`` is part of the environment too. A developer running a real proxyFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.child = subprocess.Popen(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.grep -q '"error"' /tmp/repro-$NUM-init.json && { echo "Initialize returned a protocol error. Execution limit." >&2; cat /tmp/repro-$NUM-init.json >&2; kill $SERVER_PID 2>/dev/null; exit 1; }Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.…e://host:port (http, https, socks4 or socks5). May also include credentials, as http://user:password@host:port. Only browser traffic is routed.", "isSecret": true …Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.b"sitecustomize: https://user:[email protected]/x?token=secret\x1b[2J\n"Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.…ues first, then use the [issue forms](https://github.com/stickerdaniel/linkedin-mcp-server/issues/new/choose) for anything new. AI agents follow the [issue-packet skill](https://github.com/stickerdaniel/linkedin-mcp-server/blob/main/.agent…Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.grep -q '"error"' /tmp/verify-pr-$PR-init.json && { echo "Initialize returned a protocol error. Execution limit." >&2; cat /tmp/verify-pr-$PR-init.json >&2; kill $SERVER_PID 2>/dev/null; exit 1; }Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.chmod -R 755 /opt/patchright && \Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts."https://ci-bot:[email protected]/x.zip",Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.…rotocol error. Execution limit." >&2; cat /tmp/repro-$NUM-initialized.json >&2; kill $SERVER_PID 2>/dev/null; exit 1; } ``` Capture and inspect both response bodies…Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.…e://host:port (http, https, socks4 or socks5). May also include credentials, as http://user:password@host:port. Only browser traffic is routed.", "isSecret": true …Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.uv run -m linkedin_mcp_server --transport streamable-http --port $PORT --log-level INFO > /tmp/repro-$NUM.log 2>&1 &Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.url = "https://ci-bot:[email protected]/chromium.zip"Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.if ! kill -0 "$xvfb_pid" 2>/dev/null; thenFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell."sitecustomize: https://ci-bot:[email protected]/p?key=s3cr3t working\n"Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose."label": "uv run -m linkedin_mcp_server --no-headless --transport streamable-http",Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.…ocol error. Execution limit." >&2; cat /tmp/verify-pr-$PR-initialized.json >&2; kill $SERVER_PID 2>/dev/null; exit 1; } ``` Capture and inspect both response bodies…Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.<summary>Login issues</summary> - Make sure you have only one active LinkedIn session at a time - LinkedIn may require a login confirmation in the LinkedIn mobiFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.kill -TERM "$xvfb_pid" 2>/dev/null || trueFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell."src": "https://raw.githubusercontent.com/stickerdaniel/linkedin-mcp-server/main/assets/icons/icon.png",Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.kill -TERM "$server_pid" 2>/dev/null || trueFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.rm -rf /var/lib/apt/lists/*Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.<summary>Login issues</summary> - Make sure you have only one active LinkedIn session at a time - LinkedIn may require a login confirmation in the LinkedIn mobiFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.completed = subprocess.run(command, capture_output=True, check=False, text=True)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.completed = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.…e://host:port (http, https, socks4 or socks5). May also include credentials, as http://user:password@host:port. Only browser traffic is routed.", "required": false, "def…Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.return subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.answered = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.answered = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.pulled_in_the_server_graph = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out."proxy_server": "http://u:p@host:8080",Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.return subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out."fix: ",Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent.result = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out."fix(): Subject",Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent."",Fix: Replace encoded or assembled strings with plain literals and remove undeclared network calls."plugins/linkedin-mcp-server/assets/icon.svg",Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts."fix: ",Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent.config = BrowserConfig(proxy_server="http://user:p%40ss@gate:7000")Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose."",Fix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.shaped = ToolError("Proxy refused http://acctzone9:[email protected]:7000")Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.The Docker login viewer's page, served by websockify from /usr/share/novnc next to Debian's noVNC, whose documented RFB API it uses. login_viewer.py prints its Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent."",Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent."fix: Subject.",Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent.config = BrowserConfig(proxy_server=f"http://user:{self.SECRET}@gate:7000")Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.completed = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out."",Fix: Replace encoded or assembled strings with plain literals and remove undeclared network calls."",Fix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.AppConfig(), ["--proxy-server", f"http://u:{self.SECRET}@h:8080"]Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.result = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out."linkedin_mcp_server.daemon.owner.direct_http_client",Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.monkeypatch.setenv("PROXY_SERVER", f"http://envuser:{self.SECRET}@gate:7000")Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.RuntimeError(f"failed via http://{user}:{secret}@gate.example:7000"),Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose."""A username with an empty password is a legitimate proxy credential.Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.Cost to the agent
Tokens estimated at four characters each. The tool list is re-read by the agent on every turn, so it is the number to compare between servers that do the same job: ranked across the index.
Known vulnerabilities
Vulnerability advisories (OSV) cover npm and PyPI packages; this registry has no advisory database.
What would make this Verified
11 points to 80 · weights: behavior 45%, static 25%, prompt 15%, publisher 15%- Unclaimed publisher≈ +8 on the totalClaim stickerdaniel: a verified publisher gets +50 on publisher trust. It is free and usually instant with GitHub sign-in.
- Hidden instructions≈ +6 on the totalRemove HTML comments, zero-width characters and white-on-white text that carry instructions. Everything the agent is meant to read should be visible to the person reading the file.
- Destructive file system command detected≈ +4 on the totalBuild commands from fixed arguments; do not interpolate untrusted strings into a shell.
- Credential pass-through configuration≈ +4 on the totalStop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
- Process kill command≈ +2 on the totalBuild commands from fixed arguments; do not interpolate untrusted strings into a shell.
- File permission modification command≈ +2 on the totalRequest the narrowest permission that works; replace wildcards with the exact paths or hosts.