offer-quest mcp
This MCP server exposes a single live job-search tool that returns LLM-ready Markdown listings from Indeed and LinkedIn.
One exposed tool (
search_jobs): passjob_titlesand requiredlocationsto get a structured Markdown report of current postings and internships.Search multiple roles/locations at once: comma-separated titles and cities (e.g.
AI Engineer Intern, Python Developer Intern/Delhi, Remote).Choose a country: defaults to
India.Tune result count:
max_resultsper source per combo (schema says 1–10, default 5).Filter by recency:
hours_oldlimits postings to the last N hours (default 48, max 168).Returns one string field (
result): the formatted job report for the LLM to read.
Note: the schema only defines search_jobs; the README also describes resume-ranking (rank_jobs) and ATS keyword-gap (ats_keywords) tools, which are not present in this schema.
OfferQuest MCP Server
A fast, secure, LLM-friendly Model Context Protocol (MCP) server for job and internship hunting. It searches live postings on Indeed and LinkedIn, ranks them against your resume, and tells you which keywords your resume is missing for a specific job.
Live endpoint (Streamable HTTP): https://dexter3b-offerquest-mcp.hf.space/gradio_api/mcp/
Tools
Tool | What it does |
| Live job/internship search across Indeed + LinkedIn. Returns a deduplicated Markdown report, newest first. |
| Searches fresh jobs for your target roles and scores each one out of 100 against your resume. |
| ATS keyword-gap report for one job vs. your resume: missing must-haves, nice-to-haves, and what you already cover. |
fetch_and_format_jobs
Argument | Description |
| Up to 3 comma-separated roles, e.g. |
| Up to 3 comma-separated cities, e.g. |
|
|
| Jobs per site per search, 1–15 (default 5) |
| Only postings from the last N hours, 1–168 (default 48) |
| Fetch full LinkedIn descriptions (slower, higher rate-limit risk) |
Each result includes title, company, location, job type, salary (when disclosed), posted date, direct links, a description snippet and a Job ID you can pass to ats_keywords.
rank_jobs
Argument | Description |
| Plain-text resume (20,000 characters max) |
| Up to 3 comma-separated roles you are targeting |
| Up to 3 comma-separated cities |
| Same list as above |
| How many top matches to return, 1–15 (default 8) |
| Max posting age in hours, 1–168 (default 72) |
| Better scoring, but slower |
For every match you get: a score out of 100, matched skills, missing skills, red flags (senior title, years of experience required, no description available), links, and a Job ID. The report also lists the skills most often missing from your resume across the top results.
How the score works (pure Python, no ML dependencies):
Component | Weight |
Skill overlap with the posting (76-skill curated taxonomy with aliases) | 45 |
Text similarity between resume and posting (TF-IDF cosine) | 25 |
Title match against your target roles | 20 |
Freshness of the posting | 10 |
Seniority penalty (senior/lead titles, "N+ years" requirements) | up to −40 |
Postings without a usable description are scored mostly on title and flagged as such.
ats_keywords
Argument | Description |
| Plain-text resume (20,000 characters max) |
| Either a Job ID from earlier results (valid ~1 hour) or the full pasted job description |
Returns keyword coverage %, missing must-haves, missing nice-to-haves, skills already covered, recurring terms in the posting that are absent from your resume, and placement tips.
Typical workflow
rank_jobswith your resume and target roles → get the best matches with Job IDs.ats_keywordswith your resume and a Job ID → see exactly what to add before applying.fetch_and_format_jobsfor a broader, unranked look at what's out there.
Related MCP server: LinkedIn MCP Server
Security
Scraped text is untrusted. Postings are stripped of HTML, URLs and invisible characters, scanned for prompt-injection phrases (which are removed and flagged), and fenced inside
<untrusted_posting>tags. Tool output reminds the LLM to treat it as data only.No SSRF. No tool fetches user-supplied URLs, and only links on
linkedin.com/indeed.comare ever returned.Resumes stay in memory. They are never logged, cached or echoed back.
Bounded inputs. All inputs are length-capped, and regexes are bounded to avoid ReDoS.
Abuse controls. Per-client and global rate limits, limited concurrent searches, a scrape deadline, and a TTL cache.
Masked errors. Internal errors and stack traces are never returned to the caller.
Limits
Limit | Value |
Titles / locations per call | 3 / 3 (max 6 combinations) |
Search rate limit | 10 per 10 min per client, 60 per 10 min globally |
| 40 calls per 10 min per client |
Concurrent searches | 3 |
Scrape deadline | 55 seconds |
Search cache | 15 minutes |
Job ID validity | ~1 hour |
Installation
Requires Python 3.10+.
git clone <this-repo>
cd <this-repo>
python3 -m venv myenv
source myenv/bin/activate
pip install -r requirements.txtCore dependencies: gradio[mcp], python-jobspy, pandas.
Usage
python3 app.pyThe Gradio UI opens at
http://127.0.0.1:7860with one tab per tool: Search, Rank, ATS Keywords.MCP clients connect to
http://127.0.0.1:7860/gradio_api/mcp/.
Connecting an MCP client
For clients that support remote Streamable HTTP servers, use the hosted endpoint:
https://dexter3b-offerquest-mcp.hf.space/gradio_api/mcp/For clients that only support stdio, bridge it with mcp-remote:
{
"mcpServers": {
"offerquest": {
"command": "npx",
"args": ["mcp-remote", "https://dexter3b-offerquest-mcp.hf.space/gradio_api/mcp/"]
}
}
}Deployment
The server is stateless and needs no headless browser, so it runs well on Hugging Face Spaces, Docker, Render or a plain VPS.
Notes for Hugging Face Spaces (Gradio SDK):
Start the app with
demo.launch(...). Don't run your ownuvicornon port 7860, because the Space already owns it.Launch with
ssr_mode=False. With SSR on, Gradio's Node proxy answers unknown paths with the UI, so custom routes such as/.well-known/glama.jsonnever reach Python.Custom routes are registered through
launch(app_kwargs={"routes": [...]})so they are matched before Gradio's own routes.
Job sites may rate-limit or block cloud IP addresses. When that happens, the tool returns partial results with a warning instead of failing.
Disclaimer
Job data comes from third-party sites via JobSpy. Availability and accuracy depend on those sites. Scores and keyword reports are guidance, not guarantees. Only add keywords for skills you genuinely have.
Available Tools
1 toolsearch_jobsB
Search for the latest jobs and internships and return them as a structured, LLM-ready Markdown report. Supports multiple titles and locations.
Args: job_titles: The roles you are looking for (e.g., 'Python Developer Intern'). locations: Cities or locations (e.g., 'Delhi, Remote'). country: The target country for the search. max_results: Number of jobs to fetch per source per combo (1-10). hours_old: Only show jobs posted within this many hours (default 48, max 168).
| Name | Required | Description | Default |
|---|---|---|---|
| job_titles | Yes | ||
| locations | Yes | ||
| country | No | India | |
| max_results | No | ||
| hours_old | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavioral traits. It mentions the output format ('structured, LLM-ready Markdown report') and time filtering ('hours_old'), but lacks details on rate limits, authentication needs, data sources, pagination, error handling, or what 'latest' means operationally. This leaves significant gaps for a tool with 5 parameters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized and front-loaded, starting with the core purpose. The 'Args:' section is well-structured but slightly verbose; every sentence adds value, though it could be more streamlined. No redundant information is present, making it efficient for understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 5 parameters with 0% schema coverage and no annotations, the description does a fair job explaining inputs and output format. However, it lacks details on behavioral aspects like rate limits or error handling. The presence of an output schema means return values don't need explanation, but overall completeness is adequate with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds meaning by explaining each parameter's purpose with examples (e.g., 'job_titles: The roles you are looking for'), default values, and constraints (e.g., 'max_results: 1-10', 'hours_old: default 48, max 168'). This clarifies semantics beyond the bare schema, though it doesn't cover all nuances like format specifics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches for 'latest jobs and internships' and returns them as a 'structured, LLM-ready Markdown report.' It specifies the verb (search), resource (jobs/internships), and output format. However, with no sibling tools mentioned, there's no opportunity to differentiate from alternatives, preventing a perfect score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus other methods or tools. It mentions supporting 'multiple titles and locations' but doesn't specify prerequisites, exclusions, or alternative approaches. Without siblings, it could implicitly be the go-to for job searches, but explicit usage context is missing.
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 tool update
v0.1.0- First observed
search_jobs
TDQS
Scored across 1 tool
With only one tool, there is no possibility of ambiguity or overlap between tools. The single tool 'search_jobs' has a clearly defined and distinct purpose focused on job searching.
The single tool name 'search_jobs' follows a clear verb_noun pattern, and with only one tool, consistency is inherently perfect. There are no other tools to create inconsistency.
A single tool is too few for a server named 'offer-quest mcp', which implies a broader scope related to job offers or quests. This minimal toolset feels thin and incomplete for the apparent domain, limiting functionality to only searching without other operations like applying, tracking, or managing jobs.
The tool surface is severely incomplete for a job-related domain. While 'search_jobs' covers discovery, there are significant gaps such as creating, updating, or deleting job applications, managing profiles, or handling notifications, which are typical in job search workflows. This will likely cause agent failures when trying to perform full tasks.
Maintenance
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
MCP server for Firecrawl — web search, scraping, and biomedical/arXiv paper search.
Public MCP server for discovering open jobs. Search, filter, and get application links.
Related MCP Servers
- AlicenseAqualityDmaintenanceA production-ready Model Context Protocol server that enables language models to leverage AI-powered web scraping capabilities, offering tools for transforming webpages to markdown, extracting structured data, and executing AI-powered web searches.894 PyPI113MIT
- FlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables seamless interaction with LinkedIn for job applications, profile retrieval, feed browsing, and resume analysis through natural language commands.35-

Remote Jobs MCP Serverofficial
AlicenseAqualityFmaintenanceOfficial Model Context Protocol (MCP) server to search, filter, and retrieve live remote job listings from the Jobicy database in real-time. Works with Claude Code, Cursor, Cline, and custom AI agents.22MIT- AlicenseCqualityDmaintenanceAn MCP server that enables AI-assisted job search workflows including job discovery, application tracking, resume evaluation, and cover letter generation, with support for multiple job sources and scheduled scraping.8310 npm1AGPL 3.0