Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

LinkedIn Job Search Server

БесплатноНе проверен

Enables AI assistants to search LinkedIn jobs with built-in rate limiting to prevent IP bans. Supports job search, filtering, company profiles, and job categori

GitHubEmbed

Описание

Enables AI assistants to search LinkedIn jobs with built-in rate limiting to prevent IP bans. Supports job search, filtering, company profiles, and job categories through MCP tools.

README

A Model Context Protocol (MCP) server that enables AI assistants (Claude, ChatGPT, etc.) to search LinkedIn jobs with built-in rate limiting to prevent IP bans.

Features

LinkedIn-Only Job Search — Real-time job data from LinkedIn via JobSpy
Request Throttling — Configurable delays (default: 2 seconds) between API calls
Rate Limit Handling — Graceful error messages when LinkedIn limits requests
5 MCP Tools — Search, filter, get details, company profiles, discover categories
Type-Safe — Pydantic models for all data structures
Production Ready — Comprehensive logging and error handling

Project Structure

mcp-server/
├── src/
│   ├── index.py              # MCP server with tool definitions & handlers
│   └── linkedin_client.py    # JobSpy wrapper with rate limiting
├── examples/
│   └── (future usage examples)
├── requirements.txt          # Python dependencies
├── pyproject.toml            # Project metadata
├── README.md                 # This file
├── .gitignore
└── .vscode/
    └── linkedin-mcp.json     # VS Code MCP configuration

Installation

Prerequisites

  • Python 3.10+
  • pip package manager
  • Virtual environment (recommended)

Setup

  1. Clone or navigate to the project:

    cd /Users/tarunkumaruppu/AI/mcp-server
    
  2. Create and activate a virtual environment:

    python3 -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    
  3. Install dependencies:

    pip install -r requirements.txt
    
  4. Verify installation:

    python -c "from src.linkedin_client import LinkedInJobClient; print('✅ Installation successful!')"
    

Configuration

Rate Limiting

Control how frequently the server calls LinkedIn to prevent IP bans.

Default behavior: 2 seconds between requests

To customize:

# Via environment variable (override default)
export LINKEDIN_REQUEST_DELAY=3.0  # 3 seconds between requests
python src/index.py

# Or set in code (src/index.py, line ~35):
linkedin_client = LinkedInJobClient(request_delay=3.0)

Recommended values:

  • 2.0 — Balanced (default)
  • 3.0-5.0 — Conservative (safer)
  • 1.0 — Aggressive (risk of bans)

VS Code Integration

  1. Open VS Code settings (Cmd+, on macOS)
  2. Search for "MCP Servers"
  3. The server is pre-configured in .vscode/linkedin-mcp.json
  4. Restart VS Code to enable

Or manually add to .vscode/settings.json:

{
  "mcpServers": {
    "linkedin-job-search": {
      "type": "stdio",
      "command": "python",
      "args": ["src/index.py"],
      "cwd": "/path/to/mcp-server"
    }
  }
}

Available Tools

1. search_jobs

Search for jobs on LinkedIn with optional filters.

Parameters:

  • keywords (required) — Job search keywords (e.g., "Python Developer")
  • location (optional) — Job location (default: "United States")
  • job_type (optional) — Filter by type (e.g., "full-time", "part-time")
  • experience_level (optional) — Filter by level (e.g., "entry-level", "senior")
  • hours_old (optional) — Jobs posted within last N hours (e.g., 24, 168)
  • limit (optional) — Max results (default: 25, max recommended: 50)

Example:

search_jobs(
  keywords="Data Scientist",
  location="San Francisco, CA",
  job_type="full-time",
  limit=20
)

Response:

Found 20 jobs for 'Data Scientist' in San Francisco, CA

1. Senior Data Scientist at Google (San Francisco, CA) [$150,000 - $200,000]
   Job ID: a1b2c3d4e5f6
   URL: https://www.linkedin.com/jobs/view/...
   Type: Full-time
   Posted: 2 days ago

2. get_job_details

Get detailed information about a specific job.

Parameters:

  • job_id (required) — Job ID from search results
  • job_url (required) — Job URL from search results

Example:

get_job_details(
  job_id="a1b2c3d4e5f6",
  job_url="https://www.linkedin.com/jobs/view/..."
)

Response:

Job Details (ID: a1b2c3d4e5f6)
job_id: a1b2c3d4e5f6
job_url: https://www.linkedin.com/jobs/view/...
message: Full job details are available by visiting the LinkedIn URL provided.
note: For complete job descriptions, visit the job_url directly on LinkedIn.

3. filter_jobs

Filter job results by salary, type, or keywords (local operation, no API call).

Parameters:

  • salary_min (optional) — Minimum annual salary
  • salary_max (optional) — Maximum annual salary
  • job_type (optional) — Filter by job type
  • keywords_filter (optional) — Filter by keywords in title/company

Example:

filter_jobs(
  salary_min=120000,
  salary_max=200000,
  job_type="full-time",
  keywords_filter="remote"
)

4. fetch_company_profile

Get company information from LinkedIn.

Parameters:

  • company_name (required) — Company name (e.g., "Google")

Example:

fetch_company_profile(company_name="Google")

Response:

Company Profile: Google

LinkedIn URL: https://www.linkedin.com/search/results/companies/?keywords=Google
Open Jobs: 142

5. list_job_categories

Discover supported job types and experience levels (no API call).

Example:

list_job_categories()

Response:

Supported Job Categories

Job Types:
  - Full-time
  - Part-time
  - Contract
  - Temporary
  - Internship

Experience Levels:
  - Entry-level
  - Mid-level
  - Senior
  - Executive

Note: Not all filters may be available for all searches on LinkedIn.

Rate Limiting & Error Handling

How Rate Limiting Works

  1. Request Throttle — Server waits LINKEDIN_REQUEST_DELAY seconds between API calls
  2. Timestamp Tracking — Each request timestamp is logged for debugging
  3. Sleep Before Request — If requests come too fast, the server sleeps to enforce delay

Common Errors & Solutions

❌ "LinkedIn rate limit reached"

Error: LinkedIn rate limit reached. Please wait 5-10 minutes before retrying.

Solution: Increase LINKEDIN_REQUEST_DELAY to 3-5 seconds, or wait and retry.

❌ "LinkedIn blocked the request (HTTP 403)"

Error: LinkedIn blocked the request (HTTP 403). Your IP may be temporarily banned.
       Wait 24-48 hours before retrying.

Solution: Your IP is temporarily blocked by LinkedIn. Wait 24-48 hours, then retry with higher delay.

❌ "Failed to search jobs"

Error: Failed to search jobs: [detailed error message]

Solution: Check your internet connection, keywords, and location. Review logs for details.


Logging

All requests and errors are logged to stdout with timestamps.

Log format:

2026-06-10 14:30:45,123 - src.linkedin_client - INFO - Searching LinkedIn for: Python Developer in San Francisco
2026-06-10 14:30:47,456 - src.linkedin_client - INFO - Found 25 jobs
2026-06-10 14:30:48,789 - src.index - INFO - Tool called: search_jobs with arguments: {...}

To adjust log level:

# In src/index.py, line ~20
logging.basicConfig(level=logging.DEBUG)  # For verbose output

Usage Examples

Example 1: Simple Job Search

Claude: "Find me Python developer jobs in San Francisco"

→ Tool Call: search_jobs(
    keywords="Python Developer",
    location="San Francisco, CA",
    limit=25
  )

→ Result: [25 job listings with titles, companies, salaries]

Example 2: Search with Filters

Claude: "Find senior-level data scientist jobs in NYC, full-time, posted in the last 7 days"

→ Tool Call: search_jobs(
    keywords="Data Scientist",
    location="New York, NY",
    job_type="full-time",
    experience_level="senior",
    hours_old=168,
    limit=20
  )

→ Result: [20 filtered job listings]

Example 3: Company Research

Claude: "How many open positions does Google have on LinkedIn?"

→ Tool Call: fetch_company_profile(company_name="Google")

→ Result: 
  LinkedIn URL: https://www.linkedin.com/search/results/companies/?keywords=Google
  Open Jobs: 142

Example 4: Multi-Step Job Hunt

Turn 1: Claude searches for jobs
  → search_jobs(keywords="ML Engineer", location="Remote", limit=30)
  
Turn 2: Claude asks for company info on top candidates
  → fetch_company_profile(company_name="Anthropic")
  
Turn 3: Claude filters results by salary
  → filter_jobs(salary_min=150000, salary_max=250000)

Performance & Limitations

Performance

Operation Latency API Calls
search_jobs 2-10 seconds 1
get_job_details 2-5 seconds 1
filter_jobs <1 second 0 (local)
fetch_company_profile 2-10 seconds 1
list_job_categories <1 second 0 (local)

Limitations

⚠️ JobSpy Limitations:

  • Limited job description text extraction (full details require visiting LinkedIn URL)
  • Company profile data is minimal (name, URL, job count only)
  • Salary data may be incomplete on LinkedIn

⚠️ Rate Limiting:

  • Default 2-second throttle means max ~30 jobs per minute
  • LinkedIn may impose additional limits if too many requests from same IP
  • No guaranteed uptime—LinkedIn can block access at any time

⚠️ Data Freshness:

  • Job listings are real-time from LinkedIn
  • Salaries and benefits may not be up-to-date
  • Closed jobs may still appear briefly in results

Development

Project Dependencies

  • mcp — Model Context Protocol SDK
  • jobspy — LinkedIn job scraper
  • pydantic — Data validation & type hints
  • python-dotenv — Environment variable support

Code Structure

src/linkedin_client.py:

  • LinkedInJobClient class — Main client with rate limiting
  • JobListing Pydantic model — Job data structure
  • CompanyProfile Pydantic model — Company data structure

src/index.py:

  • MCP server setup and tool definitions
  • Tool handlers (search, details, filter, company, categories)
  • Error handling and formatting

Extending the Server

To add a new tool:

  1. Define the tool schema in get_tools() (src/index.py)
  2. Implement handler in linkedin_client.py
  3. Add MCP handler in handle_call_tool() (src/index.py)
  4. Document in this README

Example:

# 1. In linkedin_client.py
def my_new_feature(self, param: str) -> dict:
    """Implementation"""
    pass

# 2. In index.py, add to get_tools():
Tool(
    name="my_tool",
    description="...",
    inputSchema={...}
)

# 3. In handle_call_tool():
elif name == "my_tool":
    return await handle_my_tool(arguments)

# 4. Create handler:
async def handle_my_tool(arguments: dict):
    ...

Troubleshooting

Issue: ModuleNotFoundError: No module named 'mcp'

Solution:

pip install -r requirements.txt

Issue: Connection timeout to LinkedIn

Solution:

  • Check internet connection
  • Verify LinkedIn is accessible from your IP (not blocked)
  • Increase LINKEDIN_REQUEST_DELAY to reduce request frequency

Issue: Empty search results

Solution:

  • Try different keywords (LinkedIn may have strict matching)
  • Expand location (try "United States" instead of specific city)
  • Check if jobs exist on LinkedIn directly

Issue: Server won't start

Solution:

# Verify Python version
python --version  # Should be 3.10+

# Check dependencies
python -c "import mcp; import jobspy; print('OK')"

# Run with verbose logging
PYTHONUNBUFFERED=1 python src/index.py

Security Considerations

Current Implementation

✅ Parameterized inputs (no SQL injection risk)
✅ Request throttling (prevents IP bans)
✅ Graceful error handling (no sensitive info leakage)
✅ Local-only operation (no cloud storage)

For Production Use

⚠️ Consider adding:

  • IP rotation for high-volume searches
  • Request caching (SQLite) to reduce API calls
  • User rate limiting (per-user request quotas)
  • Audit logging (track who searches what)
  • API key authentication (if exposing over network)

FAQ

Q: Will LinkedIn ban my IP?
A: Unlikely with the default 2-second throttle. LinkedIn allows scraping via JobSpy. Higher request rates or aggressive filtering may trigger temporary blocks (24-48 hours).

Q: Can I search all job boards at once?
A: No, this server is LinkedIn-only. Use JobSpy directly for multi-source searches.

Q: How many jobs can I search per day?
A: Unlimited theoretically, but LinkedIn may rate-limit or block after 1000+ requests/hour.

Q: Can I save job listings locally?
A: Not in this version. Extend with SQLite caching if needed.

Q: Does this tool post on LinkedIn?
A: No, it's read-only. Cannot apply to jobs, message recruiters, or modify profiles.


References


License

MIT License — See LICENSE file for details.


Support

For issues, questions, or feature requests:

  1. Check the Troubleshooting section above
  2. Review Logs for detailed error messages
  3. Verify your Configuration (request delay, credentials, internet)

Last Updated: June 10, 2026
Version: 1.0.0
Status: Production Ready

from github.com/Tarunuppu/linkedIn-mcp

Установка LinkedIn Job Search Server

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/Tarunuppu/linkedIn-mcp

FAQ

LinkedIn Job Search Server MCP бесплатный?

Да, LinkedIn Job Search Server MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для LinkedIn Job Search Server?

Нет, LinkedIn Job Search Server работает без API-ключей и переменных окружения.

LinkedIn Job Search Server — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить LinkedIn Job Search Server в Claude Desktop, Claude Code или Cursor?

Открой LinkedIn Job Search Server на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare LinkedIn Job Search Server with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории ai