v0.0.1
First release. An MCP server for LinkedIn that drives a real browser using your own logged-in session.
uvx linkedin-api-mcp auth # store your li_at cookie in the OS keyring
uvx linkedin-api-mcp --test # verify it works14 tools
Read — get_profile · get_my_profile · search_people · get_inbox · get_conversation · search_conversations · get_company · search_companies · search_jobs · get_job · search_posts · linkedin_status
Write — send_message · connect. Separately annotated, because they take actions another person sees.
What's different about it
A queue, not a promise. Every tool runs through one action queue: one LinkedIn action at a time, a floor between actions, and an hourly ceiling that refuses rather than sleeps. An agent in a retry loop is the realistic way an account gets restricted. When the ceiling trips, the model is told to stop and report — not to wait. linkedin_status shows where you stand.
Untrusted text is fenced. get_conversation and search_posts return text anyone on LinkedIn can write to you, to a model that also holds send_message and connect. That text is wrapped in delimiters carrying a nonce generated after the content exists, so injected text can't pre-forge a closing boundary.
The cookie is treated as the account. li_at survives a password change, and LinkedIn offers no way to audit live sessions. It lives in the OS keyring, never in a log, never in a return value. Errors report a failure class rather than interpolating exceptions, because Playwright embeds the URL it was driving in its exception text.
63 tests, no browser and no network — a missing LINKEDIN_COOKIE in CI is what guarantees no test can touch a real account.
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.
Known limitation
The selectors have never run against live LinkedIn. Every parser has fallbacks and degrades gracefully, but expect some to need adjustment on first real use — parse_failed errors say plainly when that's the cause. Please report them.
Disclaimer: This is an independent, community project. It is not affiliated with, authorized by, endorsed by, or sponsored by LinkedIn Corporation or Microsoft. "LinkedIn" is a registered trademark of LinkedIn Corporation and is used here only descriptively to identify the third-party service this software interoperates with.