Skip to main content
Glama

LinkedIn Analyzer

License Release Python

Analyze your own LinkedIn profile through LM Studio using an MCP server and Playwright — without the official LinkedIn API.

The tool reuses your existing browser session (including 2FA) to fetch your profile data as structured JSON, which a local LLM can then analyze for optimization opportunities.

  • This tool uses browser automation, not LinkedIn's official API.

  • Using it may violate LinkedIn's Terms of Service. Account restrictions are theoretically possible.

  • Use it only for your own profile, for personal, non-commercial purposes. Do not scrape third-party profiles, do not hammer the site.

  • You are solely responsible for how you use this software.

Related MCP server: Networking MCP

Architecture

┌─────────────┐      ┌──────────────┐      ┌─────────────────────┐      ┌──────────┐
│ LM Studio   │ ───→ │ MCP Server   │ ───→ │ Background Server   │ ───→ │ Browser  │
│ (LLM)       │ MCP  │ (stdio)      │ HTTP │ (127.0.0.1:8766)    │      │ Playwright│
└─────────────┘      └──────────────┘      └─────────────────────┘      └──────────┘

Component

Purpose

mcp-server/linkedin_mcp.py

MCP server (stdio JSON-RPC) exposed to LM Studio

background_server.py

Long-running daemon that keeps the browser open (port 8766)

session_manager.py

Encrypts and persists the browser session locally

config.py

Environment-driven configuration

Prerequisites

The repo assumes nothing except:

  • Python 3.10+ (Linux/macOS/Windows via WSL — a POSIX shell)

  • LM Studio (local, version 0.3.17+ with MCP support)

  • A LinkedIn account (you will log in manually once)

Everything else is installed by the repo itself: a virtualenv, the Python dependencies, the Playwright browser (a managed Chrome for Testing build — no separate Chrome install needed), a session-encryption key, the background server as an auto-start service (launchd on macOS, systemd on Linux, nohup fallback otherwise), and the MCP registration inside LM Studio. curl, lsof, gcc or any other CLI tools are not required.

Installation

# 1. Clone and enter the repo
git clone https://github.com/FinleyVeeDub/linkedin-analyzer.git
cd linkedin-analyzer

# 2. Configure (optional - all values have working defaults)
cp .env.example .env
# edit .env as needed (see below)

# 3. Install everything in one go: builds the environment, installs the
#    background server as an auto-start service, and registers the MCP server
#    in LM Studio (no manual JSON editing):
./scripts/install.sh

install.sh prints ok when done. It is safe to re-run (idempotent). To undo everything, run ./scripts/uninstall.sh (or ./scripts/uninstall.sh --purge to also remove the venv and saved sessions).

On Debian/Ubuntu you may need the venv module first: sudo apt-get install -y python3-venv — the scripts tell you this if it is missing.

NOTE

Playwright installs its own browser

Playwright downloads a managed Chrome for Testing build into venv/ (first run: ~150 MB) and launches that — you do not need a separate Chrome/Chromium installation. install.sh, bootstrap.sh and the LM Studio wrapper all run venv/bin/python -m playwright install chromium for you. If the browser is ever missing or broken, reinstall it with venv/bin/python -m playwright install chromium.

What gets installed

Service

Where

Purpose

Python virtualenv

venv/

Isolated Python environment

Python deps + Playwright browser

venv/

The only external dependencies

Playwright Chrome for Testing

venv/

Managed Chromium downloaded by Playwright (no system Chrome needed)

Session encryption key

~/.linkedin-analyzer/session.key

Encrypts the saved session

Background server service

launchd agent / systemd user unit

Keeps the browser open, auto-starts on boot

MCP server entry

~/.lmstudio/mcp.json

Lets LM Studio launch the MCP server

First run inside LM Studio (no install.sh)

If you skip install.sh, the wrapper (scripts/linkedin-analyzer-mcp-wrapper.sh) bootstraps everything itself the first time LM Studio starts it. The slow part (downloading the Playwright browser) runs in the background so it does not hit LM Studio's MCP startup timeout; the first tool call may answer "not ready yet" for a few seconds.

Configuration (.env)

Variable

Default

Description

HOST

127.0.0.1

Bind address of the background server

PORT

8766

Port of the background server

SESSION_DIR

./browser_sessions

Where the encrypted session file is stored

SESSION_ENCRYPTION_KEY

(empty)

Optional explicit Fernet key

SESSION_ENCRYPTION_KEY_FILE

~/.linkedin-analyzer/session.key

Key file, created automatically if missing

BROWSER_HEADLESS

False

True for automated/headless runs

[!INFO] Port 8766 may already be occupied

.env is the single source of truth for the port — nothing needs to be edited in code. Every component reads it: config.py (pydantic-settings), background_server.py (settings.PORT), linkedin_mcp.py (stdlib dotenv reader), and all scripts (start-daemon.sh, the LM Studio wrapper, bootstrap.sh, install.sh) source .env before using PORT. A real environment variable always wins over .env.

On machines where another service already binds 8766 (e.g. the Hermes agent reserves 8766, in which case the analyzer was moved to 8767), LM Studio cannot reach the daemon and the MCP tools fail with a connection error. Fix: pick a free port and set PORT in .env, e.g. PORT=8767, then restart start-daemon.sh and LM Studio.

The 8766 fallback default (only used when PORT is set neither in .env nor as an environment variable — change it here only if you want a different default for everyone):

File

Line

Usage

config.py

13

Pydantic default for PORT

background_server.py

1143

Daemon bind port (settings.PORT)

mcp-server/linkedin_mcp.py

92

MCP server's base URL to the daemon

scripts/linkedin-analyzer-mcp-wrapper.sh

50

Wrapper default

scripts/bootstrap.sh

39

Bootstrap default

scripts/install.sh

40

Service install default

start-daemon.sh

30

Daemon start default

.env.example

6

Documented default

Running

Option A — Start the daemon manually

./start-daemon.sh          # starts background_server.py on PORT (default 8766)
./stop-daemon.sh           # stops it again

The background server must keep running while you use the MCP tools — it holds the browser open.

Verify it is up:

curl http://127.0.0.1:8766/health

Option B — Auto-start wrapper (used by LM Studio)

scripts/linkedin-analyzer-mcp-wrapper.sh is the command LM Studio launches. The wrapper locates Python 3.10+ itself, builds the environment on first run (the slow steps in the background), ensures a session key exists, starts the background server once its dependencies are ready, and then runs the MCP server in stdio mode itself:

{
  "mcpServers": {
    "linkedin-analyzer": {
      "command": "/path/to/linkedin-analyzer/scripts/linkedin-analyzer-mcp-wrapper.sh"
    }
  }
}

Note: install.sh writes this entry for you into ~/.lmstudio/mcp.json with the correct absolute path. If you write it by hand, replace /path/to/linkedin-analyzer with the real absolute path of your clone. No args are needed — the wrapper starts the stdio MCP server itself.

Setup in LM Studio

  1. Run ./scripts/install.sh once in the terminal (recommended).

  2. Restart LM Studio, switch to the Program tab in the right sidebar — the linkedin-analyzer MCP server should be listed as connected.

  3. Start a chat with the system prompt — pick docs/system-prompt.en.md (or the German docs/system-prompt.de.md) and paste it in.

  4. Ask the assistant to check your session or analyze your profile.

If the MCP server does not show up, re-add it manually via Install > Edit mcp.json with the snippet from Option B, then fully restart LM Studio (a cached server definition may otherwise keep the old command).

First login (one-time)

  1. Call the linkedin_login tool — the browser opens at LinkedIn's login page.

  2. Log in manually in the browser (2FA is supported).

  3. The session auto-saves as soon as the login is detected. You can also force it with linkedin_save_session.

  4. Verify with linkedin_check_session.

MCP tools

Tool

Description

linkedin_check_session

Check whether a session exists and you are logged in

linkedin_login

Open the browser at LinkedIn's login page (does not wait for login)

linkedin_save_session

Persist the current session after a manual login

linkedin_get_profile

Fetch the raw profile data (JSON)

linkedin_analyze_profile

Fetch the profile data for analysis

linkedin_get_posts

Fetch your own recent posts from the activity tab (limit/scroll query args)

linkedin_get_post

Fetch one post by URL (url query arg, urn:li:activity:...)

linkedin_analyze_posts

Fetch your posts for analysis (limit/scroll query args)

linkedin_clear_session

Delete the saved session

Tool calls forward only whitelisted arguments (see PARAM_WHITELIST in mcp-server/linkedin_mcp.py) to the background server as query parameters; anything else in arguments is ignored.

HTTP API (background server)

Endpoint

Method

Description

/health

GET

Health check

/check

GET

Session/login status

/login

POST

Open the browser at the login page

/save

POST

Persist the current session

/session

DELETE

Clear the saved session

/profile

GET

Full profile data (name, headline, about, experience, education, skills)

/posts

GET

Own posts from the activity tab (limit, scroll query args)

/post

GET

Single post by URL (url query arg, validated against urn:li:activity:...)

/debug, /debug/dom, /debug/selectors

GET

Debugging aids

Security

Aspect

Implementation

Passwords

Never stored in code

Session

Stored locally and encrypted with Fernet (browser_sessions/)

2FA

Fully supported during the initial login

Data

Stays on your machine; the LLM only sees what you send it

Important: The browser_sessions/ files contain login tokens. They are encrypted, but treat them like passwords. The key lives in SESSION_ENCRYPTION_KEY_FILE (default ~/.linkedin-analyzer/session.key). Both are git-ignored — never commit them.

Troubleshooting

"Not logged in" / authwall redirects

curl -X DELETE http://127.0.0.1:8766/session   # clear session
curl -X POST http://127.0.0.1:8766/login       # log in again in the opened browser

MCP server does not initialize in LM Studio

  • Run ./scripts/install.sh once, restart LM Studio, and check the Program tab.

  • After changing the command, remove the MCP server and re-add it in LM Studio, then fully restart LM Studio (a cached server definition may otherwise keep the old command).

  • Test the MCP handshake directly in a terminal: printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | ./scripts/linkedin-analyzer-mcp-wrapper.sh You should get a JSON result back (no error).

  • If the wrapper fails, it writes progress to boot.log in the project directory and the daemon logs to background_server.log.

First tool call says "Background server unreachable / not ready yet"

  • On a very first run the Playwright browser is still downloading in the background. Wait a few seconds and call the tool again.

  • If it persists: check background_server.log, or run ./scripts/linkedin-analyzer-mcp-wrapper.sh --ensure-only once in the terminal (blocks until everything is ready, prints ok).

Browser does not open

  • Make sure BROWSER_HEADLESS=False in .env (or unset).

  • Reinstall the browser: venv/bin/python -m playwright install chromium

  • On Linux only, you may also need system libraries: venv/bin/python -m playwright install-deps

Server not reachable

  • Is it running? curl http://127.0.0.1:8766/health

  • Port taken? Set another PORT in .env (the wrapper respects PORT too).

LinkedIn shows a captcha / rate limit

  • Wait a few hours.

  • Clear the session and log in again.

  • Do not send requests too frequently.

Project layout

linkedin-analyzer/
├── background_server.py        # Long-running daemon (keeps browser open, HTTP API)
├── session_manager.py          # Encrypted session persistence
├── config.py                   # Environment configuration
├── mcp-server/
│   └── linkedin_mcp.py         # MCP server for LM Studio (stdio)
├── scripts/
│   └── linkedin-analyzer-mcp-wrapper.sh # Auto-start wrapper: bootstraps env + stdio MCP
├── docs/
│   ├── system-prompt.en.md     # English system prompt for LM Studio
│   └── system-prompt.de.md     # German system prompt for LM Studio
├── start-daemon.sh / stop-daemon.sh
├── requirements.txt
├── .env.example
└── browser_sessions/           # Encrypted sessions (git-ignored)

Development

Test the MCP server directly:

venv/bin/python mcp-server/linkedin_mcp.py --stdio

Then send JSON-RPC lines over stdin (initialize, tools/list, tools/call).

License

MIT — see LICENSE.

Credits

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    An MCP server for LinkedIn automation that enables users to search for jobs, retrieve profile details, manage connections, and read or send messages. It leverages Playwright and Browserbase to interact with LinkedIn through an existing authenticated browser session.
    6
    12
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Local-first MCP server for research on AI-assisted browsing of a user-owned professional-network account (e.g., LinkedIn), providing read-focused tools such as profile, company, search, and feed reads.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for programmable LinkedIn automation via Playwright, offering 20 tools for profile management, messaging, feed interaction, and job searching through real browser automation.
    29
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    Playwright-powered MCP server for LinkedIn that automates jobs, profile edits, messaging, network actions, and feed posts using a real logged-in browser session.
    36
    Apache 2.0

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/FinleyVeeDub/linkedin-analyzer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server