Openings
Server Details
Search jobs on verified employer job boards. Every link is the employer's own posting.
- Status
- Healthy
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-06-18
- URL
- Repository
- abhay-avagama/hiring-agent
- GitHub Stars
- 0
- Server Listing
- openings
TDQS
Scored across 7 tools
Each tool has a clear role: search_jobs is resume-free filtering, recommend_jobs is resume-based ranking, analyze_job_fit is a single-job deep dive, and optimize_resume is revision. The only mild overlap is between recommend_jobs and analyze_job_fit, but their descriptions distinguish list-level ranking from role-level analysis.
All tool names follow the same snake_case verb_noun convention: analyze_job_fit, get_job, get_job_coverage, optimize_resume, prepare_job_search, recommend_jobs, search_jobs. The pattern is predictable and makes the action and target clear across the set.
Seven tools is well-scoped for a job-search and resume-optimization server. Each tool covers a distinct stage of the workflow without redundancy or unnecessary bulk.
The tool surface covers the core workflow well: prepare the index, search, get details, rank by resume, analyze fit, and optimize a resume. A minor gap is the lack of any candidate-side workflow for saving, tracking, or managing applications beyond receiving the application URL.
Available Tools
7 toolsanalyze_job_fitAnalyze fit for one jobARead-onlyIdempotentInspect
Explain how one job fits a resume: which requirements the resume supports, which it does not, the screening risks, and what to prepare for an interview, each tied to text quoted from the resume rather than inferred. Use it after search_jobs or recommend_jobs has produced a job id and the candidate wants depth on a single role instead of a list. The resume is parsed in memory for this call and never stored.
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | Yes | Stable job id from search_jobs or recommend_jobs | |
| intent | No | What the candidate is actually looking for, stated explicitly rather than guessed from the resume. Every field is optional; the ones given narrow the result, and the excluded* fields remove roles the candidate does not want to see. | |
| resume | Yes | The resume itself, passed inline. It is parsed in memory for this call and never written to disk, logged, or sent anywhere else. |
Output Schema
| Name | Required | Description |
|---|---|---|
| job | Yes | The job that was analyzed |
| scores | No | |
| profile | No | What was read from the resume; not stored |
| supported | No | Requirements the resume supports, each with the quoted evidence |
| assessment | Yes | The overall read, with its reasoning |
| unsupported | No | Requirements the resume does not evidence at all |
| screeningRisks | No | What is likely to stop this application early |
| partiallySupported | No | Requirements with partial evidence, and what is missing |
| interviewPreparationGaps | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds high-value behavioral context: it emphasizes that analysis must be grounded in quoted resume text ('rather than inferred'), and it explicitly states the resume is parsed in memory and never stored, which is critical for privacy-sensitive operations. This goes beyond annotations and builds trust, though it could also mention error behavior or return format.
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 tightly written and front-loaded: the first sentence captures the core purpose and constraints, then immediately gives usage context, and ends with a critical privacy note. Every sentence contributes value without redundancy, making efficient use of the reader's attention.
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?
The description is complete for its complexity: it explains what output to expect (requirements supported/not, risks, interview prep), ties to sibling workflow, and addresses privacy. The output schema exists, so return format details are omitted appropriately. Minor gaps include not mentioning potential errors or handling of invalid job ids, but the provided info suffices for correct invocation.
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 coverage is 100%, with rich descriptions for all parameters, including jobId and resume. The description adds little parameter-specific detail beyond what the schema provides, but it reiterates that the resume is passed inline and references the job id provenance. It does not introduce new syntax or clarify edge cases not already in schema, so the baseline 3 is appropriate.
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 specific verb ('analyze') and resource ('one job') with a precise scope: it evaluates requirements, screening risks, and interview prep, and specifies that claims must be quoted from the resume, not inferred. It distinguishes itself from list-returning siblings like search_jobs and recommend_jobs by describing the depth and use case, so an agent can immediately differentiate it.
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 explicitly states when to use it: 'after search_jobs or recommend_jobs has produced a job id and the candidate wants depth on a single role instead of a list.' It implies not to use it for listing jobs and mentions the sibling tool relationship. This direct, actionable guidance leaves no ambiguity about the tool's role in the workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_jobGet job detailsARead-onlyIdempotentInspect
Get the full description and application URL for a job returned by recommend_jobs or search_jobs.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Stable job id returned by search_jobs or recommend_jobs (jobId is accepted too) |
Output Schema
| Name | Required | Description |
|---|---|---|
| job | Yes | The full job, including its description and the employer's application URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds value by specifying the exact content returned (full description and application URL), which is not implicit in the annotations or the simple parameter schema. It also clarifies the input provenance (jobs from recommend_jobs or search_jobs), enriching behavioral context beyond annotations.
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?
A single, information-dense sentence that front-loads the action and outcome, with zero filler. It efficiently communicates the tool's purpose, input source, and return content without unnecessary elaboration.
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?
The tool is simple (one parameter, no nested objects), annotations cover safety and idempotency, and an output schema exists to describe return values. The description fully covers when to use it and what it returns, leaving no critical information missing for an agent to call it correctly.
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 100% and the id parameter is well documented ('Stable job id returned by search_jobs or recommend_jobs (jobId is accepted too)'). The tool description does not add any additional parameter semantics beyond what the schema provides. Since the schema handles parameter meaning, a baseline score of 3 is appropriate.
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 states a specific verb ('Get') and a precise resource ('full description and application URL for a job'), and it explicitly ties the input to jobs returned by recommend_jobs or search_jobs. This clearly distinguishes it from siblings like analyze_job_fit or get_job_coverage, which serve different purposes.
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 clearly indicates when to use the tool: after obtaining a job from recommend_jobs or search_jobs. It doesn't explicitly exclude alternatives, but the context is sufficient for an agent to infer that this is the go-to for fetching job details, while other siblings handle analysis or optimization. No explicit 'when not to use' is given, but the purpose is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_job_coverageCheck job coverageARead-onlyIdempotentInspect
Report how many live roles the index holds for each country and how recently they were posted. Use it to set expectations before asking a candidate for anything, or to judge whether preparation is worth running; use search_jobs instead to see the roles themselves. Reads the index already on hand and never crawls.
| Name | Required | Description | Default |
|---|---|---|---|
| countries | Yes | Two-letter codes to report coverage for, such as IN or US |
Output Schema
| Name | Required | Description |
|---|---|---|
| countries | No | Per-country live and recent role counts |
| snapshotUpdatedAt | No | When the index this answer came from was last refreshed |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds valuable behavioral context beyond those hints: it reads an index already on hand and never crawls, which sets cost and side-effect expectations. No contradiction with annotations.
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?
Three concise sentences cover the core function, usage context, an alternative tool, and a behavioral caveat. No filler or redundant repetition of schema or annotation information.
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?
For a one-parameter, read-only reporting tool with an output schema, the description supplies use cases, sibling differentiation, and a clear no-crawl guarantee. Everything an agent needs to decide when to call it and what it will do is present.
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 100%: the single countries parameter is fully documented with type, pattern, min/max, uniqueness, and an example. The description adds little beyond tying 'each country' to that parameter, so baseline 3 is appropriate.
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 states a specific verb ('Report'), resource ('live roles the index holds'), grouping ('for each country'), and a recency dimension ('how recently they were posted'). It also differentiates from the sibling search_jobs, so an agent can tell at a glance what this tool does and what it does not.
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?
It explicitly tells the agent when to use the tool ('set expectations before asking a candidate', 'judge whether preparation is worth running') and names the alternative ('use search_jobs instead to see the roles themselves'). This is direct when/when-not guidance, not implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
optimize_resumeOptimize a resume for one jobARead-onlyIdempotentInspect
Propose a revision of a resume for one specific job, as suggestions, a unified diff or revised markdown. It rewrites emphasis and wording only: the original is never overwritten and no claim the resume does not already support is added. Use it after analyze_job_fit has shown which gaps are real. The resume is parsed in memory for this call and never stored.
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | Yes | Stable job id from search_jobs or recommend_jobs | |
| output | Yes | suggestions lists changes to consider; unified_diff shows them as a patch; revised_markdown returns the rewritten resume | |
| resume | Yes | The resume itself, passed inline. It is parsed in memory for this call and never written to disk, logged, or sent anywhere else. |
Output Schema
| Name | Required | Description |
|---|---|---|
| job | No | The job the revision targets |
| gaps | No | What the resume cannot honestly claim, and so was left alone |
| output | Yes | Which form was produced |
| content | No | The diff or rewritten resume, when that form was asked for |
| profile | No | |
| suggestions | Yes | Each proposed change with the evidence behind it |
| originalOverwritten | Yes | Always false: the candidate's resume is never modified in place |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive. The description reinforces this by stating the original is never overwritten and adds crucial context: the resume is parsed in memory, never stored, and no new claims are added, which is important for trust and privacy.
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?
Concise, two sentences, front-loads the main action and alternative outputs, then clarifies scope and privacy. Every sentence provides valuable information without fluff.
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 the output schema exists, the description doesn't need to explain return values, but it describes the input format, security, and usage context. It is complete for an agent to call correctly: what, when, and constraints are all clear.
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?
The schema covers all parameters with clear descriptions (e.g., jobId, output enum, resume structure). The description adds some context by explaining that output formats are for consideration vs. patch vs. revised markdown, but this is beyond schema. Since coverage is 100%, baseline is 3; the description adds marginal value but not fully necessary.
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 it proposes a revision of a resume for a specific job, and specifies three output formats. It distinguishes itself from siblings like analyze_job_fit by focusing on revision rather than analysis, and from search_jobs/recommend_jobs by being a post-analysis action.
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?
Explicitly states to use after analyze_job_fit has shown real gaps, giving clear sequencing. It also mentions that it only rewrites emphasis and wording, not adding unsupported claims, which guides when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_job_searchPrepare job searchAIdempotentInspect
Download and refresh the local job index so searches have data to read. The first call fetches the shared index of every verified source (thousands of employers); later calls crawl only missing or stale sources, at most 25 per call, returning a continuation token until nextAction reports ready. Call it when a search says setup is needed, not before every search, and not at all on the hosted server, where the index is already prepared and this returns ready at once. Uses the network and writes job data under the local Openings data directory; it never reads, writes or transmits a resume.
| Name | Required | Description | Default |
|---|---|---|---|
| countries | Yes | Two-letter codes whose sources should be prepared, such as IN or US | |
| continuation | No | Opaque token from the previous call's result. Pass it back to prepare the next batch of at most 25 sources; omit it to start |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| crawl | No | What this batch crawled: selected, succeeded, and the sources that failed |
| status | Yes | ready means searches can run now; partial means sources are still missing |
| sources | No | How many sources are in the catalog, indexed, fresh, stale, missing and pending |
| coverage | Yes | |
| nextAction | Yes | call_again means pass continuation back for the next batch; retry_later means the network refused and waiting is the fix |
| continuation | No | Token for the next batch; present only when nextAction is call_again |
| networkAttempted | No | Whether this call actually reached out to employer boards |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as not read-only, but the description adds genuinely new behavioral context: it uses the network, writes under the local Openings data directory, and never reads, writes, or transmits a resume. It also discloses the batch limit of at most 25 sources per call and the hosted-server shortcut, which are not visible in annotations. These details align with idempotentHint and destructiveHint without contradiction.
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?
Every sentence carries weight: core purpose, first-call vs continuation behavior, usage timing, environment exception, and side effects/privacy. The most decision-relevant information is front-loaded, and there is no filler or repetition of schema content.
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?
The description covers the full invocation flow including first fetch, continuation tokens, batch size, readiness signaling, the hosted-server exception, and side effects. It also includes a privacy guarantee. With an output schema present, return values need no further elaboration, and nothing an agent needs to call this tool correctly is missing.
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 coverage is 100%, so the baseline is 3; the schema already documents both parameters. The description adds semantic value for 'continuation' by explaining it is returned until nextAction reports ready and that at most 25 sources are prepared per call, going beyond the schema's generic 'Opaque token from the previous call's result' line. Countries receives no extra detail beyond the schema, but the existing schema description is already adequate.
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 opens with the concrete verb phrase 'Download and refresh the local job index', clearly stating the resource and intended effect. It further distinguishes this tool from consumers like search_jobs by framing it as the setup step that gives searches data to read. No ambiguity remains about what the tool does.
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 gives an explicit call condition: 'when a search says setup is needed', plus clear negations: 'not before every search' and 'not at all on the hosted server'. It also explains first-call versus continuation-call usage, so an agent knows exactly when to invoke and when to skip.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recommend_jobsRecommend jobs from a resumeARead-onlyIdempotentInspect
Rank jobs against a resume, quoting the evidence for each match, and separate direct matches from hidden title-family and stretch roles. Use it when the candidate has chosen to share a resume and wants matching; prefer search_jobs for plain filtering, which needs no resume and answers faster. The resume is parsed in memory for this call and never stored. When matches are thin it may refresh the local snapshot once, per the refresh policy.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many ranked matches to return | |
| intent | Yes | What the candidate is actually looking for, stated explicitly rather than guessed from the resume. Every field is optional; the ones given narrow the result, and the excluded* fields remove roles the candidate does not want to see. | |
| resume | Yes | The resume itself, passed inline. It is parsed in memory for this call and never written to disk, logged, or sent anywhere else. | |
| ranking | No | How matches are scored and how weak a match may be before it is dropped | |
| refresh | No | Whether this call may crawl employer boards before ranking. Crawling costs seconds; the default only does it when the result would otherwise be thin |
Output Schema
| Name | Required | Description |
|---|---|---|
| window | No | Which age windows were walked and which one the results came from |
| matches | Yes | Ranked matches, each carrying the job, its scores, and the resume text that supports them |
| outcome | Yes | widened means the date window had to open up to find anything; no_matches means say so rather than searching again silently |
| profile | No | What was read from the resume. It is returned so claims can be checked, and is not stored |
| ranking | No | |
| refresh | No | Whether this call crawled, and what it found |
| coverage | No | |
| snapshot | No | Age and size of the index these matches came from |
| nextMoves | No | What to try next when the result is thin; relay these instead of inventing advice |
| shortfall | No | Present when fewer matches came back than asked for |
| assumptions | No | Anything inferred rather than stated; worth repeating to the candidate |
| explanation | Yes | Why the result looks the way it does, in words meant for the candidate |
| exploration | No | Direct, hidden title-family and stretch groupings |
| filteredOut | No | Counts by reason, with a small sample, for roles the intent excluded |
| nextActions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already signal readOnly, openWorld, idempotent, and non-destructive behavior. The description adds meaningful behavioral context beyond those hints: the resume is parsed in memory and never stored, and the tool may refresh the local snapshot once when matches are thin. This is useful extra transparency about side effects and data handling, though the description could have been even more explicit about output behavior if the output schema were absent.
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 three dense sentences with no filler. It front-loads the core behavior and output style first, then gives usage guidance, then notes privacy and refresh behavior. Every sentence earns its place.
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 the rich input schema, the presence of an output schema, and annotations covering safety and open-world behavior, the description is complete for an agent to select and invoke the tool correctly. It covers what the tool does, when to use it, the no-resume alternative, and the two non-obvious runtime behaviors (in-memory resume handling and snapshot refresh).
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 100%, so the input schema already documents every parameter in detail, including nested fields like intent, ranking, and refresh. The description adds high-level context about the resume being parsed in memory, but it does not need to repeat parameter-level semantics. Baseline 3 is appropriate because the schema carries the heavy lifting.
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 opens with a specific verb and resource: 'Rank jobs against a resume, quoting the evidence for each match,' and it names the distinctive output categories (direct matches, hidden title-family, stretch roles). It also differentiates from search_jobs by noting that recommend_jobs requires a resume while search_jobs does plain filtering without one.
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 explicitly states when to use this tool ('Use it when the candidate has chosen to share a resume and wants matching') and when to prefer the alternative ('prefer search_jobs for plain filtering, which needs no resume and answers faster'). This gives an agent clear selection criteria rather than leaving the choice to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_jobsSearch jobsARead-onlyIdempotentInspect
Search jobs immediately from role, country, location and optional stated experience. No resume required. Newest first; automatically widens 7, 14, 30 days then all dates until 5 matches. For another page reuse the same filters and returned window.daysUsed as maxAgeDays, with pagination.nextOffset. Resume-based ranking is optional via recommend_jobs.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many jobs to return in this page | |
| query | No | Words to match in job title or company | |
| offset | No | Where the page starts. Use pagination.nextOffset from the previous result rather than counting by hand | |
| remote | No | True for remote-only; false for non-remote-only | |
| country | No | Two-letter country code for job eligibility, such as IN or DE | |
| location | No | Case-insensitive location substring | |
| maxAgeDays | No | Omit to widen 7/14/30/all until 5 matches. Explicit positive values exclude undated roles; 0 includes all dates. | |
| experienceYears | No | Years of experience to compare with the posting's stated min/max range; not a qualification or fit verdict. | |
| includeUnknownExperience | No | With experienceYears, also keep roles without a stated range, clearly unknown rather than matched. |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | Yes | Matches, newest first |
| window | Yes | The age window the results came from, and whether it had to widen. Say which window was used |
| guidance | No | How to present these results honestly; meant for the assistant, not the candidate |
| pagination | Yes | offset, limit, total and nextOffset. nextOffset is null on the last page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnly, idempotent, non-destructive), the description discloses rich behavioral traits: 'Newest first' ordering, the non-obvious auto-widening algorithm (7/14/30 days then all dates until 5 matches), and the pagination window semantics. The widening behavior is surprising and would mislead an agent without this disclosure.
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?
Five short sentences, each earning its place: purpose, differentiator, behavior, pagination, and sibling routing. The core purpose is front-loaded in the first sentence, and the whole description is compact (~65 words) despite covering a 9-parameter tool with complex behavior.
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?
For a complex tool with 9 parameters, an output schema (so return values are already documented), and safety annotations, the description covers everything an agent needs: purpose, differentiation, ordering, widening behavior, and the full pagination flow. No critical operational detail is missing.
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 coverage is 100%, so the baseline is 3. The description adds genuine cross-parameter meaning beyond individual schema entries: it connects the response's window.daysUsed to the maxAgeDays input parameter and links pagination.nextOffset to the offset parameter, which no single schema field description conveys.
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?
States a specific verb and resource ('Search jobs') plus the search dimensions (role, country, location, optional experience). It also differentiates from siblings: 'No resume required' and 'Resume-based ranking is optional via recommend_jobs' explicitly separate it from the resume-driven recommend_jobs tool, and 'immediately' separates it from preparation-oriented siblings like prepare_job_search.
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?
Gives explicit usage context: use this for immediate search without a resume, and names the alternative (recommend_jobs) for resume-based ranking. It also provides concrete operational guidance for pagination: reuse filters with window.daysUsed as maxAgeDays and pagination.nextOffset, which tells the agent exactly how to continue paging.
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.
7 tool updates
- Changed
analyze_job_fit15 fields changed- added
Input schema / properties / intent / descriptionAdded value: +"What the candidate is actually looking for, stated explicitly rather than guessed from the resume. Every field is optional; the ones given narrow the result, and the excluded* fields remove roles the candidate does not want to see." - added
Input schema / properties / intent / properties / countries / descriptionAdded value: +"Two-letter codes the candidate may work in, such as IN or US. This is eligibility to work, not where the office is" - added
Input schema / properties / intent / properties / excludedCountries / descriptionAdded value: +"Two-letter codes to drop even when a role is otherwise eligible" - added
Input schema / properties / intent / properties / excludedLocations / descriptionAdded value: +"Cities or regions to drop, matched like locations" - added
Input schema / properties / intent / properties / excludedRoles / descriptionAdded value: +"Role titles to drop, matched like roles" - added
Input schema / properties / intent / properties / excludedTerms / descriptionAdded value: +"Words that disqualify a role, matched as whole words in the title, such as \"intern\" or \"sales\"" - added
Input schema / properties / intent / properties / locations / descriptionAdded value: +"Cities or regions to keep, matched as case-insensitive substrings of the job's location, such as \"Bengaluru\" or \"Delhi NCR\"" - added
Input schema / properties / intent / properties / remote / descriptionAdded value: +"True to keep only remote roles, false to drop them; omit to keep both" - added
Input schema / properties / intent / properties / requiredSkills / descriptionAdded value: +"Skills a role must state to be kept, such as \"kubernetes\". Each is matched as a whole word" - added
Input schema / properties / intent / properties / roles / descriptionAdded value: +"Role titles the candidate is looking for, in their own words, such as \"backend engineer\" or \"data analyst\". Matched against the job title" - added
Input schema / properties / intent / properties / seniority / descriptionAdded value: +"Levels to keep, in the posting's own vocabulary, such as \"senior\" or \"lead\". Not a years-of-experience filter: use experienceYears in search_jobs for that" - added
Input schema / properties / jobId / descriptionAdded value: +"Stable job id from search_jobs or recommend_jobs" - added
Input schema / properties / resume / descriptionAdded value: +"The resume itself, passed inline. It is parsed in memory for this call and never written to disk, logged, or sent anywhere else." - added
Input schema / properties / resume / properties / format / descriptionAdded value: +"How content is encoded: plain text, markdown, or base64 of a PDF or DOCX file" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "assessment": { + "additionalProperties": true, + "description": "The overall read, with its reasoning", + "type": "object" + }, + "interviewPreparationGaps": { + "items": { + "type": "string" + }, + "type": "array" + }, + "job": { + "additionalProperties": true, + "description": "The job that was analyzed", + "properties": { + "age": { + "description": "Bucketed posting age; undated means the board gave no date, not that the role is fresh", + "enum": [ + "new", + "older", + "stale", + "undated" + ], + "type": "string" + }, + "company": { + "type": "string" + }, + "eligibleCountries": { + "description": "Two-letter codes the role is open to", + "items": { + "type": "string" + }, + "type": "array" + }, + "experience": { + "additionalProperties": true, + "description": "Years the posting itself states as { min, max }; null when it states none, absent when the description was not read", + "type": [ + "object", + "null" + ] + }, + "id": { + "description": "Stable id to pass to get_job, analyze_job_fit or optimize_resume", + "type": "string" + }, + "location": { + "type": "string" + }, + "postedDaysAgo": { + "type": "number" + }, + "remote": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "description": "When the board says the role was posted or last updated; absent when the board states none", + "type": "string" + }, + "url": { + "description": "The employer's own posting, which is where an application is made", + "type": "string" + }, + "workMode": { + "enum": [ + "remote", + "hybrid", + "onsite", + "unknown" + ], + "type": "string" + } + }, + "type": "object" + }, + "partiallySupported": { + "description": "Requirements with partial evidence, and what is missing", + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "profile": { + "additionalProperties": true, + "description": "What was read from the resume; not stored", + "type": "object" + }, + "scores": { + "additionalProperties": true, + "type": "object" + }, + "screeningRisks": { + "description": "What is likely to stop this application early", + "items": { + "type": "string" + }, + "type": "array" + }, + "supported": { + "description": "Requirements the resume supports, each with the quoted evidence", + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "unsupported": { + "description": "Requirements the resume does not evidence at all", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "job", + "assessment" + ], + "type": "object" +}
- Changed
get_job1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "job": { + "additionalProperties": true, + "description": "The full job, including its description and the employer's application URL", + "properties": { + "age": { + "description": "Bucketed posting age; undated means the board gave no date, not that the role is fresh", + "enum": [ + "new", + "older", + "stale", + "undated" + ], + "type": "string" + }, + "company": { + "type": "string" + }, + "eligibleCountries": { + "description": "Two-letter codes the role is open to", + "items": { + "type": "string" + }, + "type": "array" + }, + "experience": { + "additionalProperties": true, + "description": "Years the posting itself states as { min, max }; null when it states none, absent when the description was not read", + "type": [ + "object", + "null" + ] + }, + "id": { + "description": "Stable id to pass to get_job, analyze_job_fit or optimize_resume", + "type": "string" + }, + "location": { + "type": "string" + }, + "postedDaysAgo": { + "type": "number" + }, + "remote": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "description": "When the board says the role was posted or last updated; absent when the board states none", + "type": "string" + }, + "url": { + "description": "The employer's own posting, which is where an application is made", + "type": "string" + }, + "workMode": { + "enum": [ + "remote", + "hybrid", + "onsite", + "unknown" + ], + "type": "string" + } + }, + "type": "object" + } + }, + "required": [ + "job" + ], + "type": "object" +}
- Changed
get_job_coverage2 fields changed- added
Input schema / properties / countries / descriptionAdded value: +"Two-letter codes to report coverage for, such as IN or US" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "countries": { + "description": "Per-country live and recent role counts", + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "snapshotUpdatedAt": { + "description": "When the index this answer came from was last refreshed", + "type": "string" + } + }, + "type": "object" +}
- Changed
optimize_resume5 fields changed- added
Input schema / properties / jobId / descriptionAdded value: +"Stable job id from search_jobs or recommend_jobs" - added
Input schema / properties / output / descriptionAdded value: +"suggestions lists changes to consider; unified_diff shows them as a patch; revised_markdown returns the rewritten resume" - added
Input schema / properties / resume / descriptionAdded value: +"The resume itself, passed inline. It is parsed in memory for this call and never written to disk, logged, or sent anywhere else." - added
Input schema / properties / resume / properties / format / descriptionAdded value: +"How content is encoded: plain text, markdown, or base64 of a PDF or DOCX file" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "content": { + "description": "The diff or rewritten resume, when that form was asked for", + "type": "string" + }, + "gaps": { + "description": "What the resume cannot honestly claim, and so was left alone", + "items": { + "type": "string" + }, + "type": "array" + }, + "job": { + "additionalProperties": true, + "description": "The job the revision targets", + "properties": { + "age": { + "description": "Bucketed posting age; undated means the board gave no date, not that the role is fresh", + "enum": [ + "new", + "older", + "stale", + "undated" + ], + "type": "string" + }, + "company": { + "type": "string" + }, + "eligibleCountries": { + "description": "Two-letter codes the role is open to", + "items": { + "type": "string" + }, + "type": "array" + }, + "experience": { + "additionalProperties": true, + "description": "Years the posting itself states as { min, max }; null when it states none, absent when the description was not read", + "type": [ + "object", + "null" + ] + }, + "id": { + "description": "Stable id to pass to get_job, analyze_job_fit or optimize_resume", + "type": "string" + }, + "location": { + "type": "string" + }, + "postedDaysAgo": { + "type": "number" + }, + "remote": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "description": "When the board says the role was posted or last updated; absent when the board states none", + "type": "string" + }, + "url": { + "description": "The employer's own posting, which is where an application is made", + "type": "string" + }, + "workMode": { + "enum": [ + "remote", + "hybrid", + "onsite", + "unknown" + ], + "type": "string" + } + }, + "type": "object" + }, + "originalOverwritten": { + "description": "Always false: the candidate's resume is never modified in place", + "type": "boolean" + }, + "output": { + "description": "Which form was produced", + "enum": [ + "suggestions", + "unified_diff", + "revised_markdown" + ], + "type": "string" + }, + "profile": { + "additionalProperties": true, + "type": "object" + }, + "suggestions": { + "description": "Each proposed change with the evidence behind it", + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "output", + "suggestions", + "originalOverwritten" + ], + "type": "object" +}
- Changed
prepare_job_search3 fields changed- changed
Input schema / properties / continuation / descriptionPrevious value: -"Opaque token returned by the preceding preparation batch"New value: +"Opaque token from the previous call's result. Pass it back to prepare the next batch of at most 25 sources; omit it to start" - added
Input schema / properties / countries / descriptionAdded value: +"Two-letter codes whose sources should be prepared, such as IN or US" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "continuation": { + "description": "Token for the next batch; present only when nextAction is call_again", + "type": "string" + }, + "coverage": { + "additionalProperties": true, + "properties": { + "countries": { + "description": "Per-country live and recent role counts", + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "snapshotUpdatedAt": { + "description": "When the index this answer came from was last refreshed", + "type": "string" + } + }, + "type": "object" + }, + "crawl": { + "additionalProperties": true, + "description": "What this batch crawled: selected, succeeded, and the sources that failed", + "type": "object" + }, + "networkAttempted": { + "description": "Whether this call actually reached out to employer boards", + "type": "boolean" + }, + "nextAction": { + "description": "call_again means pass continuation back for the next batch; retry_later means the network refused and waiting is the fix", + "enum": [ + "ready", + "call_again", + "retry_later" + ], + "type": "string" + }, + "note": { + "type": "string" + }, + "sources": { + "additionalProperties": true, + "description": "How many sources are in the catalog, indexed, fresh, stale, missing and pending", + "type": "object" + }, + "status": { + "description": "ready means searches can run now; partial means sources are still missing", + "enum": [ + "ready", + "partial" + ], + "type": "string" + } + }, + "required": [ + "status", + "nextAction", + "coverage" + ], + "type": "object" +}
- Changed
recommend_jobs21 fields changed- added
Input schema / properties / intent / descriptionAdded value: +"What the candidate is actually looking for, stated explicitly rather than guessed from the resume. Every field is optional; the ones given narrow the result, and the excluded* fields remove roles the candidate does not want to see." - added
Input schema / properties / intent / properties / countries / descriptionAdded value: +"Two-letter codes the candidate may work in, such as IN or US. This is eligibility to work, not where the office is" - added
Input schema / properties / intent / properties / excludedCountries / descriptionAdded value: +"Two-letter codes to drop even when a role is otherwise eligible" - added
Input schema / properties / intent / properties / excludedLocations / descriptionAdded value: +"Cities or regions to drop, matched like locations" - added
Input schema / properties / intent / properties / excludedRoles / descriptionAdded value: +"Role titles to drop, matched like roles" - added
Input schema / properties / intent / properties / excludedTerms / descriptionAdded value: +"Words that disqualify a role, matched as whole words in the title, such as \"intern\" or \"sales\"" - added
Input schema / properties / intent / properties / locations / descriptionAdded value: +"Cities or regions to keep, matched as case-insensitive substrings of the job's location, such as \"Bengaluru\" or \"Delhi NCR\"" - added
Input schema / properties / intent / properties / remote / descriptionAdded value: +"True to keep only remote roles, false to drop them; omit to keep both" - added
Input schema / properties / intent / properties / requiredSkills / descriptionAdded value: +"Skills a role must state to be kept, such as \"kubernetes\". Each is matched as a whole word" - added
Input schema / properties / intent / properties / roles / descriptionAdded value: +"Role titles the candidate is looking for, in their own words, such as \"backend engineer\" or \"data analyst\". Matched against the job title" - added
Input schema / properties / intent / properties / seniority / descriptionAdded value: +"Levels to keep, in the posting's own vocabulary, such as \"senior\" or \"lead\". Not a years-of-experience filter: use experienceYears in search_jobs for that" - added
Input schema / properties / limit / descriptionAdded value: +"How many ranked matches to return" - added
Input schema / properties / ranking / descriptionAdded value: +"How matches are scored and how weak a match may be before it is dropped" - added
Input schema / properties / ranking / properties / mode / descriptionAdded value: +"evidence scores a match only on requirements the resume text supports; keyword scores on term overlap alone" - added
Input schema / properties / refresh / descriptionAdded value: +"Whether this call may crawl employer boards before ranking. Crawling costs seconds; the default only does it when the result would otherwise be thin" - added
Input schema / properties / refresh / properties / minimumMatches / descriptionAdded value: +"With auto, the match count below which a refresh is worth the wait" - added
Input schema / properties / refresh / properties / policy / descriptionAdded value: +"auto crawls once only when matches are thin and the snapshot is stale; never keeps the snapshot as it is; always crawls first" - added
Input schema / properties / refresh / properties / staleDays / descriptionAdded value: +"With auto, how old the snapshot must be before a refresh is considered" - added
Input schema / properties / resume / descriptionAdded value: +"The resume itself, passed inline. It is parsed in memory for this call and never written to disk, logged, or sent anywhere else." - added
Input schema / properties / resume / properties / format / descriptionAdded value: +"How content is encoded: plain text, markdown, or base64 of a PDF or DOCX file" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "assumptions": { + "description": "Anything inferred rather than stated; worth repeating to the candidate", + "items": { + "type": "string" + }, + "type": "array" + }, + "coverage": { + "additionalProperties": true, + "properties": { + "countries": { + "description": "Per-country live and recent role counts", + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "snapshotUpdatedAt": { + "description": "When the index this answer came from was last refreshed", + "type": "string" + } + }, + "type": "object" + }, + "explanation": { + "description": "Why the result looks the way it does, in words meant for the candidate", + "type": "string" + }, + "exploration": { + "additionalProperties": true, + "description": "Direct, hidden title-family and stretch groupings", + "type": "object" + }, + "filteredOut": { + "additionalProperties": true, + "description": "Counts by reason, with a small sample, for roles the intent excluded", + "type": "object" + }, + "matches": { + "description": "Ranked matches, each carrying the job, its scores, and the resume text that supports them", + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + }, + "nextActions": { + "items": { + "type": "string" + }, + "type": "array" + }, + "nextMoves": { + "description": "What to try next when the result is thin; relay these instead of inventing advice", + "items": { + "type": "string" + }, + "type": "array" + }, + "outcome": { + "description": "widened means the date window had to open up to find anything; no_matches means say so rather than searching again silently", + "enum": [ + "matches", + "widened", + "no_matches" + ], + "type": "string" + }, + "profile": { + "additionalProperties": true, + "description": "What was read from the resume. It is returned so claims can be checked, and is not stored", + "type": "object" + }, + "ranking": { + "additionalProperties": true, + "type": "object" + }, + "refresh": { + "additionalProperties": true, + "description": "Whether this call crawled, and what it found", + "type": "object" + }, + "shortfall": { + "additionalProperties": true, + "description": "Present when fewer matches came back than asked for", + "type": "object" + }, + "snapshot": { + "additionalProperties": true, + "description": "Age and size of the index these matches came from", + "type": "object" + }, + "window": { + "additionalProperties": true, + "description": "Which age windows were walked and which one the results came from", + "type": "object" + } + }, + "required": [ + "outcome", + "matches", + "explanation" + ], + "type": "object" +}
- Changed
search_jobs3 fields changed- added
Input schema / properties / limit / descriptionAdded value: +"How many jobs to return in this page" - added
Input schema / properties / offset / descriptionAdded value: +"Where the page starts. Use pagination.nextOffset from the previous result rather than counting by hand" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": true, + "properties": { + "guidance": { + "description": "How to present these results honestly; meant for the assistant, not the candidate", + "type": "string" + }, + "jobs": { + "description": "Matches, newest first", + "items": { + "additionalProperties": true, + "description": "One matching job", + "properties": { + "age": { + "description": "Bucketed posting age; undated means the board gave no date, not that the role is fresh", + "enum": [ + "new", + "older", + "stale", + "undated" + ], + "type": "string" + }, + "company": { + "type": "string" + }, + "eligibleCountries": { + "description": "Two-letter codes the role is open to", + "items": { + "type": "string" + }, + "type": "array" + }, + "experience": { + "additionalProperties": true, + "description": "Years the posting itself states as { min, max }; null when it states none, absent when the description was not read", + "type": [ + "object", + "null" + ] + }, + "id": { + "description": "Stable id to pass to get_job, analyze_job_fit or optimize_resume", + "type": "string" + }, + "location": { + "type": "string" + }, + "postedDaysAgo": { + "type": "number" + }, + "remote": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "description": "When the board says the role was posted or last updated; absent when the board states none", + "type": "string" + }, + "url": { + "description": "The employer's own posting, which is where an application is made", + "type": "string" + }, + "workMode": { + "enum": [ + "remote", + "hybrid", + "onsite", + "unknown" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "pagination": { + "additionalProperties": true, + "description": "offset, limit, total and nextOffset. nextOffset is null on the last page", + "type": "object" + }, + "window": { + "additionalProperties": true, + "description": "The age window the results came from, and whether it had to widen. Say which window was used", + "type": "object" + } + }, + "required": [ + "jobs", + "window", + "pagination" + ], + "type": "object" +}
7 tool updates
- First observed
analyze_job_fit - First observed
get_job - First observed
get_job_coverage - First observed
optimize_resume - First observed
prepare_job_search - First observed
recommend_jobs - First observed
search_jobs
Publisher details
- Operator
- Avagama Consulting · Publisher source
- Operator website
- https://www.avagama.co · Publisher source
- Vendor relationship
- Not applicable
- Documentation
- Not applicable
- Trust center
- Not applicable
- Restrictions
- Not applicable
Related MCP Connectors
Verified job postings from employer ATS boards, employer hiring signals and pay statistics.
1Verified job search: every listing confirmed live and accepting applicants within the last 72h.
Search a live index of millions of open jobs from employer career sites and 100+ ATS platforms.
Read job postings live from employer career sites across 10 applicant tracking systems.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceVerified job search: every listing is opened and confirmed live and accepting applicants within the last 72 hours, and re-verified on a rolling clock, so agents can recommend jobs without ghost-job or dead-link risk. Read-only, no auth.MIT

JobsPipe MCP Serverofficial
FlicenseNot gradedqualityBmaintenanceEnables searching live, normalized job postings from 30+ ATS feeds and job boards, with tools for job search, source listing, pricing plans, and Upwork jobs.-- AlicenseAqualityDmaintenanceSearch current remote / work-from-home jobs by category, region, perk, or company — with ready-to-apply links.5MIT
- AlicenseNot gradedqualityCmaintenanceEnables job search and application management across employers' own hiring systems, with tools to find jobs, verify openings, check application support, and track application status—usable without a key for basic searches.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.