Skip to content

Releases: horizonbymuneeb/linkedin-mcp-pro

v2.3.9 — Redesigned cookies UI + JSESSIONID-aware Voyager

Choose a tag to compare

@horizonbymuneeb horizonbymuneeb released this 19 Jun 13:36

What's new in v2.3.9

🍪 Cookies page redesign

  • Hero card with status icon + badge + 4-stat meta row
  • Timeline strip: last-saved / last-verified / last-failed
  • Error explainer that names the failure reason + 4 common causes
  • Tab bar (browser / li_at / json) — only one panel visible at a time
  • Cookie inventory: search box + filter chips (auth, linkedin, secure, expiring)
  • Cookie table: masked values, day-count in expires, sticky header, virtual scroll
  • Re-verify button + refresh button in inventory section

🔐 Profile endpoint: full session validation

  • Loads JSESSIONID from storage_state.json alongside li_at
  • Passes both to Voyager client so LinkedIn validates the full session
  • Previously only li_at was sent — LinkedIn rotated to require both

🩺 Profile health endpoint enhancements

  • New timeline field (last_saved, last_verified, last_failed) read from audit log
  • New last_error field with the rejection reason from LinkedIn
  • Auto-detects created_at vs ts column in audit table

Files changed

  • linkedin_mcp/static/cookies.html — full redesign (+514 / -129)
  • linkedin_mcp/cookies_api.py — timeline + last_error fields (+73)
  • linkedin_mcp/web.py — JSESSIONID loader in api_profile (+14)

Install

```bash
pipx install git+https://github.com/horizonbymuneeb/linkedin-mcp-pro.git@v2.3.9
linkedin-mcp-web --port 8080
```

⭐ Star if this saves you from a LinkedIn ban.

v1.1.0 — Tier 3 with ban-safety gates + cookies panel + login CLI

Choose a tag to compare

@horizonbymuneeb horizonbymuneeb released this 19 Jun 02:39

🔐 NEW: Cookies & Login panel

Three ways to authenticate, no browser automation needed:

A. Browser login — one-click Playwright launch (headed/headless)
B. Paste li_at — copy from LinkedIn DevTools → instant save + live verification
C. Import full cookie JSON — from EditThisCookie / Cookie-Editor extension

Plus 7 new endpoints, login CLI flags, title-based session detection.

🛡️ Tier 3 — Ban-safety infrastructure

10-rule safety gate (quota, business hours, whitelist/blacklist, cooldown, account age, warmup, negative response, shadow-ban pause). All auto-engagement tools (auto_like/comment/connect) gated through it. Default dry_run=true.

📊 Other v1.1.0 features

  • Feed listener + daily digest (read-only)
  • Auto-like by keyword (gated, conservative defaults)
  • Auto-comment by keyword (30+ blacklist phrases)
  • Auto-connect by criteria (personalized notes)
  • Voice-to-post (Whisper transcription)
  • 11 new MCP tools

🐛 Fixes

  • /api/summary: surface frontend-expected fields (was returning undefined)
  • version bumped to 1.1.0
  • test_cli_recent_empty: handle shared DB

📈 Stats

  • 581/581 tests pass
  • 54 MCP tools
  • 14 web endpoints (7 existing + 7 cookie/login)
  • 9 CLI commands (login now supports --headless/--headed/--timeout)
  • 36 source modules

🔗 See also

  • /static/cookies.html — the new cookies panel UI
  • PLAN.md — full roadmap to v2.0

v0.4.2 — Critical fixes for new users

Choose a tag to compare

@horizonbymuneeb horizonbymuneeb released this 18 Jun 15:32

🔧 Three silent-failure bugs found via end-to-end audit

A new user installing v0.4.1 would have hit these issues on first setup. All fixed.

Bug 1 — Profile filename mismatch (silent)

  • scripts/cookie_to_profile.py was writing state.json
  • linkedin_mcp.browser.auth.has_valid_session() was looking for storage_state.json
  • Result: Profile built via the script was invisible to the MCP server

Fix: Script now writes the canonical storage_state.json (matches agent-browser convention). auth.py accepts both for backward compat. Existing profiles renamed in place.

Bug 2 — __version__ was 0.1.0

  • linkedin_mcp/__init__.py said 0.1.0 despite being on v0.4.1
  • Anyone running python -c "import linkedin_mcp; print(linkedin_mcp.__version__)" got a confusing answer

Fix: Both pyproject.toml and __init__.py now report 0.4.2.

Bug 3 — Proxy was hardcoded

  • linkedin_mcp/browser/client.py had socks5://127.0.0.1:1080 hardcoded
  • No way to use a residential proxy or different port without editing source

Fix: Reads LINKEDIN_MCP_PROXY (same env var the standalone scripts use) with fallback to the hardcoded default. Documented in .env.example.

Docs refresh

  • .env.example — added LINKEDIN_MCP_PROFILE_DIR + LINKEDIN_MCP_PROXY with examples
  • examples/mcp_client_config.json — rewritten as a fully-commented template
  • USAGE.md — was still v0.3-era, now has v0.4 4-mode table + decision tree
  • CHANGELOG.md — v0.4.2 entry

Verified end-to-end

  • 179/179 tests pass
  • post_with_stealth.py --check
  • use_profile_session.py --check
  • linkedin-mcp-health ✓ (detects profile + DB + quotas)
  • linkedin_mcp.__version__ = 0.4.2

Upgrade from v0.4.1

Nothing required. The filename change is handled automatically (existing state.json files are accepted too).

Full release notes: CHANGELOG.md

v0.4.1 — Cookie → Profile conversion (30-sec bootstrap)

Choose a tag to compare

@horizonbymuneeb horizonbymuneeb released this 18 Jun 15:14

🎉 Build a persistent profile from a single li_at cookie in 30 seconds

The most user-friendly way to bootstrap linkedin-mcp-pro. If you already
have a working li_at cookie (from DevTools), this script turns it into
a self-updating session profile that lasts 6-12 months.

echo "LI_AT=AQED..." | sudo tee /etc/linkedin-mcp-pro/li_at > /dev/null
python3 scripts/cookie_to_profile.py
# → 18 LinkedIn cookies captured in state.json
# → from now on, post_with_stealth.py auto-uses the profile

What's new

  • scripts/cookie_to_profile.py — the quick path
  • Profile detection now supports both state.json AND Default/Cookies layouts
  • --check flag in use_profile_session.py no longer accidentally posts
  • Fixed PermissionError crash on root-only cookie files

Why state.json instead of persistent context?

During testing we discovered a Playwright quirk: launch_persistent_context
doesn't reliably persist HttpOnly cookies to the on-disk Cookies DB.
The li_at cookie would go missing on next launch. storage_state.json is
the official Playwright API for session persistence and works correctly
with HttpOnly cookies.

Migration from v0.4.0

Nothing required. The new script is additive. Existing users with a
working Default/Cookies profile continue to work unchanged.

Full release notes: see CHANGELOG.md

v0.4.0 — Profile sync + Termux + 5 proxy options

Choose a tag to compare

@horizonbymuneeb horizonbymuneeb released this 18 Jun 14:49

🎉 Profile sync workflow — no more pasting cookies every few days

linkedin-mcp-pro v0.4.0 introduces 3 authentication modes:

Mode Setup Cookie lifetime For
A. Profile sync 5 min, one-time 6-12 months Most users (laptop + server)
B. linkedin-mcp login 2 min 6-12 months Local machines
C. LI_AT cookie 1 min, recurring 1-7 days Headless / CI / emergency

New scripts

  • `scripts/bootstrap_session.sh` — copy laptop Chrome profile to server
  • `scripts/use_profile_session.py` — post using the synced profile
  • `scripts/termux_setup.sh` — Android phone as SOCKS proxy host

New docs

  • `docs/PROXY_SETUP.md` — 5 proxy options (SSH, cloudflared, Termux, residential, WireGuard)
  • `docs/TERMUX_SETUP.md` — full Termux guide

Get started

```bash

On your laptop (one time)

git clone https://github.com/horizonbymuneeb/linkedin-mcp-pro
./scripts/bootstrap_session.sh

On your server (from now on, automatic)

pip install -e . && linkedin-mcp-pro
```

Full release notes: see CHANGELOG.md

v0.3.0 — Persistent browser session

Choose a tag to compare

@horizonbymuneeb horizonbymuneeb released this 18 Jun 07:52

linkedin-mcp-pro v0.3.0

Major UX improvement: no more 7-day cookie expiry pain. Authenticate once through a real browser, session is reused forever.

✨ New features

  • linkedin-mcp login command — opens a browser, you log in normally (email + password + 2FA), the session is captured and saved to ~/.linkedin-mcp/profile/
  • Persistent browser profile — standard Chromium user-data-dir. Survives reinstalls, portable, can be opened in Chrome for debugging
  • BrowserChallenge exception — when LinkedIn shows a captcha / MFA / security check, the browser window stays open. Solve manually, then tell your MCP client to retry
  • LINKEDIN_MCP_PROFILE_DIR env var — override the default profile location (useful for Docker volume mounts)
  • LI_AT is now optional — used as fallback only when no profile exists

🔄 Changed

  • Default browser profile path: ./data/browser-profile/~/.linkedin-mcp/profile/ (outside project dir, survives git clean)
  • BrowserClient requires a profile by default
  • _check_for_challenges() now detects 7 URL patterns: /checkpoint, /authwall, /uas/, /login, /login-submit, /challenge, /account-restricted

📊 Tests

  • 179/179 pass (was 127, +52 new in test_v0_3_features.py)
  • Coverage: interactive_login (8 tests), BrowserChallenge (13 tests), has_valid_session (6), ensure_session (3), profile path resolution (10), and more

📚 Docs

  • USAGE.md: new "Setup and authentication" section, new "Handling security checks" section, updated troubleshooting
  • README.md: new "Quick start (v0.3+)" section, moved cookie extraction to "Legacy"
  • CHANGELOG.md: full v0.3.0 entry with migration guide

🔄 Migration from v0.2.0

pip install -U linkedin-mcp-pro
linkedin-mcp login   # one-time: log in normally
# Optionally remove LI_AT from .env (it'll be ignored)
linkedin-mcp-pro     # start MCP server

Headless users: LI_AT still works as a fallback. Or scp the profile from a local machine.

🔗 Links