job-radar

job-radar

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.

Category
访问服务器

README

<div align="center">

<img src="icon.png" alt="" width="140" />

Linkedin Posts Job Radar

Find real job openings on LinkedIn without the noise

MCP Server TypeScript Playwright React Express Vite Tailwind CSS SQLite License: ISC

</div>


Ask your AI assistant to search LinkedIn. Linkedin Posts Job Radar scrapes the results, throws away everything that isn't an employer hiring in a market you care about, and gives you a dashboard to sort what's left into Ok, Maybe and Not interested.

Everything stays on your machine. No accounts, no servers, no data leaving your laptop.

The Linkedin Posts Job Radar dashboard, filtered to posts that quote pay


Why

Search LinkedIn for "Senior Data Scientist" and you get open roles mixed in with people announcing they're available, course ads, newsletter roundups, and the same staffing-agency repost twenty times over — most of it in countries you can't work in.

Linkedin Posts Job Radar screens each post before it's saved, so you triage a short list instead of wading through hundreds:

Harvest complete: 9 new posts added, 3 duplicates skipped,
12 rejected as outside allowed markets,
18 rejected as non-vacancy or agency posts

Install

You'll need Node.js 18+ and an MCP client such as Claude Code, Claude Desktop, or Cursor. Chromium downloads itself on first use.

Quickest: no clone

Point your client straight at the repo — npm fetches and builds it for you.

<details open> <summary><b>Claude Code</b></summary>

claude mcp add job-radar -- npx -y github:MaryemeBay/linkedin-posts-job-radar

</details>

<details> <summary><b>Claude Desktop</b> — <code>claude_desktop_config.json</code></summary>

{
  "mcpServers": {
    "job-radar": {
      "command": "npx",
      "args": ["-y", "github:MaryemeBay/linkedin-posts-job-radar"]
    }
  }
}

</details>

<details> <summary><b>Cursor</b> — <code>mcp.json</code></summary>

{
  "mcpServers": {
    "job-radar": {
      "command": "npx",
      "args": ["-y", "github:MaryemeBay/linkedin-posts-job-radar"]
    }
  }
}

</details>

The first start takes a couple of minutes while it builds and fetches Chromium; later starts are immediate.

Changing the screening rules needs the source, so clone if you want to tune which markets are allowed.

Clone, to change the rules

git clone https://github.com/MaryemeBay/linkedin-posts-job-radar.git
cd linkedin-posts-job-radar
npm run setup
npm run build

Register it with the absolute path to where you cloned it:

claude mcp add job-radar -- node /absolute/path/to/linkedin-posts-job-radar/build/main.js

For Claude Desktop or Cursor use the JSON above, with "command": "node" and "args": ["/absolute/path/.../build/main.js"].

As a bundle

npm run bundle produces a .mcpb file that clients supporting MCP bundles can install directly, with no Node tooling needed on the installing machine.

Set your markets

Open src/intake/market-policy.ts and list the places you'd actually take a job:

export const ALLOWED_COUNTRIES = [
  'France',
  'United Kingdom',
  'Remote (Europe)',
  'Remote (Worldwide)',
]

Only needed if you cloned. Run npm run build after editing — anything outside this list never reaches your database.


Use it

Talk to your assistant in plain language:

"Log into my LinkedIn account" A browser window opens. Log in once — the session is saved locally, so you won't be asked again.

"Search LinkedIn for Senior Data Scientist roles in London" Harvests the results and reports what it kept and what it screened out.

"Open the dashboard" Opens localhost:7391. Rate posts Ok / Maybe / Not interested.

"Show me everything I marked Ok that quotes a salary" Filters the dashboard from the conversation.

"Delete everything I marked Not interested"

The dashboard

Rate a post and its accent rail takes on that colour, so a long list stays readable at a glance. A "Not interested" card dims until you hover it. Clicking a rating a post already has clears it, so a mis-click needs one more click rather than a fourth button.

Applied is tracked separately — the verdict is what you think of the role, Applied is whether you acted on it.

Every post shows the country and any pay it quotes, both pulled out of the post text automatically.

<details> <summary><b>Table view</b> — edit and sort every field</summary>

Table view </details>

<details> <summary><b>Dark theme</b> — follows your OS by default, toggle in the corner</summary>

Dark theme </details>


What gets thrown away

Three gates, applied as posts arrive:

Gate Rejects
Relevance Posts with no sign of an open role — commentary, roundups, course ads
Author "Open to work" posts, and staffing-agency reposts
Market Roles outside your allowed countries

Relevance looks for hiring intent broadly, because plenty of real listings never say "hiring" — Lead Data Analyst opportunity at HelloFresh in London is a job post.

Author catches agencies two ways: wording like our client, on behalf of, C2C or Outside IR35, and titles like Recruitment Consultant or Executive Recruiter. Titles that exist on both sides — plain "Recruiter", "Talent Acquisition" — never reject on their own, and Corporate Recruiter is treated as in-house. An employer's own recruiter is exactly who you want to hear from.

Market accepts a post that names any allowed country. Mentioning an unwanted one isn't disqualifying — a Paris role that mentions visa rules for applicants elsewhere is still a Paris role. Posts with no detectable location are kept, since plenty of real listings don't state one.

Want contract roles? umbrella, Outside IR35 and C2C are treated as agency signals. Remove them from AGENCY_BODY in src/intake/relevance.ts to let contract work through.

Location detection

Recognises around 105 countries by name and by city, in English, French, German, Spanish and Portuguese, plus code lists like Remote EU (CZ/EE/FI/PL/ES/SE).

An explicit location line wins outright. When a post says 📍 Location: London, UK or Lieu : Paris, that line decides — so a post headed 📍 Islamabad, Pakistan that mentions London further down is correctly an Islamabad role, not a London one.

Pay detection

Each currency figure is classified by pay period and kept only if the amount makes sense for that period. That's what tells a real salary apart from a $2,000 welcome bonus or €12.50/day meal vouchers, and what keeps $100/hour while rejecting a bare $100.

Handles $128,470 - $208,770, 96k€, £75k-£115k, 110000USD-135000USD, 60,4K GBP/yr (French decimal comma), £830/day and $7,000/month.


Your data

What Where
Harvested posts ~/.linkedin-mcp/resources/linkedin.db
LinkedIn session ~/.linkedin-mcp/auth.json

Both live outside this repo and are never committed. Nothing is sent anywhere — the dashboard is a local server, and the only network traffic is Playwright talking to LinkedIn as your own browser would.

To wipe everything: rm -rf ~/.linkedin-mcp


Tools your assistant can call

Tool What it does
linkedin_session Log in, check the session, clear stored credentials
harvest_posts Search and store posts, reporting what was screened out
vacancies Read, count or delete — filter by keyword, market, pay, verdict, applied
dashboard_filters Change the dashboard's filters from the conversation
open_dashboard / close_dashboard Start and stop the dashboard

Commands

npm run viewer      # dashboard on :7391, without going through your assistant
npm run rederive    # recompute country and pay for stored posts
npm run seed        # import posts from a JSON export
npm run build       # rebuild after changing any rule
npm run typecheck

npm run rederive -- --all re-infers every post rather than only the blanks — run it after editing a detector.

To move the dashboard off port 7391:

JOB_RADAR_PORT=9090 npm run viewer

When your MCP client launches the server, put JOB_RADAR_PORT in that server's env block so open_dashboard uses the same port.


Code layout

src/
  main.ts               MCP server: tool schemas and dispatch
  commands/             One module per tool
  linkedin/
    session/            Playwright login, credential storage
    harvest/            Search crawler, URL building, post parsing
  intake/               The screening pipeline
    ingest.ts             Applies every gate, then writes
    relevance.ts          Vacancy vs commentary vs agency
    market-policy.ts      Country allowlist  <- edit this
    location.ts           Country inference
    compensation.ts       Pay parsing
  store/                SQLite handle, schema, queries
  viewer/               Dashboard API and React app
  platform/             Paths, persisted filter state
scripts/                Maintenance scripts

<details> <summary><b>A note for contributors: the database is held in memory</b></summary>

The store is sql.js, which keeps the whole database in memory and writes it back wholesale. With two processes running — the MCP server and the dashboard — each would otherwise serve a stale snapshot and overwrite the other's rows on its next save.

store/connection.ts fingerprints the file by size and modification time, reloads when another process has written, and records its own saves so it doesn't reload needlessly. Removing that check silently loses data. </details>


Attribution

Derived from LinkedIn-Posts-Hunter-MCP-Server by Kevin Weitgenant, used under the ISC licence.

This fork reorganises the codebase around the intake pipeline, adds the relevance, agency and market screening above, adds country and pay inference, replaces a saved flag with the triage verdict, renames the MCP tools, rebuilds the dashboard, and fixes cross-process database clobbering.

Licensed ISC — see LICENSE, which carries both copyright lines.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选