求职工具集

一个包含LinkedIn动态接口封装、文档转换工具和求职提示代理的集成工具集,用于实时职位搜索、简历优化和求职流程自动化。

  • by Komarala
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 Komarala/Mcp_job_search

使用说明

MCP Job Search — LinkedIn tools, Document utilities, and Prompt agents

This workspace includes two MCP servers (LinkedIn and Document tools) plus a set of ready‑to‑use job search prompt agents. It enables live LinkedIn discovery via a thin, dynamic wrapper and local resume/job‑doc utilities like Markdown→PDF and PDF→text.

Warning: The third‑party linkedin-api package uses undocumented LinkedIn endpoints and may violate LinkedIn’s Terms of Service. Prefer official APIs where possible and use at your own risk.

What’s included

  • src/linkedin_mcp.py — Thin client around linkedin_api.linkedin.Linkedin with:
    • list_methods(...) to discover callable methods with signatures/docs
    • call_method(...) to invoke any allowed public method dynamically
    • Convenience wrappers (e.g., search_jobs, get_job, get_profile) for backwards compatibility
  • src/linkedin_tools.py — MCP server exposing dynamic LinkedIn tools:
    • li_build_session() — ensure a LinkedIn session is authenticated
    • li_methods(include_private=False, prefix=None) — list available methods
    • li_call(method, args=None, posargs=None) — call any allowed method
  • src/doc_tools.py — MCP server “doc-tools” for resume/job docs with:
    • check_prereqs() — detect pandoc, xelatex (MiKTeX), wkhtmltopdf, pdftotext; returns { ok, tools, notes }
    • md_to_pdf(md_path, out_path?, method?, page?, margin_*) — reliable Markdown→PDF via pandoc-xelatex (preferred) or wkhtmltopdf
    • pdf_to_text(pdf_path, out_path?, layout=False) — extract text using pdfminer.six
  • .github/prompts/ — prompt agents for job search workflows:
    • AI_JobSearch_Aggregator.prompt.md — searches across sources, de‑duplicates, scores fit, and outputs a Job Digest (Markdown)
    • AI_CV_CoverLetter_Tailor.prompt.md — tailors a CV (Markdown) and crafts a customized cover letter from a job digest/JD
    • Recrutting_consultant.prompt.md — end‑to‑end AI Job Search Agent producing Top 5 matches, improvements, strategy, and outreach; prefers LinkedIn MCP when available

Requirements

  • Python ≥ 3.13 (per pyproject.toml)
  • Python packages (from requirements.txt):
    • mcp, mcp[cli], requests, linkedin-api, pdfminer.six>=20221105
  • Optional native tools for doc-tools (recommended on Windows):
    • Pandoc — winget install --id=JohnMacFarlane.Pandoc -e
    • MiKTeX (XeLaTeX) — winget install --id=MiKTeX.MiKTeX -e
    • wkhtmltopdf — winget install --id=wkhtmltopdf.wkhtmltopdf -e
    • Poppler (pdftotext) — optional; pdf_to_text uses pdfminer.six by default

Setup (Windows PowerShell)

You can use the helper src/env.ps1 to set environment variables for the current shell session.

# (Optional) Create and activate a virtual environment
python -m venv .venv
.\.venv\Scripts\Activate.ps1

# Install dependencies
pip install -r requirements.txt

# Configure LinkedIn credentials for this session
$env:LINKEDIN_EMAIL = "your-email@example.com"
$env:LINKEDIN_PASSWORD = "your-password"
# Alternatively, if you have a valid LI_AT cookie token
# $env:LINKEDIN_LI_AT = "<li_at_cookie_value>"

# Or source the helper (adjust values inside as needed)
./src/env.ps1

Notes

  • Use either LINKEDIN_EMAIL+LINKEDIN_PASSWORD or LINKEDIN_LI_AT (cookie). The current code prefers username/password by default.

Running the MCP servers

Both servers are simple FastMCP processes speaking over stdio. Run whichever you need.

# LinkedIn tools server
python .\src\linkedin_tools.py

# Document tools server (Markdown↔PDF, PDF→text)
python .\src\doc_tools.py

Tools exposed (LinkedIn)

  • li_build_session() — initialize and authenticate
    • Response: { "ok": true, "auth": "username_password" | "LI_AT" }
  • li_methods(include_private: bool = false, prefix?: string) — list callable methods
  • li_call(method: string, args?: object, posargs?: any[]) — dynamic invocation

Example tool requests (shape depends on your MCP client):

{
	"tool": "li_build_session",
	"params": {}
}
{
	"tool": "li_methods",
	"params": { "prefix": "search_" }
}
{
	"tool": "li_call",
	"params": {
		"method": "search_jobs",
		"args": { "keywords": "AI", "location_name": "Germany", "limit": 10 }
	}
}

Notes

  • Argument names must match the reported signatures. For example, search_jobs uses location_name (not location).
  • Private methods (names starting with _) are blocked.

Tools exposed (Document tools)

  • check_prereqs()
    • Returns availability of pandoc, xelatex, wkhtmltopdf, pdftotext and Windows‑friendly install tips.
    • Shape: { ok: boolean, tools: { .. }, notes: string[] }
  • md_to_pdf(md_path, out_path?, method = "pandoc-xelatex" | "wkhtmltopdf", page = "a4", margin_top = "0.7in", margin_bottom = "0.7in", margin_left = "1in", margin_right = "1in")
    • Prefers Pandoc + XeLaTeX for consistent typography; falls back to Pandoc default engine if XeLaTeX missing; or Pandoc→HTML→wkhtmltopdf.
    • Returns { ok, path, method, logs } with executed command logs.
  • pdf_to_text(pdf_path, out_path?, layout = false)
    • Uses pdfminer.six (pure Python). If not installed, raises a tool error with install hint.
    • Returns { ok, path, bytes, logs, layout }.

Example requests:

{ "tool": "check_prereqs", "params": {} }
{
	"tool": "md_to_pdf",
	"params": { "md_path": ".\\ATS\\Resume.md", "method": "pandoc-xelatex" }
}
{
	"tool": "pdf_to_text",
	"params": { "pdf_path": ".\\docs\\job-posting.pdf" }
}

Prompt agents (in .github/prompts/)

Use these with your MCP‑enabled IDE/agent runner to orchestrate the workflow end‑to‑end.

  • AI_JobSearch_Aggregator.prompt.md

    • Searches across configured sources (e.g., LinkedIn, Indeed, Xing, StepStone, company sites), applies filters, de‑duplicates, and produces a scored Markdown Job Digest with metadata (tools used, totals, timestamps).

    • Accepts profile and search parameters via variables; prefers platform tools (LinkedIn MCP) when available, falls back to web search.

    • Reads a job digest/JD and a base CV (Markdown) to output a perfectly aligned CV and a 250–300 word customized cover letter.

    • Emphasizes ATS keywords, quantified achievements, and company‑specific tone; keeps formatting export‑ready.

  • Recrutting_consultant.prompt.md

    • Acts as an AI Job Search Agent: returns Top 5 matches with Fit Scores, skill match, company insights, recommendations, tailored outreach and short cover letters per top match, plus a step‑by‑step application strategy.
    • If LinkedIn MCP access is provided, it must verify posting dates and open status before recommending.
    • Includes an instruction to optionally generate per‑job .prompt.md files for tailoring and to log non‑sensitive tool usage.

Example slash usage (from the aggregator file):

/AI_JobSearch_Aggregator: name=Hemanth Yadav location=Germany, Remote roles=Embedded Test Engineer,Data Engineer skills=Python,SQL,C++,Automation limit=20 postedWithinDays=21

Using the Python client directly (optional)

from src.linkedin_mcp import LinkedInClient

cli = LinkedInClient()
cli.search_jobs(keywords="AI", location="Germany", limit=5)

# Fully dynamic invocation
jobs = cli.call_method("search_jobs", args={"keywords": "AI", "location_name": "Germany", "limit": 5})
me = cli.call_method("get_profile", args={"public_id": "me"})

Troubleshooting

  • LinkedIn auth: Missing LINKEDIN_EMAIL/LINKEDIN_PASSWORD or LINKEDIN_LI_AT → set environment variables (see Setup).
  • LinkedIn auth changes or cookies may break login; try updating linkedin-api or switching auth mode.
  • Rate limiting/suspension risks exist; reduce request volume.
  • Document tools: If pandoc/xelatex/wkhtmltopdf are missing, run check_prereqs() for Windows‑friendly install tips; pdf_to_text needs pdfminer.six (listed in requirements.txt).

Legal and ToS

This project is for educational purposes. Interacting with LinkedIn via undocumented endpoints may violate their Terms of Service. You are responsible for compliance with all applicable terms and laws.

Security & Secrets

  • Never commit real passwords, OAuth client secrets, or cookie tokens. The file src/env.ps1 contains only placeholder values.
  • Set sensitive values per‑session (e.g., $env:LINKEDIN_EMAIL = "you@example.com") or use a secrets manager.
  • Rotate any credentials previously stored in plaintext.
  • Keep debug output minimal and avoid dumping large payloads.
  • Never commit real passwords, OAuth client secrets, or cookie tokens. The file src/env.ps1 contains only placeholder values.