linkedin-mcp-server@4.29.0
VERIFIED· 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: Verified 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
Code inventory arrives with this version's next honeypot run.- It will ask for
- unknown until the next run
- Where it talks to
- unknown until the next run
- What the honeypot saw
- no credential files read · no network
- What we could not test
- server startup · the tool list · tool behavior
Not enough was observed to say yet. Not started: dependency install failed; the server itself was not observed. This version's code has not been inventoried for credentials and hosts either; both arrive with its next honeypot run (popular servers first). `vet-skills try linkedin-mcp-server` runs it now and prints the full answer.
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-01 and scored it 84/100 (Verified). In what ran, nothing we could detect went wrong: no undeclared network egress, no credential reads, no persistent instruction writes. What it does with a real credential was not observed; the static findings and the publisher carry the rest of the score. Summary: no network, touches nothing outside the project, writes no memory.
Behavior trace
Honeypot run · 0 s · 2 scenarios · 0 deviationsStatic findings
rm -rf /var/lib/apt/lists/*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.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.child = subprocess.Popen(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.``.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.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.kill -TERM "$server_pid" 2>/dev/null || trueFix: 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.kill -TERM "$xvfb_pid" 2>/dev/null || trueFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.if ! kill -0 "$xvfb_pid" 2>/dev/null; thenFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell."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.kill -TERM "$xvfb_pid" 2>/dev/null || trueFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.# .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.completed = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.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.chmod -R 755 /opt/patchright && \Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.kill -TERM "$server_pid" 2>/dev/null || trueFix: 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.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."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.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.# 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.completed = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.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.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.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."description": "Optional. Route the browser through a proxy, as scheme://host:port (http, https, socks4 or socks5). May also include credentials, as http://user:password@host:port. Only browser traffiFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose."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.result = 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.result = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out."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.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."",Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent."fix: ",Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent.Contributions are welcome. Search the existing issues first, then use the [issue forms](https://github.com/stickerdaniel/linkedin-mcp-server/issues/new/choose) for anything new. AI agents follow the [Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.kill $SERVER_PID 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.other = 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.value = "https://ru.linkedin.com/in/%D0%B0%D0%BD%D0%B4%D1%80%D0%B5%D0%B9"Fix: Put hosts, commands and strings in plain source. Decoding at runtime looks identical to malware and costs points on its own.return subprocess.run(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.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."fix: ",Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent.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.[ -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."",Fix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.kill $SERVER_PID 2>/dev/nullFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.grep -q '"error"' /tmp/verify-pr-$PR-initialized.json && { echo "notifications/initialized returned a protocol error. Execution limit." >&2; cat /tmp/verify-pr-$PR-initialized.json >&2; kill $SERVER_PFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell."""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."fix: Subject.",Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent.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.normalize_person_identifier("%D0%B0%D0%BD%D0%B4%D1%80%D0%B5%D0%B9")Fix: Put hosts, commands and strings in plain source. Decoding at runtime looks identical to malware and costs points on its own.return subprocess.run(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."fix(): Subject",Fix: Keep SKILL.md to visible, descriptive text. Remove comments and encoded text that address the agent."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."description": "Optional. Route the browser through a proxy, as scheme://host:port (http, https, socks4 or socks5). May also include credentials, as http://user:password@host:port. Only browser traffiFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose."linkedin_mcp_server.daemon.owner.direct_http_client",Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.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."description": "Optional. Route the browser through a proxy, as scheme://host:port (http, https, socks4 or socks5). May also include credentials, as http://user:password@host:port. Only browser traffiFix: 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."plugins/linkedin-mcp-server/assets/icon.svg",Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.[ -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.answered = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.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."",Fix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.assert urlparse(url).path == "/in/%D0%B0%D0%BD%D0%B4%D1%80%D0%B5%D0%B9/"Fix: Put hosts, commands and strings in plain source. Decoding at runtime looks identical to malware and costs points on its own.grep -q '"error"' /tmp/repro-$NUM-initialized.json && { echo "notifications/initialized returned a protocol error. Execution limit." >&2; cat /tmp/repro-$NUM-initialized.json >&2; kill $SERVER_PID 2>/Fix: 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.``create_mcp_server`` assembles it, with a backend whose election finds theFix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.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.# 0755 to 0700. A custom profile directly under /tmp would try to chmodFix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.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.Cost to the agent
Not measured yet; benchmarks are collected with each run since November 5, 2026. See the MCP server benchmarks.
Known vulnerabilities
Vulnerability advisories (OSV) cover npm and PyPI packages; this registry has no advisory database.