Skip to main content
Glama
linkedin-job-mcp

linkedin-job-mcp

LinkedIn Jobs MCP

LinkedIn job search and full job details for your AI apps, plus Ghost Job Radar, a dashboard that shows which job postings are likely not really open. A Windows app connects itself to Claude Code, Codex, VS Code and other MCP clients; the same tools also come as an npm package, a REST API and a command line.

npm version npm downloads CI License

The setup menu of the Windows app

Tools

Tool

What your AI app gets

search_linkedin_jobs

Jobs by keyword and location, filtered by date, job type, remote work or fewer than 10 applicants

get_linkedin_job_details

One job's full description, seniority, employment type, industries, posting age and applicant count

check_ghost_job

Ghost Job Radar's grade for one posting: how likely it is a ghost job, your chance against the competition, and the facts behind it. Needs the radar running

It reads LinkedIn's public job pages, so it needs no account and no browser. Requests are spaced out and cached.

Related MCP server: job-radar

Ghost Job Radar

A dashboard on your computer that grades every job it sees for ghost-job risk: postings that stay up far longer than usual for their occupation, reposts with unchanged text, jobs gone from the employer's own site, start dates long past, talent-pool wording, layoff news while still hiring, and what you know about the employer. Every job gets three separate verdicts: ghost-risk, your chance, and whether the employer answers.

Ghost Job Radar: every job as a mark, further out means online longer than usual

linkedin-jobs-mcp radar

With the Windows app, choose 5 in its menu or run .\linkedin-jobs-mcp.exe radar. It needs Python 3.11 or newer. The first start sets up the radar's Python environment; every start also runs the LinkedIn source, so LinkedIn search and job pages work right away. Your data stays on your computer, in %LOCALAPPDATA%\linkedin-jobs-mcp\radar (macOS: ~/Library/Application Support/linkedin-jobs-mcp/radar, Linux: ~/.local/share/linkedin-jobs-mcp/radar). A .env file there switches on more sources, such as the Bundesagentur job board or Google for Jobs; radar/README.md explains every view, signal and source.

Why a posting got its grade

Install

Windows app

  1. Download linkedin-jobs-mcp.exe from the latest release. It is one file with Node.js inside.

  2. Double-click it. The file is not code-signed, so Windows may say "Windows protected your PC": choose More info → Run anyway.

  3. Choose 1 Install and connect the apps found. The app copies itself to %LOCALAPPDATA%\Programs\linkedin-jobs-mcp\ and adds itself to every supported app it finds.

  4. Restart those apps. The app has no window of its own: they start it in the background when they need the tools.

Installing the app and connecting the apps found

npm (Windows, macOS, Linux)

Needs Node.js 18 or newer.

npm install -g linkedin-jobs-mcp
linkedin-jobs-mcp connect

Or add it to an app by hand, through npx:

{
  "mcpServers": {
    "linkedin-jobs": { "command": "npx", "args": ["-y", "linkedin-jobs-mcp"] }
  }
}

On Windows, some apps need "command": "cmd", "args": ["/c", "npx", "-y", "linkedin-jobs-mcp"].

From source

git clone https://github.com/GhoshSrinjoy/linkedin-job-mcp.git
cd linkedin-job-mcp
npm install
npm run app -- connect

Connect your apps

App

Name for connect

Where the setting goes

Claude Code

claude-code

claude mcp add --scope user

Codex

codex

~/.codex/config.toml

VS Code

vscode

%APPDATA%\Code\User\mcp.json

VS Code Insiders

vscode-insiders

%APPDATA%\Code - Insiders\User\mcp.json

Claude Desktop

claude-desktop

%APPDATA%\Claude\claude_desktop_config.json

Cursor

cursor

~/.cursor/mcp.json

Windsurf

windsurf

~/.codeium/windsurf/mcp_config.json

Gemini CLI

gemini-cli

~/.gemini/settings.json

LM Studio

lm-studio

~/.lmstudio/mcp.json

Cline

cline

%APPDATA%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json

connect only adds or replaces the linkedin-jobs entry: other servers and settings stay, and the first change keeps a copy of the file next to it (<file>.linkedin-jobs.bak). A settings file with comments is left unchanged, and the entry to add is printed instead.

The server connected in two apps

Commands

Command

What it does

linkedin-jobs-mcp

The setup menu in a console window; the MCP server when an app starts it

linkedin-jobs-mcp install

Copy the Windows app to %LOCALAPPDATA%\Programs\linkedin-jobs-mcp\ and connect the apps found

linkedin-jobs-mcp connect [app ...]

Connect the apps found, or only the named ones (also when they are not found)

linkedin-jobs-mcp disconnect [app ...]

Remove the connection from every app, or only from the named ones

linkedin-jobs-mcp status

Which apps are found and connected

linkedin-jobs-mcp config [app ...]

Print the settings to add by hand

linkedin-jobs-mcp serve [--port 3000] [--host 127.0.0.1]

REST API plus MCP over HTTP

linkedin-jobs-mcp mcp

MCP over stdio (what the connected apps run)

linkedin-jobs-mcp job <id or URL>

One job's details as JSON

linkedin-jobs-mcp search --keyword "data engineer" --location "Berlin, Germany"

Search from the command line

linkedin-jobs-mcp radar [--port 8000] [--no-browser]

Open Ghost Job Radar

linkedin-jobs-mcp uninstall

Disconnect every app and remove the installed Windows app

With the Windows app, run them from its folder, for example .\linkedin-jobs-mcp.exe status.

Add it by hand

Every app needs the same thing: the program, started with the mcp argument. VS Code (mcp.json):

{
  "servers": {
    "linkedin-jobs": {
      "type": "stdio",
      "command": "C:\\Users\\you\\AppData\\Local\\Programs\\linkedin-jobs-mcp\\linkedin-jobs-mcp.exe",
      "args": ["mcp"]
    }
  }
}

Claude Desktop, Cursor, Windsurf, Gemini CLI, LM Studio and Cline take the same entry under "mcpServers", without "type". Codex (config.toml):

[mcp_servers.linkedin-jobs]
command = "C:\\Users\\you\\AppData\\Local\\Programs\\linkedin-jobs-mcp\\linkedin-jobs-mcp.exe"
args = ["mcp"]

Claude Code:

claude mcp add --scope user linkedin-jobs -- "C:\Users\you\AppData\Local\Programs\linkedin-jobs-mcp\linkedin-jobs-mcp.exe" mcp

Ollama, through mcp-client-for-ollama: save the mcpServers entry in a file and start ollmcp -j servers.json.

linkedin-jobs-mcp config prints all of these with the real path.

MCP over HTTP

Apps that connect by URL can use the HTTP server instead. Start linkedin-jobs-mcp serve (or npm run api) and add http://127.0.0.1:3000/mcp:

claude mcp add --transport http linkedin-jobs http://127.0.0.1:3000/mcp
{ "servers": { "linkedin-jobs": { "type": "http", "url": "http://127.0.0.1:3000/mcp" } } }

The server listens on this computer only and refuses requests that name another host, so web pages cannot reach it through DNS rebinding. HOST=0.0.0.0 makes it reachable from other machines, for example from a container; protect it yourself then.

Search options

Option

Values

keyword

Job title or keywords, e.g. data engineer

location

City, region or country, e.g. Berlin, Germany

city, country

Narrow the location

geoId

LinkedIn location id, skips the location lookup

dateSincePosted

past 24 hours, past week, past month

jobType

full time, part time, contract, temporary, volunteer, internship

remoteFilter

on site, remote, hybrid

under_10_applicants

Jobs with fewer than 10 applicants

limit

Number of jobs (default 10; 25 in the REST API)

sortBy

recent or relevant

page

Page of results, from 0; a page is limit jobs long

The REST API accepts the same options. LinkedIn's public search ignores salary, experience level and verified-job filters, so there are none.

Responses

A search returns:

{
  "success": true,
  "total_jobs": 1,
  "jobs": [
    {
      "position": "Data Engineer (m/w/d)",
      "company": "Example GmbH",
      "location": "Berlin, Berlin, Germany",
      "date": "2026-10-20",
      "agoTime": "4 days ago",
      "salary": "Not specified",
      "jobUrl": "https://www.linkedin.com/jobs/view/1234567890/",
      "companyLogo": "https://media.licdn.com/…"
    }
  ],
  "search_params": { "keyword": "data engineer", "location": "Berlin, Germany", "limit": "10" }
}

Job details return:

{
  "id": "1234567890",
  "position": "Data Engineer (m/w/d)",
  "company": "Example GmbH",
  "location": "Berlin, Berlin, Germany",
  "postedAgo": "3 weeks ago",
  "applicants": "Over 200 applicants",
  "salary": null,
  "seniority": "Mid-Senior level",
  "employmentType": "Full-time",
  "jobFunction": null,
  "industries": "Software Development",
  "criteria": { "Seniority level": "Mid-Senior level", "Employment type": "Full-time", "Industries": "Software Development" },
  "acceptingApplications": true,
  "description": "We are looking for a data engineer to join our platform team. …",
  "jobUrl": "https://www.linkedin.com/jobs/view/1234567890/"
}

A job LinkedIn no longer has returns { "id": "…", "removed": true }.

REST API

npm run api or linkedin-jobs-mcp serve starts it on http://127.0.0.1:3000.

Endpoint

What it does

POST /search

Search, with the options above as a JSON body; returns { "cached", "total", "jobs" }

GET /job/:id, GET /job?url=<link>

One job's details; 404 when LinkedIn no longer has it, 400 for an invalid id or link

POST /mcp

MCP over Streamable HTTP

GET /health

{ "ok": true }

Library

const { query, getJobDetails } = require("linkedin-jobs-mcp");

const jobs = await query({ keyword: "data engineer", location: "Berlin, Germany", limit: "10" });
const job = await getJobDetails("https://www.linkedin.com/jobs/view/1234567890/");

Configuration

Set these in the environment or in a .env file in the folder you start it from.

Variable

Default

What it sets

PORT

3000

Port of the REST API and MCP over HTTP

HOST

127.0.0.1

Address the server listens on

LINKEDIN_REQUEST_TIMEOUT_MS

15000

Timeout of one request to LinkedIn

LINKEDIN_CACHE_TTL_MS

3600000

How long search results stay cached

LINKEDIN_DETAIL_MIN_INTERVAL_MS

1500

Minimum gap between two job-page requests

LINKEDIN_DETAIL_CACHE_TTL_MS

21600000

How long job details stay cached

LINKEDIN_USER_AGENT

User agent for job-page requests

API_RATE_LIMIT_WINDOW_MS

60000

Rate-limit window of the REST API

API_RATE_LIMIT_MAX

60

Requests per window and address

Build the Windows app

On Windows with Node.js 20 or newer:

npm install
npm run build:win     # dist/linkedin-jobs-mcp.exe and its SHA-256

The build bundles the code with esbuild and injects it into a copy of node.exe (a Node.js single executable application). Pushing a tag such as v1.2.0 builds the app on GitHub Actions and attaches it to a release.

Tests

npm test                              # job pages, settings files, the MCP server and the HTTP API
cd radar && python -m pytest          # Ghost Job Radar

Both run offline.

Repository layout

Path

What it is

index.js

LinkedIn search and job details

server.js, api.js

MCP server (stdio and HTTP) and REST API

app.js, clients.js, radar.js

The app: commands, client setup, starting the radar

radar/

Ghost Job Radar (Python): dashboard, scoring, research report and notes, browser extension

scripts/build-win.js

Builds the Windows app

test/

Tests of the Node part

Responsible use

The tools read public job pages slowly and cache what they read, for personal job searching and research. Automated access can conflict with LinkedIn's User Agreement, so keep the volume low and use it at your own risk.

License

PolyForm Noncommercial 1.0.0: free for personal, research and other non-commercial use. For commercial use, ask for permission.

Srinjoy Ghosh (@GhoshSrinjoy, ghoshsrinjoy97@gmail.com)

Available Tools

3 tools
check_ghost_jobA

Grade a job posting with Ghost Job Radar: how likely it is to be a ghost job (not really open), your chance against the competition, and the facts behind the grade. Needs the radar running (linkedin-jobs-mcp radar)

NameRequiredDescriptionDefault
jobYesJob link (LinkedIn, the employer's site or a job board) or the pasted ad text
companyNoCompany name, when the job is pasted text
with_newsNoAlso check company news (slower)

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It discloses the radar prerequisite and summarizes the outputs, but it does not state whether the operation is read-only, what happens on failure, or any rate/latency constraints beyond the schema's with_news note.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the action and outputs, with the prerequisite appended without excess. It does not waste space restating schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description should convey return values; it does at a high level by naming ghost likelihood, competition chance, and supporting facts. Combined with full schema coverage and the radar prerequisite, it is mostly complete, though it omits failure and availability details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents job, company, and with_news. The description adds no parameter-level meaning beyond saying it grades a job posting, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb, "Grade," and resource, "job posting," and names the distinct outputs: ghost-job likelihood, competition chance, and supporting facts. This clearly differentiates it by function from the sibling detail and search tools, even without naming them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a prerequisite that the radar must be running and implies the tool is for ghost-job assessment. However, it does not explicitly say when to choose it over get_linkedin_job_details or search_linkedin_jobs, nor when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_linkedin_job_detailsA

Get one LinkedIn job's full description, criteria (seniority, employment type, industries), posted time and the applicant count shown on the public job page

NameRequiredDescriptionDefault
jobYesLinkedIn job id (e.g. '1234567890') or job URL

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does usefully disclose the return payload (criteria fields, posted time, applicant count as shown publicly). It says nothing about failure behavior for an invalid or expired job id, whether the applicant count can be absent, scoping to public page data, or any auth/rate constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single front-loaded sentence with no filler, and the enumerated return fields are the most valuable part. The nested parenthetical and the trailing 'shown on the public job page' make it slightly dense but not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter read lookup with no output schema, the description adequately covers what comes back, which is the main thing an agent needs. The remaining gap is error/edge-case behavior for unresolvable job identifiers, a minor omission given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is a single required 'job' parameter and schema coverage is 100%, with the schema itself documenting that it accepts a job id or a job URL. The description adds no extra meaning such as URL formats accepted or whether a slug-only URL works, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Get') and enumerates the resource precisely: one job's full description, criteria (seniority, employment type, industries), posted time, and applicant count. The word 'one' plus 'full description' implicitly contrasts with search_linkedin_jobs, but no sibling is named explicitly, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the drill-down call after search_linkedin_jobs returns job ids, but the description never states when to use it, when not to, or why to prefer it over check_ghost_job. No prerequisites or alternate paths are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_linkedin_jobsA

Find open jobs on LinkedIn by keyword and location, newest first. Read-only: it reads LinkedIn's public job search without signing in, spaces its requests out and keeps each search for an hour, so repeating a search answers at once. Returns JSON with total_jobs and jobs, each with position, company, location, date, agoTime, salary (when LinkedIn shows one), jobUrl and companyLogo; on failure, such as LinkedIn limiting requests, success is false with an error. LinkedIn serves 10 jobs per request, so every 10 jobs asked for add about a second. Use get_linkedin_job_details on a jobUrl for the full description and applicant count, and check_ghost_job to see whether a posting is really open.

NameRequiredDescriptionDefault
cityNoCity to search in; when given, it is searched instead of location, e.g. 'Munich'
pageNoWhich page of results, from '0'. A page is limit jobs long: page '1' with limit '10' returns jobs 11 to 200
geoIdNoLinkedIn's numeric location id, e.g. '103644278' for the United States. Use it when a place name finds the wrong location
limitNoHow many jobs to return, as a number in a string, e.g. '25'10
sortByNo'recent' for newest first or 'relevant' for LinkedIn's best matches firstrecent
countryNoCountry to search in when location is left out, e.g. 'Germany'
jobTypeNoOnly this type of employment. Leave out for all types
keywordNoJob title, skill or company, e.g. 'data engineer'. Leave out to list all jobs in the location
locationNoCity, region or country, e.g. 'Berlin, Germany'. Leave out to search worldwide
remoteFilterNoOnly this workplace type. Leave out for all
dateSincePostedNoOnly jobs posted within this period ('24hr' and 'today' mean the past 24 hours). Leave out for any date
under_10_applicantsNoOnly jobs that fewer than 10 people have applied to so far

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations supplied, the description carries the full burden and does so: read-only, no sign-in required, request spacing, one-hour per-search caching, the 10-jobs-per-request latency cost, and the failure mode (success false plus error when LinkedIn rate-limits). It even documents the response fields despite no output schema existing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Structure is front-loaded: purpose first, then behavioral traits, then sibling routing. The long second sentence uses semicolons and colons densely but every clause carries distinct operational information, and nothing is repeated from the schema or title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter, zero-required, mutation-free tool with no annotations and no output schema, the description supplies the return shape, failure behavior, latency model, caching semantics, and next-step tools. An agent has everything needed to call it correctly and to interpret a result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3 and the schema already documents city, geoId, page/limit, and the enum filters. The description still adds genuinely useful meaning beyond the schema by explaining that LinkedIn serves results in batches of 10 and that each batch costs roughly a second, which informs how to set limit and page.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line names a specific verb and resource ("Find open jobs on LinkedIn") and pins the default ordering ("newest first"). It is immediately distinguishable from the two siblings, which are named later with their distinct roles.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It routes the agent explicitly: use get_linkedin_job_details on a returned jobUrl for descriptions/applicant counts, and check_ghost_job to verify a posting is real. That is clear alternate-tool guidance. It stops short of stating when not to use this tool at all (e.g., non-job searches), so it is short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev1.3.3
    • Changedsearch_linkedin_jobs24 fields changed
      • removedInput schema / properties / city / default
        Removed value: -""
      • changedInput schema / properties / city / description
        Previous value: -"Optional city to refine location (e.g., 'Berlin')"New value: +"City to search in; when given, it is searched instead of location, e.g. 'Munich'"
      • removedInput schema / properties / country / default
        Removed value: -""
      • changedInput schema / properties / country / description
        Previous value: -"Optional country to refine location (e.g., 'Germany')"New value: +"Country to search in when location is left out, e.g. 'Germany'"
      • removedInput schema / properties / dateSincePosted / default
        Removed value: -""
      • changedInput schema / properties / dateSincePosted / description
        Previous value: -"Date range for job posting"New value: +"Only jobs posted within this period ('24hr' and 'today' mean the past 24 hours). Leave out for any date"
      • changedInput schema / properties / dateSincePosted / enum
        Previous value: -[
        -  "past month",
        -  "past week",
        -  "past 24 hours",
        -  "24hr",
        -  "today"
        -]New value: +[
        +  "past 24 hours",
        +  "past week",
        +  "past month",
        +  "24hr",
        +  "today"
        +]
      • removedInput schema / properties / experienceLevel
        Removed value: -{
        -  "default": "",
        -  "description": "Experience level required",
        -  "enum": [
        -    "internship",
        -    "entry level",
        -    "associate",
        -    "senior",
        -    "director",
        -    "executive"
        -  ],
        -  "type": "string"
        -}
      • removedInput schema / properties / geoId / default
        Removed value: -""
      • changedInput schema / properties / geoId / description
        Previous value: -"Optional LinkedIn geoId to bypass location guessing (e.g., '103644278')"New value: +"LinkedIn's numeric location id, e.g. '103644278' for the United States. Use it when a place name finds the wrong location"
      • removedInput schema / properties / has_verification
        Removed value: -{
        -  "default": false,
        -  "description": "Filter for verified jobs only",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / jobType / default
        Removed value: -""
      • changedInput schema / properties / jobType / description
        Previous value: -"Type of employment"New value: +"Only this type of employment. Leave out for all types"
      • removedInput schema / properties / keyword / default
        Removed value: -""
      • changedInput schema / properties / keyword / description
        Previous value: -"Job search keyword (e.g., 'software engineer')"New value: +"Job title, skill or company, e.g. 'data engineer'. Leave out to list all jobs in the location"
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum number of jobs to return"New value: +"How many jobs to return, as a number in a string, e.g. '25'"
      • removedInput schema / properties / location / default
        Removed value: -""
      • changedInput schema / properties / location / description
        Previous value: -"Location to search for jobs (e.g., 'Berlin, Germany')"New value: +"City, region or country, e.g. 'Berlin, Germany'. Leave out to search worldwide"
      • changedInput schema / properties / page / description
        Previous value: -"Page number (0-based)"New value: +"Which page of results, from '0'. A page is limit jobs long: page '1' with limit '10' returns jobs 11 to 20"
      • removedInput schema / properties / remoteFilter / default
        Removed value: -""
      • changedInput schema / properties / remoteFilter / description
        Previous value: -"Remote work preference"New value: +"Only this workplace type. Leave out for all"
      • removedInput schema / properties / salary
        Removed value: -{
        -  "default": "",
        -  "description": "Minimum salary",
        -  "enum": [
        -    "40000",
        -    "60000",
        -    "80000",
        -    "100000",
        -    "120000"
        -  ],
        -  "type": "string"
        -}
      • changedInput schema / properties / sortBy / description
        Previous value: -"Sort results by"New value: +"'recent' for newest first or 'relevant' for LinkedIn's best matches first"
      • changedInput schema / properties / under_10_applicants / description
        Previous value: -"Filter for jobs with under 10 applicants"New value: +"Only jobs that fewer than 10 people have applied to so far"
  2. 3 tool updatesv1.3.0
    • First observedcheck_ghost_job
    • First observedget_linkedin_job_details
    • First observedsearch_linkedin_jobs

TDQS

A4/5.0

Scored across 3 tools

Disambiguation5/5

Each tool maps to a distinct step in a job-hunting workflow: search a list, fetch one posting's full details, and grade a posting for ghost-job likelihood. The descriptions explicitly cross-reference each other (use get_linkedin_job_details on a jobUrl, check_ghost_job for openness), leaving no realistic path for misselection.

Naming Consistency5/5

All three names use the same snake_case verb_noun pattern: search_linkedin_jobs, get_linkedin_job_details, check_ghost_job. Object naming is consistent (linkedin_job / job) and the verbs accurately signal the action.

Tool Count4/5

Three tools cover the entire stated scope with no redundancy, which is defensible for a narrow, single-domain server. It sits at the lean edge of the scale, so users needing richer filtering must rely on the search tool's parameters alone.

Completeness4/5

The search → inspect → validate loop is fully closed, with salary, applicant count, and ghost-job grading all reachable. Minor gaps remain: no company-based lookup, no way to enumerate more than what a keyword search returns, and check_ghost_job hard-depends on a separately running local radar process.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables job search and scraping across multiple job boards (LinkedIn, Indeed, Glassdoor, etc.) with advanced filtering, directly from Claude Desktop or other MCP clients.
    6
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Searches LinkedIn for job posts, filters out non-vacancies and out-of-market roles, and provides a local dashboard to triage and rate the remaining openings.
    1
    ISC
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables natural-language job search and aggregation from multiple recruitment websites with zero configuration, providing filtered results and standardized output for AI assistants.
    51 npm
    ISC
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables automated job searching from multiple boards, filtering matches against saved criteria, deduplicating seen postings, and tracking application statuses. Runs locally and integrates with Claude Desktop for natural-language queries and updates.
    -