Content
# LinkedIn MCP Server
[](https://opensource.org/licenses/MIT)
[](https://www.python.org/)
[](https://modelcontextprotocol.io/)
An MCP server that gives AI assistants full access to LinkedIn — search jobs, view profiles and companies, generate AI-powered resumes and cover letters, and track applications. Built with the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) (FastMCP).
---
## What It Does
| Category | Capabilities |
|---|---|
| **Job Search** | Search with filters (keywords, location, type, experience level, remote, recency), get job details, get recommendations |
| **Profiles & Companies** | Fetch any LinkedIn profile or company page, AI-powered profile analysis with optimization suggestions |
| **Resume Generation** | Generate resumes from LinkedIn profiles, tailor resumes to specific job postings, 3 built-in templates |
| **Cover Letters** | AI-generated cover letters personalized to each job, 2 built-in templates |
| **Application Tracking** | Track applications locally with status workflow (interested → applied → interviewing → offered/rejected/withdrawn) |
| **Output Formats** | HTML, Markdown, and PDF (via WeasyPrint) |
---
## Quick Start
### 1. Install
```bash
# Core installation
pip install -e .
# With AI features (resume/cover letter generation, profile analysis)
pip install -e ".[ai]"
# With PDF export
pip install -e ".[pdf]"
# Everything
pip install -e ".[all]"
```
### 2. Configure
```bash
cp .env.example .env
```
Edit `.env` with your credentials:
```env
LINKEDIN_USERNAME=your_email@example.com
LINKEDIN_PASSWORD=your_password
ANTHROPIC_API_KEY=sk-ant-... # Optional — enables AI features
```
### 3. Run
**Standalone:**
```bash
linkedin-mcp
```
**With Claude Desktop** — add to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"linkedin": {
"command": "linkedin-mcp"
}
}
}
```
**With Claude Code** — add to `.mcp.json`:
```json
{
"linkedin": {
"command": "linkedin-mcp"
}
}
```
---
## Tools Reference
### Job Tools (3)
| Tool | Parameters | Description |
|------|-----------|-------------|
| `search_jobs` | `keywords`, `location`, `job_type`, `experience_level`, `remote`, `date_posted`, `page`, `count` | Search LinkedIn jobs with rich filters |
| `get_job_details` | `job_id` | Get full description, skills, and metadata for a job posting |
| `get_recommended_jobs` | `count` | Get personalized job recommendations |
### Profile Tools (3)
| Tool | Parameters | Description |
|------|-----------|-------------|
| `get_profile` | `profile_id` | Fetch a LinkedIn profile (`"me"` for your own) — experience, education, skills |
| `get_company` | `company_id` | Get company info — description, size, headquarters, specialties |
| `analyze_profile` | `profile_id` | AI-powered profile review with actionable optimization suggestions |
### Document Generation Tools (4)
| Tool | Parameters | Description |
|------|-----------|-------------|
| `generate_resume` | `profile_id`, `template`, `output_format` | Generate a resume from a LinkedIn profile |
| `tailor_resume` | `profile_id`, `job_id`, `template`, `output_format` | Generate a resume tailored to a specific job posting |
| `generate_cover_letter` | `profile_id`, `job_id`, `template`, `output_format` | Create a personalized cover letter for a job |
| `list_templates` | `template_type` | List available templates (`resume`, `cover_letter`, or `all`) |
**Templates:** `modern` · `professional` · `minimal` (resume) | `professional` · `concise` (cover letter)
**Formats:** `html` · `md` · `pdf`
### Application Tracking Tools (3)
| Tool | Parameters | Description |
|------|-----------|-------------|
| `track_application` | `job_id`, `job_title`, `company`, `status`, `notes`, `url` | Start tracking a job application |
| `list_applications` | `status` | List all tracked applications, optionally filtered by status |
| `update_application_status` | `job_id`, `status`, `notes` | Update application status |
**Status values:** `interested` · `applied` · `interviewing` · `offered` · `rejected` · `withdrawn`
---
## Architecture
```
src/linkedin_mcp/
├── server.py # FastMCP entry point — 13 tools, 1 resource
├── config.py # Settings from .env (frozen dataclass)
├── exceptions.py # 7-class exception hierarchy
├── models/
│ ├── linkedin.py # Profile, Job, Company models (Pydantic v2)
│ ├── resume.py # Resume & cover letter content models
│ └── tracking.py # Application tracking model
├── services/
│ ├── linkedin_client.py # LinkedIn API wrapper (async via asyncio.to_thread)
│ ├── job_search.py # Job search with TTL caching
│ ├── profile.py # Profile/company access with caching
│ ├── resume_generator.py # AI-enhanced resume generation
│ ├── cover_letter_generator.py
│ ├── application_tracker.py # Local JSON-based application tracking
│ ├── cache.py # Unified JSON file cache with TTL
│ ├── template_manager.py # Jinja2 sandboxed template engine
│ └── format_converter.py # HTML → PDF/Markdown conversion
├── ai/
│ ├── base.py # Abstract AI provider interface
│ └── claude_provider.py # Anthropic Claude implementation
└── templates/
├── resume/ # modern.j2, professional.j2, minimal.j2
└── cover_letter/ # professional.j2, concise.j2
```
### Key Design Decisions
- **Official MCP SDK** — Uses `FastMCP` with `@mcp.tool()` decorators, not a custom protocol implementation
- **Async throughout** — All sync LinkedIn API calls wrapped in `asyncio.to_thread()` to avoid blocking
- **Layered architecture** — Tools → Services → Client, with caching at the service layer
- **AI is optional** — Core LinkedIn features work without an Anthropic API key; AI enhances resume/cover letter generation
- **Security hardened** — Jinja2 `SandboxedEnvironment`, WeasyPrint SSRF protection, path traversal guards, credential redaction, input validation
---
## Configuration
All settings are loaded from environment variables (`.env` file supported):
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `LINKEDIN_USERNAME` | Yes | — | Your LinkedIn email |
| `LINKEDIN_PASSWORD` | Yes | — | Your LinkedIn password |
| `ANTHROPIC_API_KEY` | No | — | Enables AI features (resume/cover letter generation, profile analysis) |
| `AI_MODEL` | No | `claude-sonnet-4-20250514` | Claude model to use |
| `DATA_DIR` | No | `~/.linkedin_mcp/data` | Directory for cache, tracking data, generated files |
| `CACHE_TTL_HOURS` | No | `24` | How long to cache LinkedIn API responses |
| `LOG_LEVEL` | No | `INFO` | Logging level (DEBUG, INFO, WARNING, ERROR) |
---
## Development
```bash
# Install with all dependencies
pip install -e ".[all,dev]"
# Run tests (82 tests)
pytest
# Run with coverage
pytest --cov=linkedin_mcp
# Lint
ruff check src/ tests/
```
### Test Coverage
Tests cover all layers: config, models, services (cache, tracker, job search, profile, resume/cover letter generation, LinkedIn client formatters, format converter), AI provider, and MCP tool handlers.
---
## Usage Examples
Once connected, ask your AI assistant:
> "Search for remote Python developer jobs in the US"
> "Show me the profile for satyanadella"
> "Generate a resume from my LinkedIn profile tailored to job 3847291056"
> "Create a cover letter for job 3847291056 using the concise template"
> "Track my application for the Senior Engineer role at Google — status: applied"
> "List all my applications that are in the interviewing stage"
> "Analyze my LinkedIn profile and suggest improvements"
---
## License
MIT
Connection Info
You Might Also Like
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
awesome-mcp-servers
A collection of MCP servers.
git
A Model Context Protocol server for Git automation and interaction.
remindb
An agentic memory database that cuts session tokens by 75–99%. One portable...
roampal
Memory that learns what works.
goldenmatch
Entity resolution toolkit -- deduplicate, match, privacy-preserving linkage....